// ----------------------------------------------------------------------------- /// @file spiDevice.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 spiDevice.c /// @ingroup {group_name} // ----------------------------------------------------------------------------- // Include files // ----------------------------------------------------------------------------- #include #include "stm32f10x.h" #include "spiDevice.h" // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- static ErrorStatus write(const struct IODevice* self, const char* buffer, size_t length); //static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength); // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- ErrorStatus SpiDevice_construct(struct SpiDevice* self, struct Spi* spi, const struct SpiParameters* parameters, T_PL_GPIO SPI_CE) { ErrorStatus returnValue = SUCCESS; IODevice_construct(&self->device, NULL, write); SPI_construct(self->spi, parameters); return returnValue; } static ErrorStatus write(const struct IODevice* self, const char* buffer, size_t length) { return SpiDevice_write((const struct SpiDevice*)self, buffer, length); } ErrorStatus SpiDevice_write (const struct SpiDevice* self, const char* buffer, int length) { struct spiQueueItem txItem; ErrorStatus returnValue = SUCCESS; //! Define return variable int txCounter; //! Define a loop counter var xSemaphoreTake(self->spi->spiClaimed, portMAX_DELAY); self->spi->SPI_CE = &self->SPI_CE; //! Copy the incoming data into SPI data structure for (txCounter = 0; txCounter < length; txCounter++) { txItem.byte = buffer[txCounter]; //! Copy current data in struct if (uxQueueSpacesAvailable(self->spi->txQueue) == 2) { // Prevent locking in case that more data than queue-space should be send if (self->spi->SPI_InitStruct.SPI_NSS == SPI_NSS_Soft) { GPIO_ResetBits(self->spi->SPI_CE->GPIO_Typedef, self->spi->SPI_CE->GPIO_InitStruct.GPIO_Pin); } SPI_I2S_ITConfig(self->spi->SPI_TypeDef, SPI_I2S_IT_TXE, ENABLE); } //! Add the current set of data to SPI transmission queue if (pdTRUE != xQueueSend(self->spi->txQueue, &txItem, portMAX_DELAY )) { //! Adding item was NOT successful - break out of loop returnValue = ERROR; //! Set return value to FALSE break; } } if (returnValue == SUCCESS) { // De-select the current device to avoid start-issues if (self->spi->SPI_InitStruct.SPI_NSS == SPI_NSS_Soft) { GPIO_ResetBits(self->spi->SPI_CE->GPIO_Typedef, self->spi->SPI_CE->GPIO_InitStruct.GPIO_Pin); } SPI_I2S_ITConfig(self->spi->SPI_TypeDef, SPI_I2S_IT_TXE, ENABLE); //! Try to take Semaphore - If the USART transmission is still busy, the //! Semaphore cannot be taken - FREERTOS will suspend this task until the //! Semaphore is released again xSemaphoreTake(self->spi->txSemaphore, portMAX_DELAY); /** Enabling the TX interrupt will immediately cause an interrupt because * the transmission register is still empty. The ISR will get the data * from the uart transmission queue and transmit byte-wise until the * queue is empty. * An empty queue will cause the transmission complete flag (TC) to be set, * which is polled */ while (SPI_I2S_GetFlagStatus(self->spi->SPI_TypeDef, SPI_I2S_FLAG_BSY) == SET) { //! The software must wait until TXE=1. The TXE flag remains cleared during //! all data transfers and it is set by hardware at the last frame's //! end of transmission } if (self->spi->SPI_InitStruct.SPI_NSS == SPI_NSS_Soft) { GPIO_SetBits(self->spi->SPI_CE->GPIO_Typedef, self->spi->SPI_CE->GPIO_InitStruct.GPIO_Pin); } xSemaphoreGive(self->spi->spiClaimed); } // else { //! Do nothing } return returnValue; //! Return result to caller } ErrorStatus SpiDevice_read(const struct SpiDevice* self, char* buffer, size_t length, size_t* actualLength) { ErrorStatus returnValue = SUCCESS; return returnValue; }