Apollo3 SDK平台添加支持复旦微FM25Q128 SPI Flash的方法

润欣科技
关注

FM25Q128上电初始化流程如下图所示,要使能芯片的QPI模式,需要使能状态寄存器Status Register-2中的bit1位QE,然后使用0x38命令使能进入QPI模式。退出QPI模式可以发送0xFF命令或者发送软件复位序列0x66 + 0x99,如下图5所示。

图5 FM25Q125上电初始化流程

如上所述,初次上电后,Flash芯片处于单线SPI模式,WP#和HOLD#管脚可能影响状态寄存器的写入操作,实际调试底层驱动代码的过程中,笔者也发现了这个问题,由于HOLD#没有外接上拉电阻,在SPI模式下Flash芯片的HOLD#脚电平不稳,导致读写状态寄存器时而正常,时而失败,开发板正常,客户的板子失败等现象,调试了很长时间才发现问题根源在于此。我们可以将Apollo3芯片的MSPI接口配置成SPI模式,并将连接到FM25Q128的DQ2(WP#)和DQ3(HOLD#/RESET#)的管脚GP4和GP23配置成GPIO输出,使能内部上拉电阻,并且同时输出高电平,让WP#和HOLD#管脚处于非激活状态。

我们先通过阅读Datasheet来了解一下Apollo3的GPIO口结构,以及内部上拉电阻的配置。

Apollo3的所有的GPIO都可以通过软件来配置(PADnPULL)使能内部上拉电阻(除了GPIO20为下拉),上拉电阻默认状态是禁用的。另外,包含有I2C功能的GPIO的内部上拉电阻是可以选择四种不同阻值的。我们用到的GP4和GP23不包含I2C功能,因此不能选择上拉电阻的阻值。经过与AmbiqMicro原厂工程师沟通,了解到内部通用上拉电阻的阻值大约为63KΩ,这个内部的弱上拉足可以保证在SPI模式初始化SPI Flash时,WP#和HOLD#/RESET#管脚稳定为高电平状态。参考代码如下:

#define AM_BSP_GPIO_GP23   23

#define AM_BSP_GPIO_GP4     4

const am_hal_gpio_pincfg_t g_AM_BSP_GPIO_GP23_HOLD =

.uFuncSel       = AM_HAL_PIN_23_GPIO,

.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_8MA,

.ePullup        = AM_HAL_GPIO_PIN_PULLUP_WEAK,

.eGPOutcfg   = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,

.eGPInput      = AM_HAL_GPIO_PIN_INPUT_NONE

};

const am_hal_gpio_pincfg_t g_AM_BSP_GPIO_GP4_WP =

.uFuncSel      = AM_HAL_PIN_4_GPIO,

.eDriveStrength  = AM_HAL_GPIO_PIN_DRIVESTRENGTH_8MA,

.ePullup      = AM_HAL_GPIO_PIN_PULLUP_WEAK,

.eGPOutcfg   = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,

.eGPInput      = AM_HAL_GPIO_PIN_INPUT_NONE

};

static void ConfigGP23AsGpioOutputForPullHighHoldPin (void)

//

// Configure the pin as a push-pull GPIO output.

//

am_hal_gpio_pinconfig(AM_BSP_GPIO_GP23,g_AM_BSP_GPIO_GP23_HOLD);

//

// Disable the output driver, and set the output value to the high level

// state.  Note that for Apollo3 GPIOs in push-pull mode, the output

// enable, normally a tri-state control, instead functions as an enable

// for Fast GPIO. Its state does not matter on previous chips, so for

// normal GPIO usage on Apollo3, it must be disabled.

//

am_hal_gpio_state_write(AM_BSP_GPIO_GP23,AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE);

am_hal_gpio_state_write(AM_BSP_GPIO_GP23,AM_HAL_GPIO_OUTPUT_SET);   // pull high

static void ConfigGP4AsGpioOutputForPullHighWPPin (void)

//

// Configure the pin as a push-pull GPIO output.

//

am_hal_gpio_pinconfig(AM_BSP_GPIO_GP4,g_AM_BSP_GPIO_GP4_WP);

//

// Disable the output driver, and set the output value to the high level

// state.  Note that for Apollo3 GPIOs in push-pull mode, the output

// enable, normally a tri-state control, instead functions as an enable

// for Fast GPIO. Its state does not matter on previous chips, so for

// normal GPIO usage on Apollo3, it must be disabled.

//

am_hal_gpio_state_write(AM_BSP_GPIO_GP4,AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE);

am_hal_gpio_state_write(AM_BSP_GPIO_GP4,AM_HAL_GPIO_OUTPUT_SET);   // pull high

代码详见SDK v2.0目录下的示例工程:mspi_quad_example,

文件am_devices_mspi_flash.c。

5、在SDK v2.0示例代码mspi_quad_example的基础上添加FM25Q128的支持

am_devices_mspi_flash.h文件中增加器件型号宏定义:#define FUDAN_FM25Q128

以及器件支持的相关操作命令,ID码以及容量宏定义

#if defined (FUDAN_FM25Q128)

//*******************************************************************

//

// Device specific identification.

//

//*******************************************************************

#define AM_DEVICES_MSPI_FLASH_ID          0x001840A1

#define AM_DEVICES_MSPI_FLASH_ID_MASK   0x00FFFFFF

//*******************************************************************

//

// Device specific definitions for flash commands

//

//*******************************************************************

#defineAM_DEVICES_MSPI_FLASH_READ_STATUS_REGISTER1     0x05    // RDSR1, read STATUS_REGISTER 1

#define AM_DEVICES_MSPI_FLASH_READ_STATUS_REGISTER2     0x35    // RDSR2, read STATUS_REGISTER 2

#define AM_DEVICES_MSPI_FLASH_READ_STATUS_REGISTER3     0x15    // RDSR3, read STATUS_REGISTER 3

#define AM_DEVICES_MSPI_FLASH_WRITE_STATUS_REGISTER1    0x01    // WRSR1, write STATUS_REGISTER 1

#define AM_DEVICES_MSPI_FLASH_WRITE_STATUS_REGISTER2    0x31    // WRSR2, write STATUS_REGISTER 2

#define AM_DEVICES_MSPI_FLASH_WRITE_STATUS_REGISTER3    0x11    // WRSR3, write STATUS_REGISTER 3

#define AM_DEVICES_MSPI_FLASH_ENABLE_QPI_MODE           0x38    // EQIO, Enable QPI

#define AM_DEVICES_MSPI_FLASH_DISABLE_QPI_MODE          0xFF    // Disable QPI

#define AM_DEVICES_MSPI_FLASH_ENABLE_RESET              0x66    // Enable Reset

#define AM_DEVICES_MSPI_FLASH_RESET  0x99    // Reset

#define AM_DEVICES_MSPI_FLASH_WRITE_ENABLE_VOLATILE     0x50    // Write Enable for Volatile Status Register

//*******************************************************************

//

// Device specific definitions for the Configuration register(s)

//

//*******************************************************************

#define AM_DEVICES_MSPI_CLEAR_STATUS_REGISTER1          (0x00)   // the value to clear the status register-1

#define

AM_DEVICES_MSPI_ENABLE_QUAD_STATUS_REGISTER2    (0xF2)   // LC = 11b, dummy cycles = 4 for quad enable, 0 for spi mdode

#define AM_DEVICES_MSPI_CLEAR_STATUS_REGISTER3          (0xFC)   // to clear the status register-3, the reserved bits will be bypassed

//*******************************************************************

//

// Device specific definitions for the flash size information

//

//*******************************************************************

#define AM_DEVICES_MSPI_FLASH_PAGE_SIZE       0x100

// 256 bytes, minimum program unit

#define AM_DEVICES_MSPI_FLASH_SECTOR_SIZE  0x1000

// 4K bytes

#define AM_DEVICES_MSPI_FLASH_BLOCK_SIZE   0x10000

// 64K bytes.

#define AM_DEVICES_MSPI_FLASH_MAX_SECTORS   4096

// Sectors within 3-byte address range. 4096 * 4KB = 16MB

#define AM_DEVICES_MSPI_FLASH_MAX_BLOCKS     256

// 256 * 64KB = 16MB

#endif

上电后初始化先清除SR1和SR3中的相应的状态位和错误标志位。

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存