7 changed files with 349 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,72 @@ |
|||||
|
/*
|
||||
|
* queues.c |
||||
|
* |
||||
|
* Created on: Dec 6, 2017 |
||||
|
* Author: maximilian |
||||
|
*/ |
||||
|
|
||||
|
#include "stdlib.h" |
||||
|
#include "stm32f10x.h" |
||||
|
#include "queues.h" |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
|
||||
|
static inline uint8_t osQFull(osQUEUE_t* q); |
||||
|
|
||||
|
static inline uint8_t osQEmpty(osQUEUE_t* q); |
||||
|
|
||||
|
static inline void osWrapArroundInc(uint8_t* i); |
||||
|
|
||||
|
void osQInit(osQUEUE_t* q, size_t ivarsize, void* istart) |
||||
|
{ |
||||
|
q->read_p = 0; |
||||
|
q->write_p = 0; |
||||
|
q->varsize = ivarsize; |
||||
|
q->start = istart; |
||||
|
} |
||||
|
|
||||
|
uint8_t osEnqueue(osQUEUE_t* q, void* data) |
||||
|
{ |
||||
|
if(osQFull(q)) |
||||
|
return 0; |
||||
|
else |
||||
|
{ |
||||
|
/* Copy queue element to where it belongs. */ |
||||
|
memcpy( ( q->start + (q->write_p)*(q->varsize) ), data, q->varsize); |
||||
|
osWrapArroundInc( &(q->write_p) ); |
||||
|
} |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
uint8_t osDequeue(osQUEUE_t* q, void* data) |
||||
|
{ |
||||
|
if(osQEmpty(q)) |
||||
|
return 0; |
||||
|
else |
||||
|
{ |
||||
|
memcpy(data, ( q->start + (q->read_p)*(q->varsize) ), q->varsize); |
||||
|
osWrapArroundInc( &(q->read_p) ); |
||||
|
} |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
static inline uint8_t osQFull(osQUEUE_t* q) |
||||
|
{ |
||||
|
uint8_t next = q->write_p; |
||||
|
osWrapArroundInc(&next); |
||||
|
return(next == q->read_p); |
||||
|
} |
||||
|
|
||||
|
static inline uint8_t osQEmpty(osQUEUE_t* q) |
||||
|
{ |
||||
|
return(q->write_p == q->read_p); |
||||
|
} |
||||
|
|
||||
|
static inline void osWrapArroundInc(uint8_t* i) |
||||
|
{ |
||||
|
if( (*i) < MAX_QUEUE_SIZE ) |
||||
|
(*i)++; |
||||
|
else |
||||
|
(*i) = 0; |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
/*
|
||||
|
* queues.h |
||||
|
* |
||||
|
* Created on: Dec 6, 2017 |
||||
|
* Author: maximilian |
||||
|
*/ |
||||
|
|
||||
|
#ifndef OS_QUEUES_H_ |
||||
|
#define OS_QUEUES_H_ |
||||
|
|
||||
|
#include "stm32f10x.h" |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#define MAX_QUEUE_SIZE 64 |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
uint8_t write_p; |
||||
|
uint8_t read_p; |
||||
|
/* Gives you the possibility to use the q with every data type. */ |
||||
|
void* start; |
||||
|
size_t varsize; |
||||
|
} osQUEUE_t; |
||||
|
|
||||
|
void osQInit(osQUEUE_t* q, size_t ivarsize, void* istart); |
||||
|
|
||||
|
uint8_t osEnqueue(osQUEUE_t* rx_q, void* data); |
||||
|
|
||||
|
uint8_t osDequeue(osQUEUE_t* tx_q, void* data); |
||||
|
|
||||
|
#endif /* OS_QUEUES_H_ */ |
@ -0,0 +1,70 @@ |
|||||
|
/*
|
||||
|
* system_timer.c |
||||
|
* |
||||
|
* Created on: Dec 6, 2017 |
||||
|
* Author: maximilian |
||||
|
*/ |
||||
|
|
||||
|
#include "stm32f10x.h" |
||||
|
#include "stm32f10x_flash.h" |
||||
|
#include "stm32f10x_rcc.h" |
||||
|
|
||||
|
#define ALIVE_PULSE_LENGTH 200 |
||||
|
|
||||
|
static volatile uint32_t ticky = 0; |
||||
|
|
||||
|
void InitAliveLED(void) |
||||
|
{ |
||||
|
/* Activate clock for peripheral. */ |
||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); |
||||
|
|
||||
|
/* Initialize GPIO Pin. */ |
||||
|
GPIO_InitTypeDef GPIO_InitStructure ; |
||||
|
GPIO_StructInit (&GPIO_InitStructure ); |
||||
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ; |
||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; |
||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz ; |
||||
|
GPIO_Init (GPIOA , & GPIO_InitStructure ); |
||||
|
} |
||||
|
|
||||
|
void InitClock(void) |
||||
|
{ |
||||
|
/* Configure all clocks to max for best performance.
|
||||
|
If there are EMI, power, or noise problems, try slowing the clocks.*/ |
||||
|
|
||||
|
/* First set the flash latency to work with our clock.
|
||||
|
000 Zero wait state, if 0 MHz < SYSCLK <= 24 MHz |
||||
|
001 One wait state, if 24 MHz < SYSCLK <= 48 MHz |
||||
|
010 Two wait states, if 48 MHz < SYSCLK <= 72 MHz */ |
||||
|
FLASH_SetLatency(FLASH_Latency_1); |
||||
|
|
||||
|
/* Start with HSI (High-Speed Internal) clock with 8 MHz, divide by 2 and multiply by 9 to
|
||||
|
get maximum allowed frequency: 36 MHz |
||||
|
Enable PLL, wait till it's stable, then select it as system clock*/ |
||||
|
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9); |
||||
|
RCC_PLLCmd(ENABLE); |
||||
|
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} |
||||
|
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); |
||||
|
|
||||
|
/* Set HCLK, PCLK1, and PCLK2 to SCLK. */ |
||||
|
RCC_HCLKConfig(RCC_SYSCLK_Div1); |
||||
|
RCC_PCLK1Config(RCC_HCLK_Div8); |
||||
|
RCC_PCLK2Config(RCC_HCLK_Div8); |
||||
|
|
||||
|
/* Configure Cortex-M System Tick Timer to tick every ms.*/ |
||||
|
SystemCoreClockUpdate(); |
||||
|
SysTick_Config(SystemCoreClock / 1000); |
||||
|
} |
||||
|
|
||||
|
void SysTick_Handler(void) |
||||
|
{ |
||||
|
static volatile uint8_t led_stat = 0; |
||||
|
if(ticky == ALIVE_PULSE_LENGTH) |
||||
|
{ |
||||
|
led_stat = !led_stat; |
||||
|
GPIO_WriteBit(GPIOA, GPIO_Pin_5, led_stat); |
||||
|
ticky = 0; |
||||
|
} |
||||
|
else |
||||
|
ticky++; |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
/*
|
||||
|
* system_timer.h |
||||
|
* |
||||
|
* Created on: Dec 6, 2017 |
||||
|
* Author: maximilian |
||||
|
*/ |
||||
|
|
||||
|
#ifndef PLATFORM_SYSTEM_TIMER_H_ |
||||
|
#define PLATFORM_SYSTEM_TIMER_H_ |
||||
|
|
||||
|
void InitAliveLED(void); |
||||
|
void InitClock(void); |
||||
|
|
||||
|
#endif /* PLATFORM_SYSTEM_TIMER_H_ */ |
@ -0,0 +1,144 @@ |
|||||
|
/*
|
||||
|
* usart.c |
||||
|
* |
||||
|
* Created on: Dec 6, 2017 |
||||
|
* Author: maximilian |
||||
|
*/ |
||||
|
|
||||
|
#include "usart.h" |
||||
|
#include "../os/queues.h" |
||||
|
#include "stm32f10x_gpio.h" |
||||
|
#include "stm32f10x_usart.h" |
||||
|
|
||||
|
uint8_t rx_overflow = 0; |
||||
|
|
||||
|
osQUEUE_t usart_rx_q, usart_tx_q; |
||||
|
|
||||
|
uint8_t usart_rx_data[MAX_QUEUE_SIZE]; |
||||
|
uint8_t usart_tx_data[MAX_QUEUE_SIZE]; |
||||
|
|
||||
|
|
||||
|
void usart2Init(void) |
||||
|
{ |
||||
|
/* Enable clocks. */ |
||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA , ENABLE); |
||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); |
||||
|
|
||||
|
/* Initialize used GPIOs. */ |
||||
|
GPIO_InitTypeDef GPIO_InitStruct; |
||||
|
GPIO_StructInit(&GPIO_InitStruct); |
||||
|
|
||||
|
/* Initialize USART2_TX */ |
||||
|
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; |
||||
|
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; |
||||
|
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; |
||||
|
GPIO_Init(GPIOA, &GPIO_InitStruct); |
||||
|
|
||||
|
/* Init. USART2_RX */ |
||||
|
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; |
||||
|
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; |
||||
|
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
||||
|
GPIO_Init(GPIOA, &GPIO_InitStruct); |
||||
|
|
||||
|
/* Init. USART2 peripheral. */ |
||||
|
USART_InitTypeDef USART_InitStructure ; |
||||
|
USART_StructInit(&USART_InitStructure ); |
||||
|
USART_InitStructure.USART_BaudRate = 9600; |
||||
|
USART_InitStructure.USART_WordLength = USART_StopBits_1; |
||||
|
USART_InitStructure.USART_Parity = USART_Parity_No; |
||||
|
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; |
||||
|
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; |
||||
|
USART_Init(USART2, &USART_InitStructure); |
||||
|
USART_Cmd(USART2, ENABLE); |
||||
|
|
||||
|
/* Config. interrupts. */ |
||||
|
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); |
||||
|
USART_ITConfig(USART2, USART_IT_TXE, ENABLE); |
||||
|
NVIC_EnableIRQ(USART2_IRQn); |
||||
|
|
||||
|
/* Init. SW queues. */ |
||||
|
osQInit(&usart_rx_q, sizeof(uint8_t), usart_rx_data); |
||||
|
osQInit(&usart_tx_q, sizeof(uint8_t), usart_tx_data); |
||||
|
} |
||||
|
|
||||
|
void USART2_IRQHandler(void) |
||||
|
{ |
||||
|
/* USART2 receive buffer contains a char. */ |
||||
|
if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) |
||||
|
{ |
||||
|
uint8_t data; |
||||
|
data = USART_ReceiveData(USART2) & 0xFF; |
||||
|
if(!osEnqueue(&usart_rx_q, (void*)&data)) |
||||
|
asm("NOP"); |
||||
|
// TODO: Throw receive buffer overflow error here
|
||||
|
} |
||||
|
|
||||
|
/* USART2 transmit buffer empty. */ |
||||
|
if(USART_GetITStatus(USART2, USART_IT_TXE) == SET) |
||||
|
{ |
||||
|
uint8_t data; |
||||
|
if(osDequeue(&usart_tx_q, &data)) |
||||
|
USART_SendData(USART2, data); |
||||
|
else |
||||
|
{ |
||||
|
/* Nothing to send. Disable interrupt. */ |
||||
|
USART_ITConfig(USART2, USART_IT_TXE, DISABLE); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static uint8_t usart2PutChar(uint8_t data) |
||||
|
{ |
||||
|
/* Put data in the q. */ |
||||
|
if(!osEnqueue(&usart_tx_q, (void*)&data)) |
||||
|
return 0; |
||||
|
/* Enable interrupt. */ |
||||
|
USART_ITConfig(USART2, USART_IT_TXE, ENABLE); |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
static uint8_t usart2GetChar(void) |
||||
|
{ |
||||
|
uint8_t data; |
||||
|
/* Wait until data arrives. */ |
||||
|
while(!osDequeue(&usart_rx_q, &data)){} |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
uint8_t usart2PutString(uint8_t* word, size_t size) |
||||
|
{ |
||||
|
uint8_t j = 0; |
||||
|
/* Push data as long as it needs that it comes through. */ |
||||
|
for(uint8_t i=0; i<size; i++) |
||||
|
while(!usart2PutChar(word[i])) |
||||
|
{ |
||||
|
j++; |
||||
|
if(j > 1) |
||||
|
asm("NOP"); |
||||
|
// TODO: Throw send buffer overflow error here
|
||||
|
} |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
uint8_t usart2GetString(uint8_t* word, size_t buff_size, size_t *string_size) |
||||
|
{ |
||||
|
uint8_t data; |
||||
|
*string_size = 0; |
||||
|
do |
||||
|
{ |
||||
|
data = usart2GetChar(); |
||||
|
if(data == 0) |
||||
|
return 0; |
||||
|
usart2PutChar(data); |
||||
|
if( *string_size < (buff_size-1) ) |
||||
|
word[*string_size] = data; |
||||
|
else |
||||
|
return 0; |
||||
|
// TODO: Throw buffer overflow error.
|
||||
|
(*string_size)++; |
||||
|
} while( (data != '\r') && (data != '\n') ); |
||||
|
/* Append string termination. */ |
||||
|
word[*string_size] = '\0'; |
||||
|
(*string_size)++; |
||||
|
return 1; |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
/*
|
||||
|
* usart.h |
||||
|
* |
||||
|
* Created on: Dec 6, 2017 |
||||
|
* Author: maximilian |
||||
|
*/ |
||||
|
|
||||
|
#ifndef PLATFORM_USART_H_ |
||||
|
#define PLATFORM_USART_H_ |
||||
|
|
||||
|
#include "stm32f10x.h" |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
void usart2Init(void); |
||||
|
uint8_t usart2PutString(uint8_t* word, size_t size); |
||||
|
uint8_t usart2GetString(uint8_t* word, size_t buff_size, size_t *string_size); |
||||
|
|
||||
|
#endif /* PLATFORM_USART_H_ */ |
Loading…
Reference in new issue