diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/gpio.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/gpio.h index fb34888..9f13ce7 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/gpio.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/gpio.h @@ -48,7 +48,7 @@ typedef enum { INPUT = 0, OUTPUT = !INPUT -}GpioDirection; +} GpioDirection; struct Gpio { @@ -56,6 +56,7 @@ struct Gpio T_PL_GPIO gpio; GpioDirection direction; bool status; + bool initialized; }; // ----------------------------------------------------------------------------- diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/platform.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/platform.h index c309788..4978c5c 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/platform.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/platform.h @@ -64,10 +64,6 @@ extern struct Logger* mainLog; // Export of PCBA information extern struct Pcba* pcba; - -// Export of LEDs -extern struct Gpio* const ledGreen; -extern struct Gpio* const ledOrange; // Export of ADCs extern struct Adc* const adc1; // Export of the rtc @@ -81,9 +77,22 @@ extern struct Spi* const spi3; extern struct SpiDevice* const spiDAC; extern struct SpiDevice* const spiDisplay; extern struct SpiDevice* const spiEEPROM; - +// Export of Keypad extern struct Keypad* const keypad; - +// Export of GPIOs +extern struct Gpio* const ledGreen; +extern struct Gpio* const ledOrange; +extern struct Gpio* const power6v5Enable; +extern struct Gpio* const interlock1; +extern struct Gpio* const interlock2; +extern struct Gpio* const solenoid; +extern struct Gpio* const mcp0Relay; +extern struct Gpio* const mcp1Relay; +extern struct Gpio* const mcp2Relay; +extern struct Gpio* const cat0Relay; +extern struct Gpio* const cat1Relay; +extern struct Gpio* const cat2Relay; +extern struct Gpio* const teslaLock; // ----------------------------------------------------------------------------- // Function declarations diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/spiDevice.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/spiDevice.h index 37af12d..fc1f2e8 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/spiDevice.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/spiDevice.h @@ -31,6 +31,8 @@ // Include files // ----------------------------------------------------------------------------- +#include + #include "IODevice.h" #include "spi.h" @@ -50,6 +52,7 @@ struct SpiDevice struct Spi* spi; struct SpiParameters parameters; T_PL_GPIO SPI_CE; + bool initialized; }; // ----------------------------------------------------------------------------- diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/uart.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/uart.h index 2eac7dc..1956fee 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/uart.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/inc/uart.h @@ -32,6 +32,8 @@ // Include files // ----------------------------------------------------------------------------- +#include + #include "FreeRTOS.h" #include "semphr.h" @@ -85,6 +87,7 @@ struct Uart SemaphoreHandle_t txSemaphore; //! Semaphore for transmit handler xQueueHandle txQueue; //! USART Transfer queue identifier xQueueHandle rxQueue; //! USART Receive queue identifier + bool initialized; }; // ----------------------------------------------------------------------------- diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/gpio.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/gpio.c index 70d5af9..dd835ea 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/gpio.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/gpio.c @@ -62,11 +62,20 @@ static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length ErrorStatus GPIO_construct(struct Gpio* self, GpioDirection direction, T_PL_GPIO io) { ErrorStatus returnValue = SUCCESS; - - - returnValue = IODevice_construct(&self->device, read, write); - self->direction = direction; - self->gpio = io; + if (!self->initialized) + { + returnValue = IODevice_construct(&self->device, read, write); + if (returnValue == SUCCESS) + { + self->direction = direction; + self->gpio = io; + self->initialized = true; + } + } + else + { + returnValue = ERROR; + } return returnValue; @@ -76,29 +85,34 @@ ErrorStatus GPIO_construct(struct Gpio* self, GpioDirection direction, T_PL_GPIO ErrorStatus GPIO_setValue(struct Gpio* self, bool value) { ErrorStatus returnValue = SUCCESS; - - if (self->direction == OUTPUT) + if (self->initialized) { - // Writing to output is valid - if (value) + if (self->direction == OUTPUT) + { + // Writing to output is valid + if (value) + { + GPIO_SetBits(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin); + self->status = true; + } + else { - GPIO_SetBits(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin); - self->status = true; + { + GPIO_ResetBits(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin); + self->status = false; + } } + } else { - { - GPIO_ResetBits(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin); - self->status = false; - } + // Writing to input is invalid + returnValue = ERROR; } } else { - // Writing to input is invalid returnValue = ERROR; } - return returnValue; } @@ -106,35 +120,41 @@ ErrorStatus GPIO_setValue(struct Gpio* self, bool value) ErrorStatus GPIO_getValue(struct Gpio* self, bool* value) { ErrorStatus returnValue = SUCCESS; - - if (self->direction == OUTPUT) + if (self->initialized) { - // Reading an output is impossible - but returning its current status is valid - if(GPIO_ReadOutputDataBit(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin) != 0) + if (self->direction == OUTPUT) { - *value = true; - self->status = true; + // Reading an output is impossible - but returning its current status is valid + if(GPIO_ReadOutputDataBit(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin) != 0) + { + *value = true; + self->status = true; + } + else + { + *value = false; + self->status = false; + } } else { - *value = false; - self->status = false; + // Read value on input + if(GPIO_ReadInputDataBit(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin) != 0) + { + + *value = true; + self->status = true; + } + else + { + *value = false; + self->status = false; + } } } else { - // Read value on input - if(GPIO_ReadInputDataBit(self->gpio.GPIO_Typedef, self->gpio.GPIO_InitStruct.GPIO_Pin) != 0) - { - - *value = true; - self->status = true; - } - else - { - *value = false; - self->status = false; - } + returnValue = ERROR; } return returnValue; diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c index a5bc173..4f9d9fb 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/oli_stm32_h107.c @@ -90,39 +90,48 @@ // the IO/Peripheral object // Logger -static struct Logger _mainLog = {.initialized = false}; - -// PCBA information - -// LEDs -static struct Gpio _ledGreen; -static struct Gpio _ledOrange; +static struct Logger _mainLog = {.initialized = false}; // ADC -static struct Adc _adc1; +static struct Adc _adc1 = {.initialized = false}; static struct AdcParameters _adc1Parameters; // RTC static struct Rtc _rtc; // USART -static struct Uart _uart1; +static struct Uart _uart1 = {.initialized = false}; static struct UartParameters _uart1Parameters; -static struct Uart _uart3; +static struct Uart _uart3 = {.initialized = false}; static struct UartParameters _uart3Parameters; // SPI -static struct Spi _spi1; -static struct SpiDevice _spiDAC; +static struct Spi _spi1 = {.initialized = false}; +static struct SpiDevice _spiDAC = {.initialized = false}; static struct SpiParameters _spi1DACParameters; -static struct Spi _spi3; +static struct Spi _spi3 = {.initialized = false}; static struct SpiParameters _spi3DisplayParameters; static struct SpiParameters _spi3EEPROMParameters; -static struct SpiDevice _spiDisplay; -static struct SpiDevice _spiEEPROM; +static struct SpiDevice _spiDisplay = {.initialized = false}; +static struct SpiDevice _spiEEPROM = {.initialized = false}; // Keypad -static struct Keypad _keypad; +static struct Keypad _keypad = {.initialized = false}; + +// GPIOs +static struct Gpio _ledGreen = {.initialized = false}; +static struct Gpio _ledOrange = {.initialized = false}; +static struct Gpio _power6v5Enable = {.initialized = false}; +static struct Gpio _interlock1 = {.initialized = false}; +static struct Gpio _interlock2 = {.initialized = false}; +static struct Gpio _solenoid = {.initialized = false}; +static struct Gpio _mcp0Relay = {.initialized = false}; +static struct Gpio _mcp1Relay = {.initialized = false}; +static struct Gpio _mcp2Relay = {.initialized = false}; +static struct Gpio _cat0Relay = {.initialized = false}; +static struct Gpio _cat1Relay = {.initialized = false}; +static struct Gpio _cat2Relay = {.initialized = false}; +static struct Gpio _teslaLock = {.initialized = false}; // The following pointers are for export (see platform.h) and external use. @@ -130,10 +139,7 @@ static struct Keypad _keypad; struct Logger* mainLog = &_mainLog; -struct Pcba* pcba; - -struct Gpio* const ledGreen = &_ledGreen; -struct Gpio* const ledOrange = &_ledOrange; +struct Pcba* pcba; // Singleton struct Adc* const adc1 = &_adc1; struct AdcParameters* adc1Parameters = &_adc1Parameters; @@ -156,12 +162,27 @@ struct SpiParameters* const spiEEPROMParam = &_spi3EEPROMParameters; struct Keypad* const keypad = &_keypad; +struct Gpio* const ledGreen = &_ledGreen; +struct Gpio* const ledOrange = &_ledOrange; +struct Gpio* const power6v5Enable = & _power6v5Enable; +struct Gpio* const interlock1 = &_interlock1; +struct Gpio* const interlock2 = &_interlock2; +struct Gpio* const solenoid = & _solenoid; +struct Gpio* const mcp0Relay = &_mcp0Relay; +struct Gpio* const mcp1Relay = &_mcp1Relay; +struct Gpio* const mcp2Relay = &_mcp2Relay; +struct Gpio* const cat0Relay = & _cat0Relay; +struct Gpio* const cat1Relay = &_cat1Relay; +struct Gpio* const cat2Relay = &_cat2Relay; +struct Gpio* const teslaLock = &_teslaLock; + // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- static ErrorStatus initClocks(void); static ErrorStatus initIO (void); +static T_PL_GPIO configureGPIO (GPIO_TypeDef* gpioTypeDef, GPIOMode_TypeDef gpioMode, GPIOSpeed_TypeDef gpioSpeed, uint16_t gpioPin); // ----------------------------------------------------------------------------- // Function definitions @@ -194,12 +215,6 @@ ErrorStatus initPlatform(void) /* --------------------------------------------------------------------*/ pcba = PCBA_getInstance(); - /* --------------------------------------------------------------------*/ - /* LEDs */ - /* --------------------------------------------------------------------*/ - GPIO_construct(ledGreen, OUTPUT, ledGreen->gpio); - GPIO_construct(ledOrange, OUTPUT, ledOrange->gpio); - /* --------------------------------------------------------------------*/ /* DMA1 - Channel 1 - For use with ADC1 */ /* --------------------------------------------------------------------*/ @@ -352,6 +367,43 @@ ErrorStatus initPlatform(void) IRQ_setInterruptProperties(EXTI9_5_IRQn, 12, 12, ENABLE); Keypad_construct(keypad, KEYPAD_DEBOUNCE_TIME_MS, KEYPAD_TASK_PRIORITY, KEYPAD_STACK_SIZE, KEYPAD_DEF_QUEUESIZE); + + /* --------------------------------------------------------------------*/ + /* GPIOs */ + /* --------------------------------------------------------------------*/ + // Green LED + GPIO_construct(ledGreen, OUTPUT, ledGreen->gpio); + // Orange LED + GPIO_construct(ledOrange, OUTPUT, ledOrange->gpio); + // 6V5 Power Enable + GPIO_construct(power6v5Enable, OUTPUT, power6v5Enable->gpio); + // Interlock1 + GPIO_construct(interlock1, INPUT, interlock1->gpio); + // Interlock2 + GPIO_construct(interlock2, INPUT, interlock2->gpio); + // Solenoid + GPIO_construct(solenoid, OUTPUT, solenoid->gpio); + if (PCBA_getInstance()->pcba == CathodeMCP) + { + // MCP0Relay + GPIO_construct(mcp0Relay, OUTPUT, mcp0Relay->gpio); + // MCP1Relay + GPIO_construct(mcp1Relay, OUTPUT, mcp1Relay->gpio); + // MCP2Relay + GPIO_construct(mcp2Relay, OUTPUT, mcp2Relay->gpio); + // CAT0Relay + GPIO_construct(cat0Relay, OUTPUT, cat0Relay->gpio); + // CAT1Relay + GPIO_construct(cat1Relay, OUTPUT, cat1Relay->gpio); + // CAT2Relay + GPIO_construct(cat2Relay, OUTPUT, cat2Relay->gpio); + } + if (PCBA_getInstance()->pcba == Tesla) + { + // Tesla Lock + GPIO_construct(teslaLock, INPUT, teslaLock->gpio); + } + } return returnValue; @@ -571,10 +623,8 @@ static ErrorStatus initIO (void) _spiDAC.SPI_CE.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(_spiDAC.SPI_CE.GPIO_Typedef, &_spiDAC.SPI_CE.GPIO_InitStruct); - spiDAC->spi = &_spi1; - // SPI3 CLK _spi3.SPI_CLK.GPIO_Typedef = GPIOC; _spi3.SPI_CLK.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; @@ -616,7 +666,7 @@ static ErrorStatus initIO (void) GPIO_Init(_spiEEPROM.SPI_CE.GPIO_Typedef, &_spiEEPROM.SPI_CE.GPIO_InitStruct); - // Keypad I/O + /* KEYPAD initialisation -------------------------------------------------*/ // Row1 keypad->row[0].gpio.GPIO_Typedef = GPIOD; keypad->row[0].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; @@ -675,6 +725,55 @@ static ErrorStatus initIO (void) GPIO_Init(keypad->column[3].gpio.GPIO_Typedef, &keypad->column[3].gpio.GPIO_InitStruct); GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource7); + /* GPIO initialisation ---------------------------------------------------*/ + // 6V5 enable -> PE12 output + power6v5Enable->gpio = configureGPIO(GPIOE, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_12); + // Interlock1 - PB0 input + interlock1->gpio = configureGPIO(GPIOB, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz, GPIO_Pin_0); + // Interlock2 - PB1 input + interlock2->gpio = configureGPIO(GPIOB, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz, GPIO_Pin_1); + // Solenoid - PB5 output + solenoid->gpio = configureGPIO(GPIOB, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_5); + if (PCBA_getInstance()->pcba == CathodeMCP) + { + // MCP0Relay - PD8 output + mcp0Relay->gpio = configureGPIO(GPIOD, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_8); + // MCP1Relay - PD9 output + mcp1Relay->gpio = configureGPIO(GPIOD, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_9); + // MCP2Relay - PD10 output + mcp2Relay->gpio = configureGPIO(GPIOD, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_10); + // CAT0Relay - PD11 output + cat0Relay->gpio = configureGPIO(GPIOD, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_11); + // CAT1Relay - PD12 output + cat1Relay->gpio = configureGPIO(GPIOD, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_12); + // CAT2Relay - PD13 output + cat2Relay->gpio = configureGPIO(GPIOD, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, GPIO_Pin_13); + } + else + { + + } + if (PCBA_getInstance()->pcba == Tesla) + { + // Tesla lock PB10 output + teslaLock->gpio = configureGPIO(GPIOB, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz, GPIO_Pin_10); + } + + + return returnValue; } + + +static T_PL_GPIO configureGPIO (GPIO_TypeDef* gpioTypeDef, GPIOMode_TypeDef gpioMode, GPIOSpeed_TypeDef gpioSpeed, uint16_t gpioPin) +{ + T_PL_GPIO gpio; + gpio.GPIO_Typedef = gpioTypeDef; + gpio.GPIO_InitStruct.GPIO_Mode = gpioMode; + gpio.GPIO_InitStruct.GPIO_Pin = gpioPin; + gpio.GPIO_InitStruct.GPIO_Speed = gpioSpeed; + GPIO_Init(gpio.GPIO_Typedef, &gpio.GPIO_InitStruct); + + return gpio; +} diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/spiDevice.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/spiDevice.c index e274677..69563fd 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/spiDevice.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/spiDevice.c @@ -63,9 +63,16 @@ ErrorStatus SpiDevice_construct(struct SpiDevice* self, struct Spi* spi, const s { ErrorStatus returnValue = SUCCESS; - IODevice_construct(&self->device, NULL, write); - - SPI_construct(self->spi, parameters); + if (!self->initialized) + { + IODevice_construct(&self->device, NULL, write); + SPI_construct(self->spi, parameters); + self->initialized = true; + } + else + { + returnValue = ERROR; + } return returnValue; } @@ -82,73 +89,80 @@ ErrorStatus SpiDevice_write (const struct SpiDevice* self, const char* buffer, i ErrorStatus returnValue = SUCCESS; //! Define return variable int txCounter; //! Define a loop counter var - - xSemaphoreTake(self->spi->spiClaimed, portMAX_DELAY); - if (self->spi->SPI_InitStruct.SPI_NSS == SPI_NSS_Soft) + if (self->initialized) { - self->spi->SPI_CE = &self->SPI_CE; - } + + xSemaphoreTake(self->spi->spiClaimed, portMAX_DELAY); + if (self->spi->SPI_InitStruct.SPI_NSS == SPI_NSS_Soft) + { + 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) + //! Copy the incoming data into SPI data structure + for (txCounter = 0; txCounter < length; txCounter++) { - // Prevent locking in case that more data than queue-space should be send + 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); - } - //! 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) + //! 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 { - GPIO_ResetBits(self->spi->SPI_CE->GPIO_Typedef, self->spi->SPI_CE->GPIO_InitStruct.GPIO_Pin); + //! Do nothing } - 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 - } + } + else + { + returnValue = ERROR; + } return returnValue; //! Return result to caller @@ -159,5 +173,13 @@ ErrorStatus SpiDevice_read(const struct SpiDevice* self, char* buffer, size_t le { ErrorStatus returnValue = SUCCESS; + if (self->initialized) + { + + } + else + { + returnValue = ERROR; + } return returnValue; } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/uart.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/uart.c index ffd9768..eaf0252 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/uart.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/Platform/src/uart.c @@ -65,72 +65,64 @@ ErrorStatus Uart_construct(struct Uart* self, struct UartParameters* parameters) { ErrorStatus returnValue = SUCCESS; - IODevice_construct(&self->device, read, write); - - //! Create semaphore to synchronize with USART interrupt handler - vSemaphoreCreateBinary(self->txSemaphore); - - USART_DeInit(self->USART_TypeDef); - -// self->USART_ClockInitStruct->USART_Clock = USART_Clock_Enable; -// self->USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; -// self->USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; -// self->USART_ClockInitStruct->USART_LastBit = USART_LastBit_Enable; -// -// //! Enable USART clock -// USART_ClockInit(self->USART_TypeDef, self->USART_ClockInitStruct); - - // Initialise the UART - self->USART_InitStruct.USART_BaudRate = parameters->baudrate; - self->USART_InitStruct.USART_WordLength = parameters->wordlength; - self->USART_InitStruct.USART_StopBits = parameters->stopbits; - self->USART_InitStruct.USART_Parity = parameters->parity; - self->USART_InitStruct.USART_Mode = parameters->mode; - self->USART_InitStruct.USART_HardwareFlowControl = parameters->hwFlowControl; - - USART_Init(self->USART_TypeDef, &self->USART_InitStruct); - - //! Enable USART interface - USART_Cmd(self->USART_TypeDef, ENABLE); - - //! Create a new FREERTOS queue to handle data from app to USART output - self->txQueue = xQueueCreate(parameters->txQueueSize, sizeof(struct usartQueueItem)); - //! Create a new FREERTOS queue to handle data from USART input to app - self->rxQueue = xQueueCreate(parameters->rxQueueSize, sizeof(struct usartQueueItem)); - //! Queue identifier must not be 0 (0 means that the queue is not available) - if (self->txQueue == 0) + if(!self->initialized) { - //! Queue identifier is 0 -> error - returnValue = ERROR; //! Set error flag + IODevice_construct(&self->device, read, write); + + //! Create semaphore to synchronize with USART interrupt handler + vSemaphoreCreateBinary(self->txSemaphore); + + USART_DeInit(self->USART_TypeDef); + + // Initialise the UART + self->USART_InitStruct.USART_BaudRate = parameters->baudrate; + self->USART_InitStruct.USART_WordLength = parameters->wordlength; + self->USART_InitStruct.USART_StopBits = parameters->stopbits; + self->USART_InitStruct.USART_Parity = parameters->parity; + self->USART_InitStruct.USART_Mode = parameters->mode; + self->USART_InitStruct.USART_HardwareFlowControl = parameters->hwFlowControl; + + USART_Init(self->USART_TypeDef, &self->USART_InitStruct); + + //! Enable USART interface + USART_Cmd(self->USART_TypeDef, ENABLE); + + //! Create a new FREERTOS queue to handle data from app to USART output + self->txQueue = xQueueCreate(parameters->txQueueSize, sizeof(struct usartQueueItem)); + //! Create a new FREERTOS queue to handle data from USART input to app + self->rxQueue = xQueueCreate(parameters->rxQueueSize, sizeof(struct usartQueueItem)); + //! 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 + USART_ITConfig(self->USART_TypeDef, USART_IT_RXNE, ENABLE); + self->initialized = true; + } } - if (self->rxQueue == 0) + else { - //! 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; } - struct usartQueueItem tmp; - tmp.byte = 0x01; - xQueueSend(self->rxQueue, &tmp, 0); - tmp.byte++; - xQueueSend(self->rxQueue, &tmp, 0); - tmp.byte++; - xQueueSend(self->rxQueue, &tmp, 0); - - if (returnValue == SUCCESS) - { - //! Enable the UART RX not empty interrupt - USART_ITConfig(self->USART_TypeDef, USART_IT_RXNE, ENABLE); - } - return returnValue; } @@ -169,52 +161,60 @@ ErrorStatus Uart_write(struct Uart* self, const char* buffer, int length) ErrorStatus returnValue = SUCCESS; //! Define return variable int txCounter; //! Define a loop counter var - //! Copy the incoming data into UART data structure - for (txCounter = 0; txCounter < length; txCounter++) - { - usartTxItem.byte = buffer[txCounter]; //! Copy current data in struct - if (uxQueueSpacesAvailable(self->txQueue) == 2) + if (self->initialized) + { + + //! Copy the incoming data into UART data structure + for (txCounter = 0; txCounter < length; txCounter++) { - USART_ITConfig(self->USART_TypeDef, USART_IT_TXE, ENABLE); + usartTxItem.byte = buffer[txCounter]; //! Copy current data in struct + if (uxQueueSpacesAvailable(self->txQueue) == 2) + { + USART_ITConfig(self->USART_TypeDef, USART_IT_TXE, ENABLE); + } + //! Add the current set of data to UART transmission queue + if (pdTRUE != xQueueSend(self->txQueue, &usartTxItem, portMAX_DELAY)) + { + //! Adding item was NOT successful - break out of loop + returnValue = ERROR; //! Set return value to FALSE + break; + } } - //! Add the current set of data to UART transmission queue - if (pdTRUE != xQueueSend(self->txQueue, &usartTxItem, portMAX_DELAY)) - { - //! Adding item was NOT successful - break out of loop - returnValue = ERROR; //! Set return value to FALSE - break; - } - } - if (returnValue == SUCCESS) - { - //! Semaphore has been taken - //! Enable the USARTx TXE (transmission empty) interrupt - USART_ITConfig(self->USART_TypeDef, USART_IT_TXE, ENABLE); + if (returnValue == SUCCESS) + { + //! Semaphore has been taken + //! Enable the USARTx TXE (transmission empty) interrupt + USART_ITConfig(self->USART_TypeDef, USART_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->txSemaphore, portMAX_DELAY); + //! 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->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 (USART_GetFlagStatus(self->USART_TypeDef, USART_FLAG_TC) == RESET) - { - //! The software must wait until TC=1. The TC flag remains cleared during - //! all data transfers and it is set by hardware at the last frame's - //! end of transmission - } - } - else - { - //! Do nothing - } + /** 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 (USART_GetFlagStatus(self->USART_TypeDef, USART_FLAG_TC) == RESET) + { + //! The software must wait until TC=1. The TC flag remains cleared during + //! all data transfers and it is set by hardware at the last frame's + //! end of transmission + } + } + else + { + //! Do nothing + } + } + else + { + returnValue = ERROR; + } return (returnValue); //! Return result to caller } @@ -227,20 +227,27 @@ ErrorStatus Uart_read (struct Uart* self, char* buffer, size_t length, size_t* a *actualLength = 0; struct usartQueueItem usartRxItem; - - for (loopCounter = 0; loopCounter < length; loopCounter++) + if (self->initialized) { - if (xQueueReceive(self->rxQueue, &usartRxItem, 0) != pdFALSE) + + for (loopCounter = 0; loopCounter < length; loopCounter++) { - // Item successfully fetched from Queue - buffer[loopCounter] = usartRxItem.byte; - *actualLength = *actualLength + 1; - } - else - { - break; + if (xQueueReceive(self->rxQueue, &usartRxItem, 0) != pdFALSE) + { + // Item successfully fetched from Queue + buffer[loopCounter] = usartRxItem.byte; + *actualLength = *actualLength + 1; + } + else + { + break; + } } } + else + { + returnValue = ERROR; + } return returnValue; } diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h index 331ac6b..d9e9374 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h @@ -69,6 +69,7 @@ struct HwValidationMenuItems struct Gpio* cat0Relay; struct Gpio* cat1Relay; struct Gpio* cat2Relay; + struct Gpio* teslaLock; struct Pcba* pcba; // struct Eeprom* eeprom; // Not implemented yet }; diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c index d13b626..d523704 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/main.c @@ -64,6 +64,7 @@ tick hook. */ #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) +#define INIT_START_SCREEN_DELAY (5000) // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- @@ -206,22 +207,23 @@ static void initTask(void* parameters) Version_getInstance()->patch); Display_write(display, buffer, strlen(buffer), 3, 4); - hwTestItems.display = &nhd0420.displayDevice; - hwTestItems.internalADC = adc1; - hwTestItems.externalDAC = &max5715; - hwTestItems.power6v5Enable = NULL; - hwTestItems.interlock1 = NULL; - hwTestItems.interlock2 = NULL; - hwTestItems.solenoid = NULL; - hwTestItems.mcp0Relay = NULL; - hwTestItems.mcp1Relay = NULL; - hwTestItems.mcp2Relay = NULL; - hwTestItems.cat0Relay = NULL; - hwTestItems.cat1Relay = NULL; - hwTestItems.cat2Relay = NULL; + hwTestItems.display = &nhd0420.displayDevice; + hwTestItems.internalADC = adc1; + hwTestItems.externalDAC = &max5715; + hwTestItems.power6v5Enable = power6v5Enable; + hwTestItems.interlock1 = interlock1; + hwTestItems.interlock2 = interlock2; + hwTestItems.solenoid = solenoid; + hwTestItems.mcp0Relay = mcp0Relay; + hwTestItems.mcp1Relay = mcp1Relay; + hwTestItems.mcp2Relay = mcp2Relay; + hwTestItems.cat0Relay = cat0Relay; + hwTestItems.cat1Relay = cat1Relay; + hwTestItems.cat2Relay = cat2Relay; + hwTestItems.teslaLock = teslaLock; hwTestItems.pcba = pcba; // EEPROM TO BE DONE -// HwValidationMenu_construct(hwValidation, &uart1->device, &hwTestItems, 2, 1024); +// HwValidationMenu_construct(hwValidation, &uart1->device, &hwTestItems, 1, 1024); MAX5715_construct(&max5715, &spiDAC->device); @@ -244,6 +246,9 @@ static void initTask(void* parameters) repairProcess_construct(rp, 3, 1024); xTaskCreate(printSystemInfoTask, (const char* const)"SysInfoTask", 512, NULL, 1, &sysTaskHandle); + + // Let start screen stay for 5 seconds + vTaskDelay(INIT_START_SCREEN_DELAY); // Delete this init task vTaskDelete(NULL);