aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/usart.h
blob: 30f7dc1a86f56821906d8d928e4c4340edd00c96 (plain)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#ifndef _USART_H_
#define _USART_H_
#include <inttypes.h>
#include <util.h>

/* Transmit procedure:
 * 1.  Enable the USART by writing the UE bit in USART_CR1 register to 1.
 *
 * 2.  Program the M bit in USART_CR1 to define the word length.
 *
 * 3.  Program the number of stop bits in USART_CR2.
 *
 * 4.  Select DMA enable (DMAT) in USART_CR3 if Multi buffer Communication is
 *     to take place. Configure the DMA register as explained in multibuffer
 *     communication.
 *
 * 5.  Select the desired baud rate using the USART_BRR register.
 *
 * 6.  Set the TE bit in USART_CR1 to send an idle frame as first transmission.
 *
 * 7.  Write the data to send in the USART_DR register (this clears the TXE
 *     bit). Repeat this for each data to be transmitted in case of single buffer.
 *
 * 8.  After writing the last data into the USART_DR register, wait until TC=1.
 *     This indicates that the transmission of the last frame is complete. This is
 *     required for instance when the USART is disabled or enters the Halt mode to
 *     avoid corrupting the last transmission.
 *
 * Single byte communication
 * Clearing the TXE bit is always performed by a write to the data register.
 *
 * The TXE bit is set by hardware and it indicates:
 * ?   The data has been moved from TDR to the shift register and the data transmission has
 *     started.
 * ?   The TDR register is empty.
 * ?   The next data can be written in the USART_DR register without overwriting the
 *     previous data.
 * This flag generates an interrupt if the TXEIE bit is set.
 *
 * When a transmission is taking place, a write instruction to the USART_DR
 * register stores the data in the TDR register and which is copied in the
 * shift register at the end of the current transmission.
 *
 * When no transmission is taking place, a write instruction to the USART_DR
 * register places the data directly in the shift register, the data
 * transmission starts, and the TXE bit is immediately set.
 *
 * If a frame is transmitted (after the stop bit) and the TXE bit is set, the
 * TC bit goes high. An interrupt is generated if the TCIE bit is set in the
 * USART_CR1 register.  After writing the last data into the USART_DR register,
 * it is mandatory to wait for TC=1 before disabling the USART or causing the
 * microcontroller to enter the low power mode (see Figure 241: TC/TXE behavior
 * when transmitting).
 *
 * Clearing the TC bit is performed by the following software sequence:
 * 1.     A read from the USART_SR register
 * 2.     A write to the USART_DR register
 *
 *
 * For now, use 8N1
 *
 * Baud rate is generated by programming the mantissa and fraction values of
 * USARTDIV
 *
 * baud = fck / 16*USARTDIV
 * Fck = PLK1 for USART2 and USART3 = 36MHz
 * Fck = PCLK2 for USART1 = 72MHz
 *
 * Baud    Actual  USARTDIV_36MHZ  Error     USARTDIV_72MHZ Error
 * 2400    2.400   937.5           0%        1875           0%
 * 9600    9.600   234.375         0%        468.75         0%
 * 19200   19.2    117.1875        0%        234.375        0%
 * 57600   57.6    39.0625         0%        78.125         0.%
 * 115200  115.384 19.5            0.15%     39.0625        0%
 * 230400  230.769 9.75            0.16%     19.5           0.16%
 * 460800  461.538 4.875           0.16%     9.75           0.16%
 * 921600  923.076 2.4375          0.16%     4.875          0.16%
 * 225000  2250    1               0%        2              0%
 *
 * USART_BRR[15:4] = mantissa
 * USART_BRR[3:0] = fraction
 * 111010
 * 0110
 * */
#define NR_USARTS           0x3

//#define USART1_BASE         0x40013800
//#define USART2_BASE         0x40004400
//#define USART3_BASE         0x40004800

#define USART_UE            BIT(13)
#define USART_M             BIT(12)
#define USART_TE            BIT(3)
#define USART_TXE           BIT(7)
#define USART_STOP_BITS_1   BIT_MASK_SHIFT(0b0, 12)
#define USART_STOP_BITS_05  BIT_MASK_SHIFT(0b01, 12)
#define USART_STOP_BITS_2   BIT_MASK_SHIFT(0b02, 12)
#define USART_STOP_BITS_15  BIT_MASK_SHIFT(0b02, 12)

#define USART1_CLK          72000000UL
#define USART2_CLK          36000000UL
#define USART3_CLK          36000000UL

#define B9600_MANTISSA      0xEA
#define B9600_FRACTION      0x06


typedef struct usart_port {
    volatile uint32_t SR;
    volatile uint32_t DR;
    volatile uint32_t BRR;
    volatile uint32_t CR1;
    volatile uint32_t CR2;
    volatile uint32_t CR3;
    volatile uint32_t GTPR;
} usart_port;

#ifdef __cplusplus
extern "C"{
#endif

int32_t usart_init(uint8_t);


#ifdef __cplusplus
} // extern "C"
#endif


#endif