1.代码示例路径
PRJ_M66_4.3.3\boards\apollo4l_blue_eb\examples\interfaces\mspi_ds35x1ga_quad_example\src\mspi_ds35x1ga_quad_example.c
本文中主要讲解初始化流程内容
2.MSPI通信示意图
SCK(Serial Clock):串行时钟,用于同步数据传输。主设备通过控制SCK的上升沿和下降沿来确定数据传输时机。
CS(Chip Select):片选信号,用于选择要与主设备通信的从设备。当CS被拉低时,表示当前从设备被选中,可以进行数据传输。
WP(Write Protect):WP引脚用于写保护控制。当WP引脚处于高电平时,NAND Flash芯片的写操作将被禁止,即无法对芯片进行写入操作,保护数据的安全性。当WP引脚处于低电平时,芯片可以进行正常的写入操作。
HOLD:HOLD引脚用于暂停NAND Flash的操作。当HOLD引脚处于低电平时,芯片会暂停当前的操作,但会保持状态和数据。这在某些情况下非常有用,例如当需要处理其他优先级更高的任务时,可以通过将HOLD引脚拉低来暂停芯片的操作,等到任务完成后再恢复操作。
D0-D7:数据传输总线,基于不同的外设需要配置不同的数量的通路进行传输。
3.开发板硬件信息
(1)本实验基于Apollo4BlueLite EB板进行调试的,注意调整拨码开关如下图所示:
(2)Apollo4BlueLite有3组MSPI控制器,在该示例中采用了Apollo4BlueLite芯片的MSPI2和nandflash进行通信。引脚定义如下图所示
#define AM_BSP_GPIO_MSPI2_SCK 82
#define AM_BSP_GPIO_MSPI2_CE0 91
#define AM_BSP_GPIO_MSPI2_D0 74
#define AM_BSP_GPIO_MSPI2_D1 75
#define AM_BSP_GPIO_MSPI2_D2 76
#define AM_BSP_GPIO_MSPI2_D3 77
#define AM_BSP_GPIO_NAND_FLASH_WP 76
#define AM_BSP_GPIO_NAND_FLASH_HOLD 77
(3)该示例中采用了东芯厂家的nandflash,型号为ds35x1ga,芯片信息可以参考下图中命名规则得到。
4.例程分析
(1)例程运行log如下:
MSPI NAND Flash Driver example @ 48 MHz, Mode: QUAD 1-1-4 !
Vendor Name: AMBQ
Device type: Apollo4 Lite
Starting MSPI SDR Timing Scan for MSPI2:
Configure the MSPI and Flash Device correctly!
NAND flash ID is 0xefba!
block 4 erase status 0x0!
page 256 write status 0x0!
page 256 read status 0x0!
page 256 read ECC status 0x0!
succeed and read data equals to the write data
从运行log可以看到MSPI运行时钟配置为48MHz(当前nandflash支持的最大时钟频率为104MHz)
配置模式为AM_HAL_MSPI_FLASH_QUAD_CE0_1_1_4
(2)构造测试数据
代码开始构造了2048字节的测试数据和64字节的OOB buffer(这是根据使用的nandflash设备端构造的)
■ PAGE READ / PROGRAM- (2048+64 spare) byte
(3)初始化
- am_devices_mspi_ds35x1ga_init
初始化MSPI2,初始化配置参数如下:
这里默认配置eClockFreq为48MHz,AM_HAL_MSPI_FLASH_QUAD_CE0_1_1_4(这里1_4_4表示1线发送cmd,4线发送address,4线发送data)
const am_devices_mspi_ds35x1ga_config_t MSPI_Quad_Flash_Config =
{
.eDeviceConfig = AM_HAL_MSPI_FLASH_QUAD_CE0_1_1_4,
.eClockFreq = MSPI_TEST_CLKFREQ,
.pNBTxnBuf = DMATCBBuffer,
.ui32NBTxnBufLength = (sizeof(DMATCBBuffer) / sizeof(uint32_t)),
.ui32ScramblingStartAddr = 0,
.ui32ScramblingEndAddr = 0,
};
- am_hal_mspi_initialize
初始化一个pMspiHandle的数据结构
- am_hal_mspi_power_control
使能MSPI电源控制
- am_hal_mspi_configure
主要配置了MSPI XIP功能的相关配置,这里默认是关闭XIP功能的。同时还检查了DMA transfer buffer
- am_hal_mspi_device_configure
通过该函数配置MSPI Device,这里首次将MSPI Device配置为串行模式
- am_hal_mspi_enable
使能MSPI模块,包括初始化MSPI的command queue
- am_bsp_mspi_pins_enable
根据外围存储设备的类型设置MSPI pin,这里配置AM_HAL_MSPI_FLASH_SERIAL_CE0模式,如下图配置
- am_devices_mspi_ds35x1ga_wp_hold_pinconfig
配置MSPI2的WP和HOLD管脚,使用4线传输数据时WP和SIO2引脚复用,HOLD和SIO3引脚复用
- am_devices_mspi_ds35x1ga_reset
发送复位指令给nandflash,根据下表只需要发送复位指令0xFF给device即可
FUNCTION | Command Code | Address Bytes | Dummy Bytes | Data Bytes | Comments |
RESET | FFh | 0 | 0 | 0 | Reset the device |
- am_device_init_flash
该接口通过发送set feature和get feature指令来实现对nandflash的初始化,具体实现需要根据不同厂商的flash来确定
- am_hal_mspi_disable
MSPI disable,包括disable Command Queue,复位Command queue。这里是为了重新配置MSPI做准备
- am_hal_mspi_device_configure
在这里重新配置了MSPI Device为AM_HAL_MSPI_FLASH_QUAD_CE0_1_1_4模式
- am_hal_mspi_enable
重新使能MSPI,主要是对command queue的初始化
- am_bsp_mspi_pins_enable
在这里配置MSPI PIN为AM_HAL_MSPI_FLASH_QUAD_CE0_1_1_4,可以看到这里设置了4根数据线
- am_hal_mspi_interrupt_clear
- am_hal_mspi_interrupt_enable
清除MSPI中断再使能相应的中断,这里主要配置了CQUPD中断和MSPI的ERR相关中断
(4)read ID
- am_devices_mspi_ds35x1ga_enter_command_mode
进入到指令模式,主要是需要对配置mspi为串口模式进行指令发送,另外需要注意这里会配置MSPI CLK为4MHz
- am_devices_mspi_ds35x1ga_command_read
发送read ID指令,在函数中会通过查询CTRL寄存器状态bit的方式,阻塞等待指令执行完成并拿到对应的2byte的device ID
指令结构如下
FUNCTION | Command Code | Address Bytes | Dummy Bytes | Data Bytes | Comments |
READ ID | 9Fh | 0 | 1 | 2 | Read device ID |
- am_devices_mspi_ds35x1ga_exit_command_mode
退出指令模式,配置MSPI为4线模式