📄 hal_uart.lst
字号:
87
88 #define RX_STOP_FLOW( cfg ) { \
89 if ( !(cfg->flag & UART_CFG_U1F) ) \
90 { \
91 RX0_FLOW_OFF; \
92 } \
93 else \
94 { \
95 RX1_FLOW_OFF; \
96 } \
97 if ( cfg->flag & UART_CFG_DMA ) \
98 { \
99 cfg->rxTick = DMA_RX_DLY; \
100 } \
101 cfg->flag |= UART_CFG_RXF; \
102 }
103
104 #define RX_STRT_FLOW( cfg ) { \
105 if ( !(cfg->flag & UART_CFG_U1F) ) \
106 { \
107 RX0_FLOW_ON; \
108 } \
109 else \
110 { \
111 RX1_FLOW_ON; \
112 } \
113 cfg->flag &= ~UART_CFG_RXF; \
114 }
115
116 #define UART_RX_AVAIL( cfg ) \
117 ( (cfg->rxHead >= cfg->rxTail) ? (cfg->rxHead - cfg->rxTail) : \
118 (cfg->rxMax - cfg->rxTail + cfg->rxHead +1 ) )
119
120 /* Need to leave enough of the Rx buffer free to handle the incoming bytes
121 * after asserting flow control, but before the transmitter has obeyed it.
122 * At the max expected baud rate of 115.2k, 16 bytes will only take ~1.3 msecs,
123 * but at the min expected baud rate of 38.4k, they could take ~4.2 msecs.
124 * SAFE_RX_MIN and DMA_RX_DLY must both be consistent according to
125 * the min & max expected baud rate.
126 */
127 #if !defined( SAFE_RX_MIN )
128 #define SAFE_RX_MIN 48 // bytes - max expected per poll @ 115.2k
129 // 16 bytes @ 38.4 kBaud -> 4.16 msecs -> 138 32-kHz ticks.
130 #define DMA_RX_DLY 140
131 // 2 bytes @ 38.4 kBaud -> 0.52 msecs -> 17 32-kHz ticks.
132 #define DMA_TX_DLY 20
133 #endif
134
135 // The timeout tick is at 32-kHz, so multiply msecs by 33.
136 #define RX_MSECS_TO_TICKS 33
137
138 // The timeout only supports 1 byte.
139 #if !defined( HAL_UART_RX_IDLE )
140 #define HAL_UART_RX_IDLE (6 * RX_MSECS_TO_TICKS)
141 #endif
142
143 // Only supporting 1 of the 2 USART modules to be driven by DMA at a time.
144 #if HAL_UART_DMA == 1
145 #define DMATRIG_RX HAL_DMA_TRIG_URX0
146 #define DMATRIG_TX HAL_DMA_TRIG_UTX0
147 #define DMA_UDBUF HAL_DMA_U0DBUF
148 #define DMA_PAD U0BAUD
149 #elif HAL_UART_DMA == 2
150 #define DMATRIG_RX HAL_DMA_TRIG_URX1
151 #define DMATRIG_TX HAL_DMA_TRIG_UTX1
152 #define DMA_UDBUF HAL_DMA_U1DBUF
153 #define DMA_PAD U1BAUD
154 #endif
155
156 #define DMA_RX( cfg ) { \
157 volatile uint8 ft2430 = U0DBUF; \
158 \
159 halDMADesc_t *ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX ); \
160 \
161 HAL_DMA_SET_DEST( ch, cfg->rxBuf ); \
162 \
163 HAL_DMA_SET_LEN( ch, cfg->rxMax ); \
164 \
165 HAL_DMA_CLEAR_IRQ( HAL_DMA_CH_RX ); \
166 \
167 HAL_DMA_ARM_CH( HAL_DMA_CH_RX ); \
168 }
169
170 #define DMA_TX( cfg ) { \
171 halDMADesc_t *ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX ); \
172 \
173 HAL_DMA_SET_SOURCE( ch, (cfg->txBuf + cfg->txTail) ); \
174 \
175 HAL_DMA_SET_LEN( ch, cfg->txCnt ); \
176 \
177 HAL_DMA_CLEAR_IRQ( HAL_DMA_CH_TX ); \
178 \
179 HAL_DMA_ARM_CH( HAL_DMA_CH_TX ); \
180 \
181 HAL_DMA_START_CH( HAL_DMA_CH_TX ); \
182 }
183
184 /*********************************************************************
185 * TYPEDEFS
186 */
187
188 typedef struct
189 {
190 uint8 *rxBuf;
191 uint8 rxHead;
192 uint8 rxTail;
193 uint8 rxMax;
194 uint8 rxCnt;
195 uint8 rxTick;
196 uint8 rxHigh;
197
198 uint8 *txBuf;
199 #if HAL_UART_BIG_TX_BUF
200 uint16 txHead;
201 uint16 txTail;
202 uint16 txMax;
203 uint16 txCnt;
204 #else
205 uint8 txHead;
206 uint8 txTail;
207 uint8 txMax;
208 uint8 txCnt;
209 #endif
210 uint8 txTick;
211
212 uint8 flag;
213
214 halUARTCBack_t rxCB;
215 } uartCfg_t;
216
217 /*********************************************************************
218 * CONSTANTS
219 */
220
221 // Used by DMA macros to shift 1 to create a mask for DMA registers.
222 #define HAL_DMA_CH_TX 3
223 #define HAL_DMA_CH_RX 4
224
225 #define HAL_DMA_U0DBUF 0xDFC1
226 #define HAL_DMA_U1DBUF 0xDFF9
227
228 // UxCSR - USART Control and Status Register.
229 #define CSR_MODE 0x80
230 #define CSR_RE 0x40
231 #define CSR_SLAVE 0x20
232 #define CSR_FE 0x10
233 #define CSR_ERR 0x08
234 #define CSR_RX_BYTE 0x04
235 #define CSR_TX_BYTE 0x02
236 #define CSR_ACTIVE 0x01
237
238 // UxUCR - USART UART Control Register.
239 #define UCR_FLUSH 0x80
240 #define UCR_FLOW 0x40
241 #define UCR_D9 0x20
242 #define UCR_BIT9 0x10
243 #define UCR_PARITY 0x08
244 #define UCR_SPB 0x04
245 #define UCR_STOP 0x02
246 #define UCR_START 0x01
247
248 #define UTX0IE 0x04
249 #define UTX1IE 0x08
250
251 #define UART_CFG_U1F 0x80 // USART1 flag bit.
252 #define UART_CFG_DMA 0x40 // Port is using DMA.
253 #define UART_CFG_FLW 0x20 // Port is using flow control.
254 #define UART_CFG_SP4 0x10
255 #define UART_CFG_SP3 0x08
256 #define UART_CFG_SP2 0x04
257 #define UART_CFG_RXF 0x02 // Rx flow is disabled.
258 #define UART_CFG_TXF 0x01 // Tx is in process.
259
260 /*********************************************************************
261 * GLOBAL VARIABLES
262 */
263
264 /*********************************************************************
265 * GLOBAL FUNCTIONS
266 */
267
268 /*********************************************************************
269 * LOCAL VARIABLES
270 */
271
272 #if HAL_UART_0_ENABLE
273 static uartCfg_t *cfg0;
274 #endif
275 #if HAL_UART_1_ENABLE
\ In segment XDATA_Z, align 1, keep-with-next
\ 000000 REQUIRE __INIT_XDATA_Z
276 static uartCfg_t *cfg1;
\ ??cfg1:
\ 000000 DS 2
277 #endif
278
279 /*********************************************************************
280 * LOCAL FUNCTIONS
281 */
282
283 #if HAL_UART_DMA
284 static void pollDMA( uartCfg_t *cfg );
285 #endif
286 #if HAL_UART_ISR
287 static void pollISR( uartCfg_t *cfg );
288 #endif
289
290 #if HAL_UART_DMA
291 /******************************************************************************
292 * @fn pollDMA
293 *
294 * @brief Poll a USART module implemented by DMA.
295 *
296 * @param cfg - USART configuration structure.
297 *
298 * @return none
299 *****************************************************************************/
300 static void pollDMA( uartCfg_t *cfg )
301 {
302 const uint8 cnt = cfg->rxHead;
303 uint8 *pad = cfg->rxBuf+(cfg->rxHead*2);
304
305 // Pack the received bytes to the front of the queue.
306 while ( (*pad == DMA_PAD) && (cfg->rxHead < cfg->rxMax) )
307 {
308 cfg->rxBuf[cfg->rxHead++] = *(pad+1);
309 pad += 2;
310 }
311
312 if ( !(cfg->flag & UART_CFG_RXF) )
313 {
314 /* It is necessary to stop Rx flow and wait for H/W-enqueued bytes still
315 * incoming to stop before resetting the DMA Rx engine. If DMA Rx is
316 * aborted during incoming data, a byte may be lost inside the engine
317 * during the 2-step transfer process of read/write.
318 */
319 if ( cfg->rxHead >= (cfg->rxMax - SAFE_RX_MIN) )
320 {
321 RX_STOP_FLOW( cfg );
322 }
323 // If anything received, reset the Rx idle timer.
324 else if ( cfg->rxHead != cnt )
325 {
326 cfg->rxTick = HAL_UART_RX_IDLE;
327 }
328 }
329 else if ( !cfg->rxTick && (cfg->rxHead == cfg->rxTail) )
330 {
331 HAL_DMA_ABORT_CH( HAL_DMA_CH_RX );
332 cfg->rxHead = cfg->rxTail = 0;
333 osal_memset( cfg->rxBuf, ~DMA_PAD, cfg->rxMax*2 );
334 DMA_RX( cfg );
335 RX_STRT_FLOW( cfg );
336 }
337
338 if ( HAL_DMA_CHECK_IRQ( HAL_DMA_CH_TX ) )
339 {
340 HAL_DMA_CLEAR_IRQ( HAL_DMA_CH_TX );
341 cfg->flag &= ~UART_CFG_TXF;
342 cfg->txTick = DMA_TX_DLY;
343
344 if ( (cfg->txMax - cfg->txCnt) < cfg->txTail )
345 {
346 cfg->txTail = 0; // DMA can only run to the end of the Tx buffer.
347 }
348 else
349 {
350 cfg->txTail += cfg->txCnt;
351 }
352 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -