硬汉嵌入式论坛

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

[SPI/QSPI] STM32H743 BOOTLOAD后SPI问题求教

[复制链接]

6

主题

21

回帖

39

积分

新手上路

积分
39
发表于 2024-4-27 16:01:06 | 显示全部楼层 |阅读模式

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)
{
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2024-4-27 17:26:16 | 显示全部楼层
楼主方便的话,分享些代码和配置看下
回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-27 18:02:03 | 显示全部楼层
不知道咋没发出来
BOOT跳转代码
tatic 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)
        {

        }
}
回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-27 18:02:55 | 显示全部楼层
SPI2 DMA读写代码
/*
*********************************************************************************************************
*        函 数 名: DMA1_Stream1_IRQHandler
*        功能说明: DMA1 Stream1中断服务程序
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
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);
}
回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-27 18:05:54 | 显示全部楼层
KEIL 中配置方式如下图
无标题.png
回复

使用道具 举报

76

主题

685

回帖

913

积分

金牌会员

积分
913
发表于 2024-4-27 19:41:06 | 显示全部楼层
跳入APP前恢复主控状态,比如关闭时钟清理RAM等
回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-27 20:37:45 | 显示全部楼层
上传BOOT和APP软件

V7_APP.rar

22.55 MB, 下载次数: 1

回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-27 21:12:36 | 显示全部楼层
上传了代码,删除了库文件

V7_APP.rar

1.29 MB, 下载次数: 4

V7_BOOT.rar

1.63 MB, 下载次数: 5

回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-28 11:10:16 | 显示全部楼层
庄永 发表于 2024-4-27 19:41
跳入APP前恢复主控状态,比如关闭时钟清理RAM等

这个跳转前已处理
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2024-4-29 08:09:34 | 显示全部楼层
xad74 发表于 2024-4-27 18:02
不知道咋没发出来
BOOT跳转代码
tatic void JumpToApp(void)

跳转前也使用SPI2 DMA了吗,如果也使用了最好调用相应的DeInit函数处理下

还是不行,上这个方案

实战技能分享,一劳永逸的解决BOOT跳转APP失败问题,含MDK AC5,AC6和IAR,同时制作了一个视频操作说明
https://www.armbbs.cn/forum.php? ... 9595&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

6

主题

21

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2024-4-30 10:39:28 | 显示全部楼层
eric2013 发表于 2024-4-29 08:09
跳转前也使用SPI2 DMA了吗,如果也使用了最好调用相应的DeInit函数处理下

还是不行,上这个方案

跳转前是用到了SP2和DMA,现在的问题是可以跳转,就是跳转后APP中部能使用DMA如果不使用DMA,SPI口是可以正常使用的。跳转前我禁止了SP2、DMA 、HAL_RCC_DeInit()、HAL_MspDeInit()、HAL_DeInit()不知道还要禁止那些。我初步判断可能跟D-Cache有关,但不知道如何调整
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-10 04:48 , Processed in 0.189530 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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