Gorgon_Meducer 发表于 2013-10-30 15:29:50

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

本帖最后由 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, MA02111-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, MA02111-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;
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 = 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 = 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_RESULT2
#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 = 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 = EZP_FAST_READ;   //!< fast read command
            TYPE_CONVERT(&s_chCMDBuffer, 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 = EZP_SE;
            TYPE_CONVERT(&s_chCMDBuffer, 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;

    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 = EZP_SP;         
            TYPE_CONVERT(&s_chCMDBuffer, 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 */

yandld11 发表于 2013-10-30 15:34:28

好东西!楼主~ 能简单介绍下 EzPort么。一直想用,但是没用起来。。。

hqgboy 发表于 2013-10-30 15:39:32

顶顶。
待续?

Gorgon_Meducer 发表于 2013-10-30 15:57:45

yandld11 发表于 2013-10-30 15:34 static/image/common/back.gif
好东西!楼主~ 能简单介绍下 EzPort么。一直想用,但是没用起来。。。

简要说明还是交给Freescale的FAE们吧,毕竟这是他们的地盘和本职,我就不喧宾夺主了。

renjun_EMbest 发表于 2013-10-30 20:02:42

没怎么关注Freesclae, EzPort,友情帮顶

rf_abel 发表于 2013-10-30 20:43:02

EzPort,貌似很好,听说支持,外部内存卡,向芯片类读写程序

tyqhaha 发表于 2013-10-30 22:34:33

大神啊,木有注释真是看的水中雾啊。。。

Gorgon_Meducer 发表于 2013-10-31 08:04:19

tyqhaha 发表于 2013-10-30 22:34 static/image/common/back.gif
大神啊,木有注释真是看的水中雾啊。。。

要先看数据手册啊

661球 发表于 2013-10-31 09:55:33

支持KE02么···来试一下啊

Robin_King 发表于 2013-11-1 09:59:53

顶王Sir{:victory:}

nongxiaoming 发表于 2013-11-1 10:03:56

真心不错

richards 发表于 2013-11-1 10:15:42

AtoM是之前 那个 安卓转MCU的东西么?

Gorgon_Meducer 发表于 2013-11-1 10:37:15

richards 发表于 2013-11-1 10:15 static/image/common/back.gif
AtoM是之前 那个 安卓转MCU的东西么?

是的。现在那个项目专门用来做定制Andriod设备了,我们开了一个专门的Andriod平板。

AIHHLI 发表于 2013-11-10 21:06:58

傻孩子,问你一个关于Doxygen注释的问题。
在你的代码中使用了很多此种风格的注释:
/*! \brief
*! \param
*! \param
*! \return
*/
看起来很整齐美观,但是为什么在Doxygen的文档中并没有这种风格的注释呢?
在函数中你使用
//!
这种行间注释,但是使用Doxygen生成的文档中,函数体中的行间注释会出现在函数文档尾部,这看起来似乎不正常啊。

Gorgon_Meducer 发表于 2013-11-11 11:03:51

AIHHLI 发表于 2013-11-10 21:06 static/image/common/back.gif
傻孩子,问你一个关于Doxygen注释的问题。
在你的代码中使用了很多此种风格的注释:
/*! \brief


这不科学啊……你查阅了帮助文档了么?

AIHHLI 发表于 2013-11-11 13:14:54

Gorgon_Meducer 发表于 2013-11-11 11:03 static/image/common/back.gif
这不科学啊……你查阅了帮助文档了么?

我查了,文档中写到的块注释风格有如下几种:
JavaDoc风格:
/**
* ...text...
*/

Qt风格:
/*!
* ...text...
*/

或者

/*!
    ...text...
*/

C++风格:
///
/// ...text...
///

或者

//!
//! ...text...
//!

//! 做为简要注释。

没有发现你这种风格的。
或许是我没找到?


Gorgon_Meducer 发表于 2013-11-11 14:15:47

AIHHLI 发表于 2013-11-11 13:14 static/image/common/back.gif
我查了,文档中写到的块注释风格有如下几种:
JavaDoc风格:
/**


风格问题,不要介意,我只是利用语法的可能性。

sblpp 发表于 2013-11-11 21:15:35

又见高手
头像很像小马哥啊
笑容灿烂。

bigwei 发表于 2017-1-15 21:31:18

{:lol:} 多谢分享!!!
页: [1]
查看完整版本: [分享][下载]EzPort驱动(K20测试通过)