[STM32F7] STM32F746-Disco QuadSPI 裸机间接读取无通信

[复制链接]
743|11
唐纳德d 发表于 2025-9-17 23:17 | 显示全部楼层 |阅读模式

在用QuadSPI,在裸机环境下进行操作。

问题是:从QuadSPI Flash进行间接读取时,数据线上无通信,Fifo阈值标志始终被置位。

用了TouchGFX生成的代码(在STM32CubeIDE中打开),并且在运行TouchGFX程序时设置了一个断点,检查我的QuadSPI寄存器是否具有相同或相似的值。我确保GPIO配置完全相同,所有时钟均已启用,等等。

以下是我的设置代码:

void qspi_setup_indirect_mode(void){

        //NOR Flash MT25QL128ABA 128Mb=16MB

        /*
         * Control Register
         * Prescaler: Fclock = AHBclock/2
         * FIFO Threshold: FTF is set when 4 or more bytes available to be written to FIFO
         *
         * */
        QUADSPI->CR |= QUADSPI_CR_ABORT; //abort ongoing commands
        while(QUADSPI->CR & QUADSPI_CR_ABORT); //wait while aborted
        QUADSPI->CR = 0x00; //reset register
        QUADSPI->CR |= QUADSPI_CR_SSHIFT | (0x03 << QUADSPI_CR_FTHRES_Pos) | (0x01 << QUADSPI_CR_PRESCALER_Pos);

        /*
         * Device Configuraion register
         * Clock Mode 0 (default)
         * Chip Select High Time 6 Cycles
         * Flash Size 16MB = 2^24 bytes
         *
         * */
        QUADSPI->DCR = 0x00; //reset
        QUADSPI->DCR |= (0x05 << QUADSPI_DCR_CSHT_Pos) | (23U << QUADSPI_DCR_FSIZE_Pos);

        /*
         * Communication configuration register
         * Address size 24 bits
         *
         * */
        QUADSPI->CCR = ((QUADSPI->CCR) & (~(0x03 << QUADSPI_CCR_ADSIZE_Pos))) | (0x02 << QUADSPI_CCR_ADSIZE_Pos);

        QUADSPI->CR |= QUADSPI_CR_EN; //enable QUADSPI
}

这与TouchGFX的QuadSPI参数一致。

接下来,我设置了QuadSPI的单线指令和数据模式,而地址、交替字节和空周期均关闭。然后我设置间接读取模式,指定期望接收20字节的Flash ID(根据Flash IC的数据手册),并清除QSPI标志。将指令本身(读取ID的命令)加载到通信配置寄存器的INSTRUCTION位中。根据参考手册,这应该立即触发通信。代码等待直到达到Fifo阈值(4字节)到来,以便我可以一次性从数据寄存器中读取它们(作为uint32_t)。目前我不关心后续字节的处理,只要看到有任何数据接收,就会处理。


void qspi_read_id(void){

        qspi_set_command_mode(QSPI_IMODE_1, QSPI_ADMODE_0, QSPI_ABMODE_0, 0x00, QSPI_DMODE_1);//set command mode, 1 data line for instruction, 1 data line for data

        QUADSPI->CCR &= ~QUADSPI_CCR_FMODE | (0x01 << QUADSPI_CCR_FMODE_Pos); //indirect read mode

        QUADSPI->DLR = (uint32_t) 19; //expect to receive 20 bytes

        QUADSPI->FCR |= QUADSPI_FCR_CTOF | QUADSPI_FCR_CSMF | QUADSPI_FCR_CTCF | QUADSPI_FCR_CTEF;

        QUADSPI->CCR = (MT25QL128ABA1EW9_COMMAND_READ_ID_1 << QUADSPI_CCR_INSTRUCTION_Pos); //must trigger command transmission

        while(!(QUADSPI->SR & QUADSPI_SR_FTF)); //wait until there are 4 bytes of data to read
  
}



void qspi_set_command_mode(uint8_t imode, uint8_t admode, uint8_t abmode, uint8_t dcyc, uint8_t dmode){
        /*
         * Communication configuration register
         * First, reset all mode values
         * Set new values
         * */
        QUADSPI->CCR = QUADSPI->CCR & ~(QUADSPI_CCR_IMODE) & ~(QUADSPI_CCR_ADMODE) & ~(QUADSPI_CCR_ABMODE) & ~(QUADSPI_CCR_DCYC) & ~(QUADSPI_CCR_DMODE);
        QUADSPI->CCR = QUADSPI->CCR | (imode << QUADSPI_CCR_IMODE_Pos) | (admode << QUADSPI_CCR_ADMODE_Pos) | (abmode << QUADSPI_CCR_ABMODE_Pos) | (dcyc << QUADSPI_CCR_DCYC_Pos) | (dmode << QUADSPI_CCR_DMODE_Pos);
}

最后,主函数用于测试所有功能:

c
#include "main.h"

void system_hw_setup(void);


#include "main.h"

void system_hw_setup(void);

int main(void) {

        system_hw_setup(); //initialize hardware

        uint8_t receivedQSPIdata[4];

        while (1) {
                system_msdelay(1000U);
                //BREAKPOINT HERE
                qspi_read_id();
                uint32_t temp = QUADSPI->DR;
                receivedQSPIdata[0] = temp & 0xFF;
                receivedQSPIdata[1] = (temp >> 8) & 0xFF;
                receivedQSPIdata[2] = (temp >> 16) & 0xFF;
                receivedQSPIdata[3] = (temp >> 24) & 0xFF;
                usart_dma_sendArray(USART1, receivedQSPIdata, sizeof(receivedQSPIdata));

        }
}

system_hw_setup 初始化时钟和所有硬件,包括UART、DMA、NVIC、Systick等,以及qspi_setup_indirect_mode()。所有其他功能(包括UART DMA)100%正常工作。

如果我在循环中设置一个断点,使程序在每次调用qspi_read_id()之前暂停。在第一次调用read_id之前,QuadSPI->SR状态寄存器中唯一的标志是Fifo阈值标志。如果继续运行程序,1秒后我会再次在调用read_id之前暂停,此时我已经有了“busy”、“transfer complete”以及相同的“fifo threshold”标志。



公羊子丹 发表于 2025-9-19 07:30 | 显示全部楼层
这个情况挺典型的,看着像是命令根本没发出去,SR里只是默认状态。
周半梅 发表于 2025-9-19 07:31 | 显示全部楼层
AEC-Q100拿下了,那汽车钥匙和车载支付应用就更稳了。
帛灿灿 发表于 2025-9-19 07:32 | 显示全部楼层
你最后那行写INSTRUCTION的时候直接覆盖CCR,会不会把之前的模式配置冲掉?
童雨竹 发表于 2025-9-19 07:33 | 显示全部楼层
ST25R这系列感觉就是瞄准汽车+支付双赛道的。
万图 发表于 2025-9-19 07:34 | 显示全部楼层
有了这些认证,客户选型的时候顾虑会少很多。
Wordsworth 发表于 2025-9-19 07:35 | 显示全部楼层
不知道后续会不会再扩展到交通一卡通那类行业标准?
Bblythe 发表于 2025-9-19 07:36 | 显示全部楼层
做车厂项目的同学应该挺关注AEC-Q100这一块的。
Pulitzer 发表于 2025-9-19 07:37 | 显示全部楼层
EMVCo认证下来,商用支付机也可以直接考虑用ST25R了。
Uriah 发表于 2025-9-19 07:38 | 显示全部楼层
感觉ST这波是全面覆盖高可靠和高安全应用的市场。
Clyde011 发表于 2025-9-19 07:39 | 显示全部楼层
有实际测试过读卡距离和兼容性的吗?认证是一方面,体验也很重要。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

58

主题

58

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部