|
本帖最后由 Gorgon_Meducer 于 2013-10-30 15:57 编辑
说在前面的话
这是之前做AtoM连线编程器时候的一个副产品,EzPort的驱动程序,用全状态机架构编写,
用起来也应该是蛮简单的。简单说明一下这个库的特点:
1、全状态机架构开发,非阻塞代码
2、硬件无关,库所依赖的IO口操作以及SPI的数据传输操作均通过“插入宏”的形式由外界
提供,无需修改源代码本身。插入宏通过app_cfg.h提供。
3、遵循ESSF 2.x 编码规范
目录结构
EzPort
|
- EzPort.h Ezport的接口头文件,用于向外界输出接口信
|
- EzPort.c EzPort的源文件 s
|
- app_cfg.h EzPort的配置文件,该文件自动包含了上一级的app_cfg.h所以,
用户并不需要直接修改该app_cfg.h,可以通过在文件夹外创建
一个app_cfg.h来完成对配置信息的传递
使用说明(readme.txt)
1、解压缩后将此文件夹下的所有文件放置到工程目录中
2、将EzPort.c加入到工程中参与编译
3、在readme.txt相同目录下的app_cfg.h中加入对EzPort的配置信息
4、使用的时候,包含readme.txt相同目录下的EzPort.h,例如:
#include "EzPort_driver\ezport.h"
5、具体有哪些接口可以使用,请参考EzPort文件夹下EzPort.h的内容
4、具体需要外部提供哪些支持,请参考编译时获得的错误提示。
相关下载
以下是接口头文件的内容,如果你只关心如何使用,那么应该专注于该头文件:
EzPort.h
- /***************************************************************************
- * Copyright(C)2009-2012 by Gorgon Meducer<Embedded_zhuoran@hotmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2 of the *
- * License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
- #ifndef __COMPONENT_EZPORT_H__
- #define __COMPONENT_EZPORT_H__
- /*============================ INCLUDES ======================================*/
- #include ".\app_cfg.h"
- #if USE_COMPONENT_EZPORT == ENABLED
- /*============================ MACROS ========================================*/
- /*============================ MACROFIED FUNCTIONS ===========================*/
- /*============================ TYPES =========================================*/
- /*============================ GLOBAL VARIABLES ==============================*/
- /*============================ LOCAL VARIABLES ===============================*/
- /*============================ PROTOTYPES ====================================*/
- /*! \note initialize EzPort
- * \param none
- * \return state-machine status
- */
- extern fsm_rt_t ezport_initialize( void );
- /*! \brief finalize ezport
- *! \param none
- *! \return fsm status
- */
- extern fsm_rt_t ezport_finalize(void);
- /*! \brief enable EzPort mode
- *! \param none
- *! \return state machine status
- */
- extern fsm_rt_t ezport_enable( void );
- /*! \brief disable ezport
- *! \param none
- *! \return fsm status
- */
- extern fsm_rt_t ezport_disable(void);
- /*! \brief erase chip
- *! \param none
- *! \return fsm status
- */
- extern fsm_rt_t ezport_chip_erase(void);
- /*! \brief read flash through Ezport
- *! \param wAddress target address
- *! \param pchStream data buffer
- *! \param hwSize buffer size
- *! \return fsm status
- */
- extern fsm_rt_t ezport_read(
- uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize);
- /*! \brief read flash through Ezport
- *! \param wAddress target address
- *! \param pchStream data buffer
- *! \param hwSize buffer size
- *! \return fsm status
- */
- extern fsm_rt_t ezport_write(
- uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize);
- /*! \brief verify flash through Ezport
- *! \param wAddress target address
- *! \param pchStream data buffer
- *! \param hwSize buffer size
- *! \return fsm status
- */
- extern fsm_rt_t ezport_verify(
- uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize);
- #endif
- #endif
- /* EOF */
复制代码 EzPort.c
- /***************************************************************************
- * Copyright(C)2009-2012 by Gorgon Meducer<Embedded_zhuoran@hotmail.com> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2 of the *
- * License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
- /*============================ INCLUDES ======================================*/
- #include ".\app_cfg.h"
- #if USE_COMPONENT_EZPORT == ENABLED
- /*============================ MACROS ========================================*/
- //! \ESP_STATUS register bit definition
- //! @{
- #define WIP 0 //!< Write in progress
- #define WEN 1 //!< Write Enabled
- #define BEDIS 2 //!< Bulk erase disabled
- #define FLEXRAM 3 //!< FlexRAM Mode
- #define WEF 6 //!< Write Error Flag
- #define FS 7 //!< Flash Security
- //! @}
- /*============================ MACROFIED FUNCTIONS ===========================*/
- //! \brief check macros for target device reset control
- #ifndef EZP_SET_RESET
- #error No defined macro EZP_SET_RESET for releasing target device reset pin.
- #endif
- #ifndef EZP_CLR_RESET
- #error No defined macro EZP_CLR_RESET for clearing target device reset pin.
- #endif
- //! \brief check macros for EZP_CS control
- #ifndef EZP_SET_CS
- #error No defined macro EZP_SET_CS() for setting EZP_CS pin.
- #endif
- #ifndef EZP_CLR_CS
- #error No defined macro EZP_CLR_CS() for clearing EZP_CS pin
- #endif
- //! \brief check macro for spi initialization
- #ifndef EZP_SPI_INIT
- #error No defined macro EZP_SPI_INIT() for spi initialization.
- #endif
- //! \brief check macro for spi data exchange
- #ifndef EZP_SPI_DATA_EXCHANGE
- #error No defined macro EZP_SPI_DATA_EXCHANGE(__OUTPUT, __INPUT, __LENGTH) for \
- spi data exchange.
- #endif
- //! \brief check macro for enabling spi
- #ifndef EZP_SPI_ENABLE
- #error No defined macro EZP_SPI_ENABLE for enabling spi interface
- #endif
- //! \brief check macro for disabling spi
- #ifndef EZP_SPI_DISABLE
- #error No defined macro EZP_SPI_DISABLE for disabling spi interface
- #endif
- #ifndef EZP_FLASH_SECTOR_SIZE
- #error No defined flash sector size : EZP_FLASH_SECTOR_SIZE
- #endif
- /*============================ TYPES =========================================*/
- //! \name EzPort Command
- //! @{
- enum {
- EZP_WREN = 0x06, //!< Enable write
- EZP_WRDI = 0x04, //!< Disable write
- EZP_RDSR = 0x05, //!< Read Status Register
- EZP_READ = 0x03, //!< Read Flash Data
- EZP_FAST_READ = 0x0B, //!< Fast-Read Flash Data
- EZP_SP = 0x02, //!< Program Flash Section
- EZP_SE = 0xD8, //!< Erase Flash Sector
- EZP_BE = 0xC7, //!< Erase Flash Bulk
- EZP_RESET = 0xB9, //!< Reset Target Chip
- EZP_WRFCCOB = 0xBA, //!< Write FCCOB Registers
- EZP_FAST_WRFCCOB = 0xBB, //!< Read FCCOB register at high speed
- EZP_WRFLEXRAM = 0xBC, //!< Write FlexRAM
- EZP_RDFLEXRAM = 0xBD, //!< Read FlexRAM
- EZP_FAST_RDFLEXRAM = 0xBE, //!< Read FlexRAM at high speed
- };
- //! @}
- /*============================ GLOBAL VARIABLES ==============================*/
- /*============================ LOCAL VARIABLES ===============================*/
- //! \brief command buffer
- NO_INIT static uint8_t s_chCMDBuffer[5];
- static bool s_bEzPortEnabled = false;
- static bool s_bChipErased = false;
- /*============================ PROTOTYPES ====================================*/
- static fsm_rt_t read_status(uint8_t *pchStatus);
- static fsm_rt_t check_status(bool bIgnoreFS);
- static fsm_rt_t write_cmd(uint8_t chCMD, bool bIgnoreFS);
- static fsm_rt_t send_command( uint8_t *pchOutput, uint_fast16_t hwOSize,
- uint8_t *pchInput, uint_fast16_t hwISize, uint8_t chCS);
- /*============================ IMPLEMENTATION ================================*/
- #define EZP_CMD_START 0
- #define EZP_CMD_WRITE 1
- #define EZP_CMD_READ 2
- #define EZP_CMD_FINALIZE 3
- #define EZP_CMD_RESET() do {s_chState = 0;} while(false)
- /*! \brief Function for issuing EzPort Command
- *! \param pchOutput output buffer
- *! \param hwOSize output buffer size
- *! \param pchInput input buffer
- *! \param hwISize input buffer size
- *! \param chCS CS control bits:
- *! BIT0 - disable assertion, BIT1 - disable negation
- *! \return fsm status
- */
- static fsm_rt_t send_command( uint8_t *pchOutput, uint_fast16_t hwOSize,
- uint8_t *pchInput, uint_fast16_t hwISize, uint8_t chCS)
- {
- static uint8_t s_chState = 0;
-
- //! validate command
- if (NULL == pchOutput || 0 == hwOSize) {
- return fsm_rt_cpl;
- }
- switch (s_chState) {
- case EZP_CMD_START:
- EZP_SPI_ENABLE(); //!< enable spi
- if (!(chCS & _BV(0))) {
- EZP_CLR_CS(); //!< assert EZP_CS
- }
- s_chState = EZP_CMD_WRITE; //!< transfer to next state
- case EZP_CMD_WRITE:
- //! write command
- if (fsm_rt_on_going == EZP_SPI_DATA_EXCHANGE(pchOutput, NULL, hwOSize)) {
- break;
- }
- if (NULL == pchInput || 0 == hwISize) {
- s_chState = EZP_CMD_FINALIZE;
- break;
- }
- s_chState = EZP_CMD_READ; //!< transfer to next state
- case EZP_CMD_READ:
- //! read content back
- if (fsm_rt_on_going == EZP_SPI_DATA_EXCHANGE(NULL, pchInput, hwISize)) {
- break;
- }
- s_chState = EZP_CMD_FINALIZE;
- case EZP_CMD_FINALIZE:
- default:
-
- if (!(chCS & _BV(1))) {
- EZP_SET_CS(); //!< negate EZP_CS
- }
- EZP_CMD_RESET(); //!< reset statemachine
- EZP_SPI_DISABLE(); //!< disable spi
- return fsm_rt_cpl;
- break;
- }
- return fsm_rt_on_going;
- }
- #define EZP_RDSR_START 0
- #define EZP_RDSR_SND_CMD 1
- #define EZP_RDSR_RESET() do { s_chState = 0; } while(0)
- /*! \brief read EzPort status
- *! \param pchStatus status buffer
- *! \return fsm status
- */
- ROOT static fsm_rt_t read_status(uint8_t *pchStatus)
- {
- static uint8_t s_chState = 0;
- fsm_rt_t tfsm;
- switch (s_chState) {
- case EZP_RDSR_START:
- s_chCMDBuffer[0] = EZP_RDSR; //!< read status command
- s_chState = EZP_RDSR_SND_CMD;
- case EZP_RDSR_SND_CMD:
- tfsm = send_command(s_chCMDBuffer, 1, pchStatus, 1 , 0);
- if (IS_FSM_ERR(tfsm)) {
- EZP_RDSR_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- EZP_RDSR_RESET();
- return fsm_rt_cpl;
- }
- return fsm_rt_on_going;
- }
- static fsm_rt_t check_status(bool bIgnoreFS)
- {
- NO_INIT static uint8_t s_chEzPortStatus;
- do {
- fsm_rt_t tfsm = read_status(&s_chEzPortStatus);
- if (IS_FSM_ERR(tfsm)) {
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- } else if (s_chEzPortStatus & (_BV(WEF) | _BV(WIP))) {
- //! keep pulling the status
- break;
- } else if (s_chEzPortStatus & _BV(FS) && !bIgnoreFS) {
- return fsm_rt_err;
- }
- return fsm_rt_cpl;
- } while (false);
- return fsm_rt_on_going;
- }
- #define EZP_WCMD_START 0
- #define EZP_WCMD_SND_CMD 1
- #define EZP_WCMD_RESET() do { s_chState = 0; } while(0)
- /*! \brief write simple command
- *! \param pchStatus status buffer
- *! \return fsm status
- */
- static fsm_rt_t write_cmd(uint8_t chCMD, bool bIgnoreFS)
- {
- static uint8_t s_chState = 0;
- fsm_rt_t tfsm;
- switch (s_chState) {
- case EZP_WCMD_START:
- tfsm = check_status(bIgnoreFS);
- if (IS_FSM_ERR(tfsm)) {
- EZP_WCMD_RESET();
- return tfsm;
- } else if (tfsm != fsm_rt_cpl) {
- //! on going
- break;
- }
- s_chCMDBuffer[0] = chCMD; //!< read status command
- s_chState = EZP_WCMD_SND_CMD;
- case EZP_WCMD_SND_CMD:
- tfsm = send_command(s_chCMDBuffer, 1, NULL, 0 , 0);
- if (IS_FSM_ERR(tfsm)) {
- EZP_WCMD_RESET();
- return tfsm;
- }
- if (fsm_rt_cpl != tfsm) {
- break;
- }
- EZP_WCMD_RESET();
- return fsm_rt_cpl;
- }
- return fsm_rt_on_going;
- }
- #define EZP_RST_START 0
- #define EZP_RST_DELAY_A 1
- #define EZP_RST_RELEASE_RST 2
- #define EZP_RST_DELAY_B 3
- #define EZP_RST_RESET() do {s_chState = 0;} while(0)
- /*! \brief enable EzPort mode
- *! \param none
- *! \return state machine status
- */
- ROOT fsm_rt_t ezport_enable(void)
- {
- static uint8_t s_chState = 0;
- NO_INIT static uint32_t s_wDelay;
- switch (s_chState) {
- case EZP_RST_START:
- EZP_CLR_RESET(); //!< pull-down reset pin
- EZP_CLR_CS(); //!< assert EZP_CS pin
- s_wDelay = 50 * 1000; //!< delay > 1ms
- s_chState = EZP_RST_DELAY_A;
- case EZP_RST_DELAY_A:
- if (s_wDelay) {
- s_wDelay--;
- break;
- }
- s_chState = EZP_RST_RELEASE_RST;
- case EZP_RST_RELEASE_RST:
- EZP_SET_RESET(); //!< set reset pin
- s_wDelay = 50 * 1000; //!< delay > 1ms
- s_chState = EZP_RST_DELAY_B;
-
- case EZP_RST_DELAY_B:
- if (s_wDelay) {
- s_wDelay--;
- break;
- }
- EZP_SET_CS(); //!< negate EZP_CS pin
- EZP_RST_RESET(); //!< reset state-machine
- s_bEzPortEnabled = true;
- return fsm_rt_cpl;
- }
- return fsm_rt_on_going;
- }
- /*! \brief disable ezport
- *! \param none
- *! \return fsm status
- */
- fsm_rt_t ezport_disable(void)
- {
- if (!s_bEzPortEnabled) {
- return fsm_rt_cpl;
- }
- fsm_rt_t tfsm = write_cmd(EZP_RESET, true);
- if (fsm_rt_cpl == tfsm) {
- s_bEzPortEnabled = false;
- s_bChipErased = false;
- }
- return tfsm;
- }
- /*! \note initialize EzPort
- * \param none
- * \return state-machine status
- */
- fsm_rt_t ezport_initialize( void )
- {
- return EZP_SPI_INIT(); //!< initialize SPI
- }
- fsm_rt_t ezport_finalize( void )
- {
- return ezport_disable(); //!< disable EzPort
- }
- #define EZP_ERASE_START 0
- #define EZP_ERASE_CHIP_ERASE 1
- #define EZP_ERASE_CHECK_RESULT 2
- #define EZP_ERASE_DEMO 3
- #define EZP_ERASE_DEMO_A 4
- #define EZP_ERASE_RESET() do { s_chState = 0; } while(0)
- /*! \brief erase chip
- *! \param none
- *! \return fsm status
- */
- fsm_rt_t ezport_chip_erase(void)
- {
- static uint8_t s_chState = 0;
- fsm_rt_t tfsm;
- switch (s_chState) {
- case EZP_ERASE_START:
- tfsm = write_cmd(EZP_WREN, true); //!< enable write
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- s_chState = EZP_ERASE_CHIP_ERASE;
- case EZP_ERASE_CHIP_ERASE:
- tfsm = write_cmd(EZP_BE, true); //!< chip erase
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- s_chState = EZP_ERASE_CHECK_RESULT;
- // case EZP_ERASE_CHIP_ERASE:
- // //tfsm = write_cmd(EZP_BE, true); //!< chip erase
- // static uint8_t s_chTemp;
- // tfsm = read_status(&s_chTemp);
- // if (IS_FSM_ERR(tfsm)) {
- // EZP_ERASE_RESET();
- // return tfsm;
- // } else if (fsm_rt_cpl != tfsm) {
- // break;
- // }
- // s_chState = EZP_ERASE_DEMO;
- //
- // s_chCMDBuffer[0] = EZP_WRDI; //!< read status command
- //
- // case EZP_ERASE_DEMO:
- // tfsm = send_command(s_chCMDBuffer, 1, NULL, 0 , 0);
- // if (IS_FSM_ERR(tfsm)) {
- // EZP_ERASE_RESET();
- // return tfsm;
- // } else if (fsm_rt_cpl != tfsm) {
- // break;
- // }
- // s_chState = EZP_ERASE_DEMO_A;
- //
- //
- // case EZP_ERASE_DEMO_A:
- // //static uint8_t s_chTemp;
- // tfsm = read_status(&s_chTemp);
- // if (IS_FSM_ERR(tfsm)) {
- // EZP_ERASE_RESET();
- // return tfsm;
- // } else if (fsm_rt_cpl != tfsm) {
- // break;
- // }
- // s_chState = EZP_ERASE_CHECK_RESULT;
- case EZP_ERASE_CHECK_RESULT:
- tfsm = write_cmd(EZP_WRDI, false); //!< disable write
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- s_bChipErased = true;
- EZP_ERASE_RESET();
- return fsm_rt_cpl;
- }
- return fsm_rt_on_going;
- }
- #define EZP_READ_START 0
- #define EZP_READ_STATUS 1
- #define EZP_READ_SND_CMD 2
- #define EZP_READ_RESET() do { s_chStatus = 0; } while(0)
- /*! \brief read flash through Ezport
- *! \param wAddress target address
- *! \param pchStream data buffer
- *! \param hwSize buffer size
- *! \return fsm status
- */
- fsm_rt_t ezport_read(uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize)
- {
- static uint8_t s_chStatus = 0;
- fsm_rt_t tfsm;
-
- if (0 == hwSize) {
- //! nothing need to read
- return fsm_rt_cpl;
- } else if (NULL == pchStream) {
- //! illegal PTR
- return fsm_rt_err;
- }
- switch (s_chStatus) {
- case EZP_READ_START:
- if ( (wAddress > (((uint32_t)1<<24) - 1))
- || (wAddress & 0x03)) { //!< the two LSBs must be zero.
- return fsm_rt_err;
- }
- s_chStatus = EZP_READ_STATUS;
- case EZP_READ_STATUS:
- tfsm = check_status(false);
- if (IS_FSM_ERR(tfsm)) {
- EZP_READ_RESET();
- return tfsm;
- } else if (tfsm != fsm_rt_cpl) {
- //! on going
- break;
- }
- s_chCMDBuffer[0] = EZP_FAST_READ; //!< fast read command
- TYPE_CONVERT(&s_chCMDBuffer[1], uint32_t) = wAddress;
- s_chStatus = EZP_READ_SND_CMD;
-
- case EZP_READ_SND_CMD:
- tfsm = send_command(s_chCMDBuffer, 5, pchStream, hwSize, 0);
- if (IS_FSM_ERR(tfsm)) {
- EZP_READ_RESET();
- return tfsm;
- } else if (tfsm != fsm_rt_cpl) {
- break;
- }
- EZP_READ_RESET();
- return fsm_rt_cpl;
- }
- return fsm_rt_on_going;
- }
- #define EZP_ERASE_SECTOR_START 0
- #define EZP_ERASE_SECTOR_CHECK_STATUS 1
- #define EZP_ERASE_SECTOR_ERASE 2
- #define EZP_ERASE_SECTOR_CHECK_RESULT 3
- #define EZP_ERASE_SECTOR_RESET() do { s_chStatus = 0; } while(0)
- /*! \brief erase specified sector
- *! \param wAddress target address
- *! \return fsm status
- */
- static fsm_rt_t erase_sector(uint32_t wAddress)
- {
- static uint8_t s_chStatus = 0;
- fsm_rt_t tfsm;
- switch (s_chStatus) {
- case EZP_ERASE_SECTOR_START:
- tfsm = write_cmd(EZP_WREN, true); //!< enable write
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_SECTOR_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
-
- s_chStatus = EZP_ERASE_SECTOR_CHECK_STATUS;
- case EZP_ERASE_SECTOR_CHECK_STATUS:
- tfsm = check_status(false); //!< chip erase
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_SECTOR_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- s_chCMDBuffer[0] = EZP_SE;
- TYPE_CONVERT(&s_chCMDBuffer[1], uint32_t) = wAddress & ~0x07;
- s_chStatus = EZP_ERASE_SECTOR_ERASE;
-
- case EZP_ERASE_SECTOR_ERASE:
- tfsm = send_command(s_chCMDBuffer, 4, NULL, 0, 0);
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_SECTOR_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- s_chStatus = EZP_ERASE_SECTOR_CHECK_RESULT;
- case EZP_ERASE_SECTOR_CHECK_RESULT:
- tfsm = write_cmd(EZP_WRDI,true); //!< disable write
- if (IS_FSM_ERR(tfsm)) {
- EZP_ERASE_SECTOR_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- EZP_ERASE_SECTOR_RESET();
- return fsm_rt_cpl;
- }
- return fsm_rt_on_going;
- }
- #define EZP_WRITE_START 0
- #define EZP_WRITE_CHECK_CONTENT 1
- #define EZP_WRITE_READ_SECTOR 2
- #define EZP_WRITE_ERASE_SECTOR 3
- #define EZP_WRITE_CHECK_STATUS 4
- #define EZP_WRITE_ENABLE_WRITE 5
- #define EZP_WRITE_WRITE_SECTOR_CMD 6
- #define EZP_WRITE_WRITE_SECTOR_DATA 7
- #define EZP_WRITE_VERIFY_SECTOR_DATA 8
- #define EZP_WRITE_DISABLE_WRITE 9
- #define EZP_WRITE_RESET() do { s_chStatus = 0; } while(0)
- /*! \brief read flash through Ezport
- *! \param wAddress target address
- *! \param pchStream data buffer
- *! \param hwSize buffer size
- *! \return fsm status
- */
- fsm_rt_t ezport_write(uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize)
- {
- static uint8_t s_chStatus = 0;
- NO_INIT static uint32_t s_wAddress;
- NO_INIT static uint32_t s_wSectorAddress;
- NO_INIT static uint16_t s_hwSize;
- NO_INIT static uint8_t *s_pchSrc;
- NO_INIT static uint8_t *s_pchVerify;
- NO_INIT static uint16_t s_hwLength;
- NO_INIT static uint8_t s_chSectorBuffer[EZP_FLASH_SECTOR_SIZE];
- fsm_rt_t tfsm;
- if (0 == hwSize) {
- return fsm_rt_cpl;
- } else if (NULL == pchStream) {
- return fsm_rt_err;
- }
- switch (s_chStatus) {
- case EZP_WRITE_START:
- if ( (wAddress > (((uint32_t)1<<24) - 1))
- || (wAddress & 0x07)) { //!< the three LSBs must be zero.
- return fsm_rt_err;
- }
-
- s_wAddress = wAddress;
- s_hwSize = hwSize;
- s_pchSrc = pchStream;
- s_pchVerify = pchStream;
- s_chStatus = EZP_WRITE_CHECK_CONTENT;
-
- case EZP_WRITE_CHECK_CONTENT:
- tfsm = check_status(false);
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- if (!s_hwSize) {
- //! all data has been written
- s_chStatus = EZP_WRITE_DISABLE_WRITE;
- break;
- }
- s_wSectorAddress = s_wAddress & ~(EZP_FLASH_SECTOR_SIZE - 1);
- s_chStatus = EZP_WRITE_READ_SECTOR;
- // do {
- // uint_fast16_t hwLength = sizeof(s_chSectorBuffer);
- // uint8_t *pchSrc = s_chSectorBuffer;
- // do {
- // *pchSrc++ = 0;
- // } while(--hwLength);
- // } while (false);
- case EZP_WRITE_READ_SECTOR:
- //! read block
- tfsm = ezport_read(
- s_wSectorAddress, s_chSectorBuffer, sizeof(s_chSectorBuffer));
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
-
- //! fill sector
- do {
- uint_fast16_t hwStart = s_wAddress & (EZP_FLASH_SECTOR_SIZE - 1);
- uint_fast16_t hwLength;
- s_hwLength = sizeof(s_chSectorBuffer) - hwStart;
- uint8_t *pchDes = s_chSectorBuffer + hwStart;
- s_hwLength = MIN(s_hwLength, s_hwSize);
- hwLength = s_hwLength;
- do {
- *pchDes++ = *s_pchSrc++;
- } while (--hwLength);
- } while (false);
- // if (s_bChipErased) {
- // s_chStatus = EZP_WRITE_CHECK_STATUS;
- // } else {
- // s_chStatus = EZP_WRITE_ERASE_SECTOR;
- // }
- s_chStatus = EZP_WRITE_ERASE_SECTOR;
- break;
- case EZP_WRITE_ERASE_SECTOR:
- tfsm = erase_sector(s_wSectorAddress);
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- //! check status
- s_chStatus = EZP_WRITE_CHECK_STATUS;
- case EZP_WRITE_CHECK_STATUS:
- tfsm = check_status(false);
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- //! transfer to next state
- s_chStatus = EZP_WRITE_ENABLE_WRITE;
- case EZP_WRITE_ENABLE_WRITE:
- tfsm = write_cmd(EZP_WREN,false); //!< enable write
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- //!< program flash command
- s_chCMDBuffer[0] = EZP_SP;
- TYPE_CONVERT(&s_chCMDBuffer[1], uint32_t) = s_wSectorAddress;
- s_chStatus = EZP_WRITE_WRITE_SECTOR_CMD;
- case EZP_WRITE_WRITE_SECTOR_CMD:
- //!< write command, disable EZP_CS signal negation
- tfsm = send_command(s_chCMDBuffer, 4, NULL, 0, _BV(1));
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- s_chStatus = EZP_WRITE_WRITE_SECTOR_DATA;
- case EZP_WRITE_WRITE_SECTOR_DATA:
- //! write data, disable EZP_CS signal assertion
- tfsm = send_command(s_chSectorBuffer, sizeof(s_chSectorBuffer), NULL, 0, _BV(0));
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- // do {
- // uint_fast16_t hwLength = sizeof(s_chSectorBuffer);
- // uint8_t *pchSrc = s_chSectorBuffer;
- // do {
- // *pchSrc++ = 0;
- // } while(--hwLength);
- // } while (false);
- s_chStatus = EZP_WRITE_VERIFY_SECTOR_DATA;
- break;
- case EZP_WRITE_VERIFY_SECTOR_DATA:
- //! verify data
- tfsm = ezport_read(
- s_wSectorAddress, s_chSectorBuffer, sizeof(s_chSectorBuffer));
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- //! fill sector
- do {
- uint_fast16_t hwStart = s_wAddress & (EZP_FLASH_SECTOR_SIZE - 1);
- uint_fast16_t hwLength = s_hwLength;
- s_hwSize -= hwLength; //!< update size
- s_wAddress += hwLength; //!< update address
- uint8_t *pchDes = s_chSectorBuffer + hwStart;
- do {
- if (*pchDes++ != *s_pchVerify++) {
- EZP_WRITE_RESET();
- return fsm_rt_err;
- }
- } while (--hwLength);
- } while (false);
- s_chStatus = EZP_WRITE_CHECK_CONTENT;
- case EZP_WRITE_DISABLE_WRITE:
- tfsm = write_cmd(EZP_WRDI,true); //!< disable write
- if (IS_FSM_ERR(tfsm)) {
- EZP_WRITE_RESET();
- return tfsm;
- } else if (fsm_rt_cpl != tfsm) {
- break;
- }
- EZP_WRITE_RESET();
- return fsm_rt_cpl;
- }
-
- return fsm_rt_on_going;
- }
- #endif
-
- /* EOF */
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|