📄 hal_uart.lst
字号:
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
276 static uartCfg_t *cfg1;
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 }
353 else if ( !(cfg->flag & UART_CFG_TXF) && !cfg->txTick )
354 {
355 if ( cfg->txTail != cfg->txHead )
356 {
357 if ( cfg->txTail < cfg->txHead )
358 {
359 cfg->txCnt = cfg->txHead - cfg->txTail;
360 }
361 else // Can only run DMA engine up to max, then restart at zero.
362 {
363 cfg->txCnt = cfg->txMax - cfg->txTail + 1;
364 }
365
366 cfg->flag |= UART_CFG_TXF;
367 DMA_TX( cfg );
368 }
369 }
370 }
371 #endif
372
373 #if HAL_UART_ISR
374 /******************************************************************************
375 * @fn pollISR
376 *
377 * @brief Poll a USART module implemented by ISR.
378 *
379 * @param cfg - USART configuration structure.
380 *
381 * @return none
382 *****************************************************************************/
383 static void pollISR( uartCfg_t *cfg )
384 {
385 uint8 cnt = UART_RX_AVAIL( cfg );
386
387 if ( !(cfg->flag & UART_CFG_RXF) )
388 {
389 // If anything received, reset the Rx idle timer.
390 if ( cfg->rxCnt != cnt )
391 {
392 cfg->rxTick = HAL_UART_RX_IDLE;
393 cfg->rxCnt = cnt;
394 }
395
396 /* It is necessary to stop Rx flow in advance of a full Rx buffer because
397 * bytes can keep coming while sending H/W fifo flushes.
398 */
399 if ( cfg->rxCnt >= (cfg->rxMax - SAFE_RX_MIN) )
400 {
401 RX_STOP_FLOW( cfg );
402 }
403 }
404 }
405 #endif
406
407 /******************************************************************************
408 * @fn HalUARTInit
409 *
410 * @brief Initialize the UART
411 *
412 * @param none
413 *
414 * @return none
415 *****************************************************************************/
\ In segment BANKED_CODE, align 1, keep-with-next
416 void HalUARTInit( void )
\ HalUARTInit:
417 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -