Skip to content

Instantly share code, notes, and snippets.

@earlwlkr
Created December 10, 2014 16:15
Show Gist options
  • Save earlwlkr/15b92512140fc02b32da to your computer and use it in GitHub Desktop.
Save earlwlkr/15b92512140fc02b32da to your computer and use it in GitHub Desktop.
/************************************************************************/
/* 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