-
Notifications
You must be signed in to change notification settings - Fork 0
/
Serial.c
115 lines (95 loc) · 4.29 KB
/
Serial.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*----------------------------------------------------------------------------
* Name: Serial.c
* Purpose: Low Level Serial Routines
* Note(s): possible defines select the used communication interface:
* __DBG_ITM - ITM SWO interface
* - USART2 interface (default)
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use this software.
*
* This software is supplied "AS IS" without warranties of any kind.
*
* Copyright (c) 2014 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------*/
#include "stm32f4xx.h" // Device header
#include "Serial.h"
#ifdef __DBG_ITM
volatile int ITM_RxBuffer; /* CMSIS Debug Input */
#endif
/*----------------------------------------------------------------------------
Define USART
*----------------------------------------------------------------------------*/
#define USARTx USART2
/*----------------------------------------------------------------------------
Define Baudrate setting (BRR) for USART
*----------------------------------------------------------------------------*/
#define __DIV(__PCLK, __BAUD) ((__PCLK*25)/(4*__BAUD))
#define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100)
#define __DIVFRAQ(__PCLK, __BAUD) (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) * 16 + 50) / 100)
#define __USART_BRR(__PCLK, __BAUD) ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F))
/*----------------------------------------------------------------------------
Initialize UART pins, Baudrate
*----------------------------------------------------------------------------*/
void SER_Initialize (void) {
#ifdef __DBG_ITM
ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* CMSIS Debug Input */
#else
RCC->AHB1ENR |= ( 1ul << 0); /* Enable GPIOA clock */
if(USARTx == USART2)
RCC->APB1ENR |= ( 1ul << 17); /* Enable USART#2 clock */
else
RCC->APB2ENR |= ( 1ul << 4); /* Enable USART#1 clock */
/* Configure PA3 to USART2_RX, PA2 to USART2_TX */
if(USARTx == USART2)
{
GPIOA->AFR[0] &= ~((15ul << 4* 3) | (15ul << 4* 2) );
GPIOA->AFR[0] |= (( 7ul << 4* 3) | ( 7ul << 4* 2) );
GPIOA->MODER &= ~(( 3ul << 2* 3) | ( 3ul << 2* 2) );
GPIOA->MODER |= (( 2ul << 2* 3) | ( 2ul << 2* 2) );
}else
{
GPIOA->AFR[1] &= ~((15ul << 4* 2) | (15ul << 4* 1) );
GPIOA->AFR[1] |= (( 7ul << 4* 2) | ( 7ul << 4* 1) );
GPIOA->MODER &= ~(( 3ul << 2* 10) | ( 3ul << 2* 9) );
GPIOA->MODER |= (( 2ul << 2* 10) | ( 2ul << 2* 9) );
}
if(USARTx == USART2)
USARTx->BRR = __USART_BRR(12000000ul, 115200ul); /* 115200 baud @ 12MHz */
else
USARTx->BRR = __USART_BRR(24000000ul, 115200ul); /* 115200 baud @ 24MHz */
USARTx->CR3 = 0x0000; /* no flow control */
USARTx->CR2 = 0x0000; /* 1 stop bit */
USARTx->CR1 = (( 1ul << 2) | /* enable RX */
( 1ul << 3) | /* enable TX */
( 0ul << 12) | /* 1 start bit, 8 data bits */
( 1ul << 13) ); /* enable USART */
#endif
}
/*----------------------------------------------------------------------------
Write character to Serial Port
*----------------------------------------------------------------------------*/
int SER_PutChar (int ch) {
#ifdef __DBG_ITM
ITM_SendChar (ch & 0xFF);
#else
while (!(USARTx->SR & 0x0080));
USARTx->DR = (ch & 0xFF);
#endif
return (ch);
}
/*----------------------------------------------------------------------------
Read character from Serial Port
*----------------------------------------------------------------------------*/
int SER_GetChar (void) {
#ifdef __DBG_ITM
if (ITM_CheckChar())
return ITM_ReceiveChar();
#else
if (USARTx->SR & 0x0020)
return (USARTx->DR);
#endif
return (-1);
}