Created
December 10, 2014 16:15
-
-
Save earlwlkr/15b92512140fc02b32da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************************************************************/ | |
/* Author: cqkhanh */ | |
/* Date: 21/11/2014*/ | |
/* Brief: Driver for UART*/ | |
/* History Prepared/Updated by */ | |
/* +21/11/2014: initial version cqkhanh */ | |
/* +26/11/2014: update send and receive functions earlwlkr */ | |
/************************************************************************/ | |
/* Include */ | |
#include <stdint.h> | |
#include "stm32f4xx_gpio.h" | |
#include "stm32f4xx_usart.h" | |
#include "misc.h" | |
#include "uart_interrupt.h" | |
/* Private Macro */ | |
#define UART_NUM USART3 | |
#define UART_CLK RCC_APB1Periph_USART3 | |
#define UART_PORT_CLK RCC_AHB1Periph_GPIOB | |
#define UART_PORT GPIOB | |
#define UART_PIN_TX GPIO_Pin_10 | |
#define UART_PINSOURCE_TX GPIO_PinSource10 | |
#define UART_PIN_RX GPIO_Pin_11 | |
#define UART_PINSOURCE_RX GPIO_PinSource11 | |
uint32_t stage = 0; | |
uint32_t send_index = 0; | |
/* Public function body */ | |
/************************************************************************/ | |
/** | |
* @brief Initialize uart | |
* @param void | |
* @retval UERR_OK if success | |
*/ | |
uart_err_t UART_Init (bool use_interrupt) | |
{ | |
uart_err_t res = UERR_OK; | |
USART_InitTypeDef USART_InitStruct; | |
GPIO_InitTypeDef gpioInitStructure; | |
NVIC_InitTypeDef NVIC_InitStructure; | |
/* Unlock clocks for GPIO. */ | |
RCC_APB1PeriphClockCmd(UART_CLK, ENABLE); | |
RCC_AHB1PeriphClockCmd(UART_PORT_CLK, ENABLE); | |
/* Config GPI struct variable. */ | |
gpioInitStructure.GPIO_Pin = UART_PIN_TX | UART_PIN_RX; | |
gpioInitStructure.GPIO_Mode = GPIO_Mode_AF; | |
gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
gpioInitStructure.GPIO_OType = GPIO_OType_PP; | |
gpioInitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; | |
/* Connect the pin to the desired peripherals' Alternate Function. */ | |
GPIO_PinAFConfig(UART_PORT, UART_PINSOURCE_TX, GPIO_AF_USART3); | |
GPIO_PinAFConfig(UART_PORT, UART_PINSOURCE_RX, GPIO_AF_USART3); | |
GPIO_Init(UART_PORT, &gpioInitStructure); | |
/* Init USART struct. */ | |
USART_StructInit(&USART_InitStruct); | |
USART_Init(UART_NUM, &USART_InitStruct); | |
if (use_interrupt) | |
{ | |
/* Init NVIC. */ | |
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); | |
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; | |
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; | |
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; | |
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | |
NVIC_Init(&NVIC_InitStructure); | |
USART_ITConfig(UART_NUM, USART_IT_RXNE, ENABLE); | |
USART_ITConfig(UART_NUM, USART_IT_TXE, ENABLE); | |
} | |
USART_Cmd(UART_NUM, ENABLE); | |
return res; | |
} | |
/************************************************************************/ | |
/************************************************************************/ | |
/** | |
* @brief Sends a character. | |
* @param ch: the character to send. | |
* @retval UERR_OK if success | |
*/ | |
uart_err_t UART_Send (uint16_t ch) | |
{ | |
uart_err_t res = UERR_OK; | |
USART_SendData(UART_NUM, ch); | |
while (SET != USART_GetFlagStatus(UART_NUM, USART_FLAG_TXE)); | |
return res; | |
} | |
/************************************************************************/ | |
/************************************************************************/ | |
/** | |
* @brief Sends a message. | |
* @param msg: the message to send. | |
msg_length: the message's length. | |
* @retval UERR_OK if success | |
*/ | |
uart_err_t UART_SendMessage (const uint16_t msg[], uint32_t msg_length) | |
{ | |
uint32_t i = 0; | |
for (; i != msg_length; ++i) | |
{ | |
uart_err_t error_code = UART_Send(msg[i]); | |
if (UERR_OK != error_code) | |
return error_code; | |
} | |
return UERR_OK; | |
} | |
/************************************************************************/ | |
/************************************************************************/ | |
/** | |
* @brief Receives the most recent character. | |
* @param p_ch: the character to store value to. | |
* @retval UERR_OK if success | |
*/ | |
uart_err_t UART_Receive (uint16_t* p_ch) | |
{ | |
uart_err_t res = UERR_OK; | |
/* Wait for receive flag to be set */ | |
while (SET != USART_GetFlagStatus(UART_NUM, USART_FLAG_RXNE)); | |
*p_ch = USART_ReceiveData(UART_NUM); | |
return res; | |
} | |
/************************************************************************/ | |
/************************************************************************/ | |
/** | |
* @brief This function handles USARTx global interrupt request. | |
* @param None | |
* @retval None | |
*/ | |
void USART3_IRQHandler (void) | |
{ | |
const uint16_t prompt[] = {'I', 'n', 'p', 'u', 't', ' ', | |
'y', 'o', 'u', 'r', ' ', 'c', 'h', 'a', 'r', | |
'a', 'c', 't', 'e', 'r', ':', ' '}; | |
uint32_t prompt_length = sizeof(prompt) / sizeof(prompt[0]); | |
const uint16_t err_msg[] = {'D', 'o', 'n', 't', ' ', | |
's', 'u', 'p', 'p', 'o', 'r', 't'}; | |
uint32_t err_msg_length = sizeof(err_msg) / sizeof(err_msg[0]); | |
if (SET == USART_GetITStatus(UART_NUM, USART_IT_RXNE)) | |
{ | |
uint16_t ch; | |
UART_Receive(&ch); | |
if (ch < 32 || ch > 126) | |
{ | |
UART_SendMessage(err_msg, err_msg_length); | |
UART_Send(ch); | |
} | |
else | |
{ | |
UART_Send(ch); | |
} | |
UART_Send('\n'); | |
stage = 0; | |
} | |
else if (SET == USART_GetITStatus(UART_NUM, USART_IT_TXE)) | |
{ | |
if (stage == 0) | |
{ | |
USART_SendData(UART_NUM, prompt[send_index++]); | |
if (send_index >= prompt_length) | |
{ | |
send_index = 0; | |
stage = 1; | |
} | |
} | |
} | |
} | |
/************************************************************************/ | |
/* End module */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment