mk64f 做为spi从机,dma传输十几秒后,spi模块关闭

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

mk64f 做为spi从机,dma传输十几秒后,spi模块关闭

576 Views
feefefe
Contributor I

作为从机,spi通讯一定时间后模块自己关闭了。HALH 为1(stop传输)我用的freeROTS心痛,spi部分代码如下

#include"main.h"

#include "fsl_edma_driver.h"

#include "fsl_dspi_edma_slave_driver.h"

#include "fsl_debug_console.h"

#include "FFTdeal.h"

/*******************************************************************************

 

  • Prototypes

******************************************************************************/

 

 

/*******************************************************************************

 

  • Variables

******************************************************************************/

uint8_t receiveBuffer[TRANSFER_SIZE] = ;

uint8_t sendBuffer[4];

SemaphoreHandle_t xSemaphoreSPI = NULL;

uint8_t ADflag;

void dspi(void *pvParameters)

{

          unsigned int i,num=0;

        int16_t *p;

      dspi_status_t dspiResult;

    // Set up and init the slave.

    edma_state_t dmaState;

    edma_user_config_t dmaUserConfig;

    dspi_edma_slave_state_t edmaSlaveState;

    dspi_edma_slave_user_config_t edmaSlaveConfig;

     // Init OSA layer, used in DSPI_DRV_MasterTransferBlocking.

       /* Init board clock */

  // Configure SPI pins

          configure_spi_pins(DSPI_SLAVE_INSTANCE);

      // Initialze eDMA driver.

    dmaUserConfig.chnArbitration = kEDMAChnArbitrationRoundrobin;

    EDMA_DRV_Init(&dmaState, &dmaUserConfig);

      // Setup the configuration and get user options.

    edmaSlaveConfig.dataConfig.bitsPerFrame = 16;

    edmaSlaveConfig.dataConfig.clkPhase     = kDspiClockPhase_FirstEdge;

    edmaSlaveConfig.dataConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;

    edmaSlaveConfig.dummyPattern            = 0;

    // Initialize slave driver.

    dspiResult = DSPI_DRV_EdmaSlaveInit(DSPI_SLAVE_INSTANCE,

                                            &edmaSlaveState,

                                            &edmaSlaveConfig);

     //     GPIO_DRV_WritePinOutput(spiEN,1);

          for(i=0;i<     TRANSFER_SIZE;i++) //数据缓存清除

               {

                    receiveBuffer[i]=0;

               }

          vSemaphoreCreateBinary( xSemaphoreSPI );

               xSemaphoreTake(xSemaphoreSPI,portMAX_DELAY);

     while(true)

     {

 

 

          GPIO_DRV_WritePinOutput(spiEN,1);     //通知主机可以发送

          dspiResult = DSPI_DRV_EdmaSlaveTransferBlocking(DSPI_SLAVE_INSTANCE,

                                                        NULL,

                                                        receiveBuffer,

                                                        TRANSFER_SIZE,

                                                        SLAVE_TRANSFER_TIMEOUT);

          GPIO_DRV_WritePinOutput(spiEN,0);     //通知主机停止发送

        if (dspiResult != kStatus_DSPI_Success)

        {

            PRINTF("\r\nERROR: transfer error \r\n");

             

        }

          if(receiveBuffer[TRANSFER_SIZE-1]==0xaa&&receiveBuffer[TRANSFER_SIZE-1]==0xaa)//如果数据正确,data buffer

          {

                p=(int16_t*)receiveBuffer;

               adArray[ADflag].Analog1_1[num] =*p++;

               adArray[ADflag].Analog1_2[num] =*p++;

               adArray[ADflag].Ua1[num]       =*p++;

               adArray[ADflag].Ub1[num]       =*p++;

               adArray[ADflag].Uc1[num]       =*p++;

               adArray[ADflag].Ia1[num]       =*p++;

               adArray[ADflag].Ib1[num]       =*p++;

               adArray[ADflag].Ic1[num]       =*p++;

                

               adArray[ADflag].Analog2_1[num] =*p++;

               adArray[ADflag].Analog2_2[num] =*p++;

               adArray[ADflag].Ua2[num]       =*p++;

               adArray[ADflag].Ub2[num]       =*p++;

               adArray[ADflag].Uc2[num]       =*p++;

               adArray[ADflag].Ia2[num]       =*p++;

               adArray[ADflag].Ib2[num]       =*p++;

               adArray[ADflag].Ic2[num]       =*p;          

                num++;

               if(num>=FFTLEN)

               {

                    num=0;

                    if(ADflag==0)

                         ADflag=1;

                    else ADflag=0;

                    xSemaphoreGive(xSemaphoreSPI );

               }

 

 

          }

           

          stackDepth= uxTaskGetStackHighWaterMark(NULL);//发送信号量 进行FFT运算

      }

}

 

 

 

 

 

开始通讯时正常,时间不定大概10几秒后,spi模块自己关闭

 

 

 

请问什么情况能使spi自己停止传输?

Labels (1)
0 Kudos
1 Reply

444 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Fee Fefe,

我感觉问题应该在freeRtos的使用上,你的semaphore使用方式不对, 我猜是系统里有不止一个任务在使用这个SPI端口,但是你在while(true)外面获取这个semaphore, 而在里面释放它,那什么时候再次去获取呢?在每次while循环中,会不会碰到一种情况,在你调用DSPI_DRV_EdmaSlaveTransferBlocking()时候,另一个任务也正在使用这个SPI呢?这样就会造成冲突,有可能发生你碰到的问题。建议修改一下task的具体实现方式。


Have a great day,
Kan

NXP Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos