K60: Flush of SPI and SPI DMA not removing bytes already in the hardware registers.

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

K60: Flush of SPI and SPI DMA not removing bytes already in the hardware registers.

ソリューションへジャンプ
747件の閲覧回数
spearson
Contributor III

I am running an SPISlave_LDD connected to a DMA_LDD.  At some point I receive a bad packet and my protocol flushes the system:

void SPIDriver_flush(void) {

    IPIFSpi2Tx_CancelTransfer(Spi2Tx_DeviceData);

    SS1_CancelBlockTransmission(SS1_DeviceData);

    IPIFSpi2Rx_CancelTransfer(Spi2Rx_DeviceData);

    SS1_CancelBlockReception(SS1_DeviceData);

...

}

Without getting into too much detail, my sentinel is 0xC3 (the first char sent by the SPI master when looking at the waveform on an oscilloscope) which is delayed by two chars.

[000]  0x0C 0x0C 0xC3 0x00 0xA4 0x98 0x00 0x00 0x00 0x00 0x0C 0x0C 0x0C 0x0C 0x0C 0x0C

The two chars seem to be coming from the SPI and DMA hardware registers:

Adding a read of the SPI register after the flush removes one of the two errant chars:

void SPIDriver_flush(void) {

    IPIFSpi2Tx_CancelTransfer(Spi2Tx_DeviceData);

    SS1_CancelBlockTransmission(SS1_DeviceData);

    IPIFSpi2Rx_CancelTransfer(Spi2Rx_DeviceData);

    SS1_CancelBlockReception(SS1_DeviceData);

   int x =  (volatile)SPI2_POPR;

...

}

[000]  0x0C 0xC3 0x00 0xA4 0x98 0x00 0x00 0x00 0x00 0x0C 0x0C 0x0C 0x0C 0x0C 0x0C  0x0C

Adding a DMA read of two characters after the flush removes both errant chars:

void SPIDriver_flush(void) {

    IPIFSpi2Tx_CancelTransfer(IPIFSpi2Tx_DeviceData);

    SS1_CancelBlockTransmission(SS1_DeviceData);

    IPIFSpi2Rx_CancelTransfer(IPIFSpi2Rx_DeviceData);

    SS1_CancelBlockReception(SS1_DeviceData);

    int x =  (volatile)SPI2_POPR;

    unsigned char foo[2];

    (void)IPIFSpi2Rx_SetDestinationAddress(Spi2Rx_DeviceData, (LDD_DMA_TAddress)&foo);

    (void)IPIFSpi2Rx_SetDestinationTransferSize(Spi2Rx_DeviceData, (LDD_DMA_TTransferSize)2)

    (void)IPIFSpi2Rx_EnableChannel(Spi2Rx_DeviceData);

...

}

[000]  0xC3 0x00 0xA4 0x98 0x00 0x00 0x00 0x00 0x0C 0x0C 0x0C 0x0C 0x0C 0x0C  0x0C 0x0C

Is there a better way to ensure a complete flush of the hardware or is this an appropriate solution?

Thanks in advance,

1 解決策
534件の閲覧回数
spearson
Contributor III

Replaced the read of the SPI (bolded text) with the function below.  It has better performance than the dummy reads and better matches the flush operation.


void SPIDriver_clearHardwareFifos(void){

/* Halt the SPI */

SPI2_MCR |= SPI_MCR_HALT_MASK;

/* Clear Tx/Rx Fifo */

SPI2_MCR |= (SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK);

/* Stop clearing Tx/Rx Fifo */

SPI2_MCR &= ~(SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK);

/* Start the SPI */

SPI2_MCR &= ~SPI_MCR_HALT_MASK;

}

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
535件の閲覧回数
spearson
Contributor III

Replaced the read of the SPI (bolded text) with the function below.  It has better performance than the dummy reads and better matches the flush operation.


void SPIDriver_clearHardwareFifos(void){

/* Halt the SPI */

SPI2_MCR |= SPI_MCR_HALT_MASK;

/* Clear Tx/Rx Fifo */

SPI2_MCR |= (SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK);

/* Stop clearing Tx/Rx Fifo */

SPI2_MCR &= ~(SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK);

/* Start the SPI */

SPI2_MCR &= ~SPI_MCR_HALT_MASK;

}

0 件の賞賛
返信
534件の閲覧回数
adriancano
NXP Employee
NXP Employee

Hi,

I apologize for the late response. I think the method you are using is fine, since Processor Expert methods do not allow the complete functionality of the SPI module and flushing is and specific method that is not implemented directly by the LDD drivers.


Hope this information can help you.

Best Regards,
Adrian Sanchez Cano
Technical Support Engineer
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 件の賞賛
返信