打印
[STM32H7]

STM32H743 BOOTLOAD后SPI问题求教

[复制链接]
851|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xad74|  楼主 | 2024-4-27 18:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32H743 SPI2采用DMA方式进行数据收发,在不加BOOTLOAD功能时SPI数据收发正常,当加入BOOTLOAD 功能后程序能够从BOOT程序跳转到APP程序指示灯等功能正常,但SPI2在DMA方式时无法接到数据,改为非DMA方式时数据接收正常,由于收发数据量比较大所以无法将SPI的DMA方式改为非DMA方式,地址偏移量设置:#define VECT_TAB_OFFSET  0x100000UL//0x00020000UL
BOOT跳转程序代码如下
static void JumpToApp(void)
{
        uint32_t i=0;
        void (*AppJump)(void);         /* 声明一个函数指针 */
   
    /* 关闭全局中断 */
        DISABLE_INT();
   
    /* 设置所有时钟到默认状态,使用HSI时钟 */
        HAL_RCC_DeInit();
        SPI2->CR1&=~(1<<0);                        //SPE=1,停止SPI2
        RCC->APB1LENR&=~(1<<14);        //关闭SPI2时
        RCC->APB1LRSTR&=~(1<<14);        //停止复位SPI2
       
        RCC->AHB1ENR&=~(1<<0);                //禁止DMA1时钟使能
        DMA1_Stream1->CR&=~(1<<0);         //关闭DMA传输
    DMA1_Stream0->CR&=~(1<<0);         //关闭DMA传输
       
        /* 关闭滴答定时器,复位到默认值 */
        SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

        /* 关闭所有中断,清除所有中断挂起标志 */
        for (i = 0; i < 8; i++)
        {
                NVIC->ICER[i]=0xFFFFFFFF;
                NVIC->ICPR[i]=0xFFFFFFFF;
        }       

        /* 使能全局中断 */
        ENABLE_INT();

        /* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */
        AppJump = (void (*)(void)) (*((uint32_t *) (AppAddr + 4)));

        /* 设置主堆栈指针 */
        __set_MSP(*(uint32_t *)AppAddr);
       
        /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
        __set_CONTROL(0);

        /* 跳转到系统BootLoader */
        AppJump();

        /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
        while (1)
        {

        }
}
SPI2 DMA读写函数
void SPI2_DMA_WRITE(uint8_t* Addref, uint8_t* pTxBuf, uint16_t tx_len)
{
        uint16_t i;
       
        if (tx_len > W5500_SPI_BUFFER_SIZE)
        {
                return;
        }

        memset(SPI2_DMA_TxBuff, 0, tx_len + 3);

        SPI2_DMA_TxBuff[0] = Addref[0];
        SPI2_DMA_TxBuff[1] = Addref[1];
        SPI2_DMA_TxBuff[2] = Addref[2];

        for(i=0; i<tx_len; i++)
                SPI2_DMA_TxBuff[3 + i] = pTxBuf[i];
       
        wTransferState = TRANSFER_WAIT;
        W5500_1_CS0();
//        SPI2_TransmitReceive_DMA((uint8_t*)SPI2_DMA_TxBuff, (uint8_t *)SPI2_DMA_RxBuff, tx_len+3);
        if(HAL_SPI_TransmitReceive_DMA(&hspi2, (uint8_t*)SPI2_DMA_TxBuff, (uint8_t *)SPI2_DMA_RxBuff, tx_len+3) != HAL_OK)       
        {
                Error_Handler(__FILE__, __LINE__);
        }
        while (wTransferState == TRANSFER_WAIT){;}
        W5500_1_CS1();
}

void SPI2_DMA_READ(uint8_t* Addref, uint8_t* pRxBuf, uint16_t rx_len)
{
        if (rx_len > W5500_SPI_BUFFER_SIZE)
        {
                return;
        }
   
        memset(SPI2_DMA_TxBuff, 0, rx_len + 3);       
        memset(SPI2_DMA_RxBuff, 0, rx_len + 3);

        SPI2_DMA_TxBuff[0] = Addref[0];
        SPI2_DMA_TxBuff[1] = Addref[1];
        SPI2_DMA_TxBuff[2] = Addref[2];
        wTransferState = TRANSFER_WAIT;
       
        W5500_1_CS0();
//        SPI2_TransmitReceive_DMA((uint8_t*)SPI2_DMA_TxBuff, (uint8_t *)SPI2_DMA_RxBuff, rx_len+3);
        if(HAL_SPI_TransmitReceive_DMA(&hspi2, (uint8_t*)SPI2_DMA_TxBuff, (uint8_t *)SPI2_DMA_RxBuff, rx_len+3) != HAL_OK)       
        {
                Error_Handler(__FILE__, __LINE__);
        }       
        while (wTransferState == TRANSFER_WAIT){;}
        W5500_1_CS1();
        memcpy(pRxBuf, SPI2_DMA_RxBuff + 3, rx_len);
}

使用特权

评论回复
沙发
xad74|  楼主 | 2024-4-27 21:11 | 只看该作者
上传了代码

V7_APP.rar

1.29 MB

V7_BOOT.rar

1.63 MB

使用特权

评论回复
板凳
xad74|  楼主 | 2024-4-28 11:14 | 只看该作者
下沉的这么快吗

使用特权

评论回复
地板
香水城| | 2024-4-28 13:16 | 只看该作者
你在跳转前将D-Cache也关闭掉试试。

使用特权

评论回复
5
香水城| | 2024-4-28 13:23 | 只看该作者
另外,你看看跳转前、后跟SPI通信有关的数据内存地址分别是在哪里?有无因为DCache导致的一致性问题。

使用特权

评论回复
6
我喜欢打游戏| | 2024-4-28 16:49 | 只看该作者
估计是DCache的一致性问题

使用特权

评论回复
7
中国龙芯CDX| | 2024-4-29 16:53 | 只看该作者
SPI应该是很好用的通信方式

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

168

帖子

3

粉丝