[分享][下载]EzPort驱动(K20测试通过)

2020-02-11 09:52发布

本帖最后由 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_driverezport.h"
5、具体有哪些接口可以使用,请参考EzPort文件夹下EzPort.h的内容
4、具体需要外部提供哪些支持,请参考编译时获得的错误提示。

相关下载

Ezport_driver.rar (40.79 KB, 下载次数: 25) 2013-10-30 15:56 上传 点击文件名下载附件



以下是接口头文件的内容,如果你只关心如何使用,那么应该专注于该头文件:

EzPort.h

  1. /***************************************************************************
  2. *   Copyright(C)2009-2012 by Gorgon Meducer<Embedded_zhuoran@hotmail.com> *
  3. *                                                                         *
  4. *   This program is free software; you can redistribute it and/or modify  *
  5. *   it under the terms of the GNU Lesser General Public License as        *
  6. *   published by the Free Software Foundation; either version 2 of the    *
  7. *   License, or (at your option) any later version.                       *
  8. *                                                                         *
  9. *   This program is distributed in the hope that it will be useful,       *
  10. *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  11. *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  12. *   GNU General Public License for more details.                          *
  13. *                                                                         *
  14. *   You should have received a copy of the GNU Lesser General Public      *
  15. *   License along with this program; if not, write to the                 *
  16. *   Free Software Foundation, Inc.,                                       *
  17. *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  18. ***************************************************************************/

  19. #ifndef __COMPONENT_EZPORT_H__
  20. #define __COMPONENT_EZPORT_H__

  21. /*============================ INCLUDES ======================================*/
  22. #include ".app_cfg.h"

  23. #if USE_COMPONENT_EZPORT == ENABLED

  24. /*============================ MACROS ========================================*/
  25. /*============================ MACROFIED FUNCTIONS ===========================*/
  26. /*============================ TYPES =========================================*/
  27. /*============================ GLOBAL VARIABLES ==============================*/
  28. /*============================ LOCAL VARIABLES ===============================*/
  29. /*============================ PROTOTYPES ====================================*/
  30. /*! ote initialize EzPort
  31. *  param none
  32. *   eturn state-machine status
  33. */  
  34. extern fsm_rt_t ezport_initialize( void );

  35. /*! rief finalize ezport
  36. *! param none
  37. *! eturn fsm status
  38. */
  39. extern fsm_rt_t ezport_finalize(void);

  40. /*! rief enable EzPort mode
  41. *! param none
  42. *! eturn state machine status
  43. */
  44. extern fsm_rt_t ezport_enable( void );

  45. /*! rief disable ezport
  46. *! param none
  47. *! eturn fsm status
  48. */
  49. extern fsm_rt_t ezport_disable(void);

  50. /*! rief erase chip
  51. *! param none
  52. *! eturn fsm status
  53. */
  54. extern fsm_rt_t ezport_chip_erase(void);

  55. /*! rief read flash through Ezport
  56. *! param wAddress target address
  57. *! param pchStream data buffer
  58. *! param hwSize buffer size
  59. *! eturn fsm status
  60. */
  61. extern fsm_rt_t ezport_read(
  62.     uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize);

  63. /*! rief read flash through Ezport
  64. *! param wAddress target address
  65. *! param pchStream data buffer
  66. *! param hwSize buffer size
  67. *! eturn fsm status
  68. */
  69. extern fsm_rt_t ezport_write(
  70.     uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize);

  71. /*! rief verify flash through Ezport
  72. *! param wAddress target address
  73. *! param pchStream data buffer
  74. *! param hwSize buffer size
  75. *! eturn fsm status
  76. */
  77. extern fsm_rt_t ezport_verify(
  78.     uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize);

  79. #endif

  80. #endif
  81. /* EOF */
复制代码
EzPort.c

  1. /***************************************************************************
  2. *   Copyright(C)2009-2012 by Gorgon Meducer<Embedded_zhuoran@hotmail.com> *
  3. *                                                                         *
  4. *   This program is free software; you can redistribute it and/or modify  *
  5. *   it under the terms of the GNU Lesser General Public License as        *
  6. *   published by the Free Software Foundation; either version 2 of the    *
  7. *   License, or (at your option) any later version.                       *
  8. *                                                                         *
  9. *   This program is distributed in the hope that it will be useful,       *
  10. *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  11. *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  12. *   GNU General Public License for more details.                          *
  13. *                                                                         *
  14. *   You should have received a copy of the GNU Lesser General Public      *
  15. *   License along with this program; if not, write to the                 *
  16. *   Free Software Foundation, Inc.,                                       *
  17. *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  18. ***************************************************************************/

  19. /*============================ INCLUDES ======================================*/
  20. #include ".app_cfg.h"

  21. #if USE_COMPONENT_EZPORT == ENABLED
  22. /*============================ MACROS ========================================*/

  23. //! ESP_STATUS register bit definition
  24. //! @{
  25. #define WIP         0       //!< Write in progress
  26. #define WEN         1       //!< Write Enabled
  27. #define BEDIS       2       //!< Bulk erase disabled
  28. #define FLEXRAM     3       //!< FlexRAM Mode
  29. #define WEF         6       //!< Write Error Flag
  30. #define FS          7       //!< Flash Security
  31. //! @}

  32. /*============================ MACROFIED FUNCTIONS ===========================*/

  33. //! rief check macros for target device reset control
  34. #ifndef EZP_SET_RESET
  35. #error No defined macro EZP_SET_RESET for releasing target device reset pin.
  36. #endif
  37. #ifndef EZP_CLR_RESET
  38. #error No defined macro EZP_CLR_RESET for clearing target device reset pin.
  39. #endif

  40. //! rief check macros for EZP_CS control
  41. #ifndef EZP_SET_CS
  42. #error No defined macro EZP_SET_CS() for setting EZP_CS pin.
  43. #endif
  44. #ifndef EZP_CLR_CS
  45. #error No defined macro EZP_CLR_CS() for clearing EZP_CS pin
  46. #endif

  47. //! rief check macro for spi initialization
  48. #ifndef EZP_SPI_INIT
  49. #error No defined macro EZP_SPI_INIT() for spi initialization.
  50. #endif

  51. //! rief check macro for spi data exchange
  52. #ifndef EZP_SPI_DATA_EXCHANGE
  53. #error No defined macro EZP_SPI_DATA_EXCHANGE(__OUTPUT, __INPUT, __LENGTH) for
  54.        spi data exchange.
  55. #endif

  56. //! rief check macro for enabling spi
  57. #ifndef EZP_SPI_ENABLE
  58. #error No defined macro EZP_SPI_ENABLE for enabling spi interface
  59. #endif

  60. //! rief check macro for disabling spi
  61. #ifndef EZP_SPI_DISABLE
  62. #error No defined macro EZP_SPI_DISABLE for disabling spi interface
  63. #endif

  64. #ifndef EZP_FLASH_SECTOR_SIZE
  65. #error No defined flash sector size : EZP_FLASH_SECTOR_SIZE
  66. #endif

  67. /*============================ TYPES =========================================*/

  68. //! ame EzPort Command
  69. //! @{
  70. enum {
  71.     EZP_WREN            = 0x06, //!< Enable write
  72.     EZP_WRDI            = 0x04, //!< Disable write
  73.     EZP_RDSR            = 0x05, //!< Read Status Register
  74.     EZP_READ            = 0x03, //!< Read Flash Data
  75.     EZP_FAST_READ       = 0x0B, //!< Fast-Read Flash Data
  76.     EZP_SP              = 0x02, //!< Program Flash Section
  77.     EZP_SE              = 0xD8, //!< Erase Flash Sector
  78.     EZP_BE              = 0xC7, //!< Erase Flash Bulk
  79.     EZP_RESET           = 0xB9, //!< Reset Target Chip
  80.     EZP_WRFCCOB         = 0xBA, //!< Write FCCOB Registers
  81.     EZP_FAST_WRFCCOB    = 0xBB, //!< Read FCCOB register at high speed
  82.     EZP_WRFLEXRAM       = 0xBC, //!< Write FlexRAM
  83.     EZP_RDFLEXRAM       = 0xBD, //!< Read FlexRAM
  84.     EZP_FAST_RDFLEXRAM  = 0xBE, //!< Read FlexRAM at high speed
  85. };
  86. //! @}


  87. /*============================ GLOBAL VARIABLES ==============================*/
  88. /*============================ LOCAL VARIABLES ===============================*/
  89. //! rief command buffer
  90. NO_INIT static uint8_t s_chCMDBuffer[5];
  91. static bool s_bEzPortEnabled = false;
  92. static bool s_bChipErased = false;

  93. /*============================ PROTOTYPES ====================================*/
  94. static fsm_rt_t read_status(uint8_t *pchStatus);
  95. static fsm_rt_t check_status(bool bIgnoreFS);
  96. static fsm_rt_t write_cmd(uint8_t chCMD, bool bIgnoreFS);
  97. static fsm_rt_t send_command( uint8_t *pchOutput, uint_fast16_t hwOSize,
  98.      uint8_t *pchInput, uint_fast16_t hwISize, uint8_t chCS);

  99. /*============================ IMPLEMENTATION ================================*/

  100. #define EZP_CMD_START           0
  101. #define EZP_CMD_WRITE           1
  102. #define EZP_CMD_READ            2
  103. #define EZP_CMD_FINALIZE        3
  104. #define EZP_CMD_RESET()         do {s_chState = 0;} while(false)

  105. /*! rief Function for issuing EzPort Command
  106. *! param pchOutput output buffer
  107. *! param hwOSize output buffer size
  108. *! param pchInput input buffer
  109. *! param hwISize input buffer size
  110. *! param chCS CS control bits:
  111. *!        BIT0 - disable assertion, BIT1 - disable negation
  112. *! eturn fsm status
  113. */
  114. static fsm_rt_t send_command( uint8_t *pchOutput, uint_fast16_t hwOSize,
  115.      uint8_t *pchInput, uint_fast16_t hwISize, uint8_t chCS)
  116. {
  117.     static uint8_t s_chState = 0;
  118.    
  119.     //! validate command
  120.     if (NULL == pchOutput || 0 == hwOSize) {
  121.         return fsm_rt_cpl;
  122.     }

  123.     switch (s_chState) {
  124.         case EZP_CMD_START:
  125.             EZP_SPI_ENABLE();                       //!< enable spi
  126.             if (!(chCS & _BV(0))) {
  127.                 EZP_CLR_CS();                       //!< assert EZP_CS
  128.             }
  129.             s_chState = EZP_CMD_WRITE;              //!< transfer to next state

  130.         case EZP_CMD_WRITE:
  131.             //! write command
  132.             if (fsm_rt_on_going == EZP_SPI_DATA_EXCHANGE(pchOutput, NULL, hwOSize)) {
  133.                 break;
  134.             }
  135.             if (NULL == pchInput || 0 == hwISize) {
  136.                 s_chState = EZP_CMD_FINALIZE;
  137.                 break;
  138.             }
  139.             s_chState = EZP_CMD_READ;               //!< transfer to next state

  140.         case EZP_CMD_READ:
  141.             //! read content back
  142.             if (fsm_rt_on_going == EZP_SPI_DATA_EXCHANGE(NULL, pchInput, hwISize)) {
  143.                 break;
  144.             }
  145.             s_chState = EZP_CMD_FINALIZE;

  146.         case EZP_CMD_FINALIZE:
  147.         default:
  148.             
  149.             if (!(chCS & _BV(1))) {
  150.                 EZP_SET_CS();                       //!< negate EZP_CS
  151.             }
  152.             EZP_CMD_RESET();                        //!< reset statemachine
  153.             EZP_SPI_DISABLE();                      //!< disable spi
  154.             return fsm_rt_cpl;
  155.             break;
  156.     }

  157.     return fsm_rt_on_going;
  158. }

  159. #define EZP_RDSR_START          0
  160. #define EZP_RDSR_SND_CMD        1
  161. #define EZP_RDSR_RESET()        do { s_chState = 0; } while(0)

  162. /*! rief read EzPort status
  163. *! param pchStatus status buffer
  164. *! eturn fsm status
  165. */
  166. ROOT static fsm_rt_t read_status(uint8_t *pchStatus)
  167. {
  168.     static uint8_t s_chState = 0;
  169.     fsm_rt_t tfsm;

  170.     switch (s_chState) {
  171.         case EZP_RDSR_START:
  172.             s_chCMDBuffer[0] = EZP_RDSR;   //!< read status command
  173.             s_chState = EZP_RDSR_SND_CMD;

  174.         case EZP_RDSR_SND_CMD:
  175.             tfsm = send_command(s_chCMDBuffer, 1, pchStatus, 1 , 0);
  176.             if (IS_FSM_ERR(tfsm)) {
  177.                 EZP_RDSR_RESET();
  178.                 return tfsm;
  179.             } else if (fsm_rt_cpl != tfsm) {
  180.                 break;
  181.             }
  182.             EZP_RDSR_RESET();
  183.             return fsm_rt_cpl;
  184.     }

  185.     return fsm_rt_on_going;
  186. }

  187. static fsm_rt_t check_status(bool bIgnoreFS)
  188. {
  189.     NO_INIT static uint8_t s_chEzPortStatus;
  190.     do {
  191.         fsm_rt_t tfsm = read_status(&s_chEzPortStatus);
  192.         if (IS_FSM_ERR(tfsm)) {
  193.             return tfsm;
  194.         } else if (fsm_rt_cpl != tfsm) {
  195.             break;
  196.         } else if (s_chEzPortStatus & (_BV(WEF) | _BV(WIP))) {
  197.             //! keep pulling the status
  198.             break;
  199.         } else if (s_chEzPortStatus & _BV(FS) && !bIgnoreFS) {
  200.             return fsm_rt_err;
  201.         }
  202.         return fsm_rt_cpl;
  203.     } while (false);

  204.     return fsm_rt_on_going;
  205. }

  206. #define EZP_WCMD_START          0
  207. #define EZP_WCMD_SND_CMD        1
  208. #define EZP_WCMD_RESET()        do { s_chState = 0; } while(0)

  209. /*! rief write simple command
  210. *! param pchStatus status buffer
  211. *! eturn fsm status
  212. */
  213. static fsm_rt_t write_cmd(uint8_t chCMD, bool bIgnoreFS)
  214. {
  215.     static uint8_t s_chState = 0;
  216.     fsm_rt_t tfsm;

  217.     switch (s_chState) {
  218.         case EZP_WCMD_START:
  219.             tfsm = check_status(bIgnoreFS);
  220.             if (IS_FSM_ERR(tfsm)) {
  221.                 EZP_WCMD_RESET();
  222.                 return tfsm;
  223.             } else if (tfsm != fsm_rt_cpl) {
  224.                 //! on going
  225.                 break;
  226.             }
  227.             s_chCMDBuffer[0] = chCMD;   //!< read status command
  228.             s_chState = EZP_WCMD_SND_CMD;

  229.         case EZP_WCMD_SND_CMD:
  230.             tfsm = send_command(s_chCMDBuffer, 1, NULL, 0 , 0);
  231.             if (IS_FSM_ERR(tfsm)) {
  232.                 EZP_WCMD_RESET();
  233.                 return tfsm;
  234.             }
  235.             if (fsm_rt_cpl != tfsm) {
  236.                 break;
  237.             }
  238.             EZP_WCMD_RESET();
  239.             return fsm_rt_cpl;
  240.     }

  241.     return fsm_rt_on_going;
  242. }


  243. #define EZP_RST_START           0
  244. #define EZP_RST_DELAY_A         1
  245. #define EZP_RST_RELEASE_RST     2
  246. #define EZP_RST_DELAY_B         3
  247. #define EZP_RST_RESET()         do {s_chState = 0;} while(0)

  248. /*! rief enable EzPort mode
  249. *! param none
  250. *! eturn state machine status
  251. */
  252. ROOT fsm_rt_t ezport_enable(void)
  253. {
  254.     static uint8_t s_chState = 0;
  255.     NO_INIT static uint32_t s_wDelay;

  256.     switch (s_chState) {
  257.         case EZP_RST_START:
  258.             EZP_CLR_RESET();                //!< pull-down reset pin
  259.             EZP_CLR_CS();                   //!< assert EZP_CS pin
  260.             s_wDelay = 50 * 1000;           //!< delay > 1ms
  261.             s_chState = EZP_RST_DELAY_A;

  262.         case EZP_RST_DELAY_A:
  263.             if (s_wDelay) {
  264.                 s_wDelay--;
  265.                 break;
  266.             }
  267.             s_chState = EZP_RST_RELEASE_RST;

  268.         case EZP_RST_RELEASE_RST:
  269.             EZP_SET_RESET();                //!< set reset pin
  270.             s_wDelay = 50 * 1000;           //!< delay > 1ms
  271.             s_chState = EZP_RST_DELAY_B;
  272.    
  273.         case EZP_RST_DELAY_B:
  274.             if (s_wDelay) {
  275.                 s_wDelay--;
  276.                 break;
  277.             }
  278.             EZP_SET_CS();                   //!< negate EZP_CS pin
  279.             EZP_RST_RESET();                //!< reset state-machine
  280.             s_bEzPortEnabled = true;
  281.             return fsm_rt_cpl;
  282.     }

  283.     return fsm_rt_on_going;
  284. }


  285. /*! rief disable ezport
  286. *! param none
  287. *! eturn fsm status
  288. */
  289. fsm_rt_t ezport_disable(void)
  290. {
  291.     if (!s_bEzPortEnabled) {
  292.         return fsm_rt_cpl;
  293.     }
  294.     fsm_rt_t tfsm = write_cmd(EZP_RESET, true);
  295.     if (fsm_rt_cpl == tfsm) {
  296.         s_bEzPortEnabled = false;
  297.         s_bChipErased = false;
  298.     }

  299.     return tfsm;
  300. }


  301. /*! ote initialize EzPort
  302. *  param none
  303. *   eturn state-machine status
  304. */  
  305. fsm_rt_t ezport_initialize( void )
  306. {
  307.     return EZP_SPI_INIT();              //!< initialize SPI
  308. }

  309. fsm_rt_t ezport_finalize( void )
  310. {
  311.     return ezport_disable();            //!< disable EzPort
  312. }


  313. #define EZP_ERASE_START         0
  314. #define EZP_ERASE_CHIP_ERASE    1
  315. #define EZP_ERASE_CHECK_RESULT  2
  316. #define EZP_ERASE_DEMO          3
  317. #define EZP_ERASE_DEMO_A        4
  318. #define EZP_ERASE_RESET()       do { s_chState = 0; } while(0)

  319. /*! rief erase chip
  320. *! param none
  321. *! eturn fsm status
  322. */
  323. fsm_rt_t ezport_chip_erase(void)
  324. {
  325.     static uint8_t s_chState = 0;
  326.     fsm_rt_t tfsm;

  327.     switch (s_chState) {
  328.         case EZP_ERASE_START:
  329.             tfsm = write_cmd(EZP_WREN, true);         //!< enable write
  330.             if (IS_FSM_ERR(tfsm)) {
  331.                 EZP_ERASE_RESET();
  332.                 return tfsm;
  333.             } else if (fsm_rt_cpl != tfsm) {
  334.                 break;
  335.             }
  336.             s_chState = EZP_ERASE_CHIP_ERASE;

  337.         case EZP_ERASE_CHIP_ERASE:
  338.             tfsm = write_cmd(EZP_BE, true);           //!< chip erase
  339.             if (IS_FSM_ERR(tfsm)) {
  340.                 EZP_ERASE_RESET();
  341.                 return tfsm;
  342.             } else if (fsm_rt_cpl != tfsm) {
  343.                 break;
  344.             }
  345.             s_chState = EZP_ERASE_CHECK_RESULT;

  346. //        case EZP_ERASE_CHIP_ERASE:
  347. //            //tfsm = write_cmd(EZP_BE, true);           //!< chip erase
  348. //            static uint8_t s_chTemp;
  349. //            tfsm = read_status(&s_chTemp);
  350. //            if (IS_FSM_ERR(tfsm)) {
  351. //                EZP_ERASE_RESET();
  352. //                return tfsm;
  353. //            } else if (fsm_rt_cpl != tfsm) {
  354. //                break;
  355. //            }
  356. //            s_chState = EZP_ERASE_DEMO;
  357. //   
  358. //            s_chCMDBuffer[0] = EZP_WRDI;   //!< read status command
  359. //     
  360. //        case EZP_ERASE_DEMO:
  361. //            tfsm = send_command(s_chCMDBuffer, 1, NULL, 0 , 0);
  362. //            if (IS_FSM_ERR(tfsm)) {
  363. //                EZP_ERASE_RESET();
  364. //                return tfsm;
  365. //            } else if (fsm_rt_cpl != tfsm) {
  366. //                break;
  367. //            }
  368. //            s_chState = EZP_ERASE_DEMO_A;
  369. //
  370. //
  371. //        case EZP_ERASE_DEMO_A:
  372. //            //static uint8_t s_chTemp;
  373. //            tfsm = read_status(&s_chTemp);
  374. //            if (IS_FSM_ERR(tfsm)) {
  375. //                EZP_ERASE_RESET();
  376. //                return tfsm;
  377. //            } else if (fsm_rt_cpl != tfsm) {
  378. //                break;
  379. //            }
  380. //            s_chState = EZP_ERASE_CHECK_RESULT;

  381.         case EZP_ERASE_CHECK_RESULT:
  382.             tfsm = write_cmd(EZP_WRDI, false);         //!< disable write
  383.             if (IS_FSM_ERR(tfsm)) {
  384.                 EZP_ERASE_RESET();
  385.                 return tfsm;
  386.             } else if (fsm_rt_cpl != tfsm) {
  387.                 break;
  388.             }
  389.             s_bChipErased = true;
  390.             EZP_ERASE_RESET();
  391.             return fsm_rt_cpl;
  392.     }

  393.     return fsm_rt_on_going;
  394. }

  395. #define EZP_READ_START          0
  396. #define EZP_READ_STATUS         1
  397. #define EZP_READ_SND_CMD        2
  398. #define EZP_READ_RESET()        do { s_chStatus = 0; } while(0)

  399. /*! rief read flash through Ezport
  400. *! param wAddress target address
  401. *! param pchStream data buffer
  402. *! param hwSize buffer size
  403. *! eturn fsm status
  404. */
  405. fsm_rt_t ezport_read(uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize)
  406. {
  407.     static uint8_t s_chStatus = 0;
  408.     fsm_rt_t tfsm;
  409.    
  410.     if (0 == hwSize) {
  411.         //! nothing need to read
  412.         return fsm_rt_cpl;
  413.     } else if (NULL == pchStream) {
  414.         //! illegal PTR
  415.         return fsm_rt_err;
  416.     }

  417.     switch (s_chStatus) {
  418.         case EZP_READ_START:
  419.             if (    (wAddress > (((uint32_t)1<<24) - 1))
  420.                 ||  (wAddress & 0x03))  {       //!< the two LSBs must be zero.
  421.                 return fsm_rt_err;
  422.             }
  423.             s_chStatus = EZP_READ_STATUS;

  424.         case EZP_READ_STATUS:
  425.             tfsm = check_status(false);
  426.             if (IS_FSM_ERR(tfsm)) {
  427.                 EZP_READ_RESET();
  428.                 return tfsm;
  429.             } else if (tfsm != fsm_rt_cpl) {
  430.                 //! on going
  431.                 break;
  432.             }
  433.             s_chCMDBuffer[0] = EZP_FAST_READ;   //!< fast read command
  434.             TYPE_CONVERT(&s_chCMDBuffer[1], uint32_t) = wAddress;
  435.             s_chStatus = EZP_READ_SND_CMD;
  436.         
  437.         case EZP_READ_SND_CMD:
  438.             tfsm = send_command(s_chCMDBuffer, 5, pchStream, hwSize, 0);
  439.             if (IS_FSM_ERR(tfsm)) {
  440.                 EZP_READ_RESET();
  441.                 return tfsm;
  442.             } else if (tfsm != fsm_rt_cpl) {
  443.                 break;
  444.             }
  445.             EZP_READ_RESET();
  446.             return fsm_rt_cpl;
  447.     }

  448.     return fsm_rt_on_going;
  449. }

  450. #define EZP_ERASE_SECTOR_START          0
  451. #define EZP_ERASE_SECTOR_CHECK_STATUS   1
  452. #define EZP_ERASE_SECTOR_ERASE          2
  453. #define EZP_ERASE_SECTOR_CHECK_RESULT   3
  454. #define EZP_ERASE_SECTOR_RESET()        do { s_chStatus = 0; } while(0)

  455. /*! rief erase specified sector
  456. *! param wAddress target address
  457. *! eturn fsm status
  458. */
  459. static fsm_rt_t erase_sector(uint32_t wAddress)
  460. {
  461.     static uint8_t s_chStatus = 0;

  462.     fsm_rt_t tfsm;

  463.     switch (s_chStatus) {
  464.         case EZP_ERASE_SECTOR_START:
  465.             tfsm = write_cmd(EZP_WREN, true);         //!< enable write
  466.             if (IS_FSM_ERR(tfsm)) {
  467.                 EZP_ERASE_SECTOR_RESET();
  468.                 return tfsm;
  469.             } else if (fsm_rt_cpl != tfsm) {
  470.                 break;
  471.             }
  472.             
  473.             s_chStatus = EZP_ERASE_SECTOR_CHECK_STATUS;

  474.         case EZP_ERASE_SECTOR_CHECK_STATUS:
  475.             tfsm = check_status(false);              //!< chip erase
  476.             if (IS_FSM_ERR(tfsm)) {
  477.                 EZP_ERASE_SECTOR_RESET();
  478.                 return tfsm;
  479.             } else if (fsm_rt_cpl != tfsm) {
  480.                 break;
  481.             }
  482.             s_chCMDBuffer[0] = EZP_SE;
  483.             TYPE_CONVERT(&s_chCMDBuffer[1], uint32_t) = wAddress & ~0x07;
  484.             s_chStatus = EZP_ERASE_SECTOR_ERASE;
  485.         
  486.         case EZP_ERASE_SECTOR_ERASE:
  487.             tfsm = send_command(s_chCMDBuffer, 4, NULL, 0, 0);
  488.             if (IS_FSM_ERR(tfsm)) {
  489.                 EZP_ERASE_SECTOR_RESET();
  490.                 return tfsm;
  491.             } else if (fsm_rt_cpl != tfsm) {
  492.                 break;
  493.             }
  494.             s_chStatus = EZP_ERASE_SECTOR_CHECK_RESULT;

  495.         case EZP_ERASE_SECTOR_CHECK_RESULT:
  496.             tfsm = write_cmd(EZP_WRDI,true);         //!< disable write
  497.             if (IS_FSM_ERR(tfsm)) {
  498.                 EZP_ERASE_SECTOR_RESET();
  499.                 return tfsm;
  500.             } else if (fsm_rt_cpl != tfsm) {
  501.                 break;
  502.             }
  503.             EZP_ERASE_SECTOR_RESET();
  504.             return fsm_rt_cpl;
  505.     }

  506.     return fsm_rt_on_going;
  507. }

  508. #define EZP_WRITE_START                 0
  509. #define EZP_WRITE_CHECK_CONTENT         1
  510. #define EZP_WRITE_READ_SECTOR           2
  511. #define EZP_WRITE_ERASE_SECTOR          3
  512. #define EZP_WRITE_CHECK_STATUS          4
  513. #define EZP_WRITE_ENABLE_WRITE          5
  514. #define EZP_WRITE_WRITE_SECTOR_CMD      6
  515. #define EZP_WRITE_WRITE_SECTOR_DATA     7
  516. #define EZP_WRITE_VERIFY_SECTOR_DATA    8
  517. #define EZP_WRITE_DISABLE_WRITE         9
  518. #define EZP_WRITE_RESET()               do { s_chStatus = 0; } while(0)

  519. /*! rief read flash through Ezport
  520. *! param wAddress target address
  521. *! param pchStream data buffer
  522. *! param hwSize buffer size
  523. *! eturn fsm status
  524. */
  525. fsm_rt_t ezport_write(uint32_t wAddress, uint8_t *pchStream, uint16_t hwSize)
  526. {
  527.     static uint8_t s_chStatus = 0;
  528.     NO_INIT static uint32_t s_wAddress;
  529.     NO_INIT static uint32_t s_wSectorAddress;
  530.     NO_INIT static uint16_t s_hwSize;
  531.     NO_INIT static uint8_t  *s_pchSrc;
  532.     NO_INIT static uint8_t  *s_pchVerify;
  533.     NO_INIT static uint16_t s_hwLength;
  534.     NO_INIT static uint8_t s_chSectorBuffer[EZP_FLASH_SECTOR_SIZE];

  535.     fsm_rt_t tfsm;

  536.     if (0 == hwSize) {
  537.         return fsm_rt_cpl;
  538.     } else if (NULL == pchStream) {
  539.         return fsm_rt_err;
  540.     }

  541.     switch (s_chStatus) {
  542.         case EZP_WRITE_START:
  543.             if (    (wAddress > (((uint32_t)1<<24) - 1))
  544.                 ||  (wAddress & 0x07))  {       //!< the three LSBs must be zero.
  545.                 return fsm_rt_err;
  546.             }
  547.             
  548.             s_wAddress = wAddress;
  549.             s_hwSize = hwSize;
  550.             s_pchSrc = pchStream;
  551.             s_pchVerify = pchStream;
  552.             s_chStatus = EZP_WRITE_CHECK_CONTENT;

  553.         
  554.         case EZP_WRITE_CHECK_CONTENT:
  555.             tfsm = check_status(false);
  556.             if (IS_FSM_ERR(tfsm)) {
  557.                 EZP_WRITE_RESET();
  558.                 return tfsm;
  559.             } else if (fsm_rt_cpl != tfsm) {
  560.                 break;
  561.             }

  562.             if (!s_hwSize) {
  563.                 //! all data has been written
  564.                 s_chStatus = EZP_WRITE_DISABLE_WRITE;
  565.                 break;
  566.             }
  567.             s_wSectorAddress = s_wAddress & ~(EZP_FLASH_SECTOR_SIZE - 1);
  568.             s_chStatus = EZP_WRITE_READ_SECTOR;

  569. //            do {
  570. //                uint_fast16_t hwLength = sizeof(s_chSectorBuffer);
  571. //                uint8_t *pchSrc = s_chSectorBuffer;
  572. //                do {
  573. //                    *pchSrc++ = 0;
  574. //                } while(--hwLength);
  575. //            } while (false);


  576.         case EZP_WRITE_READ_SECTOR:
  577.             //! read block
  578.             tfsm = ezport_read(
  579.                 s_wSectorAddress, s_chSectorBuffer, sizeof(s_chSectorBuffer));
  580.             if (IS_FSM_ERR(tfsm)) {
  581.                 EZP_WRITE_RESET();
  582.                 return tfsm;
  583.             } else if (fsm_rt_cpl != tfsm) {
  584.                 break;
  585.             }
  586.             
  587.             //! fill sector
  588.             do {
  589.                 uint_fast16_t hwStart = s_wAddress & (EZP_FLASH_SECTOR_SIZE - 1);
  590.                 uint_fast16_t hwLength;
  591.                 s_hwLength = sizeof(s_chSectorBuffer) - hwStart;
  592.                 uint8_t *pchDes = s_chSectorBuffer + hwStart;
  593.                 s_hwLength = MIN(s_hwLength, s_hwSize);
  594.                 hwLength = s_hwLength;
  595.                 do {
  596.                     *pchDes++ = *s_pchSrc++;
  597.                 } while (--hwLength);
  598.             } while (false);

  599. //            if (s_bChipErased) {
  600. //                s_chStatus =  EZP_WRITE_CHECK_STATUS;
  601. //            } else {
  602. //                s_chStatus = EZP_WRITE_ERASE_SECTOR;
  603. //            }
  604.             s_chStatus = EZP_WRITE_ERASE_SECTOR;
  605.             break;                              

  606.         case EZP_WRITE_ERASE_SECTOR:
  607.             tfsm = erase_sector(s_wSectorAddress);
  608.             if (IS_FSM_ERR(tfsm)) {
  609.                 EZP_WRITE_RESET();
  610.                 return tfsm;
  611.             } else if (fsm_rt_cpl != tfsm) {
  612.                 break;
  613.             }
  614.             //! check status
  615.             s_chStatus =  EZP_WRITE_CHECK_STATUS;

  616.         case EZP_WRITE_CHECK_STATUS:
  617.             tfsm = check_status(false);
  618.             if (IS_FSM_ERR(tfsm)) {
  619.                 EZP_WRITE_RESET();
  620.                 return tfsm;
  621.             } else if (fsm_rt_cpl != tfsm) {
  622.                 break;
  623.             }
  624.             //! transfer to next state
  625.             s_chStatus = EZP_WRITE_ENABLE_WRITE;

  626.         case EZP_WRITE_ENABLE_WRITE:
  627.             tfsm = write_cmd(EZP_WREN,false);         //!< enable write
  628.             if (IS_FSM_ERR(tfsm)) {
  629.                 EZP_WRITE_RESET();
  630.                 return tfsm;
  631.             } else if (fsm_rt_cpl != tfsm) {
  632.                 break;
  633.             }
  634.             //!< program flash command
  635.             s_chCMDBuffer[0] = EZP_SP;         
  636.             TYPE_CONVERT(&s_chCMDBuffer[1], uint32_t) = s_wSectorAddress;

  637.             s_chStatus = EZP_WRITE_WRITE_SECTOR_CMD;

  638.         case EZP_WRITE_WRITE_SECTOR_CMD:
  639.             //!< write command, disable EZP_CS signal negation
  640.             tfsm = send_command(s_chCMDBuffer, 4, NULL, 0, _BV(1));
  641.             if (IS_FSM_ERR(tfsm)) {
  642.                 EZP_WRITE_RESET();
  643.                 return tfsm;
  644.             } else if (fsm_rt_cpl != tfsm) {
  645.                 break;
  646.             }
  647.             s_chStatus = EZP_WRITE_WRITE_SECTOR_DATA;

  648.         case EZP_WRITE_WRITE_SECTOR_DATA:
  649.             //! write data, disable EZP_CS signal assertion
  650.             tfsm = send_command(s_chSectorBuffer, sizeof(s_chSectorBuffer), NULL, 0, _BV(0));
  651.             if (IS_FSM_ERR(tfsm)) {
  652.                 EZP_WRITE_RESET();
  653.                 return tfsm;
  654.             } else if (fsm_rt_cpl != tfsm) {
  655.                 break;
  656.             }
  657. //            do {
  658. //                uint_fast16_t hwLength = sizeof(s_chSectorBuffer);
  659. //                uint8_t *pchSrc = s_chSectorBuffer;
  660. //                do {
  661. //                    *pchSrc++ = 0;
  662. //                } while(--hwLength);
  663. //            } while (false);
  664.             s_chStatus = EZP_WRITE_VERIFY_SECTOR_DATA;
  665.             break;

  666.         case EZP_WRITE_VERIFY_SECTOR_DATA:
  667.             //! verify data
  668.             tfsm = ezport_read(
  669.                 s_wSectorAddress, s_chSectorBuffer, sizeof(s_chSectorBuffer));
  670.             if (IS_FSM_ERR(tfsm)) {
  671.                 EZP_WRITE_RESET();
  672.                 return tfsm;
  673.             } else if (fsm_rt_cpl != tfsm) {
  674.                 break;
  675.             }
  676.             //! fill sector
  677.             do {
  678.                 uint_fast16_t hwStart = s_wAddress & (EZP_FLASH_SECTOR_SIZE - 1);
  679.                 uint_fast16_t hwLength = s_hwLength;
  680.                 s_hwSize -= hwLength;           //!< update size
  681.                 s_wAddress += hwLength;         //!< update address
  682.                 uint8_t *pchDes = s_chSectorBuffer + hwStart;
  683.                 do {
  684.                     if (*pchDes++ != *s_pchVerify++) {
  685.                         EZP_WRITE_RESET();
  686.                         return fsm_rt_err;
  687.                     }
  688.                 } while (--hwLength);
  689.             } while (false);
  690.             s_chStatus = EZP_WRITE_CHECK_CONTENT;

  691.         case EZP_WRITE_DISABLE_WRITE:
  692.             tfsm = write_cmd(EZP_WRDI,true);         //!< disable write
  693.             if (IS_FSM_ERR(tfsm)) {
  694.                 EZP_WRITE_RESET();
  695.                 return tfsm;
  696.             } else if (fsm_rt_cpl != tfsm) {
  697.                 break;
  698.             }
  699.             EZP_WRITE_RESET();
  700.             return fsm_rt_cpl;
  701.     }
  702.    
  703.     return fsm_rt_on_going;
  704. }

  705. #endif
  706.   
  707. /* EOF */
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。