AnsweredAssumed Answered

K61 using SPI with DMA, EOQ management issue

Question asked by Boris Alfani on Jun 11, 2018

Hello I'm finding some issues in using SPI through DMA in K61 processor.
I think I'm doing something wrong, but I didn't find what.

I'm in the condition that when the SPI Master starts to transmit data, it never stops.
This below is a brief description about my SPI driver implementation (please note that I don't have any opertive system and I can't use one, my SW sould be the operative system)


I configure SPI2 in Master mode, and I set the DIS_TXF and DIS_RXF flangs in Module Control Register:
  wstSPIdev[enDev].pRegs->MCR |= SPI_MCR_DIS_TXF_MASK;
  wstSPIdev[enDev].pRegs->MCR |= SPI_MCR_DIS_RXF_MASK;

 

(Please note: wstSPIdev is an array of structures and  wstSPIdev[enDev].pRegs is the SPI_MemMapPtr pointer)

 

Than I set the RSER in order to generate DMA requests on TXFIFO is not full and when the Receive FIFO Drain events:

 

  wstSPIdev[enDev].pRegs->RSER = 0;
  wstSPIdev[enDev].pRegs->RSER |= SPI_RSER_TFFF_RE_MASK | SPI_RSER_TFFF_DIRS_MASK;
  wstSPIdev[enDev].pRegs->RSER |= SPI_RSER_RFDF_DIRS_MASK | SPI_RSER_RFDF_RE_MASK;

 

Thena I configure 2 DMA channels, one for transitting and one for receiving. In this moment we don't care about receiving process.
The transmission DMA has the PUSHR register as destination address, and a buffer as source address. The source address in incremented by 4 each minor loop, while the destination address is not incremented, of coruse. The minor loop is configured to 4 and the major loop is configured to the size of the buffer. The  SLAST value of the DMA is set as (0-(major loop * minor loop)), in this way when the major loop ends, the source address is set to the begin of the buffer.

 

This below is the function that fills the buffer. It is called each time a transmission has been requested:
static void wvSpiPrepareTxBuffer(EN_SPI_DEVID enDev, ULONG ulLen, UBYTE* pubSend, SPI_CS enCs)
{
  ULONG uli;
  ULONG ulSpiCmd = 0;
  if(wstSPIdev[enDev].enRole == SPI_ROLE_MASTER)
  {
    ulSpiCmd = SPI_PUSHR_CTAS(0) | SPI_PUSHR_PCS( enCs );
  }

  for(uli=0; uli < ulLen; ++uli)
  {
    wstSPIdev[enDev].ulDataTx[wstSPIdev[enDev].uwPushIdx] = ulSpiCmd | pubSend[uli];
    wstSPIdev[enDev].uwPushIdx++;
    if(wstSPIdev[enDev].uwPushIdx >= SPI_BUFF_SIZE)
    {
      wstSPIdev[enDev].uwPushIdx = 0;
    }
  }
  if(wstSPIdev[enDev].enRole == SPI_ROLE_MASTER)
  {
    wstSPIdev[enDev].ulDataTx[wstSPIdev[enDev].uwPushIdx-1] |= SPI_PUSHR_EOQ_MASK;
  }
  wstSPIdev[enDev].ulByteToTransfer = ulLen;
}

 

Afeter calling the function above, my SW clear the EOQF in SR register and remove the Halt condition in MCR register
  wvSpiPrepareTxBuffer(enDev, ulLen, pubSend, enCs);
  wstSPIdev[enDev].pRegs->SR |= SPI_SR_EOQF_MASK;
  wstSPIdev[enDev].pRegs->MCR &= ~SPI_MCR_HALT_MASK;   /* rimuove HALT */

 

What I expect: the transmition DMA starts to fill the PUSHR register and keep to fill it each time the TX FIFO is no more full, untill when the element of the buffer whit the EOQ command is sent. At this point I expect that the SR[EOQF] is activated and the SPI stops sending data, the SPI clock and PCS become inactive.

 

What I get: the SPI starts transfer data and the SR[EOQF] never becomes active, therefore the SPI keep going on to trasfer the data feeded by the DMA.

 

what's it wrong in my code or in my understanding of the K61's user guide?

Outcomes