car_hw: add gitignored usart lib for sonar driver
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
LIB_USART_OBJ_PREFIX=libusart_
|
||||||
|
|
||||||
|
$(LIB_USART_OBJ): \
|
||||||
|
$(call dircs_to_prefxd_objs,$(LIB_USART_DIR),$(LIB_USART_OBJ_PREFIX))
|
||||||
|
$(LD_ALL_DEPS)
|
||||||
|
|
||||||
|
$(BIN_DIR)/$(LIB_USART_OBJ_PREFIX)%.o: $(LIB_USART_DIR)/%.c \
|
||||||
|
$(call dirhs,$(LIB_USART_DIR))
|
||||||
|
$(CC_ALL_DEPS)
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* Reworker but not completely refactored lib from
|
||||||
|
* http://microtechnics.ru/biblioteka-dlya-raboty-s-usart-v-stm32/
|
||||||
|
*/
|
||||||
|
#include "usart.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stm32f4xx_rcc.h>
|
||||||
|
#include <stm32f4xx_usart.h>
|
||||||
|
|
||||||
|
// Variables for GPIO and USART configuration
|
||||||
|
GPIO_InitTypeDef MT_USART_CfgGPIO;
|
||||||
|
USART_InitTypeDef MT_USART_CfgUSART;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
USART_TypeDef *usart;
|
||||||
|
// Ready to transmit and ready to receive flags
|
||||||
|
volatile bool MT_USART_ReadyToExchange;
|
||||||
|
// Number of bytes to send
|
||||||
|
uint8_t MT_USART_NumOfDataToSend;
|
||||||
|
// Number of bytes to receive
|
||||||
|
uint8_t MT_USART_NumOfDataToReceive;
|
||||||
|
// Pointer to the data that will be sent
|
||||||
|
uint8_t *MT_USART_SendDataPtr;
|
||||||
|
// Pointer to the buffer where received data will be saved
|
||||||
|
uint8_t *MT_USART_ReceivedDataPtr;
|
||||||
|
// Number of sended bytes
|
||||||
|
volatile uint8_t MT_USART_NumOfDataSended;
|
||||||
|
// Number of received bytes
|
||||||
|
volatile uint8_t MT_USART_NumOfDataReceived;
|
||||||
|
} usart_state_t;
|
||||||
|
|
||||||
|
static usart_state_t usart_states[3] = {
|
||||||
|
{
|
||||||
|
.usart = USART1,
|
||||||
|
.MT_USART_ReadyToExchange = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.usart = USART2,
|
||||||
|
.MT_USART_ReadyToExchange = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.usart = USART3,
|
||||||
|
.MT_USART_ReadyToExchange = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usart1_init(void)
|
||||||
|
{
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
|
||||||
|
GPIO_StructInit(&MT_USART_CfgGPIO);
|
||||||
|
MT_USART_CfgGPIO.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Pin = GPIO_Pin_9;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
MT_USART_CfgGPIO.GPIO_OType = GPIO_OType_PP;
|
||||||
|
MT_USART_CfgGPIO.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOA, &MT_USART_CfgGPIO);
|
||||||
|
|
||||||
|
MT_USART_CfgGPIO.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Pin = GPIO_Pin_10;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
MT_USART_CfgGPIO.GPIO_OType = GPIO_OType_PP;
|
||||||
|
MT_USART_CfgGPIO.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOA, &MT_USART_CfgGPIO);
|
||||||
|
|
||||||
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
|
||||||
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
|
||||||
|
|
||||||
|
USART_StructInit(&MT_USART_CfgUSART);
|
||||||
|
MT_USART_CfgUSART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||||
|
MT_USART_CfgUSART.USART_BaudRate = MT_USART_BAUDRATE;
|
||||||
|
USART_Init(USART1, &MT_USART_CfgUSART);
|
||||||
|
|
||||||
|
//NVIC_EnableIRQ(USART1_IRQn);
|
||||||
|
USART_Cmd(USART1, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usart2_init(void)
|
||||||
|
{
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
|
||||||
|
GPIO_StructInit(&MT_USART_CfgGPIO);
|
||||||
|
MT_USART_CfgGPIO.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Pin = GPIO_Pin_2;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
MT_USART_CfgGPIO.GPIO_OType = GPIO_OType_PP;
|
||||||
|
MT_USART_CfgGPIO.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOA, &MT_USART_CfgGPIO);
|
||||||
|
|
||||||
|
GPIO_StructInit(&MT_USART_CfgGPIO);
|
||||||
|
MT_USART_CfgGPIO.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Pin = GPIO_Pin_3;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
MT_USART_CfgGPIO.GPIO_OType = GPIO_OType_PP;
|
||||||
|
MT_USART_CfgGPIO.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOA, &MT_USART_CfgGPIO);
|
||||||
|
|
||||||
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
|
||||||
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
|
||||||
|
|
||||||
|
USART_StructInit(&MT_USART_CfgUSART);
|
||||||
|
MT_USART_CfgUSART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||||
|
MT_USART_CfgUSART.USART_BaudRate = MT_USART_BAUDRATE;
|
||||||
|
USART_Init(USART2, &MT_USART_CfgUSART);
|
||||||
|
|
||||||
|
//NVIC_EnableIRQ(USART2_IRQn);
|
||||||
|
USART_Cmd(USART2, ENABLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usart3_init(void)
|
||||||
|
{
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
|
||||||
|
|
||||||
|
GPIO_StructInit(&MT_USART_CfgGPIO);
|
||||||
|
MT_USART_CfgGPIO.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Pin = GPIO_Pin_10;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
MT_USART_CfgGPIO.GPIO_OType = GPIO_OType_PP;
|
||||||
|
MT_USART_CfgGPIO.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOC, &MT_USART_CfgGPIO);
|
||||||
|
|
||||||
|
MT_USART_CfgGPIO.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Pin = GPIO_Pin_11;
|
||||||
|
MT_USART_CfgGPIO.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
MT_USART_CfgGPIO.GPIO_OType = GPIO_OType_PP;
|
||||||
|
MT_USART_CfgGPIO.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOC, &MT_USART_CfgGPIO);
|
||||||
|
|
||||||
|
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
|
||||||
|
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);
|
||||||
|
|
||||||
|
USART_StructInit(&MT_USART_CfgUSART);
|
||||||
|
MT_USART_CfgUSART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||||
|
MT_USART_CfgUSART.USART_BaudRate = MT_USART_BAUDRATE;
|
||||||
|
USART_Init(USART3, &MT_USART_CfgUSART);
|
||||||
|
|
||||||
|
//NVIC_EnableIRQ(USART3_IRQn);
|
||||||
|
USART_Cmd(USART3, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usart_init(enum usart_id_t usart_id)
|
||||||
|
{
|
||||||
|
switch(usart_id) {
|
||||||
|
case USART1_ID:
|
||||||
|
usart1_init();
|
||||||
|
break;
|
||||||
|
case USART2_ID:
|
||||||
|
usart2_init();
|
||||||
|
break;
|
||||||
|
case USART3_ID:
|
||||||
|
usart3_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void usart_send_data(enum usart_id_t usart_id, uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
usart_state_t *usart = &usart_states[usart_id];
|
||||||
|
while (!usart->MT_USART_ReadyToExchange);
|
||||||
|
|
||||||
|
usart->MT_USART_SendDataPtr = data;
|
||||||
|
usart->MT_USART_NumOfDataToSend = size;
|
||||||
|
usart->MT_USART_NumOfDataSended = 0;
|
||||||
|
usart->MT_USART_ReadyToExchange = false;
|
||||||
|
//USART_ITConfig(usart->usart, USART_IT_TC, ENABLE);
|
||||||
|
|
||||||
|
while (usart->MT_USART_NumOfDataSended != size) {
|
||||||
|
USART_SendData(usart->usart, (uint8_t)*usart->MT_USART_SendDataPtr);
|
||||||
|
while (USART_GetFlagStatus(usart->usart, USART_FLAG_TC) == RESET);
|
||||||
|
usart->MT_USART_SendDataPtr++;
|
||||||
|
usart->MT_USART_NumOfDataSended++;
|
||||||
|
}
|
||||||
|
usart->MT_USART_ReadyToExchange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usart_rcv_data(enum usart_id_t usart_id, uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
usart_state_t *usart = &usart_states[usart_id];
|
||||||
|
while (!usart->MT_USART_ReadyToExchange);
|
||||||
|
|
||||||
|
usart->MT_USART_ReceivedDataPtr = data;
|
||||||
|
usart->MT_USART_NumOfDataToReceive = size;
|
||||||
|
usart->MT_USART_NumOfDataReceived = 0;
|
||||||
|
usart->MT_USART_ReadyToExchange = false;
|
||||||
|
//USART_ITConfig(usart->usart, USART_IT_RXNE, ENABLE);
|
||||||
|
|
||||||
|
while (usart->MT_USART_NumOfDataReceived != size) {
|
||||||
|
while (USART_GetFlagStatus(usart->usart, USART_FLAG_RXNE) == RESET);
|
||||||
|
*usart->MT_USART_ReceivedDataPtr = USART_ReceiveData(usart->usart);
|
||||||
|
usart->MT_USART_ReceivedDataPtr++;
|
||||||
|
usart->MT_USART_NumOfDataReceived++;
|
||||||
|
}
|
||||||
|
usart->MT_USART_ReadyToExchange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART_IRQHandler(enum usart_id_t usart_id)
|
||||||
|
{
|
||||||
|
usart_state_t *usart = &usart_states[usart_id];
|
||||||
|
|
||||||
|
if (USART_GetITStatus(usart->usart, USART_IT_RXNE) != RESET)
|
||||||
|
{
|
||||||
|
USART_ClearITPendingBit(usart->usart, USART_IT_RXNE);
|
||||||
|
*usart->MT_USART_ReceivedDataPtr = USART_ReceiveData(usart->usart);
|
||||||
|
usart->MT_USART_ReceivedDataPtr++;
|
||||||
|
usart->MT_USART_NumOfDataReceived++;
|
||||||
|
if (usart->MT_USART_NumOfDataReceived == usart->MT_USART_NumOfDataToReceive)
|
||||||
|
{
|
||||||
|
USART_ITConfig(usart->usart, USART_IT_RXNE, DISABLE);
|
||||||
|
usart->MT_USART_ReadyToExchange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USART_GetITStatus(usart->usart, USART_IT_TC) != RESET)
|
||||||
|
{
|
||||||
|
USART_ClearITPendingBit(usart->usart, USART_IT_TC);
|
||||||
|
USART_SendData(usart->usart, (uint8_t)*usart->MT_USART_SendDataPtr);
|
||||||
|
usart->MT_USART_SendDataPtr++;
|
||||||
|
usart->MT_USART_NumOfDataSended++;
|
||||||
|
if (usart->MT_USART_NumOfDataSended == usart->MT_USART_NumOfDataToSend)
|
||||||
|
{
|
||||||
|
USART_ITConfig(usart->usart, USART_IT_TC, DISABLE);
|
||||||
|
usart->MT_USART_ReadyToExchange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Warning: USART1 doesn't pass uarts_test
|
||||||
|
enum usart_id_t {
|
||||||
|
USART1_ID = 0, // PA9: TX, PA10: RX
|
||||||
|
USART2_ID = 1, // PA2: TX, PA3: RX
|
||||||
|
USART3_ID = 2, // PC10: TX, PC11: RX
|
||||||
|
};
|
||||||
|
|
||||||
|
void usart_init(enum usart_id_t usart_id);
|
||||||
|
void usart_send_data(enum usart_id_t usart_id, uint8_t *data, size_t size);
|
||||||
|
void usart_rcv_data(enum usart_id_t usart_id, uint8_t *data, size_t size);
|
||||||
|
|
||||||
|
#define MT_USART_BAUDRATE 9600
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include <car_time.h>
|
||||||
|
#include <car_leds.h>
|
||||||
|
|
||||||
|
#include <usart.h>
|
||||||
|
#include <usart_test.h>
|
||||||
|
// 2, 1 - ok
|
||||||
|
// 2, 2 - ok
|
||||||
|
// 3, 3 - ok
|
||||||
|
// 2, 3 - ok
|
||||||
|
// 3, 2 - ok
|
||||||
|
void usart_test(enum usart_id_t src_usart_id, enum usart_id_t dst_usart_id)
|
||||||
|
{
|
||||||
|
uint8_t byte_sent = 0;
|
||||||
|
uint8_t byte_rcvd = 0;
|
||||||
|
while (1) {
|
||||||
|
car_leds_clear_all();
|
||||||
|
car_time_wait(500);
|
||||||
|
|
||||||
|
usart_send_data(src_usart_id, &byte_sent, 1);
|
||||||
|
usart_rcv_data(dst_usart_id, &byte_rcvd, 1);
|
||||||
|
if (byte_rcvd == byte_sent)
|
||||||
|
car_led_set(CAR_LED_GREEN, true);
|
||||||
|
else
|
||||||
|
car_led_set(CAR_LED_RED, true);
|
||||||
|
++byte_sent;
|
||||||
|
car_time_wait(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
|
void usart_test(enum usart_id_t src_usart_id, enum usart_id_t dst_usart_id);
|
||||||
Reference in New Issue
Block a user