硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4489|回复: 6
收起左侧

[HAL学习笔记] HAL库源文件stm32h7xx_hal_qspi.c学习笔记,QSPI Flash(2018-10-05 V1.0)

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106826
QQ
发表于 2018-10-5 00:17:15 | 显示全部楼层 |阅读模式
说明:
QSPI的内存映射模式,自动查询模式和间接模式。

间接模式就是相对于内存映射时,可以是总线直接访问来说的。


==============================================================================
                                                                  ##### 驱动如何使用  #####
==============================================================================  

1、底层初始化HAL_QSPI_MspInit。
(1)__HAL_RCC_QSPI_CLK_ENABLE
(2)函数__HAL_RCC_QSPI_FORCE_RESET() 配合 __HAL_RCC_QSPI_RELEASE_RESET()可复位QSPI(3)__HAL_RCC_GPIOx_CLK_ENABLE
(3)HAL_GPIO_Init配置复用模式
(4)如果使用中断模式,调用函数HAL_NVIC_SetPriority() 和 HAL_NVIC_EnableIRQ()设置
(5)使用DMA传输时,用的是MDMA,
        a、__HAL_RCC_MDMA_CLK_ENABLE
        b、HAL_MDMA_Init
        c、__HAL_LINKDMA
       如果需要中断处理,需要配置NVIC
        a、HAL_NVIC_SetPriority
        b、HAL_NVIC_EnableIRQ
        c、SDMMC的中断使能和禁止函数__HAL_SD_ENABLE_IT,__HAL_SD_DISABLE_IT
        d、中断标志位处理__HAL_SD_GET_IT和__HAL_SD_CLEAR_IT
        e、SDMCC不需要通用的DMA,因为内部自带一个DMA。
(7)函数HAL_QSPI_Init配置flash大小,时钟分频,fifo阀值,时钟模式,采样偏移,CS高电平时间。

2、间接模式
(1)函数HAL_QSPI_Command或者HAL_QSPI_Command_IT配置命令时序
        a、这几个阶段都是可以配置是否使用的。
        b、指令阶段。
        c、地址阶段。
        d、可选字节阶段。
        e、空周期阶段。
        f、数据阶段。
        DDR模式配置,时钟的上升沿和下降沿均可做数据收发。
        Sending Instruction Only Once (SIOO)模式配置,这种模式发送一次指令后,就可以方便的做读写操作,不过需要外部Flash支持这种模式才行。

(2)如果命令不需要数据,则将其直接发送到内存:
        在轮询模式下,输出功能在传输完成时完成。
        在中断模式下,传输完成后将调用HAL_QSPI_CmdCpltCallback。

(3)间接模式写操作可以调用use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() 或者 HAL_QSPI_Transmit_IT()
        a、在轮询模式下,写操作在传输完成时完成。
        b、在中断模式,达到FIFO阀值的时调用回调函数HAL_QSPI_FifoThresholdCallback,传输完成的时候调用回调函数HAL_QSPI_TxCpltCallback。
        c、在DMA模式,半传输完成的时候调用回调函数HAL_QSPI_TxHalfCpltCallback,而全部传输完成的时候调用回调函数HAL_QSPI_TxCpltCallback

(4)间接模式读操作可以调用HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() 或者 HAL_QSPI_Receive_IT()
        a、在轮询模式下,读操作在传输完成时完成。
        b、在中断模式,达到FIFO阀值的时调用回调函数HAL_QSPI_FifoThresholdCallback,传输完成的时候调用回调函数HAL_QSPI_RxCpltCallback。
        c、在DMA模式,半传输完成的时候调用回调函数HAL_QSPI_RxHalfCpltCallback,而全部传输完成的时候调用回调函数HAL_QSPI_RxCpltCallback。

3、自动查询模式
(1)函数HAL_QSPI_AutoPolling() 或者 HAL_QSPI_AutoPolling_IT()配置时序
        a、这几个阶段都是可以配置是否使用的。
        b、指令阶段。
        c、地址阶段。
        d、可选字节阶段。
        e、空周期阶段。
        f、数据阶段。
        g、Sending Instruction Only Once (SIOO)模式配置,这种模式发送一次指令后,就可以方便的做读写操作,不过需要外部Flash支持这种模式才行。
        h、状态字节的大小,匹配值,使用的掩码,匹配模式(OR / AND),轮询间隔和激活自动停止。
(2)配置完成后:
        a、在轮询模式下,写操作在达到状态匹配时完成,同时激活自动停止以避免无限循环。
        b、在中断模式下,每次状态匹配时都会调用HAL_QSPI_StatusMatchCallback()。

4、内存映射模式
(1)函数HAL_QSPI_MemoryMapped配置命令时序和内存映射
        a、这几个阶段都是可以配置是否使用的。
        b、指令阶段。
        c、地址阶段。
        d、可选字节阶段。
        e、空周期阶段。
        f、数据阶段。     
        g、DR模式配置,时钟的上升沿和下降沿均可做数据收发。
        h、Sending Instruction Only Once (SIOO)模式配置,这种模式发送一次指令后,就可以方便的做读写操作,不过需要外部Flash支持这种模式才行。
        i、超时激活和超时时间。
(2)配置完成后,只要地址范围内的AHB总线访问完成,就会使用QuadSPI。超时到期时将调用HAL_QSPI_TimeOutCallback()。

5、错误管理和终止功能
(1)HAL_QSPI_GetError()函数给出上一次操作期间引发的错误。
(2)HAL_QSPI_Abort()和HAL_QSPI_AbortIT()函数中止任何正在进行的操作并刷新fifo:
        a、在轮询模式下,当传输完成位被置位,忙位清零时,写操作完成。
        b、在中断模式下,当传输完成位被置位时,回调函数HAL_QSPI_AbortCpltCallback()将被调用。

6、控制和状态获取功能
(1)HAL_QSPI_GetState() 用于获取当前的驱动状态f。
(2)HAL_QSPI_SetTimeout() 配置溢出时间。
(3)HAL_QSPI_SetFifoThreshold() 配置FIFO的阀值。
(4)HAL_QSPI_GetFifoThreshold() 给出当前的FIFO阀值。

7、QSPI的一个勘误处理:
     在读传输结束时写入FIFO的额外数据



/* 初始化和复位初始化 */
HAL_StatusTypeDef     HAL_QSPI_Init     (QSPI_HandleTypeDef *hqspi);
HAL_StatusTypeDef     HAL_QSPI_DeInit   (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_MspInit  (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi);

/* QSPI IRQ */
void                  HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi);

/* QSPI 间接模式 */
HAL_StatusTypeDef     HAL_QSPI_Command      (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout);
HAL_StatusTypeDef     HAL_QSPI_Transmit     (QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout);
HAL_StatusTypeDef     HAL_QSPI_Receive      (QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout);
HAL_StatusTypeDef     HAL_QSPI_Command_IT   (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd);
HAL_StatusTypeDef     HAL_QSPI_Transmit_IT  (QSPI_HandleTypeDef *hqspi, uint8_t *pData);
HAL_StatusTypeDef     HAL_QSPI_Receive_IT   (QSPI_HandleTypeDef *hqspi, uint8_t *pData);
HAL_StatusTypeDef     HAL_QSPI_Transmit_DMA (QSPI_HandleTypeDef *hqspi, uint8_t *pData);
HAL_StatusTypeDef     HAL_QSPI_Receive_DMA  (QSPI_HandleTypeDef *hqspi, uint8_t *pData);

/* QSPI 状态标志查询模式 */
HAL_StatusTypeDef     HAL_QSPI_AutoPolling   (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout);
HAL_StatusTypeDef     HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg);

/* QSPI 内存映射模式 */
HAL_StatusTypeDef     HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg);

/* 非阻塞回调函数 */
void                  HAL_QSPI_ErrorCallback        (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_AbortCpltCallback    (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi);

/* QSPI 间接模式 */
void                  HAL_QSPI_CmdCpltCallback      (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_RxCpltCallback       (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_TxCpltCallback       (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_RxHalfCpltCallback   (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_TxHalfCpltCallback   (QSPI_HandleTypeDef *hqspi);

/* QSPI 状态标志查询模式 */
void                  HAL_QSPI_StatusMatchCallback  (QSPI_HandleTypeDef *hqspi);

/* QSPI 内存映射模式 */
void                  HAL_QSPI_TimeOutCallback      (QSPI_HandleTypeDef *hqspi);

/* 外设控制和状态函数 */
HAL_QSPI_StateTypeDef HAL_QSPI_GetState        (QSPI_HandleTypeDef *hqspi);
uint32_t              HAL_QSPI_GetError        (QSPI_HandleTypeDef *hqspi);
HAL_StatusTypeDef     HAL_QSPI_Abort           (QSPI_HandleTypeDef *hqspi);
HAL_StatusTypeDef     HAL_QSPI_Abort_IT        (QSPI_HandleTypeDef *hqspi);
void                  HAL_QSPI_SetTimeout      (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
HAL_StatusTypeDef     HAL_QSPI_SetFifoThreshold(QSPI_HandleTypeDef *hqspi, uint32_t Threshold);
uint32_t

回复

使用道具 举报

1

主题

28

回帖

31

积分

新手上路

积分
31
发表于 2020-3-17 15:59:50 | 显示全部楼层
什么原因会导致 QSPI_WaitFlagStateUntilTimeout 这里超时?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106826
QQ
 楼主| 发表于 2020-3-18 17:43:08 | 显示全部楼层
chiyoohui 发表于 2020-3-17 15:59
什么原因会导致 QSPI_WaitFlagStateUntilTimeout 这里超时?

暂时没有遇到过。
回复

使用道具 举报

1

主题

28

回帖

31

积分

新手上路

积分
31
发表于 2020-3-20 08:25:54 | 显示全部楼层
eric2013 发表于 2020-3-18 17:43
暂时没有遇到过。

这几天碰上了,找出来的原因是RL-TCPnet做服务器时,PC机有反复频率也较快的“连接-断开连接-连接”这样子就会导致QSPI这里超时
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106826
QQ
 楼主| 发表于 2020-3-20 09:01:13 | 显示全部楼层
chiyoohui 发表于 2020-3-20 08:25
这几天碰上了,找出来的原因是RL-TCPnet做服务器时,PC机有反复频率也较快的“连接-断开连接-连接”这样 ...

不清楚哦,你自己研究下吧。
回复

使用道具 举报

1

主题

24

回帖

27

积分

新手上路

积分
27
发表于 2020-3-23 08:56:41 | 显示全部楼层
有没有发现W25Q256和W25Q16这两种程序是不是不能通用
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106826
QQ
 楼主| 发表于 2020-3-23 09:01:02 | 显示全部楼层
nzk123 发表于 2020-3-23 08:56
有没有发现W25Q256和W25Q16这两种程序是不是不能通用

以我们的程序为例。
我们W25Q256是用的4线模式QSPI模式,而我们的W25Q64是标准1线SPI模式,即使是同一个芯片,不同线制接线方式,命令也是不同的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-6 02:08 , Processed in 0.179188 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表