From 478337c4c5b402b19966231ca8b1cd42b1565e1d Mon Sep 17 00:00:00 2001 From: Eugene Batalov Date: Mon, 22 Aug 2016 10:25:18 +0300 Subject: [PATCH] car_hw: add gitignored usart lib for sonar driver --- car_hw/src/lib/usart/Makefile | 9 ++ car_hw/src/lib/usart/usart.c | 229 ++++++++++++++++++++++++++++++ car_hw/src/lib/usart/usart.h | 17 +++ car_hw/src/lib/usart/usart_test.c | 28 ++++ car_hw/src/lib/usart/usart_test.h | 5 + 5 files changed, 288 insertions(+) create mode 100644 car_hw/src/lib/usart/Makefile create mode 100644 car_hw/src/lib/usart/usart.c create mode 100644 car_hw/src/lib/usart/usart.h create mode 100644 car_hw/src/lib/usart/usart_test.c create mode 100644 car_hw/src/lib/usart/usart_test.h diff --git a/car_hw/src/lib/usart/Makefile b/car_hw/src/lib/usart/Makefile new file mode 100644 index 00000000000..aecf5818a1b --- /dev/null +++ b/car_hw/src/lib/usart/Makefile @@ -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) diff --git a/car_hw/src/lib/usart/usart.c b/car_hw/src/lib/usart/usart.c new file mode 100644 index 00000000000..048aa359b91 --- /dev/null +++ b/car_hw/src/lib/usart/usart.c @@ -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 +#include +#include + +// 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; + } + } +} diff --git a/car_hw/src/lib/usart/usart.h b/car_hw/src/lib/usart/usart.h new file mode 100644 index 00000000000..9187dfc5d77 --- /dev/null +++ b/car_hw/src/lib/usart/usart.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +// 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 diff --git a/car_hw/src/lib/usart/usart_test.c b/car_hw/src/lib/usart/usart_test.c new file mode 100644 index 00000000000..feafce9544c --- /dev/null +++ b/car_hw/src/lib/usart/usart_test.c @@ -0,0 +1,28 @@ +#include +#include + +#include +#include +// 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); + } +} diff --git a/car_hw/src/lib/usart/usart_test.h b/car_hw/src/lib/usart/usart_test.h new file mode 100644 index 00000000000..f1136df9d06 --- /dev/null +++ b/car_hw/src/lib/usart/usart_test.h @@ -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);