Browse Source

Non-blocking UART driver seems to do its job, also the queues seem to work. No semaphores implemented yet.

master
Maximilian Stiefel 7 years ago
parent
commit
f26b0ef566
  1. BIN
      docs/pdfs/SPL.pdf
  2. 72
      software/os/queues.c
  3. 31
      software/os/queues.h
  4. 70
      software/platform/system_timer.c
  5. 14
      software/platform/system_timer.h
  6. 144
      software/platform/usart.c
  7. 18
      software/platform/usart.h

BIN
docs/pdfs/SPL.pdf

Binary file not shown.

72
software/os/queues.c

@ -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;
}

31
software/os/queues.h

@ -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_ */

70
software/platform/system_timer.c

@ -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++;
}

14
software/platform/system_timer.h

@ -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_ */

144
software/platform/usart.c

@ -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;
}

18
software/platform/usart.h

@ -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…
Cancel
Save