AnsweredAssumed Answered

Continuous Serial Communications Clock of K21F DSPI

Question asked by Fred Fu Employee on Dec 2, 2014
Latest reply on Dec 12, 2014 by Fred Fu

       One of my key customer is using DSPI1 to read extern flash, now they meet one problem, they want to read flash content via DMA,but SPI1 has only one DMA request source number for Transmit or Receive, so they send the flash command manually(without DMA), then enable DMA and set CONT_SCKE to generate continuous SCK signal to read flash,DMA can't get any data, the buffer is empty,We use Oscilloscope to observe wave, we can find the data from Flash;If they sent the dummy data( CONT_SCKE is clear) manually and received data using DMA, it is OK. I don't know if there is any error on SPI setting and DMA setting, or K21 can't support the usage? Thanks


int STDCALL SFlashHwInit(VOID)
{
  //SPI配置结构体定义
    SPI_InitTypeDef   SPI_InitStructure = SPI_INIT_DEFAULT;
 
  //时钟初始化
    SIM_SCGxClockEnable(SCG6, SFLASH_SPI_CLK_MASK);
    SIM_SCGxClockEnable(SCG5, SFLASH_GPIO_CLK_MASK);
   
//SPI IO口设置
GPIO_Set(SFLASH_SCK_GPIO, SFLASH_SCK_PIN, GPIO_Direction_OUT, SFLASH_SCK_MUX, GPIO_SlewRate_Fast | GPIO_DriveStrength_High);
GPIO_Set(SFLASH_MOSI_GPIO, SFLASH_MOSI_PIN, GPIO_Direction_OUT, SFLASH_MOSI_MUX, GPIO_SlewRate_Fast);
GPIO_Set(SFLASH_CS_GPIO, SFLASH_CS_PIN, GPIO_Direction_OUT, SFLASH_CS_MUX, GPIO_SlewRate_Fast);
GPIO_Set(SFLASH_MISO_GPIO, SFLASH_MISO_PIN, GPIO_Direction_IN, SFLASH_MISO_MUX, GPIO_SlewRate_Fast);
GPIO_Set(GPIOA, GPIO_Pin_13, GPIO_Direction_OUT, GPIO_MUX_ALT1, GPIO_SlewRate_Fast);
    GPIO_SetBits(SFLASH_CS_GPIO, SFLASH_CS_PIN);
    #ifdef SFLASH_WP_PIN
GPIO_Set(SFLASH_WP_GPIO, SFLASH_WP_PIN, GPIO_Direction_OUT, SFLASH_WP_MUX, GPIO_SlewRate_Fast);
#endif

    //spi, clock is 48/2 = 24 MHz
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_BaudrateScaler = SPI_BAUDRATE_SCALER_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_PSCState = SPI_PSC0State_High;
    SPI_InitStructure.SPI_BaudratePreScaler = SPI_BAUDRATE_PRESCALER_2;
    SPI_Init(SFLASH_SPI, &SPI_InitStructure);
    SPI1DMAConfig(szSPIBuf, SPI_DMA_BUF_LEN);
    SPI_Cmd(SFLASH_SPI, ENABLE);
#ifdef SFLASH_WP_PIN
    //WP设为上拉输入,由硬件上拉,此处也做上拉处理
    GPIO_SetBits(SFLASH_WP_GPIO, SFLASH_WP_PIN);
#endif

     //DMA_ReqCmd(DMA_CH3, ENABLE);
  
    return SUCCESS;
}

// void _SFlashWaitData(void)
// {
//  while ((SFLASH_SPI->SR & SPI_FLAG_RFDF) == RESET)
//  {
//   ;
//  }
//  SFLASH_SPI->SR |= SPI_FLAG_RFDF;
// }

INT SPI1DMAConfig(P_U8 DMABuf, UINT DMABufLen)
{
    DMA_InitTypeDef DMA_InitStructure;

  // 打开DMA时钟
    SIM_ModuleClockCmd(DMA_CLK, ENABLE);
    SIM_ModuleClockCmd(DMAMUX_CLK, ENABLE);
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;

    DMA_InitStructure.DMA_Channelx = DMA_CH3;
    DMA_InitStructure.DMA_Source_Req = 18;//SPI1_REV_DMAREQ;
    DMA_InitStructure.DMA_Trigger = DMA_Trigger_Disable;
    DMA_InitStructure.DMA_Major_Iteration_Count = DMABufLen;
    DMA_InitStructure.DMA_Minor_loop_Length = 1;
    DMA_InitStructure.DMA_Source_Addr = (U32)(&(SPI_POPR_REG(SPI1)));
    DMA_InitStructure.DMA_Source_Size = DMA_SRC_8BIT;
    DMA_InitStructure.DMA_Source_Addr_inc = 0;
    DMA_InitStructure.DMA_Source_Adj_Addr = 0;
    DMA_InitStructure.DMA_Dest_Addr = (U32)DMABuf;
    DMA_InitStructure.DMA_Dest_Size = DMA_DST_8BIT;
    DMA_InitStructure.DMA_Dest_Addr_inc = 1;
    DMA_InitStructure.DMA_Dest_Adj_Addr = (U32)(-DMABufLen);
    DMA_InitStructure.DMA_AutoClose = DMA_AutoClose_NOT;
   
    DMA_Init(&DMA_InitStructure);
    //DMA_ReqCmd(DMA_CH3, ENABLE);
    //USART_DMARxCmd(pUartBase, ENABLE);
    SPI_RSER_REG(SPI1_BASE_PTR) |= SPI_RSER_RFDF_RE_MASK | SPI_RSER_RFDF_DIRS_MASK;// | SPI_RSER_TFFF_RE_MASK | SPI_RSER_TFFF_DIRS_MASK;
   
    return SUCCESS;
}

INT STDCALL SFlashDrvReadBytes(UINT uAddr, PVOID pBuf, INT uRdSize)
{
    UINT uRdNum;
    UINT uRdRemainNum;
    UINT uSFlashAddr;
PBYTE pRdBuf = pBuf;
//U32 u32DummyData = SFCMD_DUMMY;

    uRdNum = 0;
    uSFlashAddr = uAddr - SFLASH_ADDR_BEGIN;
    uRdNum = uRdSize>>2UL;
    uRdRemainNum = uRdSize & 0x3;
    //ENTER_HW_IRQL_PRTCT   
//DMA_ReqCmd(DISABLE);
        _SFlashCSLow();
        _SFlashSendByte(SFCMD_READ_50MHZ);
        //发送地址,24位地址,发送3次,STM32F10X的SPI 8位数据帧格式发送的是低8位数据
        _SFlashSendByte((uSFlashAddr & 0xFF0000)>>16UL);
        _SFlashSendByte((uSFlashAddr & 0xFF00)>>8UL);
        _SFlashSendByte(uSFlashAddr & 0xFF);
        //接收数据
        ClearRecvData();       
    //设置数据长度,长度每次递减。也可以称为 当前主循环计数器 current major loop count
  DMA_BASE_PTR->TCD[DMA_CH3].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(uRdSize);
  //起始循环计数器,当主循环计数器为零的时候,将装载起始循环计数器的值
  DMA_BASE_PTR->TCD[DMA_CH3].BITER_ELINKNO = DMA_CITER_ELINKNO_CITER(uRdSize);

  DMA_BASE_PTR->TCD[DMA_CH3].DLAST_SGA = (U32)(-uRdSize);
  DMA_ReqCmd(DMA_CH3, ENABLE);
  //u32DummyData |= (SPI_PUSHR_REG(SFLASH_SPI)  & 0xffff0000);
  #define _DMA_SPI_
  #ifndef _DMA_SPI_
        for(; uRdNum != 0; uRdNum--)
        {
            //((PBYTE)pBuf)[uRdNum++] = _SFlashSendByte(SFCMD_DUMMY);
   //
   _SFlashSendData(SFLASH_SPI, SPI_PUSHR_REG(SFLASH_SPI));
   _SFlashWaitSend();
   //*pRdBuf++ = _SFlashReciveData(SFLASH_SPI);
           
            _SFlashSendData(SFLASH_SPI, SPI_PUSHR_REG(SFLASH_SPI));
   _SFlashWaitSend();
   //*pRdBuf++ = _SFlashReciveData(SFLASH_SPI);
           
            _SFlashSendData(SFLASH_SPI, SPI_PUSHR_REG(SFLASH_SPI));
   _SFlashWaitSend();
   //*pRdBuf++ = _SFlashReciveData(SFLASH_SPI);
           
            _SFlashSendData(SFLASH_SPI, SPI_PUSHR_REG(SFLASH_SPI));
   _SFlashWaitSend();
   //*pRdBuf++ = _SFlashReciveData(SFLASH_SPI);
        }
        for(; uRdRemainNum != 0; uRdRemainNum--)
        {
            _SFlashSendData(SFLASH_SPI, SPI_PUSHR_REG(SFLASH_SPI));
   _SFlashWaitSend();
   //*pRdBuf++ = _SFlashReciveData(SFLASH_SPI);
        }
    extern U8 szSPIBuf[];

    memcpy(pRdBuf, szSPIBuf, uRdSize);

  //   SPI_MCR_REG(SPI1) |= SPI_MCR_CONT_SCKE_MASK;

  //for(uRdRemainNum = uRdSize; uRdRemainNum > 0; uRdRemainNum--)
  //{
  // //while((SFLASH_SPI->SR & SPI_FLAG_TCF) == 0)
  // //{
  // //}
  // //SFLASH_SPI->SR |= SPI_FLAG_TCF;
  // *pRdBuf++ = _SFlashReciveData(SFLASH_SPI);
  //}
  //  SPI_MCR_REG(SPI1) &= ~SPI_MCR_CONT_SCKE_MASK;

  #else
  SPI_MCR_REG(SPI1) |= SPI_MCR_CONT_SCKE_MASK;
  while((DMA_TCD3_CSR & 0x80) == 0);
  SPI_MCR_REG(SPI1) &= ~SPI_MCR_CONT_SCKE_MASK;

  extern U8 szSPIBuf[];
  //uRdSize = (uRdSize >= DMA_CITER_ELINKNO_CITER(DMA_BASE_PTR->TCD[DMA_CH3].CITER_ELINKNO)) ? DMA_CITER_ELINKNO_CITER(DMA_BASE_PTR->TCD[DMA_CH3].CITER_ELINKNO) : uRdSize;
  memcpy(pRdBuf, szSPIBuf, uRdSize);
  DMA_TCD3_CSR |= 0x10;
  #endif
        //拉高SFlash的CS
        _SFlashCSHigh();
DMA_ReqCmd(DMA_CH3, DISABLE);

    //EXIT_HW_IRQL_PRTCT

    return uRdSize;
}

 

For picture:
Green: SCK
Blue: MISO
Purple: MISO
Yellow: CS

 

SPI杩炵画鏃堕挓娉㈠舰锛堢豢鑹叉椂閽燂紝钃濊壊鎺ユ敹鏁版嵁锛岀传鑹插彂閫佹暟鎹紝榛勮壊鐗囬€夛級.PNG

Outcomes