// ----------------------------------------------------------------------------- /// @file spi.c /// @brief Description // ----------------------------------------------------------------------------- // Micro-Key bv // Industrieweg 28, 9804 TG Noordhorn // Postbus 92, 9800 AB Zuidhorn // The Netherlands // Tel: +31 594 503020 // Fax: +31 594 505825 // Email: support@microkey.nl // Web: www.microkey.nl // ----------------------------------------------------------------------------- /// $Revision$ /// $Author$ /// $Date$ // (c) 2017 Micro-Key bv // ----------------------------------------------------------------------------- /// @file spi.c /// @ingroup {group_name} // ----------------------------------------------------------------------------- // Include files // ----------------------------------------------------------------------------- #include #include "Logger.h" #include "spi.h" // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- ErrorStatus SPI_construct(struct Spi* self, const struct SpiParameters* parameters) { ErrorStatus returnValue = SUCCESS; if (!self->initialized) { //! Create semaphore to synchronize with USART interrupt handler vSemaphoreCreateBinary(self->txSemaphore); //! Create semaphore to avoid multiple usage vSemaphoreCreateBinary(self->spiClaimed); SPI_I2S_DeInit(self->SPI_TypeDef); self->SPI_InitStruct.SPI_Direction = parameters->SPI_Direction; self->SPI_InitStruct.SPI_Mode = parameters->SPI_Mode; self->SPI_InitStruct.SPI_DataSize = parameters->SPI_DataSize; self->SPI_InitStruct.SPI_CPOL = parameters->SPI_CPOL; self->SPI_InitStruct.SPI_CPHA = parameters->SPI_CPHA; self->SPI_InitStruct.SPI_NSS = parameters->SPI_NSS; self->SPI_InitStruct.SPI_BaudRatePrescaler = parameters->SPI_BaudRatePrescaler; self->SPI_InitStruct.SPI_FirstBit = parameters->SPI_FirstBit; self->SPI_InitStruct.SPI_CRCPolynomial = parameters->SPI_CRCPolynomial; SPI_Init(self->SPI_TypeDef, &self->SPI_InitStruct); if (parameters->SPI_NSS == SPI_NSS_Hard) { SPI_NSSInternalSoftwareConfig(self->SPI_TypeDef, parameters->SPI_NSS_internal); SPI_SSOutputCmd(self->SPI_TypeDef, ENABLE); } //! Enable USART interface SPI_Cmd(self->SPI_TypeDef, ENABLE); //! Create a new FREERTOS queue to handle data from app to SPI output self->txQueue = xQueueCreate(parameters->txQueueSize, sizeof(struct spiQueueItem)); //! Create a new FREERTOS queue to handle data from SPI input to app self->rxQueue = xQueueCreate(parameters->rxQueueSize, sizeof(struct spiQueueItem)); //! Queue identifier must not be 0 (0 means that the queue is not available) if (self->txQueue == 0) { //! Queue identifier is 0 -> error returnValue = ERROR; //! Set error flag } if (self->rxQueue == 0) { //! Queue identifier is 0 -> error returnValue = ERROR; //! Set error flag } //! Queue identifier is not 0 -> queue is available //! take txSemaphore if (xSemaphoreTake(self->txSemaphore, 0) == pdFALSE) { //! An error has occurred returnValue = ERROR; } if (returnValue == SUCCESS) { //! Enable the UART RX not empty interrupt // SPI_I2S_ITConfig(self->SPI_TypeDef, SPI_I2S_IT_RXNE, ENABLE); } if (returnValue == SUCCESS) { self->initialized = true; } } return returnValue; } ErrorStatus SPI_destruct (struct Spi* self) { ErrorStatus returnValue = SUCCESS; self->initialized = false; return returnValue; } ErrorStatus SPI_getDefaultParameters(struct SpiParameters* parameters) { ErrorStatus returnValue = SUCCESS; parameters->SPI_BaudRatePrescaler = SPI_DEF_BaudRatePrescaler; parameters->SPI_CPHA = SPI_DEF_CPHA; parameters->SPI_CPOL = SPI_DEF_CPOL; parameters->SPI_CRCPolynomial = SPI_DEF_CRCPolynomial; parameters->SPI_DataSize = SPI_DEF_DataSize; parameters->SPI_Direction = SPI_DEF_Direction; parameters->SPI_FirstBit = SPI_DEF_FirstBit; parameters->SPI_Mode = SPI_DEF_Mode; parameters->SPI_NSS = SPI_DEF_NSS; parameters->rxQueueSize = SPI_DEF_RX_QUEUE; parameters->txQueueSize = SPI_DEF_TX_QUEUE; return returnValue; }