硬汉嵌入式论坛

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

[SPI/QSPI] SPI修改为DMA方式后,程序卡死在FDCAN_CalcultateRamBlockAddresses

[复制链接]

5

主题

6

回帖

21

积分

新手上路

积分
21
发表于 2022-4-12 17:11:50 | 显示全部楼层 |阅读模式
1、最近在将7606的SPI的的的查询方式修改为DMA方式操作,修改程序后,只接受成功数据一次,程序就卡死了,而且卡死的位置很奇怪 FDCAN_CalcultateRamBlockAddresses函数内的下面此处
/* Flush the allocated Message RAM area */
    for (RAMcounter = hfdcan->msgRam.StandardFilterSA; RAMcounter < hfdcan->msgRam.EndAddress; RAMcounter += 4U)
    {
      *(uint32_t *)(RAMcounter) = 0x00000000;
    }


2、在安富莱例程上进行的修改,bsp_spi_bus.c进行了修改部分内容
uint32_t g_spiADLen;ALIGN_32BYTES(__attribute__((section(".RAM_D3"))))DMA_HandleTypeDef hdma_spi6_rx;
ALIGN_32BYTES(__attribute__((section(".RAM_D3"))))DMA_HandleTypeDef hdma_spi6_tx;

ALIGN_32BYTES(__attribute__((section(".RAM_D3")))) uint8_t g_spiADTxBuf[16];  
ALIGN_32BYTES(__attribute__((section(".RAM_D3")))) uint8_t g_spiADRxBuf[16];

//硬件初始化
void HAL_SPI_MspInit(SPI_HandleTypeDef *_hspi)
{
if(_hspi->Instance==SPI6)
                {
                        /* SPI和GPIP时钟 */
                        SPI6_SCK_CLK_ENABLE();
                        SPI6_MISO_CLK_ENABLE();               
                        SPI6_CLK_ENABLE();

                        /* SPI SCK */
                        GPIO_InitStruct.Pin       = SPI6_SCK_PIN;
                        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
                        GPIO_InitStruct.Pull      = GPIO_NOPULL;
                        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
                        GPIO_InitStruct.Alternate = SPI6_SCK_AF;
                        HAL_GPIO_Init(SPI6_SCK_GPIO, &GPIO_InitStruct);

                        /* SPI MISO */
                        GPIO_InitStruct.Pin = SPI6_MISO_PIN;
                        GPIO_InitStruct.Alternate = SPI6_MISO_AF;
                        HAL_GPIO_Init(SPI6_MISO_GPIO, &GPIO_InitStruct);
                        //配置其DMA
                         SPI6_DMA_Config();
                }
        }
}

void SPI6_DMA_Config(void)
{
        /* 使能DMA时钟 */
        __HAL_RCC_BDMA_CLK_ENABLE();

        /* SPI6 DMA Init */
    /* SPI6_RX Init */
    hdma_spi6_rx.Instance = SPI6_MISO_STREAM;
    hdma_spi6_rx.Init.Request = BDMA_REQUEST_SPI6_RX;
    hdma_spi6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_spi6_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi6_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi6_rx.Init.Mode = DMA_NORMAL;
    hdma_spi6_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_spi6_rx) != HAL_OK)
    {
      //Error_Handler();
                        return;
    }

    __HAL_LINKDMA(&hspi6,hdmarx,hdma_spi6_rx);

    /* SPI6_TX Init */
    hdma_spi6_tx.Instance = SPI6_MOSI_STREAM;
    hdma_spi6_tx.Init.Request = BDMA_REQUEST_SPI6_TX;
    hdma_spi6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_spi6_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi6_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi6_tx.Init.Mode = DMA_NORMAL;
    hdma_spi6_tx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_spi6_tx) != HAL_OK)
    {
      //Error_Handler();
                        return;
    }

    __HAL_LINKDMA(&hspi6,hdmatx,hdma_spi6_tx);

        /* 配置DMA发送中断 */
        HAL_NVIC_SetPriority(SPI6_BDMA_TX_IRQn, 2, 0);
        HAL_NVIC_EnableIRQ(SPI6_BDMA_TX_IRQn);
   // HAL_DMA_RegisterCallback(&hdma_spi6_rx, HAL_DMA_XFER_CPLT_CB_ID, SPI6_DMA_ReciveNew);
        /* 配置DMA接收中断 */
        HAL_NVIC_SetPriority(SPI6_BDMA_RX_IRQn, 2, 0);
        HAL_NVIC_EnableIRQ(SPI6_BDMA_RX_IRQn);

        /* 配置SPI中断 */
        HAL_NVIC_SetPriority(SPI6_IRQn, 2, 0);
        HAL_NVIC_EnableIRQ(SPI6_IRQn);
}

void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
        if(hspi->Instance==SPI2)
        {
                wTransferflashState = TRANSFER_COMPLETE;
        }

        if (hspi->Instance == SPI6)
        {
                 HAL_SPI_DMAStop(&hspi6);//先关掉DMA
                 wTransfer7606State = TRANSFER_COMPLETE;
        }

}



void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
        if(hspi->Instance==SPI2)
        {
                wTransferflashState = TRANSFER_ERROR;
        }

        if (hspi->Instance == SPI6)
        {
                HAL_SPI_DMAStop(&hspi6);//先关掉DMA
                wTransfer7606State = TRANSFER_ERROR;
        }

}


void bsp_spiDMAADTransfer(uint16_t Size)
{
        if (Size > SPI_BUFFER_SIZE)
        {
                return;
        }


        //wTransfer7606State = TRANSFER_WAIT;
        SCB_CleanDCache();

        if (HAL_SPI_TransmitReceive_DMA(&hspi6, (uint8_t*)g_spiADTxBuf, (uint8_t*)g_spiADRxBuf, Size) != HAL_OK)
        {
                Error_Handler(__FILE__, __LINE__);
        }

//        while (wTransfer7606State == TRANSFER_WAIT)
//        {
//                ;
//        }

}


回复

使用道具 举报

5

主题

6

回帖

21

积分

新手上路

积分
21
 楼主| 发表于 2022-4-12 17:12:58 | 显示全部楼层
请大神们指导下
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107137
QQ
发表于 2022-4-12 18:09:23 | 显示全部楼层
这个确实诡异,修改SPI DMA,怎么卡在FDCAN里面了。
回复

使用道具 举报

0

主题

19

回帖

19

积分

新手上路

积分
19
发表于 2022-4-16 15:02:49 | 显示全部楼层
注意HAL_SPI_DMASTOP是把SPI得TX和RX得同时停止
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-20 08:50 , Processed in 0.190114 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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