1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: #include <sys/machine.h>
15: #ifdef CPU_STM32L4
16:
17: #include <tk/tkernel.h>
18: #include "../../ser.h"
19: #include "../../../include/dev_def.h"
20: #if DEV_SER_ENABLE
21: 22: 23: 24: 25:
26:
27: 28: 29:
30: const LOCAL UW ba[DEV_SER_UNITNM] = { USART1_BASE, USART2_BASE, USART3_BASE};
31:
32: #define USART_CR1(x) (ba[x] + USARTx_CR1)
33: #define USART_CR2(x) (ba[x] + USARTx_CR2)
34: #define USART_CR3(x) (ba[x] + USARTx_CR3)
35: #define USART_BRR(x) (ba[x] + USARTx_BRR)
36: #define USART_GTPR(x) (ba[x] + USARTx_GTPR)
37: #define USART_RTOR(x) (ba[x] + USARTx_RTOR)
38: #define USART_RQR(x) (ba[x] + USARTx_RQR)
39: #define USART_ISR(x) (ba[x] + USARTx_ISR)
40: #define USART_ICR(x) (ba[x] + USARTx_ICR)
41: #define USART_RDR(x) (ba[x] + USARTx_RDR)
42: #define USART_TDR(x) (ba[x] + USARTx_TDR)
43:
44: 45: 46:
47: typedef struct {
48: UW mode;
49: UW speed;
50: } T_DEV_SER_LLDEVCB;
51:
52: LOCAL T_DEV_SER_LLDEVCB ll_devcb[DEV_SER_UNITNM];
53:
54: 55: 56:
57: void usart_inthdr( UINT intno)
58: {
59: UW data, err;
60: UW isr;
61: W unit;
62:
63: unit = intno -INTNO_USART1;
64:
65: isr = in_w(USART_ISR(unit));
66:
67: out_w(USART_ICR(unit), USART_ICR_ALL);
68: ClearInt(intno);
69:
70:
71: if( isr & USART_ISR_RXNE) {
72: data = in_w(USART_RDR(unit));
73: dev_ser_notify_rcv(unit, data);
74: }
75:
76:
77: if( isr & USART_ISR_TXE ) {
78: if( dev_ser_get_snddat(unit, &data)) {
79: out_w(USART_TDR(unit), data);
80: } else {
81: *(_UW*)( USART_CR1(unit)) &= ~USART_CR1_TXEIE;
82: }
83: }
84:
85:
86: err = isr & USART_ISR_ERR;
87: if(err) {
88: dev_ser_notify_err(unit, err);
89: }
90: }
91:
92: 93: 94:
95: #define MASK_MODE_CR1 (USART_CR1_M1| USART_CR1_M0|USART_CR1_PS|USART_CR1_PCE)
96:
97: LOCAL void start_com(UW unit, UW mode, UW speed)
98: {
99:
100:
101: out_w(USART_CR2(unit), mode & USART_CR2_STOP);
102: out_w(USART_CR3(unit), mode & (USART_CR3_RTSE | USART_CR3_CTSE));
103: out_w(USART_BRR(unit), speed);
104:
105:
106: out_w(USART_CR1(unit),
107: USART_CR1_RXNEIE | USART_CR1_PEIE
108: | (mode & MASK_MODE_CR1 )
109: | USART_CR1_UE | USART_CR1_RE | USART_CR1_TE
110: );
111: }
112:
113: 114: 115:
116: LOCAL void stop_com(UW unit)
117: {
118: if(unit != DEVCNF_SER_DBGUN) {
119: out_w(USART_CR1(unit), 0);
120: } else {
121: out_w(USART_CR1(unit), USART_CR1_DEBUG);
122: }
123: }
124:
125: 126: 127:
128: EXPORT ER dev_ser_llctl( UW unit, INT cmd, UW parm)
129: {
130: ER err = E_OK;
131:
132: switch(cmd) {
133: case LLD_SER_MODE:
134: ll_devcb[unit].mode = parm;
135: break;
136:
137: case LLD_SER_SPEED:
138: ll_devcb[unit].speed = (TMCLK*1000*1000)/parm;
139: break;
140:
141: case LLD_SER_START:
142: out_w(USART_CR1(unit), 0);
143: out_w(USART_ICR(unit), USART_ICR_ALL);
144: ClearInt(INTNO_USART1 + unit);
145: EnableInt(INTNO_USART1 + unit, DEVCNF_SER_INTPRI);
146: start_com( unit, ll_devcb[unit].mode, ll_devcb[unit].speed);
147: break;
148:
149: case LLD_SER_STOP:
150: DisableInt(INTNO_USART1 + unit);
151: stop_com(unit);
152: break;
153:
154: case LLD_SER_SEND:
155: if(in_w(USART_ISR(unit)) & USART_ISR_TXE) {
156: out_w(USART_TDR(unit), parm);
157: *(_UW*)( USART_CR1(unit)) |= USART_CR1_TXEIE;
158: err = E_OK;
159: } else {
160: err = E_BUSY;
161: }
162: break;
163:
164: case LLD_SER_BREAK:
165: if(parm) {
166: out_w(USART_RQR(unit), USART_RQR_SBKRQ);
167: }
168: break;
169: }
170:
171: return err;
172: }
173:
174: 175: 176:
177: EXPORT ER dev_ser_llinit( T_SER_DCB *p_dcb)
178: {
179: const T_DINT dint = {
180: .intatr = TA_HLNG,
181: .inthdr = usart_inthdr,
182: };
183: UW unit;
184: ER err;
185:
186: unit = p_dcb->unit;
187:
188: #if DEVCONF_SER_INIT_MCLK
189: switch(unit) {
190: case 0:
191: *(_UW*)RCC_APB2ENR |= RCC_APB2ENR_USART1EN;
192: break;
193: case 1:
194: *(_UW*)RCC_APB1ENR1 |= RCC_APB1ENR1_USART2EN;
195: break;
196: case 2:
197: *(_UW*)RCC_APB1ENR1 |= RCC_APB1ENR1_USART3EN;
198: break;
199: }
200: #endif
201:
202:
203: stop_com(unit);
204:
205:
206: p_dcb->intno_rcv = p_dcb->intno_snd = INTNO_USART1 + unit;
207:
208:
209: err = tk_def_int((INTNO_USART1 + unit), &dint);
210:
211: return err;
212: }
213:
214: #endif
215: #endif