Moved platform
git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@222 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
/// @file led.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 led.c
|
||||
/// @ingroup {group_name}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Include files
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "led.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 LED_construct (struct Led* self)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
IODevice_construct(&self->device, read, write);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
static ErrorStatus write(const struct IODevice* self, const char* buffer, size_t length)
|
||||
{
|
||||
(void)length;
|
||||
|
||||
if (buffer != 0)
|
||||
{
|
||||
return LED_turnOn((struct Led*)self);
|
||||
}
|
||||
else
|
||||
{
|
||||
return LED_turnOff((struct Led*)self);
|
||||
}
|
||||
}
|
||||
static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength)
|
||||
{
|
||||
struct Led* led = (struct Led*)self;
|
||||
(void)length;
|
||||
*actualLength = 1;
|
||||
*buffer = (char)led->status;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ErrorStatus LED_turnOn(struct Led* led)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
GPIO_SetBits(led->ledGpio.GPIO_Typedef, led->ledGpio.GPIO_InitStruct.GPIO_Pin);
|
||||
led->status = true;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
ErrorStatus LED_turnOff(struct Led* const led)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
GPIO_ResetBits(led->ledGpio.GPIO_Typedef, led->ledGpio.GPIO_InitStruct.GPIO_Pin);
|
||||
led->status = false;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
/// @file oli_stm32_h107.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 oli_stm32_h107.c
|
||||
/// @ingroup {group_name}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Include files
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "stm32f10x_gpio.h"
|
||||
#include "stm32f10x_it.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "spiDevice.h"
|
||||
#include "led.h"
|
||||
#include "spi.h"
|
||||
#include "uart.h"
|
||||
#include "keypadMatrix.h"
|
||||
#include "nhd0420.h"
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Constant and macro definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// UART1 Settings (Logger/Console)
|
||||
#define UART_LOG_TYPEDEF (USART1)
|
||||
#define UART_LOG_BAUDRATE (57600)
|
||||
#define UART_LOG_TX_QUEUE (256)
|
||||
|
||||
// SPI1 settings
|
||||
#define SPI_DAC_TYPEDEF (SPI1)
|
||||
#define SPI_DAC_Direction (SPI_Direction_2Lines_FullDuplex)
|
||||
#define SPI_DAC_Mode (SPI_Mode_Master)
|
||||
#define SPI_DAC_DataSize (SPI_DataSize_8b)
|
||||
#define SPI_DAC_CPOL (SPI_CPOL_High)
|
||||
#define SPI_DAC_CPHA (SPI_CPHA_2Edge)
|
||||
#define SPI_DAC_NSS (SPI_NSS_Hard)
|
||||
#define SPI_DAC_BaudRatePrescaler (SPI_BaudRatePrescaler_128)
|
||||
#define SPI_DAC_FirstBit (SPI_FirstBit_MSB)
|
||||
#define SPI_DAC_CRCPolynomial (7)
|
||||
#define SPI_DAC_RX_QUEUE (32)
|
||||
#define SPI_DAC_TX_QUEUE (32)
|
||||
|
||||
// SPI3 settings (LCD / EEPROM)
|
||||
#define SPI_LCD_EEPROM_TYPEDEF (SPI3)
|
||||
#define SPI_LCD_EEPROM_Direction (SPI_Direction_2Lines_FullDuplex)
|
||||
#define SPI_LCD_EEPROM_RX_QUEUE (32)
|
||||
#define SPI_LCD_EEPROM_TX_QUEUE (32)
|
||||
|
||||
// Keypad Settings
|
||||
#define KEYPAD_DEBOUNCE_TIME_MS (20)
|
||||
// -----------------------------------------------------------------------------
|
||||
// Type definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// File-scope variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// The following static file-scope variables represent the actual storage of
|
||||
// the IO/Peripheral object
|
||||
|
||||
// LEDs
|
||||
static struct Led _ledGreen;
|
||||
static struct Led _ledOrange;
|
||||
|
||||
// USART
|
||||
static struct Uart _uart1;
|
||||
static struct UartParameters _uart1Parameters;
|
||||
|
||||
// SPI
|
||||
static struct Spi _spi1;
|
||||
static struct SpiDevice _spiDAC;
|
||||
static struct Spi _spi3;
|
||||
static struct SpiParameters _spi3DisplayParameters;
|
||||
static struct SpiParameters _spi3EEPROMParameters;
|
||||
static struct SpiDevice _spiDisplay;
|
||||
static struct SpiDevice _spiEEPROM;
|
||||
|
||||
// Keypad
|
||||
static struct Keypad _keypad;
|
||||
static struct KeypadParameters _keypadParameters;
|
||||
|
||||
// The following pointers are for export (see platform.h) and external use.
|
||||
// Note that the pointer content is marked "const"
|
||||
struct Led* const ledGreen = &_ledGreen;
|
||||
struct Led* const ledOrange = &_ledOrange;
|
||||
|
||||
struct Uart* const uart1 = &_uart1;
|
||||
struct UartParameters* uartLoggerParam = &_uart1Parameters;
|
||||
|
||||
struct Spi* const spi1 = &_spi1;
|
||||
struct Spi* const spi3 = &_spi3;
|
||||
struct SpiDevice* const spiDAC = &_spiDAC;
|
||||
struct SpiDevice* const spiDisplay = &_spiDisplay;
|
||||
struct SpiParameters* const spiDisplayParam = &_spi3DisplayParameters;
|
||||
struct SpiDevice* const spiEEPROM = &_spiEEPROM;
|
||||
struct SpiParameters* const spiEEPROMParam = &_spi3EEPROMParameters;
|
||||
|
||||
struct Keypad* const keypad = &_keypad;
|
||||
struct KeypadParameters* const keypadParam = &_keypadParameters;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function declarations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static ErrorStatus initIO (void);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//#ifdef OLI_STM32_H107
|
||||
|
||||
ErrorStatus initPlatform(void)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
if (returnValue == SUCCESS)
|
||||
{
|
||||
returnValue = initIO();
|
||||
|
||||
LED_construct(ledGreen);
|
||||
LED_construct(ledOrange);
|
||||
|
||||
// Initialize the Console UART
|
||||
IRQ_setInterruptProperties(USART1_IRQn, 15, 15, ENABLE);
|
||||
uart1->USART_TypeDef = UART_LOG_TYPEDEF;
|
||||
Uart_getDefaultParameters(uartLoggerParam);
|
||||
// Adjust to higher baudrate for intensive logging
|
||||
uartLoggerParam->baudrate = UART_LOG_BAUDRATE;
|
||||
// Adjust the TX queue size for intensive logging
|
||||
uartLoggerParam->txQueueSize = UART_LOG_TX_QUEUE;
|
||||
returnValue = Uart_construct(uart1, uartLoggerParam);
|
||||
|
||||
// IRQ_setInterruptProperties(SPI1_IRQn, 11, 11, ENABLE);
|
||||
// spi1->initialized = false;
|
||||
// spi1->SPI_TypeDef = SPI_DAC_TYPEDEF;
|
||||
// SPI_getDefaultParameters(&_spi1Parameters);
|
||||
// SPI_construct(spi1, &_spi1Parameters);
|
||||
|
||||
IRQ_setInterruptProperties(SPI3_IRQn, 12, 12, ENABLE);
|
||||
spi3->initialized = false;
|
||||
spi3->SPI_TypeDef = SPI_LCD_EEPROM_TYPEDEF;
|
||||
// Get the SPI parameters from the NHD0420 driver. They are more critical than the parameters from the EEPROM
|
||||
NHD0420_getSpiParameters(spiDisplayParam);
|
||||
// In order to use multiple slaves on this bus (and to increase performance), some parameters are altered
|
||||
// Use full-duples instead of TX only, because the EEPROM is both write- and readable
|
||||
spiDisplayParam->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
// Adjust the RX and TX queues for multiple use
|
||||
spiDisplayParam->rxQueueSize = SPI_LCD_EEPROM_RX_QUEUE;
|
||||
spiDisplayParam->txQueueSize = SPI_LCD_EEPROM_TX_QUEUE;
|
||||
///TODO SPI_CE should be initialized individually
|
||||
GPIO_SetBits(spiDisplay->SPI_CE.GPIO_Typedef, spiDisplay->SPI_CE.GPIO_InitStruct.GPIO_Pin);
|
||||
SpiDevice_construct(spiDisplay, spi3, spiDisplayParam, spiDisplay->SPI_CE);
|
||||
SpiDevice_construct(spiEEPROM, spi3, spiEEPROMParam, spiEEPROM->SPI_CE);
|
||||
|
||||
// Set-up the interrupts for the Keypad columns
|
||||
keypad->column[0].EXTI_InitStruct.EXTI_Line = EXTI_Line4;
|
||||
keypad->column[0].EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
keypad->column[0].EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||||
keypad->column[0].EXTI_InitStruct.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&keypad->column[0].EXTI_InitStruct);
|
||||
// Enable the interrupts for the Keypad columns
|
||||
keypad->column[1].EXTI_InitStruct.EXTI_Line = EXTI_Line5;
|
||||
keypad->column[1].EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
keypad->column[1].EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||||
keypad->column[1].EXTI_InitStruct.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&keypad->column[1].EXTI_InitStruct);
|
||||
// Enable the interrupts for the Keypad columns
|
||||
keypad->column[2].EXTI_InitStruct.EXTI_Line = EXTI_Line6;
|
||||
keypad->column[2].EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
keypad->column[2].EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||||
keypad->column[2].EXTI_InitStruct.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&keypad->column[2].EXTI_InitStruct);
|
||||
// Enable the interrupts for the Keypad columns
|
||||
keypad->column[3].EXTI_InitStruct.EXTI_Line = EXTI_Line7;
|
||||
keypad->column[3].EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
keypad->column[3].EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
|
||||
keypad->column[3].EXTI_InitStruct.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&keypad->column[3].EXTI_InitStruct);
|
||||
|
||||
IRQ_setInterruptProperties(EXTI4_IRQn, 11, 0, ENABLE);
|
||||
IRQ_setInterruptProperties(EXTI9_5_IRQn, 11, 0, ENABLE);
|
||||
|
||||
Keypad_getDefaultParameters(keypadParam);
|
||||
Keypad_construct(keypad, keypadParam, KEYPAD_DEBOUNCE_TIME_MS);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
//#endif
|
||||
|
||||
|
||||
static ErrorStatus initIO (void)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
|
||||
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
|
||||
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
|
||||
//! Enable USART clock
|
||||
|
||||
/* Peripheral bus power --------------------------------------------------*/
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
|
||||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, DISABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
|
||||
|
||||
/*LED IO initialisation --------------------------------------------------*/
|
||||
// Init LED Green
|
||||
ledGreen->ledGpio.GPIO_Typedef = GPIOC;
|
||||
ledGreen->ledGpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
ledGreen->ledGpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
|
||||
ledGreen->ledGpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(ledGreen->ledGpio.GPIO_Typedef, &ledGreen->ledGpio.GPIO_InitStruct);
|
||||
|
||||
// Init LED Orange
|
||||
ledOrange->ledGpio.GPIO_Typedef = GPIOC;
|
||||
ledOrange->ledGpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
ledOrange->ledGpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
|
||||
ledOrange->ledGpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(ledOrange->ledGpio.GPIO_Typedef, &ledOrange->ledGpio.GPIO_InitStruct);
|
||||
|
||||
/* USART1 initialisation -------------------------------------------------*/
|
||||
// Init TX line
|
||||
_uart1.USART_TX.GPIO_Typedef = GPIOB;
|
||||
_uart1.USART_TX.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_uart1.USART_TX.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
|
||||
_uart1.USART_TX.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_uart1.USART_TX.GPIO_Typedef, &_uart1.USART_TX.GPIO_InitStruct);
|
||||
|
||||
// Init RX line
|
||||
_uart1.USART_RX.GPIO_Typedef = GPIOB;
|
||||
_uart1.USART_RX.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_uart1.USART_RX.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
|
||||
_uart1.USART_RX.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_uart1.USART_RX.GPIO_Typedef, &_uart1.USART_RX.GPIO_InitStruct);
|
||||
// Apply pin-remapping for UART1 I/Os (alternative I/Os usage)
|
||||
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
|
||||
|
||||
/* SPI initialisation ----------------------------------------------------*/
|
||||
// SPI1 CLK
|
||||
_spi1.SPI_CLK.GPIO_Typedef = GPIOA;
|
||||
_spi1.SPI_CLK.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_spi1.SPI_CLK.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
|
||||
_spi1.SPI_CLK.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spi1.SPI_CLK.GPIO_Typedef, &_spi1.SPI_CLK.GPIO_InitStruct);
|
||||
// SPI1 MISO
|
||||
_spi1.SPI_MISO.GPIO_Typedef = GPIOA;
|
||||
_spi1.SPI_MISO.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_spi1.SPI_MISO.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
|
||||
_spi1.SPI_MISO.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spi1.SPI_MISO.GPIO_Typedef, &_spi1.SPI_MISO.GPIO_InitStruct);
|
||||
// SPI1 MOSI
|
||||
_spi1.SPI_MOSI.GPIO_Typedef = GPIOA;
|
||||
_spi1.SPI_MOSI.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_spi1.SPI_MOSI.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
|
||||
_spi1.SPI_MOSI.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spi1.SPI_MOSI.GPIO_Typedef, &_spi1.SPI_MOSI.GPIO_InitStruct);
|
||||
// SPI1 CE
|
||||
_spiDAC.SPI_CE.GPIO_Typedef = GPIOA;
|
||||
_spiDAC.SPI_CE.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_spiDAC.SPI_CE.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
|
||||
_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;
|
||||
_spi3.SPI_CLK.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
|
||||
_spi3.SPI_CLK.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spi3.SPI_CLK.GPIO_Typedef, &_spi3.SPI_CLK.GPIO_InitStruct);
|
||||
// SPI3 MISO
|
||||
_spi3.SPI_MISO.GPIO_Typedef = GPIOC;
|
||||
_spi3.SPI_MISO.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_spi3.SPI_MISO.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
|
||||
_spi3.SPI_MISO.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spi3.SPI_MISO.GPIO_Typedef, &_spi3.SPI_MISO.GPIO_InitStruct);
|
||||
// SPI3 MOSI
|
||||
_spi3.SPI_MOSI.GPIO_Typedef = GPIOC;
|
||||
_spi3.SPI_MOSI.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
_spi3.SPI_MOSI.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
|
||||
_spi3.SPI_MOSI.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spi3.SPI_MOSI.GPIO_Typedef, &_spi3.SPI_MOSI.GPIO_InitStruct);
|
||||
|
||||
// Apply pin-remapping for SPI3 I/Os (alternative I/Os usage)
|
||||
GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE);
|
||||
|
||||
// SPI3 Display shares all parameters with SPI3 but the ChipEnable, which is different
|
||||
_spiDisplay.spi = &_spi3;
|
||||
// SPI3 CE EEPROM
|
||||
_spiDisplay.SPI_CE.GPIO_Typedef = GPIOE;
|
||||
_spiDisplay.SPI_CE.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
_spiDisplay.SPI_CE.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
|
||||
_spiDisplay.SPI_CE.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spiDisplay.SPI_CE.GPIO_Typedef, &_spiDisplay.SPI_CE.GPIO_InitStruct);
|
||||
|
||||
// SPI3 EEPROM shares all parameters with SPI3 but the ChipEnable, which is different
|
||||
_spiEEPROM.spi = &_spi3;
|
||||
// SPI3 CE EEPROM
|
||||
_spiEEPROM.SPI_CE.GPIO_Typedef = GPIOE;
|
||||
_spiEEPROM.SPI_CE.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
_spiEEPROM.SPI_CE.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
|
||||
_spiEEPROM.SPI_CE.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(_spiEEPROM.SPI_CE.GPIO_Typedef, &_spiEEPROM.SPI_CE.GPIO_InitStruct);
|
||||
|
||||
|
||||
// Keypad I/O
|
||||
// Row1
|
||||
keypad->row[0].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->row[0].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
keypad->row[0].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
|
||||
keypad->row[0].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->row[0].gpio.GPIO_Typedef, &keypad->row[0].gpio.GPIO_InitStruct);
|
||||
|
||||
// Row2
|
||||
keypad->row[1].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->row[1].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
keypad->row[1].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
|
||||
keypad->row[1].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->row[1].gpio.GPIO_Typedef, &keypad->row[1].gpio.GPIO_InitStruct);
|
||||
// Row3
|
||||
keypad->row[2].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->row[2].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
keypad->row[2].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
|
||||
keypad->row[2].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->row[2].gpio.GPIO_Typedef, &keypad->row[2].gpio.GPIO_InitStruct);
|
||||
// Row4
|
||||
keypad->row[3].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->row[3].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
keypad->row[3].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
|
||||
keypad->row[3].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->row[3].gpio.GPIO_Typedef, &keypad->row[3].gpio.GPIO_InitStruct);
|
||||
|
||||
// Column1
|
||||
keypad->column[0].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->column[0].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
|
||||
keypad->column[0].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
|
||||
keypad->column[0].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->column[0].gpio.GPIO_Typedef, &keypad->column[0].gpio.GPIO_InitStruct);
|
||||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource4);
|
||||
|
||||
// Column2
|
||||
keypad->column[1].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->column[1].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
|
||||
keypad->column[1].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
|
||||
keypad->column[1].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->column[1].gpio.GPIO_Typedef, &keypad->column[1].gpio.GPIO_InitStruct);
|
||||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource5);
|
||||
|
||||
// Column3
|
||||
keypad->column[2].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->column[2].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
|
||||
keypad->column[2].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
|
||||
keypad->column[2].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->column[2].gpio.GPIO_Typedef, &keypad->column[2].gpio.GPIO_InitStruct);
|
||||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource6);
|
||||
|
||||
// Column4
|
||||
keypad->column[3].gpio.GPIO_Typedef = GPIOD;
|
||||
keypad->column[3].gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
|
||||
keypad->column[3].gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
|
||||
keypad->column[3].gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(keypad->column[3].gpio.GPIO_Typedef, &keypad->column[3].gpio.GPIO_InitStruct);
|
||||
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource7);
|
||||
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
/// @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 <stdbool.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);
|
||||
|
||||
//! 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
/// @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 <stdio.h>
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
/// @file uart.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 uart.c
|
||||
/// @ingroup {group_name}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Include files
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#include "stm32f10x_usart.h"
|
||||
|
||||
#include "uart.h"
|
||||
#include "misc.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);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
ErrorStatus Uart_construct(struct Uart* self, struct UartParameters* parameters)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
IODevice_construct(&self->device, NULL, 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_Disable;
|
||||
|
||||
//! 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)
|
||||
{
|
||||
//! 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);
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
ErrorStatus Uart_getDefaultParameters(struct UartParameters* parameters)
|
||||
{
|
||||
ErrorStatus returnValue = SUCCESS;
|
||||
|
||||
parameters->baudrate = UART_DEF_BAUDRATE;
|
||||
parameters->wordlength = UART_DEF_WORDLENGTH;
|
||||
parameters->stopbits = UART_DEF_STOPBITS;
|
||||
parameters->mode = UART_DEF_MODE;
|
||||
parameters->parity = UART_DEF_PARITY;
|
||||
parameters->hwFlowControl = UART_DEF_HW_FLOW_CONTROL;
|
||||
parameters->txQueueSize = UART_DEF_TX_QUEUE;
|
||||
parameters->rxQueueSize = UART_DEF_RX_QUEUE;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
static ErrorStatus write(const struct IODevice* self, const char* buffer, size_t length)
|
||||
{
|
||||
return Uart_Write((struct Uart*)self, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
ErrorStatus Uart_Write(struct Uart* self, const char* buffer, int length)
|
||||
{
|
||||
struct usartQueueItem usartTxItem;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/** 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
|
||||
}
|
||||
|
||||
|
||||
return (returnValue); //! Return result to caller
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user