int readfromspi_dma ( uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer ) { uint8 spiBuffer[64] = ""; uint16 counter; int stat ; #ifdef SAFE_DMA_AND_BUFF uint16 count; count = (uint16)(headerLength + readlength); if (count > MAX_DMABUF_SIZE ) { return DWT_ERROR; } #endif stat = decamutexon() ; //PORT_SPI_CLEAR_CS_FAST // give extra time for SPI slave device port_SPI3_set_chip_select(); HAL_SPI_TransmitReceive_DMA(&hspi3, headerBuffer, tmp_buf, count); while(DMA_RX_CH->NDTR !=0); //pool until last clock from SPI_RX while((SPI3->SR & (1 << 0)) != 0); // wait while RXNE flag is not 1 (RX is not empty) //while((SPI3->SR & (1 << 7)) != 0); // wait while BSY flag is 1 (SPI is busy) //result of read operation for (count=headerLength; count<(headerLength+readlength); count++) { *readBuffer++ = tmp_buf[count]; } port_SPI3_clear_chip_select(); //PORT_SPI_SET_CS_FAST decamutexoff(stat); return DWT_SUCCESS; }
int writetospi_dma ( uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer ) { int stat ; #ifdef SAFE_DMA_AND_BUFF if ((headerLength + bodylength) > MAX_DMABUF_SIZE) { return DWT_ERROR; } #endif stat = decamutexon() ; /* check spi_transaction finished */ // while((SPIx->SR & SPI_I2S_FLAG_BSY) !=0 ); PORT_SPI_CLEAR_CS_FAST // give extra time for SPI slave device DMA_TX_CH->CPAR =(uint32) &(SPIx->DR) ; /*header*/ DMA_TX_CH->CMAR = (uint32)(headerBuffer) ; DMA_TX_CH->CNDTR = headerLength ; PORT_DMA_START_TX_FAST /* Start transfer */ while((DMA_TX_CH->CNDTR) !=0);/* pool until last clock from SPI_TX register done */ PORT_DMA_STOP_TX_FAST /* do not wait SPI finished cause SPI slow. perform switching on next buffer while spi transaction in wire */ /*data*/ DMA_TX_CH->CMAR = (uint32)(bodyBuffer); DMA_TX_CH->CNDTR = bodylength ; PORT_DMA_START_TX_FAST /* Start transfer */ while((DMA_TX_CH->CNDTR) !=0);/* pool until last clock from SPI_TX register done */ while((SPIx->SR & SPI_I2S_FLAG_BSY) !=0 );/* Wait until last byte of transmission will leave SPI wire */ PORT_DMA_STOP_TX_FAST /* finish */ PORT_SPI_SET_CS_FAST SPIx->DR; // perform a dummy read operation to clear OverRun & RxNe flags in SPI SR register decamutexoff(stat); return DWT_SUCCESS; }
/*! ------------------------------------------------------------------------------------------------------------------ * Function: writetospi() * * Low level abstract function to write to the SPI * Takes two separate byte buffers for write header and write data * returns 0 for success, or -1 for error */ int writetospi ( uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer ) { int i=0; decaIrqStatus_t stat ; stat = decamutexon() ; /* Wait for SPIx Tx buffer empty */ //while (port_SPIx_busy_sending()); dw_set_device_select(); //cs low for(i=0; i<headerLength; i++) { while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(DW1000_SPI, headerBuffer[i]); //port_SPIx_send_data(headerBuffer[i]); //send data on the SPI while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_RXNE) == RESET){} SPI_I2S_ReceiveData(DW1000_SPI); } for(i=0; i<bodylength; i++) { while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(DW1000_SPI, bodyBuffer[i]); //port_SPIx_send_data(bodyBuffer[i]); //send data on the SPI while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_RXNE) == RESET){} SPI_I2S_ReceiveData(DW1000_SPI); //while (port_SPIx_no_data()); //wait for rx buffer to fill //port_SPIx_receive_data(); //this clears RXNE bit } dw_reset_device_select(); //CS high decamutexoff(stat) ; return 0; } // end writetospi()
/*! ------------------------------------------------------------------------------------------------------------------ * Function: readfromspi() * * Low level abstract function to read from the SPI * Takes two separate byte buffers for write header and read data * returns the offset into read buffer where first byte of read data may be found, * or returns -1 if there was an error */ int readfromspi ( uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer ) { int i=0; decaIrqStatus_t stat ; stat = decamutexon() ; /* Wait for SPIx Tx buffer empty */ //while (port_SPIx_busy_sending()); dw_set_device_select(); //CS low for(i=0; i<headerLength; i++) { while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(DW1000_SPI, headerBuffer[i]); //port_SPIx_send_data(headerBuffer[i]); //send data on the SPI while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_RXNE) == RESET){} SPI_I2S_ReceiveData(DW1000_SPI); } for(i=0; i<readlength; i++) { while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_TXE) == RESET){} SPI_I2S_SendData(DW1000_SPI, 0); //port_SPIx_send_data(headerBuffer[i]); //send data on the SPI while (SPI_I2S_GetFlagStatus(DW1000_SPI, SPI_I2S_FLAG_RXNE) == RESET){} readBuffer[i] = SPI_I2S_ReceiveData(DW1000_SPI); } dw_reset_device_select(); //CS high decamutexoff(stat) ; return 0; } // end readfromspi()
int readfromspi_serial ( uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer ) { int i=0; uint8 temp; decaIrqStatus_t stat ; stat = decamutexon() ; /* Wait for SPIx Tx buffer empty */ //while (port_SPIx_busy_sending()); SPIx_CS_GPIO->BSRR = SPIx_CS; for(i=0; i<headerLength; i++) { SPIx->DR = headerBuffer[i]; while((SPIx->SR & SPI_FLAG_RXNE) == (uint16_t)RESET); temp = SPIx->DR ; } for(i=0; i<readlength; i++) { SPIx->DR = 0; while((SPIx->SR & SPI_FLAG_RXNE) == (uint16_t)RESET); readBuffer[i] = SPIx->DR ;//port_SPIx_receive_data(); //this clears RXNE bit } SPIx_CS_GPIO->BSRR = SPIx_CS; decamutexoff(stat) ; return 0; } // end readfromspi()
int writetospi_serial ( uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer ) { int i=0; decaIrqStatus_t stat ; stat = decamutexon() ; SPIx_CS_GPIO->BSRR = SPIx_CS; for(i=0; i<headerLength; i++) { SPIx->DR = headerBuffer[i]; while ((SPIx->SR & SPI_FLAG_RXNE) == (uint16_t)RESET); SPIx->DR ; } for(i=0; i<bodylength; i++) { SPIx->DR = bodyBuffer[i]; while((SPIx->SR & SPI_FLAG_RXNE) == (uint16_t)RESET); SPIx->DR ; } SPIx_CS_GPIO->BSRR = SPIx_CS; decamutexoff(stat) ; return 0; } // end writetospi()
int writetospi_dma ( uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer ) { int stat ; #ifdef SAFE_DMA_AND_BUFF if ((headerLength + bodylength) > MAX_DMABUF_SIZE) { return DWT_ERROR; } #endif stat = decamutexon() ; memcpy(&tmp_buf[0], headerBuffer, headerLength); memcpy(&tmp_buf[headerLength], bodyBuffer, bodylength); port_SPI3_set_chip_select(); HAL_SPI_Transmit_DMA(&hspi3, tmp_buf, headerLength+bodylength); while(DMA_TX_CH->NDTR !=0); //pool until last clock from SPI_RX while((SPI3->SR & (1 << 1)) == 0); // wait while TXE flag is 0 (TX is not empty) //while((SPI3->SR & (1 << 7)) != 0); // wait while BSY flag is 1 (SPI is busy) port_SPI3_clear_chip_select(); //PORT_SPI_SET_CS_FAST decamutexoff(stat); return DWT_SUCCESS; }
int readfromspi_dma ( uint16 headerLength, const uint8 *headerBuffer, uint32 readlength, uint8 *readBuffer ) { int stat ; #ifdef SAFE_DMA_AND_BUFF uint16 count; count = (uint16)(headerLength + readlength); if (count > MAX_DMABUF_SIZE ) { return DWT_ERROR; } #endif stat = decamutexon() ; /* check any spi_transaction finished */ // while((SPIx->SR & SPI_I2S_FLAG_BSY) !=0 ); // do not use library function cause it slow PORT_SPI_CLEAR_CS_FAST // give extra time for SPI slave device DMA_TX_CH->CMAR = (uint32)(headerBuffer); // no matter what we send to spi after header when perform a reading operation DMA_RX_CH->CPAR = DMA_TX_CH->CPAR = (uint32)&(SPIx->DR); #ifdef SAFE_DMA_AND_BUFF SPIx->CR2 |= (SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx) ; /* connect SPI_Tx & SPI_Rx to DMA */ DMA_RX_CH->CMAR = (uint32)(&tmp_buf) ; /* read buffer */ DMA_RX_CH->CNDTR = DMA_TX_CH->CNDTR = count ; //length /* Start write/read transfer*/ /* read data */ PORT_DMA_START_RX_FAST PORT_DMA_START_TX_FAST while(DMA_RX_CH->CNDTR !=0); /* pool until last clock from SPI_RX */ PORT_DMA_STOP_TX_FAST PORT_DMA_STOP_RX_FAST /* result of read operation*/ for (count=headerLength; count<(headerLength+readlength); count++) { *readBuffer++ = tmp_buf[count]; } #else SPIx->CR2 |= (SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx) ; /* connect SPI_Tx & SPI_Rx to DMA */ DMA_RX_CH->CMAR = (uint32) readBuffer ; /* read buffer addr */ DMA_TX_CH->CNDTR = headerLength+readlength; DMA_RX_CH->CNDTR = headerLength; /* Start. write command */ /* DMA_RX Disable Memory increment and Start */ DMA_RX_CH->CCR = DMA_CCR1_EN | /* start Rx */ DMA_DIR_PeripheralSRC | DMA_PeripheralInc_Disable | DMA_MemoryInc_Disable |\ DMA_PeripheralDataSize_Byte | DMA_MemoryDataSize_Byte | DMA_Mode_Normal |\ DMA_Priority_High | DMA_M2M_Disable ; PORT_DMA_START_TX_FAST while(DMA_RX_CH->CNDTR !=0); /* pool until last clock from SPI_RX */ PORT_DMA_STOP_RX_FAST DMA_RX_CH->CNDTR = readlength; /* read data length */ DMA_RX_CH->CCR |= (DMA_MemoryInc_Enable); /* DMA_Rx Enable Memory increment */ /* DMA_Rx should be started after new readlength and changing of Memory increment mode */ PORT_DMA_START_RX_FAST while(DMA_RX_CH->CNDTR !=0); /* pool until last clock from SPI_RX */ PORT_DMA_STOP_TX_FAST PORT_DMA_STOP_RX_FAST #endif PORT_SPI_SET_CS_FAST SPIx->CR2 &= ~(SPI_I2S_DMAReq_Rx) ; //Disconnect Rx from DMA_SPI ! decamutexoff(stat); return DWT_SUCCESS; }