- added IODevice support

- fixed some issues with the logger and stack sizes

git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@216 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
mmi
2017-09-26 11:11:33 +00:00
parent 7bcde7ff5d
commit 1bcb4809db
48 changed files with 1033 additions and 11740 deletions

View File

@@ -14,6 +14,8 @@ LIBRARY_NAME = ../libPlatform.a
CCFLAGS = -c -O2 -Wall -g -fno-common -mcpu=cortex-m3 -mthumb -DOLI_STM32_H107 \
-Iinc \
-I../Misc/inc \
-I../Keypad/inc \
-I../Display/inc \
-I$(ROOTDIR)/hsb-mrts/inc \
-I$(ROOTDIR)/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc \
-I$(ROOTDIR)/FreeRTOS/Source/include \
@@ -23,12 +25,17 @@ CCFLAGS = -c -O2 -Wall -g -fno-common -mcpu=cortex-m3 -mthumb -DOLI_STM32_H107 \
ARFLAGS = rs
OBJECTS = \
stm32f10x_it.o \
led.o \
spi.o \
uart.o \
oli_stm32_h107.o \
vpath %.o $(OBJDIR)
vpath %.c \
$(SRCDIR)
$(SRCDIR) \
$(ROOTDIR)/hsb-mrts/src
all: $(LIBRARY_NAME)

View File

@@ -0,0 +1,87 @@
// -----------------------------------------------------------------------------
/// @file led.h
/// @brief File 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
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file led.h
/// @ingroup {group_name}
#ifndef LED_INC_LED_H_
#define LED_INC_LED_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <stdbool.h>
#include "platform.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct Led
{
T_PL_GPIO ledGpio;
bool status;
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
/** ----------------------------------------------------------------------------
* LED_turnOn
* Turns on the LED identified with the ID
*
* @param ledID Unique identifier of the LED
*
* @return ErrorStatus SUCCESS if init was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus LED_turnOn(struct Led* const led);
/** ----------------------------------------------------------------------------
* LED_turnOff
* Turns off the LED identified with the ID
*
* @param ledID Unique identifier of the LED
*
* @return ErrorStatus SUCCESS if init was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus LED_turnOff(struct Led* const led);
#endif /* LED_INC_LED_H_ */

View File

@@ -11,9 +11,9 @@
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision: $
/// $Author: $
/// $Date: $
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
@@ -34,6 +34,8 @@
// Include files
// -----------------------------------------------------------------------------
#include <stdio.h>
#include "FreeRTOSConfig.h"
#include "stm32f10x.h"
@@ -71,6 +73,9 @@ extern struct SpiDevice* const spiDAC;
extern struct SpiDevice* const spiDisplay;
extern struct SpiDevice* const spiEEPROM;
extern struct Keypad* const keypad;
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,172 @@
// -----------------------------------------------------------------------------
/// @file spi.h
/// @brief File 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
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file spi.h
/// @ingroup {group_name}
#ifndef MISC_INC_SPI_H_
#define MISC_INC_SPI_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <stdbool.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "platform.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define SPI_DEF_Direction (SPI_Direction_2Lines_FullDuplex)
#define SPI_DEF_Mode (SPI_Mode_Master)
#define SPI_DEF_DataSize (SPI_DataSize_8b)
#define SPI_DEF_CPOL (SPI_CPOL_Low)
#define SPI_DEF_CPHA (SPI_CPHA_1Edge)
#define SPI_DEF_NSS (SPI_NSS_Hard)
#define SPI_DEF_BaudRatePrescaler (SPI_BaudRatePrescaler_2)
#define SPI_DEF_FirstBit (SPI_FirstBit_MSB)
#define SPI_DEF_CRCPolynomial (7)
#define SPI_DEF_RX_QUEUE (16)
#define SPI_DEF_TX_QUEUE (16)
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct spiQueueItem
{
char byte;
};
struct Spi
{
SPI_TypeDef* SPI_TypeDef;
SPI_InitTypeDef SPI_InitStruct;
T_PL_GPIO SPI_CLK;
T_PL_GPIO* SPI_CE;
T_PL_GPIO SPI_MOSI;
T_PL_GPIO SPI_MISO;
SemaphoreHandle_t spiClaimed; //! Semaphore to protect SPI bus
//! against multiple use
SemaphoreHandle_t txSemaphore; //! Semaphore for transmit handler
//! to allow wait state while
//! transmission is active
xQueueHandle txQueue; //! SPI Transfer queue identifier
xQueueHandle rxQueue; //! SPI Receive queue identifier
bool initialized;
};
struct SpiParameters
{
uint16_t SPI_Direction;
uint16_t SPI_Mode;
uint16_t SPI_DataSize;
uint16_t SPI_CPOL;
uint16_t SPI_CPHA;
uint16_t SPI_NSS;
uint16_t SPI_BaudRatePrescaler;
uint16_t SPI_FirstBit;
uint16_t SPI_CRCPolynomial;
UBaseType_t txQueueSize;
UBaseType_t rxQueueSize;
};
struct SpiDevice
{
struct Spi* spi;
struct SpiParameters* spiParameters;
T_PL_GPIO SPI_CE;
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
/** ----------------------------------------------------------------------------
* Spi_construct
* Description of function
*
* @param self The SPi object to initialize
* @param parameters The SPI parameters to use
*
* @return ErrorStatus SUCCESS if writing message was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus SPI_construct(struct Spi* self, struct SpiParameters* parameters);
/** ----------------------------------------------------------------------------
* SPI_destruct
* Destructor for SPI interface in argument "self"
*
* @param self SPI to destruct
*
* @return ErrorStatus SUCCESS if destruct was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus SPI_destruct(struct Spi* self);
/** ----------------------------------------------------------------------------
* Spi_getDefaultParameters
* Function that assigns default parameters to the spi struct
*
* @param parameters
*
* @return ErrorStatus SUCCESS if destruct was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus SPI_getDefaultParameters(struct SpiParameters* parameters);
/** ----------------------------------------------------------------------------
* Spi_Write
* Write the data in buffer to the SPI in argument self
*
* @param self The UART class object
* @param buffer Message string to send
* @parm length Message length
*
* @return ErrorStatus SUCCESS if writing message was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus SPI_write (struct SpiDevice* self, const uint8_t* buffer, int length);
#endif /* MISC_INC_SPI_H_ */

View File

@@ -0,0 +1,146 @@
// -----------------------------------------------------------------------------
/// @file uart.h
/// @brief File 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
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file uart.h
/// @ingroup {group_name}
#ifndef MISC_INC_UART_H_
#define MISC_INC_UART_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "FreeRTOS.h"
#include "semphr.h"
#include "platform.h"
#include "IODevice.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define UART_DEF_BAUDRATE (9600)
#define UART_DEF_WORDLENGTH (USART_WordLength_8b)
#define UART_DEF_STOPBITS (USART_StopBits_1)
#define UART_DEF_PARITY (USART_Parity_No)
#define UART_DEF_MODE (USART_Mode_Tx | USART_Mode_Rx)
#define UART_DEF_HW_FLOW_CONTROL (USART_HardwareFlowControl_None)
#define UART_DEF_RX_QUEUE (32)
#define UART_DEF_TX_QUEUE (32)
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct usartQueueItem
{
char byte;
};
struct UartParameters
{
uint32_t baudrate;
uint16_t wordlength;
uint16_t stopbits;
uint16_t parity;
uint16_t mode;
uint16_t hwFlowControl;
UBaseType_t txQueueSize;
UBaseType_t rxQueueSize;
};
struct Uart
{
struct IODevice device;
USART_TypeDef* USART_TypeDef;
USART_InitTypeDef USART_InitStruct;
USART_ClockInitTypeDef* USART_ClockInitStruct;
T_PL_GPIO USART_RX;
T_PL_GPIO USART_TX;
T_PL_GPIO USART_CTS;
T_PL_GPIO USART_RTS;
SemaphoreHandle_t txSemaphore; //! Semaphore for transmit handler
xQueueHandle txQueue; //! USART Transfer queue identifier
xQueueHandle rxQueue; //! USART Receive queue identifier
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
/** ----------------------------------------------------------------------------
* Uart_construct
* Description of function
*
* @param _self The UART object to initialize
* @param baudrate Baudrate to use
* @param wordlength Wordlength for the UART
* @param stopbits Number of stopbits to use
* @param parity Parity of the UART
* @param mode Mode (TX, RX, Both)
* @param hwFlowControl Control of hardware flow control
*
* @return ErrorStatus SUCCESS if writing message was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus Uart_construct(struct Uart* self, struct UartParameters* parameters);
/** ----------------------------------------------------------------------------
* Uart_getDefaultParameters
* Function that assigns default parameters to the uart struct
*
* @param parameters
*
* @return ErrorStatus
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus Uart_getDefaultParameters(struct UartParameters* parameters);
/** ----------------------------------------------------------------------------
* Uart_Write
* Description of function
*
* @param self The UART class object
* @param buffer Message string to send
* @param length Message length
*
* @return ErrorStatus SUCCESS if writing message was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus Uart_Write(struct Uart* self, const char* buffer, int length);
#endif /* MISC_INC_UART_H_ */

View File

@@ -0,0 +1,79 @@
// -----------------------------------------------------------------------------
/// @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
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus LED_turnOn(struct Led* const 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;
}

View File

@@ -11,9 +11,9 @@
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision: $
/// $Author: $
/// $Date: $
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
@@ -34,6 +34,8 @@
#include "led.h"
#include "spi.h"
#include "uart.h"
#include "keypadMatrix.h"
#include "nhd0420.h"
// -----------------------------------------------------------------------------
@@ -43,12 +45,6 @@
// UART1 Settings (Logger/Console)
#define UART_LOG_TYPEDEF (USART1)
#define UART_LOG_BAUDRATE (57600)
#define UART_LOG_WORDLENGTH (USART_WordLength_8b)
#define UART_LOG_STOPBITS (USART_StopBits_1)
#define UART_LOG_PARITY (USART_Parity_No)
#define UART_LOG_MODE (USART_Mode_Tx | USART_Mode_Rx)
#define UART_LOG_HW_FLOW_CONTROL (USART_HardwareFlowControl_None)
#define UART_LOG_RX_QUEUE (256)
#define UART_LOG_TX_QUEUE (256)
// SPI1 settings
@@ -65,20 +61,11 @@
#define SPI_DAC_RX_QUEUE (32)
#define SPI_DAC_TX_QUEUE (32)
// SPI3 settings
#define SPI_LCD_TYPEDEF (SPI3)
#define SPI_LCD_Direction (SPI_Direction_2Lines_FullDuplex)
#define SPI_LCD_Mode (SPI_Mode_Master)
#define SPI_LCD_DataSize (SPI_DataSize_8b)
#define SPI_LCD_CPOL (SPI_CPOL_High)
#define SPI_LCD_CPHA (SPI_CPHA_2Edge)
#define SPI_LCD_NSS (SPI_NSS_Soft)
// Display has max SPI CLK of 100 kHz
#define SPI_LCD_BaudRatePrescaler (SPI_BaudRatePrescaler_128)
#define SPI_LCD_FirstBit (SPI_FirstBit_MSB)
#define SPI_LCD_CRCPolynomial (7)
#define SPI_LCD_RX_QUEUE (32)
#define SPI_LCD_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)
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
@@ -97,14 +84,20 @@ static struct Led _ledOrange;
// USART
static struct Uart _uart1;
static struct UartParameters _uart1Parameters;
// SPI
static struct Spi _spi1;
static struct SpiParameters _spi1Parameters;
static struct SpiDevice _spiDAC;
static struct Spi _spi3;
static struct SpiParameters _spi3Parameters;
static struct SpiDevice _spiDisplay;
static struct SpiDevice _spiEEPROM;
// Keypad
static struct Keypad _keypad;
// 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;
@@ -116,6 +109,8 @@ struct SpiDevice* const spiDAC = &_spiDAC;
struct SpiDevice* const spiDisplay = &_spiDisplay;
struct SpiDevice* const spiEEPROM = &_spiEEPROM;
struct Keypad* const keypad = &_keypad;
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
@@ -139,17 +134,60 @@ ErrorStatus initPlatform(void)
// Initialize the Console UART
IRQ_setInterruptProperties(USART1_IRQn, 15, 15, ENABLE);
uart1->USART_TypeDef = UART_LOG_TYPEDEF;
returnValue = Uart_Init(uart1, UART_LOG_BAUDRATE, UART_LOG_WORDLENGTH, UART_LOG_STOPBITS, UART_LOG_PARITY, UART_LOG_MODE, UART_LOG_HW_FLOW_CONTROL, UART_LOG_TX_QUEUE, UART_LOG_RX_QUEUE);
Uart_getDefaultParameters(&_uart1Parameters);
// Adjust to higher baudrate for intensive logging
_uart1Parameters.baudrate = UART_LOG_BAUDRATE;
// Adjust the TX queue size for intensive logging
_uart1Parameters.txQueueSize = UART_LOG_TX_QUEUE;
returnValue = Uart_construct(uart1, &_uart1Parameters);
IRQ_setInterruptProperties(SPI1_IRQn, 11, 11, ENABLE);
spi1->initialized = false;
spi1->SPI_TypeDef = SPI_DAC_TYPEDEF;
SPI_construct(spi1, SPI_DAC_Direction, SPI_DAC_Mode, SPI_DAC_DataSize, SPI_DAC_CPOL, SPI_DAC_CPHA, SPI_DAC_NSS, SPI_DAC_BaudRatePrescaler, SPI_DAC_FirstBit, SPI_DAC_CRCPolynomial, SPI_DAC_TX_QUEUE, SPI_DAC_RX_QUEUE);
SPI_getDefaultParameters(&_spi1Parameters);
SPI_construct(spi1, &_spi1Parameters);
IRQ_setInterruptProperties(SPI3_IRQn, 12, 12, ENABLE);
spi3->initialized = false;
spi3->SPI_TypeDef = SPI_LCD_TYPEDEF;
SPI_construct(spi3, SPI_LCD_Direction, SPI_LCD_Mode, SPI_LCD_DataSize, SPI_LCD_CPOL, SPI_LCD_CPHA, SPI_LCD_NSS, SPI_LCD_BaudRatePrescaler, SPI_LCD_FirstBit, SPI_LCD_CRCPolynomial, SPI_LCD_TX_QUEUE, SPI_LCD_RX_QUEUE);
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(&_spi3Parameters);
// 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
_spi3Parameters.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
// Adjust the RX and TX queues for multiple use
_spi3Parameters.rxQueueSize = SPI_LCD_EEPROM_RX_QUEUE;
_spi3Parameters.txQueueSize = SPI_LCD_EEPROM_TX_QUEUE;
SPI_construct(spi3, &_spi3Parameters);
// Enable 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);
}
@@ -173,6 +211,8 @@ static ErrorStatus initIO (void)
RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//! Enable USART clock
/* Peripheral bus power --------------------------------------------------*/
@@ -180,6 +220,8 @@ static ErrorStatus initIO (void)
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);
@@ -285,5 +327,65 @@ static ErrorStatus initIO (void)
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;
}

View File

@@ -0,0 +1,226 @@
// -----------------------------------------------------------------------------
/// @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, 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 USART output
self->txQueue = xQueueCreate(parameters->txQueueSize, sizeof(struct spiQueueItem));
//! Create a new FREERTOS queue to handle data from USART 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;
}
ErrorStatus SPI_write (struct SpiDevice* self, const uint8_t* 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;
// De-select the current device to avoid start-issues
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);
}
//! Copy the incoming data into BLUETOOTH data structure
for (txCounter = 0; txCounter < length; txCounter++)
{
txItem.byte = buffer[txCounter]; //! Copy current data in struct
//! Add the current set of data to bluetooth transmission queue
if (pdTRUE != xQueueSend(self->spi->txQueue, &txItem, 0))
{
//! Adding item was NOT successful - break out of loop
returnValue = ERROR; //! Set return value to FALSE
break;
}
}
if (returnValue == SUCCESS)
{
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);
}
//! Semaphore has been taken
//! Enable the SPI TXE (transmission empty) interrupt
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
}

View File

@@ -0,0 +1,205 @@
// -----------------------------------------------------------------------------
/// @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(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(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 BLUETOOTH data structure
for (txCounter = 0; txCounter < length; txCounter++)
{
usartTxItem.byte = buffer[txCounter]; //! Copy current data in struct
//! Add the current set of data to bluetooth transmission queue
if (pdTRUE != xQueueSend(self->txQueue, &usartTxItem, 0))
{
//! 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
}