first commit
This commit is contained in:
73
application/application.c
Normal file
73
application/application.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* application.c
|
||||
*
|
||||
* Created on: Jan 30, 2022
|
||||
* Author: ftobler
|
||||
*/
|
||||
|
||||
#include "application.h"
|
||||
#include "stdint.h"
|
||||
#include "main.h"
|
||||
#include "gpio.h"
|
||||
#include "serial.h"
|
||||
|
||||
|
||||
Serial serialUSB;
|
||||
Serial serialRS485;
|
||||
|
||||
void setup() {
|
||||
Serial_init(&serialUSB, &huart1);
|
||||
Serial_init(&serialRS485, &huart2);
|
||||
//gpio_SetPin(UART2_FLOW_GPIO_Port, UART2_FLOW_Pin);
|
||||
Serial_initFlow(&serialRS485, UART2_FLOW_GPIO_Port, UART2_FLOW_Pin);
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
while (Serial_available(&serialRS485)) {
|
||||
uint8_t b = Serial_read(&serialRS485);
|
||||
Serial_write(&serialUSB, b);
|
||||
}
|
||||
while (Serial_available(&serialUSB)) {
|
||||
uint8_t b = Serial_read(&serialUSB);
|
||||
Serial_write(&serialRS485, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t counter = 0;
|
||||
uint32_t mode = 0;
|
||||
|
||||
void systick() {
|
||||
counter++;
|
||||
if (counter >= 250) {
|
||||
counter = 0;
|
||||
mode = (mode + 1) % 4;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
gpio_SetPin(LED0_GPIO_Port, LED0_Pin);
|
||||
gpio_ResetPin(LED1_GPIO_Port, LED1_Pin);
|
||||
gpio_ResetPin(LED2_GPIO_Port, LED2_Pin);
|
||||
gpio_ResetPin(LED3_GPIO_Port, LED3_Pin);
|
||||
break;
|
||||
case 1:
|
||||
gpio_ResetPin(LED0_GPIO_Port, LED0_Pin);
|
||||
gpio_SetPin(LED1_GPIO_Port, LED1_Pin);
|
||||
gpio_ResetPin(LED2_GPIO_Port, LED2_Pin);
|
||||
gpio_ResetPin(LED3_GPIO_Port, LED3_Pin);
|
||||
break;
|
||||
case 2:
|
||||
gpio_ResetPin(LED0_GPIO_Port, LED0_Pin);
|
||||
gpio_ResetPin(LED1_GPIO_Port, LED1_Pin);
|
||||
gpio_SetPin(LED2_GPIO_Port, LED2_Pin);
|
||||
gpio_ResetPin(LED3_GPIO_Port, LED3_Pin);
|
||||
break;
|
||||
case 3:
|
||||
gpio_ResetPin(LED0_GPIO_Port, LED0_Pin);
|
||||
gpio_ResetPin(LED1_GPIO_Port, LED1_Pin);
|
||||
gpio_ResetPin(LED2_GPIO_Port, LED2_Pin);
|
||||
gpio_SetPin(LED3_GPIO_Port, LED3_Pin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
22
application/application.h
Normal file
22
application/application.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* application.h
|
||||
*
|
||||
* Created on: Jan 30, 2022
|
||||
* Author: ftobler
|
||||
*/
|
||||
|
||||
#ifndef APPLICATION_H_
|
||||
#define APPLICATION_H_
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
extern Serial serialUSB;
|
||||
extern Serial serialRS485;
|
||||
|
||||
|
||||
void setup();
|
||||
void loop();
|
||||
void systick();
|
||||
|
||||
|
||||
#endif /* APPLICATION_H_ */
|
27
application/gpio.c
Normal file
27
application/gpio.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* gpio.c
|
||||
*
|
||||
* Created on: 25.10.2020
|
||||
* Author: ftobler
|
||||
*/
|
||||
|
||||
|
||||
#include "stm32f0xx_hal.h"
|
||||
#include "gpio.h"
|
||||
|
||||
uint8_t gpio_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
|
||||
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_SetPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
|
||||
GPIOx->BSRR = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
|
||||
void gpio_ResetPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
|
||||
GPIOx->BSRR = (uint32_t)(GPIO_Pin << 16);
|
||||
}
|
||||
|
||||
|
17
application/gpio.h
Normal file
17
application/gpio.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* gpio.h
|
||||
*
|
||||
* Created on: 25.10.2020
|
||||
* Author: ftobler
|
||||
*/
|
||||
|
||||
#ifndef APP_GPIO_H_
|
||||
#define APP_GPIO_H_
|
||||
|
||||
|
||||
uint8_t gpio_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
void gpio_SetPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
void gpio_ResetPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
|
||||
|
||||
#endif
|
213
application/serial.c
Normal file
213
application/serial.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Serial.c
|
||||
*
|
||||
* Created on: Oct 17, 2020
|
||||
* Author: Florin (Nicolas)
|
||||
*/
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
#include "stm32f0xx.h"
|
||||
#include "stm32f0xx_hal_def.h"
|
||||
#include "gpio.h"
|
||||
|
||||
//public functions
|
||||
|
||||
|
||||
|
||||
static void Serial_enableTx(Serial* this);
|
||||
static void initBuf(Buffer* b);
|
||||
static inline uint8_t Buffer_getByte(Buffer* b);
|
||||
static inline uint32_t Buffer_getAvailable(Buffer* b);
|
||||
static inline void Buffer_setByte(Buffer* b, uint8_t data);
|
||||
|
||||
|
||||
|
||||
void ISR_Serial(Serial* this) {
|
||||
|
||||
UART_HandleTypeDef *huart = this->handler;
|
||||
|
||||
uint32_t isrflags = READ_REG(huart->Instance->ISR);
|
||||
uint32_t cr1its = READ_REG(huart->Instance->CR1);
|
||||
//uint32_t cr3its = READ_REG(huart->Instance->CR3);
|
||||
|
||||
|
||||
uint32_t errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
|
||||
if (errorflags == 0) {
|
||||
//handle normal
|
||||
if (((isrflags & USART_ISR_RXNE) != 0U) && ((cr1its & USART_CR1_RXNEIE) != 0U)) {
|
||||
//received something
|
||||
// if (huart->RxState == HAL_UART_STATE_BUSY_RX) {
|
||||
uint16_t uhMask = huart->Mask;
|
||||
uint16_t uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
|
||||
uint8_t data = (uint8_t)(uhdata & (uint8_t)uhMask);
|
||||
Buffer_setByte(&this->in, data);
|
||||
// } else {
|
||||
// /* Clear RXNE interrupt flag */
|
||||
// __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
//handle the errors (receive error)
|
||||
}
|
||||
|
||||
if (((isrflags & USART_ISR_TXE) != 0U) && ((cr1its & USART_CR1_TXEIE) != 0U)) {
|
||||
//sent something
|
||||
//if (huart->gState == HAL_UART_STATE_BUSY_TX) {
|
||||
uint8_t outAvail = Buffer_getAvailable(&this->out);
|
||||
if (outAvail == 0) {
|
||||
/* Disable the UART Transmit Data Register Empty Interrupt */
|
||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
/* Tx process is ended, restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Enable the UART Transmit Complete Interrupt */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
|
||||
} else {
|
||||
huart->Instance->TDR = Buffer_getByte(&this->out);
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U)) {
|
||||
//transmission ended
|
||||
|
||||
/* Disable the UART Transmit Complete Interrupt */
|
||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
|
||||
|
||||
this->txnComplete = 1;
|
||||
|
||||
if (this->flow) {
|
||||
gpio_ResetPin(this->flowPort, this->flowPin);
|
||||
}
|
||||
}
|
||||
huart->Instance->ICR = 0b00000000000000100000101001011111;
|
||||
//huart->Instance->ICR = 0; //clear all isr flags
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Serial_init(Serial* this, UART_HandleTypeDef* handler) {
|
||||
this->handler = handler;
|
||||
initBuf(&this->in);
|
||||
initBuf(&this->out);
|
||||
this->flow = 0;
|
||||
|
||||
UART_HandleTypeDef *huart = handler;
|
||||
/* Computation of UART mask to apply to RDR register */
|
||||
UART_MASK_COMPUTATION(huart);
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->RxState = HAL_UART_STATE_BUSY_RX;
|
||||
|
||||
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||||
}
|
||||
|
||||
|
||||
void Serial_initFlow(Serial* this, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
|
||||
this->flow = 1;
|
||||
this->flowPort = GPIOx;
|
||||
this->flowPin = GPIO_Pin;
|
||||
}
|
||||
|
||||
uint16_t Serial_available(Serial* this){
|
||||
return Buffer_getAvailable(&this->in);
|
||||
}
|
||||
|
||||
void Serial_flushRX(Serial* this){
|
||||
initBuf(&this->in);
|
||||
}
|
||||
|
||||
void Serial_flushTX(Serial* this){
|
||||
initBuf(&this->out);
|
||||
}
|
||||
|
||||
void Serial_print(Serial* this, const char* str){
|
||||
const uint8_t* ptr = (uint8_t*)str;
|
||||
while (*ptr != '\0'){
|
||||
Buffer_setByte(&this->out, *ptr);
|
||||
ptr++;
|
||||
}
|
||||
Serial_enableTx(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* unguarded about overflow!
|
||||
* use Serial_available!
|
||||
*/
|
||||
uint8_t Serial_read(Serial* this) {
|
||||
return Buffer_getByte(&this->in);
|
||||
}
|
||||
|
||||
uint16_t Serial_readBuf(Serial* this, uint8_t* buf, uint16_t len) {
|
||||
uint16_t count = 0;
|
||||
while (Buffer_getAvailable(&this->in) && (count < len)) {
|
||||
buf[count] = Buffer_getByte(&this->in);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
|
||||
// uint16_t max = Buffer_getAvailable(&this->in);
|
||||
// if (max > len) {
|
||||
// len = max;
|
||||
// }
|
||||
// for (uint16_t i = 0; i < len; i++) {
|
||||
// buf[i] = Buffer_getByte(&this->in);
|
||||
// }
|
||||
// return len;
|
||||
}
|
||||
|
||||
|
||||
void Serial_writeBuf(Serial* this, const uint8_t* buf, uint16_t len) {
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
Buffer_setByte(&this->out, buf[i]);
|
||||
}
|
||||
Serial_enableTx(this);
|
||||
}
|
||||
void Serial_write(Serial* this, const uint8_t data) {
|
||||
Buffer_setByte(&this->out, data);
|
||||
Serial_enableTx(this);
|
||||
}
|
||||
|
||||
|
||||
static void Serial_enableTx(Serial* this) {
|
||||
if (this->flow) {
|
||||
gpio_SetPin(this->flowPort, this->flowPin);
|
||||
}
|
||||
UART_HandleTypeDef *huart = this->handler;
|
||||
if (huart->gState == HAL_UART_STATE_READY) {
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_BUSY_TX;
|
||||
/* Enable the Transmit Data Register Empty interrupt */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
|
||||
/* Interrupt fires as soon as register is empty (probalbly right now) */
|
||||
} else {
|
||||
//huart->gState = HAL_UART_STATE_BUSY_TX;
|
||||
}
|
||||
this->txnComplete = 0;
|
||||
}
|
||||
|
||||
|
||||
static void initBuf(Buffer* b) {
|
||||
b->head = 0;
|
||||
b->tail = 0;
|
||||
}
|
||||
static inline uint8_t Buffer_getByte(Buffer* b) {
|
||||
uint32_t tail = b->tail;
|
||||
uint8_t data = b->buf[tail];
|
||||
b->tail = (tail + 1) % BUFFER_LEN;
|
||||
return data;
|
||||
}
|
||||
static inline uint32_t Buffer_getAvailable(Buffer* b) {
|
||||
return (b->head - b->tail) % BUFFER_LEN;
|
||||
}
|
||||
static inline void Buffer_setByte(Buffer* b, uint8_t data) {
|
||||
uint32_t head = b->head;
|
||||
b->buf[head] = data;
|
||||
b->head = (head + 1) % BUFFER_LEN;
|
||||
}
|
51
application/serial.h
Normal file
51
application/serial.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Serialh
|
||||
*
|
||||
* Created on: 17.10.2020
|
||||
* Author: Florin (Nicolas)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERIAL_H_
|
||||
#define SERIAL_H_
|
||||
|
||||
//public types
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define BUFFER_LEN 256
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t head;
|
||||
uint32_t tail;
|
||||
uint8_t buf[BUFFER_LEN];
|
||||
} Buffer;
|
||||
|
||||
typedef struct {
|
||||
UART_HandleTypeDef * handler;
|
||||
Buffer out;
|
||||
Buffer in;
|
||||
uint8_t txnComplete;
|
||||
uint8_t flow;
|
||||
GPIO_TypeDef* flowPort;
|
||||
uint16_t flowPin;
|
||||
} Serial;
|
||||
|
||||
|
||||
|
||||
//public function declarations
|
||||
void ISR_Serial(Serial* this);
|
||||
|
||||
void Serial_init(Serial* this, UART_HandleTypeDef* handler);
|
||||
void Serial_initFlow(Serial* this, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
|
||||
uint16_t Serial_available(Serial* this);
|
||||
void Serial_flushRX(Serial* this);
|
||||
void Serial_flushTX(Serial* this);
|
||||
void Serial_print(Serial* this, const char* str);
|
||||
uint8_t Serial_read(Serial* this);
|
||||
uint16_t Serial_readBuf(Serial* this, uint8_t* buf, uint16_t len);
|
||||
void Serial_writeBuf(Serial* this, const uint8_t* buf, uint16_t len);
|
||||
void Serial_write(Serial* this, const uint8_t data);
|
||||
|
||||
#endif /* SERIAL_H_ */
|
Reference in New Issue
Block a user