comparison serial/uartfax.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*******************************************************************************
2 *
3 * UARTFAX.C
4 *
5 * This driver allows to control the UARTs of chipset 1.5 for fax and data
6 * services. It performs flow control: RTS/CTS, XON/XOFF.
7 *
8 * On C & D-Sample, DCD and DTR signals are supported on UART modem only with 2
9 * I/Os.
10 *
11 * On E-Sample, DCD and DTR signals are directly handled by Calypso+.
12 *
13 * On Calypso, RTS and CTS are supported on both UARTs.
14 *
15 * On Calypso+, RTS and CTS are supported on UART Modem1 & IrDA. UART Modem2 is
16 * not available through DB9 connector on E-Sample.
17 *
18 * (C) Texas Instruments 1999 - 2003
19 *
20 ******************************************************************************/
21
22 /*
23 * E-Sample
24 *
25 * UART Modem1 UART Irda
26 *
27 * DB9 Calypso+ DB9 Calypso+
28 *
29 * 1 DCD DCD output 1 1, 6 and 4 are connected together on DB9
30 * 2 RX TX output 2 RX TX2 output
31 * 3 TX RX input 3 TX RX2 input
32 * 4 DTR DSR input 4
33 * 5 GND 5 GND
34 * 6 NC 6
35 * 7 RTS CTS input 7 RTS CTS2 input
36 * 8 CTS RTS output 8 CTS RTS2 output
37 * 9 NC 9 NC
38 *
39 */
40
41 /*
42 * C & D-Sample
43 *
44 * UART Modem UART Irda
45 *
46 * DB9 Calypso DB9 Calypso
47 *
48 * 1 DCD I/O 2 output 1 1, 6 and 4 are connected together on DB9
49 * 2 RX TX output 2 RX TX2 output
50 * 3 TX RX input 3 TX RX2 input
51 * 4 DTR I/O 3 input 4
52 * 5 GND 5 GND
53 * 6 NC 6
54 * 7 RTS CTS input 7 RTS CTS2 input
55 * 8 CTS RTS output 8 CTS RTS2 output
56 * 9 NC 9 NC
57 *
58 */
59
60 /*
61 * B-Sample
62 *
63 * UART Modem UART Irda
64 *
65 * DB9 Ulysse DB9 Ulysse
66 *
67 * 1 1, 6 and 4 are connected together on DB9 (Modem and Irda)
68 * 2 RX TX 2 RX TX
69 * 3 TX RX 3 TX RX
70 * 4 4
71 * 5 GND 5 GND
72 * 6 6
73 * 7 RTS CTS 7 7 and 8 are connected together on DB9
74 * 8 CTS RTS 8
75 * 9 NC 9 NC
76 *
77 */
78
79 #include "../include/config.h"
80
81 #include <string.h>
82
83 /*
84 * rv_general.h is needed for macros Min & Min3.
85 */
86 #include "../riviera/rv/rv_general.h"
87 #include "../nucleus/nucleus.h"
88
89 #include "../include/sys_types.h"
90 #include "faxdata.h"
91 #include "uartfax.h"
92
93 /*
94 * Needed to reset and restart the sleep timer in case of incoming characters.
95 */
96
97 #include "serialswitch.h"
98 extern SYS_BOOL uart_sleep_timer_enabled;
99
100 #include "../bsp/mem.h"
101 #include "../bsp/armio.h"
102
103 #if CONFIG_TARGET_GTAMODEM
104 #define EXTHOST_WAKEUP_GPIO 1
105 #else
106 #undef EXTHOST_WAKEUP_GPIO
107 #endif
108
109 /*
110 * Maximal value for an unsigned 32 bits.
111 */
112
113 #define MAX_UNSIGNED_32 (0xFFFFFFFFU)
114
115 #define FIFO_SIZE (64) /* In bytes. */
116
117
118 /*
119 * TLR is used to program the RX FIFO trigger levels. FCR[7:4] are not used.
120 * No trigger level used for TX FIFO. THR_IT generated on TX FIFO empty.
121 */
122
123 #define RX_FIFO_TRIGGER_LEVEL (12 << 4)
124
125
126 /*
127 * 16750 addresses. Registers accessed when LCR[7] = 0.
128 */
129
130 #define RHR (0x00) /* Rx buffer register - Read access */
131 #define THR (0x00) /* Tx holding register - Write access */
132 #define IER (0x01) /* Interrupt enable register */
133
134 /*
135 * 16750 addresses. Registers accessed when LCR[7] = 1.
136 */
137
138 #define DLL (0x00) /* Divisor latch (LSB) */
139 #define DLM (0x01) /* Divisor latch (MSB) */
140
141
142 /*
143 * EFR is accessed when LCR[7:0] = 0xBF.
144 */
145
146 #define EFR (0x02) /* Enhanced feature register */
147
148
149 /*
150 * 16750 addresses. Bit 5 of the FCR register is accessed when LCR[7] = 1.
151 */
152
153 #define IIR (0x02) /* Interrupt ident. register - Read only */
154 #define FCR (0x02) /* FIFO control register - Write only */
155 #define LCR (0x03) /* Line control register */
156 #define MCR (0x04) /* Modem control register */
157 #define LSR (0x05) /* Line status register */
158 #define MSR (0x06) /* Modem status register */
159 #define TCR (0x06) /* Transmission control register */
160 #define TLR (0x07) /* Trigger level register */
161 #define MDR1 (0x08) /* Mode definition register 1 */
162 #define SCR (0x10) /* Supplementary Control register */
163 #define SSR (0x11) /* Supplementary Status register */
164 #define UASR (0x0E) /* Autobauding Status register */
165
166 /*
167 * Supplementary control register.
168 */
169
170 #define TX_EMPTY_CTL_IT (0x08)
171 #define RX_CTS_WAKE_UP_ENABLE_BIT (4) /* Use RESET_BIT and SET_BIT macros. */
172 #define DSR_IT_BIT (5) /* Use RESET_BIT and SET_BIT macros. */
173
174 /*
175 * Enhanced feature register.
176 */
177
178 #define ENHANCED_FEATURE_BIT (4) /* Use RESET_BIT and SET_BIT macros. */
179 #define AUTO_CTS_BIT (7) /* Transmission is halted when the CTS pin is high (inactive). */
180
181 /*
182 * Mode definition register 1.
183 */
184
185 #define UART_MODE (0x00)
186 #define SIR_MODE (0x01)
187 #define UART_MODE_AUTOBAUDING (0x02) /* Reserved in UART/IrDA. */
188 #define RESET_DEFAULT_STATE (0x07)
189 #define IR_SLEEP_DISABLED (0x00)
190 #define IR_SLEEP_ENABLED (0x08)
191 #define SIR_TX_WITHOUT_ACREG2 (0x00) /* Reserved in UART/modem. */
192 #define SIR_TX_WITH_ACREG2 (0x20) /* Reserved in UART/modem. */
193 #define FRAME_LENGTH_METHOD (0x00) /* Reserved in UART/modem. */
194 #define EOT_BIT_METHOD (0x80) /* Reserved in UART/modem. */
195
196 /*
197 * Supplementary Status Register
198 */
199
200 #define TX_FIFO_FULL (0x01)
201
202
203 /*
204 * Interrupt enable register.
205 */
206
207 #define ERBI (0x01) /* Enable received data available interrupt */
208 #define ETBEI (0x02) /* Enable transmitter holding register empty interrupt */
209 #define ELSI (0x04) /* Enable receiver line status interrupt */
210 #define EDSSI (0x08) /* Enable modem status interrupt */
211 #define IER_SLEEP (0x10) /* Enable sleep mode */
212
213 /*
214 * Modem control register.
215 */
216
217 #define MDCD (0x01) /* Data Carrier Detect. */
218 #define MRTS (0x02) /* Request To Send. */
219 #define TCR_TLR_BIT (6)
220
221 /*
222 * Line status register.
223 */
224
225 #define DR (0x01) /* Data ready */
226 #define OE (0x02) /* Overrun error */
227 #define PE (0x04) /* Parity error */
228 #define FE (0x08) /* Framing error */
229 #define BI (0x10) /* Break interrupt */
230 #define THRE (0x20) /* Transmitter holding register (FIFO empty) */
231 #define TEMT (0x40) /* Transmitter empty (FIFO and TSR both empty) */
232
233 #define BYTE_ERROR (OE | PE | FE | BI)
234
235 /*
236 * Interrupt identification register.
237 * Bit 0 is set to 0 if an IT is pending.
238 * Bits 1 and 2 are used to identify the IT.
239 */
240
241 #define IIR_BITS_USED (0x07)
242 #define IT_PENDING (0x01)
243 #define RX_DATA (0x04)
244 #define TX_EMPTY (0x02)
245 #define MODEM_STATUS (0x00)
246
247 /*
248 * Modem status register.
249 */
250
251 #define DELTA_CTS (0x01)
252 #define DELTA_DSR (0x02)
253 #define MCTS (0x10) /* Clear to send */
254 #define MDSR (0x20) /* Data set ready */
255
256 /*
257 * Line control register.
258 */
259
260 #define WLS_5 (0x00) /* Word length: 5 bits */
261 #define WLS_6 (0x01) /* Word length: 6 bits */
262 #define WLS_7 (0x02) /* Word length: 7 bits */
263 #define WLS_8 (0x03) /* Word length: 8 bits */
264 #define STB (0x04) /* Number of stop bits: 0: 1, 1: 1,5 or 2 */
265 #define PEN (0x08) /* Parity enable */
266 #define EPS (0x10) /* Even parity select */
267 #define BREAK_CONTROL (0x40) /* Enable a break condition */
268 #define DLAB (0x80) /* Divisor latch access bit */
269
270 /*
271 * FIFO control register.
272 */
273
274 #define FIFO_ENABLE (0x01)
275 #define RX_FIFO_RESET (0x02)
276 #define TX_FIFO_RESET (0x04)
277
278 /*
279 * These constants define the states of the escape sequence detection.
280 */
281
282 #define INITIALIZATION (0)
283 #define NO_ESCAPE_SEQUENCE (1)
284 #define ONE_CHAR_DETECTED (2)
285 #define TWO_CHARS_DETECTED (3)
286 #define THREE_CHARS_DETECTED (4)
287
288 #define CHARACTERS_IN_ESC_SEQ (3)
289 #define DEFAULT_ESC_SEQ_CHARACTER '+'
290 #define DEFAULT_GUARD_PERIOD (1000) /* 1 second. */
291
292 /*
293 * 3 HISR are used to avoid to execute operations from the LISR.
294 */
295
296 #define RX_HISR_PRIORITY (2)
297
298 // NGENGE increase hisr stack otherwise overflows with multiple callbacks
299 //#define RX_HISR_STACK_SIZE (512) /* Bytes. */
300 #define RX_HISR_STACK_SIZE (768) /* Bytes. */
301
302 #define TX_HISR_PRIORITY (2)
303
304 // NGENGE increase hisr stack otherwise overflows with multiple callbacks
305 //#define TX_HISR_STACK_SIZE (512) /* Bytes. */
306 #define TX_HISR_STACK_SIZE (768) /* Bytes. */
307
308 #define V24_HISR_PRIORITY (2)
309 #define V24_HISR_STACK_SIZE (512) /* Bytes. */
310
311 /*
312 * When the break interrupt indicator (BI) is set in the line status register
313 * (LSR), it indicates that the received data input was held in the low state
314 * for longer than a full-word transmission time. In the FIFO mode, when a break
315 * occurs, only one 0 character is loaded into the FIFO. The next character
316 * transfer is enabled after SIN goes to the marking state for at least two RCLK
317 * samples and then receives the next valid start bit.
318 * This constant defined a defined break length returned by the US_GetLineState
319 * function.
320 */
321
322 #define MINIMAL_BREAK_LENGTH (2)
323
324 #define BREAK_HISR_PRIORITY (2)
325 #define BREAK_HISR_STACK_SIZE (512) /* Bytes. */
326
327 /*
328 * These macros allow to read and write a UART register.
329 */
330
331 #define READ_UART_REGISTER(UART,REG) \
332 *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))
333
334 #define WRITE_UART_REGISTER(UART,REG,VALUE) \
335 *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG))) = (VALUE)
336
337 #define RESET_BIT(UART,REG,BIT) \
338 (WRITE_UART_REGISTER ( \
339 UART, REG, READ_UART_REGISTER (UART, REG) & ~(1 << (BIT))))
340
341 #define SET_BIT(UART,REG,BIT) \
342 (WRITE_UART_REGISTER ( \
343 UART, REG, READ_UART_REGISTER (UART, REG) | (1 << (BIT))))
344
345
346 /*
347 * These macros allow to enable or disable the wake-up interrupt.
348 */
349
350 #define ENABLE_WAKEUP_INTERRUPT(UART) \
351 SET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);
352
353 #define DISABLE_WAKEUP_INTERRUPT(UART) \
354 RESET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);
355
356
357 /*
358 * These macros allow to enable or disable the DSR interrupt.
359 */
360
361 #define ENABLE_DSR_INTERRUPT(UART) \
362 SET_BIT(UART, SCR, DSR_IT_BIT);
363
364 #define DISABLE_DSR_INTERRUPT(UART) \
365 RESET_BIT(UART, SCR, DSR_IT_BIT);
366
367
368 /*
369 * The transmitter is disabled only when the application disables the driver.
370 * To disable the driver, the receiver and the transmitter are disabled by the
371 * application. The transmitter is disabled first to test if the driver is
372 * disabled.
373 */
374
375 #define DRIVER_DISABLED(UART) ((UART)->tx_stopped_by_application)
376
377 #define DISABLE_DRIVER(UART) \
378 { \
379 (UART)->tx_stopped_by_application = 1; \
380 (UART)->rx_stopped_by_application = 1; \
381 }
382
383 #define ENABLE_DRIVER(UART) \
384 { \
385 (UART)->rx_stopped_by_application = 0; \
386 (UART)->tx_stopped_by_application = 0; \
387 }
388
389 /*
390 * Low and high watermarks for the RX buffer. If it is enabled, the flow
391 * control is activated or deactivated according to these values.
392 * The high watermark value allows to copy an array filled with the RX FIFO
393 * into the RX buffer.
394 */
395
396 #define RX_LOW_WATERMARK(RX_BUFFER_SIZE) (FIFO_SIZE)
397 #define RX_HIGH_WATERMARK(RX_BUFFER_SIZE) ((RX_BUFFER_SIZE) - 2 * FIFO_SIZE)
398
399 /*
400 * This macro allows to know if the RX buffer is full. It must be called only
401 * from the RX HISR. If it is called from the application, the rx_in and
402 * rx_fifo_in pointers may be updated if a RX interrupt occurs or if the
403 * RX HISR is activated.
404 */
405
406 #define RX_BUFFER_FULL(UART) \
407 (((UART)->rx_in == (UART)->rx_out - 1) || \
408 ((UART)->rx_in == (UART)->rx_out + (UART)->buffer_size))
409
410 /*
411 * This macro allows to know if the TX buffer is empty.
412 */
413
414 #define TX_BUFFER_EMPTY(UART) \
415 ((UART)->tx_in == (UART)->tx_out)
416
417 /*
418 * This macro is used to convert a time (unit: ms) into a number of TDMA.
419 * 1 TDMA = 4.6 ms (23/5).
420 */
421
422 #define CONVERT_TIME_IN_TDMA(TIME) (((TIME) * 5) / 23)
423
424 /*
425 * This structure describes an UART compatible with the UART 16750 and
426 * contains some fields to manage this UART.
427 */
428
429 typedef struct s_uart {
430
431 SYS_UWORD32 base_address;
432
433 /*
434 * HISR executed from the RX/TX interrupt handler.
435 */
436
437 NU_HISR rx_hisr_ctrl_block;
438 NU_HISR tx_hisr_ctrl_block;
439 NU_HISR v24_hisr_ctrl_block;
440
441 char rx_hisr_stack[RX_HISR_STACK_SIZE];
442 char tx_hisr_stack[TX_HISR_STACK_SIZE];
443 char v24_hisr_stack[V24_HISR_STACK_SIZE];
444
445 /*
446 * 2 arrays are used to store bytes read in RX FIFO. A UART RX interrupt
447 * may occur while executing RX operations in RX HISR. To avoid overwriting
448 * the array in which received bytes are stored, a second array is used.
449 */
450
451 SYS_UWORD8 *rx_buffer_used_by_rx_lisr;
452 SYS_UWORD8 *rx_buffer_used_by_rx_hisr;
453 SYS_UWORD8 rx_fifo_byte_1[FIFO_SIZE];
454 SYS_UWORD8 rx_fifo_byte_2[FIFO_SIZE];
455 SYS_UWORD16 bytes_in_rx_buffer_1;
456 SYS_UWORD16 bytes_in_rx_buffer_2;
457
458 /*
459 * RX and TX buffers.
460 * One character is not used in each buffer to allow to know if the buffer
461 * is empty or not (See macro RX_BUFFER_FULL). If buffers are empty,
462 * rx_in = rx_out and tx_in = tx_out. It is impossible to use fields to
463 * count the number of bytes in each buffer because these fields may be
464 * updated from the application and from the interrupt handlers. That avoids
465 * to have conflicts.
466 */
467
468 SYS_UWORD16 buffer_size;
469 SYS_UWORD16 rx_threshold_level;
470 SYS_UWORD16 tx_threshold_level;
471 SYS_UWORD8 rx_buffer[FD_MAX_BUFFER_SIZE + 1];
472 SYS_UWORD8 tx_buffer[FD_MAX_BUFFER_SIZE + 1];
473 SYS_UWORD8 *rx_in;
474 SYS_UWORD8 *rx_out;
475 SYS_UWORD8 *tx_in;
476 SYS_UWORD8 *tx_out;
477
478 /*
479 * Escape sequence.
480 * the field esc_seq_modified may have 2 values:
481 * - 0: No modification.
482 * - 1: Parameters are in the process of modification: The detection
483 * is stopped.
484 */
485
486 NU_TIMER guard_period_timer_ctrl_block;
487 SYS_UWORD8 esc_seq_modified;
488 SYS_UWORD8 esc_seq_detection_state;
489 SYS_UWORD8 esc_seq_character;
490 UNSIGNED guard_period;
491 UNSIGNED current_time;
492 UNSIGNED previous_time;
493
494 /*
495 * Flow control.
496 */
497
498 T_flowCtrlMode flow_control_mode;
499 SYS_BOOL send_xon_xoff;
500 SYS_UWORD8 xon_xoff_to_send;
501 SYS_UWORD8 xon_character;
502 SYS_UWORD8 xoff_character;
503 SYS_BOOL rx_stopped_by_application;
504 SYS_BOOL rx_stopped_by_driver;
505 SYS_BOOL rx_stopped_by_lisr;
506 SYS_BOOL tx_stopped_by_application;
507 SYS_BOOL tx_stopped_by_driver;
508 /* SYS_BOOL tx_stopped_by_lisr;*/
509
510 /*
511 * Break.
512 */
513
514 SYS_BOOL break_received;
515 SYS_BOOL break_to_send;
516 SYS_BOOL break_in_progress;
517 NU_HISR break_hisr_ctrl_block;
518 char break_hisr_stack[BREAK_HISR_STACK_SIZE];
519 NU_TIMER break_timer_ctrl_block;
520 UNSIGNED baudrate;
521 UNSIGNED autobauding;
522 UNSIGNED bits_per_char; /* Including start, stop and parity bits. */
523 UNSIGNED break_length; /* In bytes. */
524 UNSIGNED time_without_character;
525
526 /*
527 * Callback (UAF_ReadData and UAF_WriteData).
528 * rd: read, wr: write.
529 */
530
531 SYS_BOOL esc_seq_received;
532 SYS_UWORD8 rts_level; /* RTS on RS232 side, CTS on chipset side.
533 1: The RS232 line is deactivated (low). */
534
535 #if TARGET_HAS_DTR_INPUT
536 SYS_UWORD8 dtr_level; /* Controlled with an I/O on C & D-Sample and
537 handled by Calypso+ on E-Sample.
538 1: The RS232 line is deactivated (low). */
539 /*
540 * When the DTR interrupt is detected the user's Rx callback function must
541 * be called but if the Rx FIFO is not empty the Rx HISR must be activated
542 * to read the bytes received in the Rx FIFO and to put them into the Rx
543 * buffer before to call the user's Rx callback function.
544 * If the Rx HISR is activated due to a Rx interrupt the user's Rx callback
545 * function will be called if conditions to call it are fulfilled. If it is
546 * activated due to the DTR interrupt the user's Rx callback function must
547 * be called without any conditions.
548 * Because the Rx HISR may have been activated but not executed before the
549 * DTR interrupt we must be sure that the user's Rx callback function will
550 * be called for each Rx HISR activation. Call is done for Rx HISR activated
551 * on Rx interrupt if conditions are fulfilled.
552 * A circular buffer of 2 elements is used to memorize the source of
553 * interrupt. Before the activation of the Rx HISR, the source of interrupt
554 * is memorized into this array. When the code of the Rx HISR is executed
555 * the user's Rx callback function is called if the source of interrupt was
556 * the DTR interrupt regardless of the other conditions.
557 * The level of DTR is saved to provide the level detected on Rx interrupt
558 * or DTR interrupt in the 'state' parameter of the user's Rx callback
559 * function.
560 */
561
562 SYS_BOOL dtr_change_detected[2];
563 SYS_UWORD8 dtr_level_saved[2];
564 SYS_UWORD8 index_it;
565 SYS_UWORD8 index_hisr;
566 #endif /* BOARD 8 or 9 or 40 or 41 or CHIPSET 12 */
567
568 SYS_BOOL reading_suspended;
569 SYS_BOOL writing_suspended;
570 SYS_BOOL rd_call_from_hisr_in_progress;
571 SYS_BOOL wr_call_from_hisr_in_progress;
572 T_reInstMode rd_call_setup;
573 T_reInstMode wr_call_setup;
574 SYS_UWORD8 *rd_address[2];
575 SYS_UWORD8 *wr_address[2];
576 SYS_UWORD16 rd_size_before_call[2];
577 SYS_UWORD16 rd_size_after_call[2];
578 SYS_UWORD16 wr_size_before_call[2];
579 SYS_UWORD16 wr_size_after_call[2];
580
581 void (*readOutFunc) (SYS_BOOL cldFromIrq,
582 T_reInstMode *reInstall,
583 SYS_UWORD8 nsource,
584 SYS_UWORD8 *source[],
585 SYS_UWORD16 size[],
586 SYS_UWORD32 state);
587
588 void (*writeInFunc) (SYS_BOOL cldFromIrq,
589 T_reInstMode *reInstall,
590 SYS_UWORD8 ndest,
591 SYS_UWORD8 *dest[],
592 SYS_UWORD16 size[]);
593
594 /*
595 * These fields are used to store the state defined in UAF_GetLineState.The
596 * first field is used when UAF_GetLineState and UAF_ReadData are not called.
597 * When one of these functions is called the second field is used. That
598 * avoids to lose events when UAF_GetLineState or UAF_ReadData resets the
599 * first field.
600 */
601
602 SYS_UWORD32 state_1;
603 SYS_UWORD32 state_2;
604 SYS_UWORD32 *state;
605
606 /*
607 * Errors counters.
608 */
609
610 SYS_UWORD32 framing_error;
611 SYS_UWORD32 parity_error;
612 SYS_UWORD32 overrun_error;
613 SYS_UWORD32 spurious_interrupts;
614
615 SYS_UWORD16 max_rx_fifo_level;
616
617 } t_uart;
618
619
620 static t_uart uart_parameters;
621
622
623 static const SYS_UWORD32 base_address[NUMBER_OF_FD_UART] =
624 {
625 MEM_UART_IRDA,
626 MEM_UART_MODEM
627 #if (CHIPSET == 12)
628 , MEM_UART_MODEM2
629 #endif
630 };
631
632
633 /*
634 * DLL (LSB) and DLH (MSB) registers values using the 13 MHz clock.
635 */
636
637 static const SYS_UWORD8 dll[] =
638 {
639 0, /* Auto baud: */
640 81, /* 75 baud. */
641 40, /* 150 baud. */
642 148, /* 300 baud. */
643 74, /* 600 baud. */
644 165, /* 1200 baud. */
645 83, /* 2400 baud. */
646 169, /* 4800 baud. */
647 113, /* 7200 baud. */
648 84, /* 9600 baud. */
649 56, /* 14400 baud. */
650 42, /* 19200 baud. */
651 28, /* 28800 baud. */
652 24, /* 33900 baud: not supported. */
653 21, /* 38400 baud. */
654 14, /* 57600 baud. */
655 7, /* 115200 baud. */
656 0, /* 203125 baud: not supported. */
657 0, /* 406250 baud: not supported. */
658 0 /* 812500 baud: not supported. */
659 };
660
661 static const SYS_UWORD8 dlh[] =
662 {
663 0, /* Auto baud: */
664 42, /* 75 baud. */
665 21, /* 150 baud. */
666 10, /* 300 baud. */
667 5, /* 600 baud. */
668 2, /* 1200 baud. */
669 1, /* 2400 baud. */
670 0, /* 4800 baud. */
671 0, /* 7200 baud. */
672 0, /* 9600 baud. */
673 0, /* 14400 baud. */
674 0, /* 19200 baud. */
675 0, /* 28800 baud. */
676 0, /* 33900 baud: not supported. */
677 0, /* 38400 baud. */
678 0, /* 57600 baud. */
679 0, /* 115200 baud. */
680 0, /* 203125 baud: not supported. */
681 0, /* 406250 baud: not supported. */
682 0 /* 812500 baud: not supported. */
683 };
684
685 static const UNSIGNED baudrate_value[] =
686 {
687 1,
688 75,
689 150,
690 300,
691 600,
692 1200,
693 2400,
694 4800,
695 7200,
696 9600,
697 14400,
698 19200,
699 28800,
700 0, /* Not supported. */
701 38400,
702 57600,
703 115200,
704 0, /* Not supported. */
705 0, /* Not supported. */
706 0 /* Not supported. */
707 };
708
709
710
711
712 /*******************************************************************************
713 *
714 * get_bytes_in_rx_buffer
715 *
716 * Purpose : Gets the number of bytes in the RX buffer.
717 *
718 * Arguments: In : uart: Pointer on the UART structure.
719 * Out: none
720 *
721 * Returns : The number of bytes in the RX buffer.
722 *
723 ******************************************************************************/
724
725 static SYS_UWORD16
726 get_bytes_in_rx_buffer (t_uart *uart)
727 {
728 SYS_UWORD16 bytes_in_rx_buffer;
729 volatile SYS_UWORD8 *rx_in;
730
731 rx_in = uart->rx_in;
732
733 if (uart->rx_out <= rx_in)
734 bytes_in_rx_buffer = (SYS_UWORD16) (rx_in - uart->rx_out);
735 else
736 bytes_in_rx_buffer =
737 (SYS_UWORD16) (rx_in - uart->rx_out + uart->buffer_size + 1);
738
739 return (bytes_in_rx_buffer);
740 }
741
742 /*******************************************************************************
743 *
744 * get_bytes_in_tx_buffer
745 *
746 * Purpose : Gets the number of bytes in the TX buffer.
747 *
748 * Arguments: In : uart: Pointer on the UART structure.
749 * Out: none
750 *
751 * Returns : The number of bytes in the TX buffer.
752 *
753 ******************************************************************************/
754
755 static SYS_UWORD16
756 get_bytes_in_tx_buffer (t_uart *uart)
757 {
758 SYS_UWORD16 bytes_in_tx_buffer;
759 volatile SYS_UWORD8 *tx_out;
760
761 tx_out = uart->tx_out;
762
763 if (tx_out <= uart->tx_in)
764 bytes_in_tx_buffer = (SYS_UWORD16) (uart->tx_in - tx_out);
765 else
766 bytes_in_tx_buffer =
767 (SYS_UWORD16) (uart->tx_in - tx_out + uart->buffer_size + 1);
768
769 return (bytes_in_tx_buffer);
770 }
771
772 /*******************************************************************************
773 *
774 * compute_break_time
775 *
776 * Purpose : Computes a number of TDMA from 3 parameters:
777 * - baudrate,
778 * - bits per character including start bit, stop bits and parity,
779 * - number of characters.
780 * Due to the TDMA value (4.6 ms), a minimal value is sent: 2 TDMA.
781 *
782 * Arguments: In : baudrate
783 * bits_per_char
784 * number_of_chars
785 * Out: none
786 *
787 * Returns : The number of TDMA.
788 *
789 ******************************************************************************/
790
791 static UNSIGNED
792 compute_break_time (UNSIGNED baudrate,
793 UNSIGNED bits_per_char,
794 UNSIGNED number_of_chars)
795 {
796 UNSIGNED number_of_tdma;
797
798 number_of_tdma = CONVERT_TIME_IN_TDMA (
799 1000 * bits_per_char * number_of_chars / baudrate);
800
801 if (number_of_tdma == 0)
802 number_of_tdma = 1;
803
804 number_of_tdma++;
805
806 return (number_of_tdma);
807 }
808
809 /*******************************************************************************
810 *
811 * update_reading_callback
812 *
813 * Purpose : Updates the sizes array and the addresses array and get and builds
814 * the state parameter defined in UAF_GetLineState to call the
815 * readOutFunc function.
816 *
817 * Arguments: In : uart : Pointer on the UART structure.
818 * call_source: 0: application, 1: HISR (Rx or V24), 3: Rx HISR
819 * Out: none
820 *
821 * Returns : none
822 *
823 ******************************************************************************/
824
825 static void
826 update_reading_callback (t_uart *uart,
827 SYS_BOOL call_source)
828 {
829 SYS_UWORD32 state;
830 SYS_UWORD8 dtr_level;
831 SYS_UWORD8 fragments_number;
832 SYS_UWORD16 bytes_in_rx_buffer;
833 volatile SYS_UWORD8 *rx_in;
834
835 /*
836 * Update the sizes array and the addresses array.
837 * A copy of rx_in is used because it may be updated by the interrupt
838 * handler if this function is called from the application.
839 */
840
841 rx_in = uart->rx_in;
842
843 if (uart->rx_out < rx_in) {
844
845 fragments_number = 1;
846
847 uart->rd_address[0] = uart->rx_out;
848 uart->rd_size_before_call[0] = (SYS_UWORD16) (rx_in - uart->rx_out);
849 uart->rd_size_after_call[0] = uart->rd_size_before_call[0];
850
851 uart->rd_size_before_call[1] = 0;
852 uart->rd_size_after_call[1] = 0;
853
854 bytes_in_rx_buffer = uart->rd_size_before_call[0];
855
856 } else if (rx_in == uart->rx_out) { /* RX buffer empty. */
857
858 fragments_number = 1;
859
860 uart->rd_address[0] = uart->rx_out;
861 uart->rd_size_before_call[0] = 0;
862 uart->rd_size_after_call[0] = 0;
863
864 uart->rd_size_before_call[1] = 0;
865 uart->rd_size_after_call[1] = 0;
866
867 bytes_in_rx_buffer = 0;
868
869 } else {
870
871 fragments_number = 2;
872
873 uart->rd_address[0] = uart->rx_out;
874 uart->rd_size_before_call[0] =
875 uart->buffer_size + 1 - (SYS_UWORD16) (uart->rx_out -
876 &(uart->rx_buffer[0]));
877 uart->rd_size_after_call[0] = uart->rd_size_before_call[0];
878
879 uart->rd_address[1] = &(uart->rx_buffer[0]);
880 uart->rd_size_before_call[1] = (SYS_UWORD16) (rx_in -
881 &(uart->rx_buffer[0]));
882 uart->rd_size_after_call[1] = uart->rd_size_before_call[1];
883
884 bytes_in_rx_buffer =
885 uart->rd_size_before_call[0] + uart->rd_size_before_call[1];
886
887 if (!uart->rd_size_before_call[1])
888 fragments_number = 1;
889 }
890
891 /*
892 * Build the state parameter defined in UAF_GetLineState.
893 * The field state_2 is used when state_1 is set to 0 to avoid to
894 * lose events detected in the RX interrupt handler.
895 */
896
897 #if TARGET_HAS_DTR_INPUT
898 if (call_source == 3) /* Call from Rx HISR */
899 dtr_level = uart->dtr_level_saved[uart->index_hisr];
900 else
901 dtr_level = uart->dtr_level;
902 #endif
903
904 state = uart->state_2;
905 uart->state_2 = 0;
906 uart->state = &(uart->state_2);
907
908 state |= uart->state_1;
909 uart->state_1 = 0;
910 uart->state = &(uart->state_1);
911
912 state |= ((((SYS_UWORD32) uart->rts_level) << RTS) |
913
914 #if TARGET_HAS_DTR_INPUT
915 (((SYS_UWORD32) dtr_level) << DTR) |
916 #endif
917
918 (((SYS_UWORD32) (uart->tx_stopped_by_application |
919 uart->tx_stopped_by_driver)) << TXSTP) |
920
921 (((SYS_UWORD32) (uart->rx_stopped_by_application |
922 uart->rx_stopped_by_driver)) << RXSTP) |
923
924 (((SYS_UWORD32) (uart->buffer_size - bytes_in_rx_buffer)) << RXBLEV));
925
926 /*
927 * Fields SA, SB and X are set according to the flow control:
928 *
929 * None RTS/CTS XON/XOFF
930 * SA DTR DTR DTR
931 * SB RTS 0 RTS
932 * X 0 RTS XON:0 XOFF:1 (transmitter)
933 *
934 * DTR is supported on C, D & E-Sample.
935 */
936
937 #if TARGET_HAS_DTR_INPUT
938 state |= (((SYS_UWORD32) uart->dtr_level) << SA);
939 #endif
940
941 if (uart->flow_control_mode != fc_rts)
942 state |= (((SYS_UWORD32) uart->rts_level) << SB);
943
944 if (uart->flow_control_mode == fc_rts)
945 state |= (((SYS_UWORD32) uart->rts_level) << X);
946
947 else if ((uart->flow_control_mode == fc_xoff) &&
948 (uart->tx_stopped_by_application ||
949 uart->tx_stopped_by_driver))
950 state |= (1 << X);
951
952 /*
953 * Call the readOutFunc function with these parameters.
954 */
955
956 uart->rd_call_setup = rm_notDefined;
957
958 (*(uart->readOutFunc)) (call_source & 0x01, /* From HISR or application */
959 &(uart->rd_call_setup),
960 fragments_number,
961 &(uart->rd_address[0]),
962 &(uart->rd_size_after_call[0]),
963 state);
964 }
965
966 /*******************************************************************************
967 *
968 * update_writing_callback
969 *
970 * Purpose : Updates the sizes array and the addresses array to call the
971 * writeInFunc function.
972 *
973 * Arguments: In : uart : Pointer on the UART structure.
974 * call_source: 0: application, 1: HISR
975 * Out: none
976 *
977 * Returns : none
978 *
979 ******************************************************************************/
980
981 static void
982 update_writing_callback (t_uart *uart,
983 SYS_BOOL call_source)
984 {
985 SYS_UWORD8 fragments_number;
986 volatile SYS_UWORD8 *tx_out;
987
988 /*
989 * Update the array of sizes and the array of addresses.
990 * A copy of tx_out is used because it may be updated by the interrupt
991 * handler if this function is called from the application.
992 */
993
994 tx_out = uart->tx_out;
995
996 if (uart->tx_in < tx_out) {
997
998 fragments_number = 1;
999
1000 uart->wr_address[0] = uart->tx_in;
1001 uart->wr_size_before_call[0] =
1002 (SYS_UWORD16) (tx_out - uart->tx_in - 1);
1003 uart->wr_size_after_call[0] = uart->wr_size_before_call[0];
1004
1005 uart->wr_size_before_call[1] = 0;
1006 uart->wr_size_after_call[1] = 0;
1007
1008 } else if (tx_out == &(uart->tx_buffer[0])) {
1009
1010 fragments_number = 1;
1011
1012 uart->wr_address[0] = uart->tx_in;
1013 uart->wr_size_before_call[0] =
1014 uart->buffer_size -
1015 (SYS_UWORD16) (uart->tx_in - &(uart->tx_buffer[0]));
1016 uart->wr_size_after_call[0] = uart->wr_size_before_call[0];
1017
1018 uart->wr_size_before_call[1] = 0;
1019 uart->wr_size_after_call[1] = 0;
1020
1021 } else {
1022
1023 fragments_number = 2;
1024
1025 uart->wr_address[0] = uart->tx_in;
1026 uart->wr_size_before_call[0] =
1027 uart->buffer_size + 1 -
1028 (SYS_UWORD16) (uart->tx_in - &(uart->tx_buffer[0]));
1029 uart->wr_size_after_call[0] = uart->wr_size_before_call[0];
1030
1031 uart->wr_address[1] = &(uart->tx_buffer[0]);
1032 uart->wr_size_before_call[1] =
1033 (SYS_UWORD16) (tx_out - &(uart->tx_buffer[0]) - 1);
1034 uart->wr_size_after_call[1] = uart->wr_size_before_call[1];
1035
1036 if (!uart->wr_size_before_call[1])
1037 fragments_number = 1;
1038 }
1039
1040 /*
1041 * Call the writeInFunc function with these parameters;
1042 */
1043
1044 uart->wr_call_setup = rm_notDefined;
1045
1046 (*(uart->writeInFunc)) (call_source,
1047 &(uart->wr_call_setup),
1048 fragments_number,
1049 &(uart->wr_address[0]),
1050 &(uart->wr_size_after_call[0]));
1051 }
1052
1053 /*******************************************************************************
1054 *
1055 * stop_break
1056 *
1057 * Purpose : The timer is activated to expire when a time corresponding to the
1058 * sending time of 2 characters at least has elapsed. After a break,
1059 * no character may be sent during this period.
1060 *
1061 * Arguments: In : id: parameter not used.
1062 * Out: none
1063 *
1064 * Returns : none
1065 *
1066 ******************************************************************************/
1067
1068 static VOID
1069 stop_break (UNSIGNED id)
1070 {
1071 t_uart *uart;
1072
1073 uart = &uart_parameters;
1074
1075 uart->break_to_send = 0;
1076 uart->break_in_progress = 0;
1077
1078 #if ((CHIPSET != 5) && (CHIPSET != 6))
1079 /*
1080 * Disable sleep mode.
1081 */
1082
1083 WRITE_UART_REGISTER (
1084 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
1085 #endif
1086
1087 /*
1088 * Unmask Tx interrupt.
1089 */
1090
1091 WRITE_UART_REGISTER (
1092 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
1093 }
1094
1095 /*******************************************************************************
1096 *
1097 * hisr_start_break
1098 *
1099 * Purpose : Enables the timer used to control the time without character.
1100 *
1101 * Arguments: In : none
1102 * Out: none
1103 *
1104 * Returns : none
1105 *
1106 ******************************************************************************/
1107
1108 static VOID
1109 hisr_start_break (VOID)
1110 {
1111 t_uart *uart;
1112
1113 uart = &uart_parameters;
1114
1115 (void) NU_Control_Timer (&(uart->break_timer_ctrl_block),
1116 NU_DISABLE_TIMER);
1117
1118 (void) NU_Reset_Timer (&(uart->break_timer_ctrl_block),
1119 stop_break,
1120 uart->time_without_character,
1121 0, /* The timer expires once. */
1122 NU_DISABLE_TIMER);
1123
1124 (void) NU_Control_Timer (&(uart->break_timer_ctrl_block),
1125 NU_ENABLE_TIMER);
1126 }
1127
1128 /*******************************************************************************
1129 *
1130 * stop_receiver
1131 *
1132 * Purpose : Activates DTR or RTS or sends XOFF.
1133 *
1134 * Arguments: In : uart: Pointer on the UART structure.
1135 * Out: none
1136 *
1137 * Returns : none
1138 *
1139 ******************************************************************************/
1140
1141 static void
1142 stop_receiver (t_uart *uart)
1143 {
1144 #if ((CHIPSET != 5) && (CHIPSET != 6))
1145 /*
1146 * Disable sleep mode.
1147 */
1148
1149 WRITE_UART_REGISTER (
1150 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
1151 #endif
1152
1153 switch (uart->flow_control_mode) {
1154
1155 case fc_rts:
1156
1157 /*
1158 * CTS (RTS on UART side) is deactivated (high).
1159 */
1160
1161 WRITE_UART_REGISTER (
1162 uart, MCR, READ_UART_REGISTER (uart, MCR) & ~MRTS);
1163 break;
1164
1165 case fc_xoff:
1166
1167 uart->xon_xoff_to_send = uart->xoff_character;
1168 uart->send_xon_xoff = 1;
1169
1170 /*
1171 * Unmask Tx interrupt.
1172 */
1173
1174 WRITE_UART_REGISTER (
1175 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
1176 break;
1177 }
1178 }
1179
1180 /*******************************************************************************
1181 *
1182 * start_receiver
1183 *
1184 * Purpose : Deactivates DTR or RTS or sends XON.
1185 *
1186 * Arguments: In : uart: Pointer on the UART structure.
1187 * Out: none
1188 *
1189 * Returns : none
1190 *
1191 ******************************************************************************/
1192
1193 static void
1194 start_receiver (t_uart *uart)
1195 {
1196 #if ((CHIPSET != 5) && (CHIPSET != 6))
1197 /*
1198 * Disable sleep mode.
1199 */
1200
1201 WRITE_UART_REGISTER (
1202 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
1203 #endif
1204
1205 switch (uart->flow_control_mode) {
1206
1207 case fc_rts:
1208
1209 /*
1210 * CTS (RTS on UART side) is activated (low).
1211 */
1212
1213 WRITE_UART_REGISTER (
1214 uart, MCR, READ_UART_REGISTER (uart, MCR) | MRTS);
1215 break;
1216
1217 case fc_xoff:
1218
1219 uart->xon_xoff_to_send = uart->xon_character;
1220 uart->send_xon_xoff = 1;
1221
1222 /*
1223 * Unmask Tx interrupt.
1224 */
1225
1226 WRITE_UART_REGISTER (
1227 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
1228 break;
1229 }
1230 }
1231
1232 /*******************************************************************************
1233 *
1234 * add_esc_seq_char_in_rx_buffer
1235 *
1236 * Purpose : Writes one escape sequence character in the RX buffer.
1237 *
1238 * Arguments: In : uart: Pointer on the UART structure.
1239 * Out: none
1240 *
1241 * Returns : none
1242 *
1243 ******************************************************************************/
1244
1245 static void
1246 add_esc_seq_char_in_rx_buffer (t_uart *uart)
1247 {
1248 /*
1249 * IF the RX buffer is not full, write an escape sequence character in the
1250 * RX buffer and check wrap-around.
1251 */
1252
1253 if (!RX_BUFFER_FULL (uart)) {
1254
1255 *(uart->rx_in++) = uart->esc_seq_character;
1256
1257 if (uart->rx_in == &(uart->rx_buffer[0]) + uart->buffer_size + 1)
1258 uart->rx_in = &(uart->rx_buffer[0]);
1259 }
1260 }
1261
1262 /*******************************************************************************
1263 *
1264 * analyze_guard_period_timer_expiration
1265 *
1266 * Purpose : According to the state of the escape sequence detection, 1 or 2
1267 * escape sequence characters may be written into the TX buffer or
1268 * the escape sequence is declared as detected.
1269 * If 1 or 2 escape sequence characters have been detected the
1270 * guard period must not expire.
1271 * If 3 characters have been detected the escape sequence must
1272 * expire.
1273 *
1274 * Arguments: In : id: parameter not used.
1275 * Out: none
1276 *
1277 * Returns : none
1278 *
1279 ******************************************************************************/
1280
1281 static VOID
1282 analyze_guard_period_timer_expiration (UNSIGNED id)
1283 {
1284 t_uart *uart;
1285 SYS_UWORD16 bytes_in_rx_buffer;
1286
1287 uart = &uart_parameters;
1288
1289 switch (uart->esc_seq_detection_state) {
1290
1291 case ONE_CHAR_DETECTED:
1292
1293 /*
1294 * 1 escape sequence character has been detected. The guard period has
1295 * ellapsed. This character is written into the TX buffer.
1296 */
1297
1298 add_esc_seq_char_in_rx_buffer (uart);
1299 break;
1300
1301 case TWO_CHARS_DETECTED:
1302
1303 /*
1304 * 2 escape sequence characters have been detected. The guard period has
1305 * ellapsed. These characters are written into the TX buffer.
1306 */
1307
1308 add_esc_seq_char_in_rx_buffer (uart);
1309 add_esc_seq_char_in_rx_buffer (uart);
1310
1311 break;
1312
1313 case THREE_CHARS_DETECTED:
1314
1315 /*
1316 * 3 escape sequence characters have been detected and the guard period
1317 * has ellapsed. The escape sequence is detected.
1318 */
1319
1320 uart->esc_seq_received = 1;
1321 *(uart->state) |= (1 << ESC);
1322
1323 break;
1324 }
1325
1326 uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
1327
1328 /*
1329 * If the high watermark is reached, RTS is activated or XOFF is sent
1330 * according to the flow control mode.
1331 */
1332
1333 bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
1334
1335 if ((uart->flow_control_mode != fc_none) &&
1336 (bytes_in_rx_buffer >= RX_HIGH_WATERMARK (uart->buffer_size))) {
1337
1338 /*
1339 * Check if receipt must be stopped.
1340 */
1341
1342 if (!uart->rx_stopped_by_driver) {
1343
1344 uart->rx_stopped_by_driver = 1;
1345 if (!uart->rx_stopped_by_application)
1346 stop_receiver (uart);
1347 }
1348 }
1349
1350 /*
1351 * If a reading was suspended or if the callback function is installed,
1352 * it is called if one of these conditions is fulfiled:
1353 * - the RX threshold level is reached,
1354 * - a break has been detected,
1355 * - an escape sequence has been detected,
1356 */
1357
1358 if ((!uart->rd_call_from_hisr_in_progress) &&
1359 (uart->reading_suspended ||
1360 (uart->rd_call_setup == rm_reInstall))) {
1361
1362 if ((bytes_in_rx_buffer >= uart->rx_threshold_level) ||
1363 uart->break_received ||
1364 uart->esc_seq_received) {
1365
1366 uart->rd_call_from_hisr_in_progress = 1;
1367 update_reading_callback (uart, 1); /* 1: call from HISR. */
1368
1369 uart->reading_suspended = 0;
1370 uart->break_received = 0;
1371 uart->esc_seq_received = 0;
1372 }
1373 }
1374 }
1375
1376 /*******************************************************************************
1377 *
1378 * stop_guard_period_timer
1379 *
1380 * Purpose : Stops the timer used to detect the guard period expiration.
1381 *
1382 * Arguments: In : uart: Pointer on the UART structure.
1383 * Out: none
1384 *
1385 * Returns : none
1386 *
1387 ******************************************************************************/
1388
1389 static void
1390 stop_guard_period_timer (t_uart *uart)
1391 {
1392 (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
1393 NU_DISABLE_TIMER);
1394 }
1395
1396 /*******************************************************************************
1397 *
1398 * start_guard_period_timer
1399 *
1400 * Purpose : Starts a timer which expires if the guard period has ellapsed.
1401 *
1402 * Arguments: In : uart: Pointer on the UART structure.
1403 * Out: none
1404 *
1405 * Returns : none
1406 *
1407 ******************************************************************************/
1408
1409 static void
1410 start_guard_period_timer (t_uart *uart)
1411 {
1412 (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
1413 NU_DISABLE_TIMER);
1414
1415 (void) NU_Reset_Timer (&(uart->guard_period_timer_ctrl_block),
1416 analyze_guard_period_timer_expiration,
1417 uart->guard_period,
1418 0, /* The timer expires once. */
1419 NU_DISABLE_TIMER);
1420
1421 (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
1422 NU_ENABLE_TIMER);
1423 }
1424
1425 /*******************************************************************************
1426 *
1427 * detect_escape_sequence
1428 *
1429 * Purpose : The state machine used to detect an escape sequence is updated
1430 * according to the array of bytes to analyse. If the state machine
1431 * goes to the initial state due to a break in the sequence
1432 * detection, the previous characters are put into the RX buffer.
1433 *
1434 * Arguments: In : uart: Pointer on the UART structure.
1435 * Out: none
1436 *
1437 * Returns : 0: Break in detection or a sequence has been detected.
1438 * 1: A sequence may be detected.
1439 *
1440 ******************************************************************************/
1441
1442 static int
1443 detect_escape_sequence (t_uart *uart)
1444 {
1445 int detection_result;
1446 SYS_UWORD8 *rx_fifo_byte;
1447 SYS_UWORD16 bytes_in_rx_buffer;
1448 UNSIGNED elapsed_time;
1449
1450 detection_result = 0;
1451
1452 rx_fifo_byte = uart->rx_buffer_used_by_rx_hisr;
1453 if (rx_fifo_byte == &(uart->rx_fifo_byte_1[0]))
1454 bytes_in_rx_buffer = uart->bytes_in_rx_buffer_1;
1455 else
1456 bytes_in_rx_buffer = uart->bytes_in_rx_buffer_2;
1457
1458 if (uart->current_time > uart->previous_time)
1459 elapsed_time = uart->current_time - uart->previous_time;
1460 else
1461 elapsed_time =
1462 MAX_UNSIGNED_32 - uart->previous_time + uart->current_time;
1463
1464 switch (uart->esc_seq_detection_state) {
1465
1466 case INITIALIZATION:
1467
1468 /*
1469 * It is the first character received. It may be the first character
1470 * of an escape sequence. The elapsed_time variable is set to the
1471 * guard period value to consider this character as the first character
1472 * of an escape sequence.
1473 */
1474
1475 if (!uart->esc_seq_modified) {
1476
1477 elapsed_time = uart->guard_period;
1478 uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
1479 }
1480
1481 /* No break! */
1482
1483 case NO_ESCAPE_SEQUENCE:
1484
1485 /*
1486 * To go to the next state (one, two or three characters detected):
1487 * - a guard period must have elapsed since the last receipt,
1488 * - the characters must belong to the escape sequence.
1489 */
1490
1491 if ((elapsed_time >= uart->guard_period) &&
1492 (!uart->esc_seq_modified)) {
1493
1494 switch (bytes_in_rx_buffer) {
1495
1496 case 1:
1497
1498 if (*rx_fifo_byte++ == uart->esc_seq_character) {
1499
1500 uart->esc_seq_detection_state = ONE_CHAR_DETECTED;
1501 start_guard_period_timer (uart);
1502 detection_result = 1;
1503 }
1504
1505 break;
1506
1507 case 2:
1508
1509 if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
1510 (*rx_fifo_byte++ == uart->esc_seq_character)) {
1511
1512 uart->esc_seq_detection_state = TWO_CHARS_DETECTED;
1513 start_guard_period_timer (uart);
1514 detection_result = 1;
1515 }
1516
1517 break;
1518
1519 case 3:
1520
1521 if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
1522 (*rx_fifo_byte++ == uart->esc_seq_character) &&
1523 (*rx_fifo_byte++ == uart->esc_seq_character)) {
1524
1525 uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
1526 start_guard_period_timer (uart);
1527 detection_result = 1;
1528 }
1529
1530 break;
1531
1532 default:
1533
1534 /*
1535 * No action.
1536 */
1537
1538 break;
1539 }
1540 }
1541
1542 uart->previous_time = uart->current_time;
1543
1544 break;
1545
1546 case ONE_CHAR_DETECTED:
1547
1548 /*
1549 * To go to the next state (two or three characters detected):
1550 * - the difference between the current time and the previous time
1551 * must be less than the guard period,
1552 * - the characters must belong to the escape sequence.
1553 * Otherwise, an escape sequence character is written in the RX buffer.
1554 */
1555
1556 if (!uart->esc_seq_modified) {
1557
1558 switch (bytes_in_rx_buffer) {
1559
1560 case 1:
1561
1562 if (*rx_fifo_byte++ == uart->esc_seq_character) {
1563
1564 uart->esc_seq_detection_state = TWO_CHARS_DETECTED;
1565 detection_result = 1;
1566 }
1567
1568 break;
1569
1570 case 2:
1571
1572 if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
1573 (*rx_fifo_byte++ == uart->esc_seq_character)) {
1574
1575 start_guard_period_timer (uart); /* Reset the timer. */
1576
1577 uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
1578 detection_result = 1;
1579 }
1580
1581 break;
1582
1583 default:
1584
1585 /*
1586 * No action.
1587 */
1588
1589 break;
1590 }
1591 }
1592
1593 if (!detection_result) {
1594
1595 add_esc_seq_char_in_rx_buffer (uart);
1596
1597 uart->previous_time = uart->current_time;
1598 uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
1599 }
1600
1601 break;
1602
1603 case TWO_CHARS_DETECTED:
1604
1605 /*
1606 * To go to the next state (three chars detected):
1607 * - the difference between the current time and the previous time
1608 * must be less than the guard period,
1609 * - the character must belong to the escape sequence.
1610 * Otherwise, 2 escape sequence characters are written in the RX buffer.
1611 */
1612
1613 if (!uart->esc_seq_modified) {
1614
1615 switch (bytes_in_rx_buffer) {
1616
1617 case 1:
1618
1619 if (*rx_fifo_byte++ == uart->esc_seq_character) {
1620
1621 start_guard_period_timer (uart); /* Reset the timer. */
1622
1623 uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
1624 detection_result = 1;
1625 }
1626
1627 break;
1628
1629 default:
1630
1631 /*
1632 * No action.
1633 */
1634
1635 break;
1636 }
1637 }
1638
1639 if (!detection_result) {
1640
1641 add_esc_seq_char_in_rx_buffer (uart);
1642 add_esc_seq_char_in_rx_buffer (uart);
1643
1644 uart->previous_time = uart->current_time;
1645 uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
1646 }
1647
1648 break;
1649
1650 case THREE_CHARS_DETECTED:
1651
1652 /*
1653 * An escape sequence is detected if a guard period has elapsed since
1654 * the last receipt. Otherwise, 3 escape sequence characters are
1655 * written in the RX buffer.
1656 */
1657
1658 stop_guard_period_timer (uart);
1659
1660 add_esc_seq_char_in_rx_buffer (uart);
1661 add_esc_seq_char_in_rx_buffer (uart);
1662 add_esc_seq_char_in_rx_buffer (uart);
1663
1664 uart->previous_time = uart->current_time;
1665 uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
1666
1667 break;
1668 }
1669
1670 return (detection_result);
1671 }
1672
1673 /*******************************************************************************
1674 *
1675 * send_break
1676 *
1677 * Purpose : This function may only called if the TX FIFO is empty.
1678 * Null characters are written in the TX FIFO. The number of bytes to
1679 * write has been defined with UAF_SetLineState. Enables the break
1680 * condition.
1681 *
1682 * Arguments: In : uart: Pointer on the UART structure.
1683 * Out: none
1684 *
1685 * Returns : Number of bytes sent.
1686 *
1687 ******************************************************************************/
1688
1689 static SYS_UWORD16
1690 send_break (t_uart *uart)
1691 {
1692 SYS_UWORD16 bytes_in_tx_fifo;
1693
1694 bytes_in_tx_fifo = 0;
1695 uart->break_in_progress = 1;
1696
1697 #if ((CHIPSET != 5) && (CHIPSET != 6))
1698 /*
1699 * Disable sleep mode.
1700 */
1701
1702 WRITE_UART_REGISTER (
1703 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
1704 #endif
1705
1706 WRITE_UART_REGISTER (
1707 uart, LCR, READ_UART_REGISTER (uart, LCR) | BREAK_CONTROL);
1708
1709 #if ((CHIPSET != 5) && (CHIPSET != 6))
1710 /*
1711 * Re-enable sleep mode.
1712 */
1713
1714 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
1715 /*
1716 WRITE_UART_REGISTER (
1717 uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
1718
1719 */
1720 #endif
1721
1722 while (uart->break_length) {
1723
1724 WRITE_UART_REGISTER (uart, THR, 0x00);
1725 uart->break_length--;
1726 bytes_in_tx_fifo++;
1727 }
1728
1729 return (bytes_in_tx_fifo);
1730 }
1731
1732 /*******************************************************************************
1733 *
1734 * build_rx_fifo_array
1735 *
1736 * Purpose : Reads the RX FIFO to build an array with bytes read.
1737 * A byte is written in this array if no error is detected.
1738 *
1739 * Arguments: In : uart: Pointer on the UART structure.
1740 * Out: none
1741 *
1742 * Returns : The number of bytes in RX FIFO.
1743 *
1744 ******************************************************************************/
1745
1746 static SYS_UWORD16
1747 build_rx_fifo_array (t_uart *uart)
1748 {
1749 SYS_UWORD8 status;
1750 SYS_UWORD8 *first_byte;
1751 SYS_UWORD8 *current_byte;
1752 SYS_UWORD16 *bytes_in_rx_buffer;
1753 SYS_UWORD16 bytes_received;
1754 SYS_UWORD8 cbyte;
1755
1756 volatile int x;
1757
1758 x = 1;
1759
1760 bytes_received = 0;
1761
1762
1763 /*
1764 * Switch to the other buffer.
1765 */
1766
1767 first_byte = uart->rx_buffer_used_by_rx_lisr;
1768 if (first_byte == &(uart->rx_fifo_byte_1[0])) {
1769
1770 first_byte = &(uart->rx_fifo_byte_2[0]);
1771 bytes_in_rx_buffer = &(uart->bytes_in_rx_buffer_2);
1772
1773 } else {
1774
1775 first_byte = &(uart->rx_fifo_byte_1[0]);
1776 bytes_in_rx_buffer = &(uart->bytes_in_rx_buffer_1);
1777 }
1778
1779 current_byte = first_byte;
1780
1781 if (*bytes_in_rx_buffer) {
1782
1783 /* The Rx buffer is not empty and is being used by HISR ! */
1784 /* Hence stop the flow control */
1785 stop_receiver (uart);
1786
1787 /*
1788 * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
1789 */
1790 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
1791
1792 /* Mask The Rx and interrupt */
1793
1794 WRITE_UART_REGISTER (
1795 uart, IER, READ_UART_REGISTER (uart, IER) &
1796 ~(ERBI | EDSSI));
1797
1798 uart->rx_stopped_by_lisr = 1;
1799 return (bytes_received);
1800
1801 }
1802
1803 uart->rx_buffer_used_by_rx_lisr = first_byte;
1804
1805 status = READ_UART_REGISTER (uart, LSR);
1806
1807 /*
1808 * Build an array with the bytes contained in the RX FIFO.
1809 */
1810
1811 while (status & DR) { /* While RX FIFO is not empty... */
1812
1813 *current_byte = READ_UART_REGISTER (uart, RHR);
1814
1815 /*
1816 * Check if a parity error or a framing error is associated with the
1817 * received data. If there is an error the byte is not copied into the
1818 * bytes array.
1819 */
1820
1821 if (status & BYTE_ERROR) {
1822
1823 if (status & OE)
1824 uart->overrun_error++;
1825
1826 if (status & PE)
1827 uart->parity_error++;
1828
1829 if (status & FE)
1830 uart->framing_error++;
1831
1832 /*
1833 * Check break detection.
1834 */
1835
1836 if (status & BI) {
1837
1838 uart->break_received = 1;
1839 *(uart->state) |=
1840 ((1 << BRK) | (MINIMAL_BREAK_LENGTH << BRKLEN));
1841 }
1842
1843 } else /* No error */
1844 current_byte++;
1845
1846 status = READ_UART_REGISTER (uart, LSR);
1847 }
1848
1849 bytes_received = (SYS_UWORD16) (current_byte - first_byte);
1850 *bytes_in_rx_buffer = bytes_received;
1851
1852 /*
1853 * Re-switch to the other buffer if no valid character has been received.
1854 */
1855
1856 if (!bytes_received) {
1857
1858 if (uart->rx_buffer_used_by_rx_lisr == &(uart->rx_fifo_byte_1[0]))
1859 uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_2[0]);
1860
1861 else
1862 uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_1[0]);
1863 }
1864
1865 if (bytes_received > uart->max_rx_fifo_level)
1866 uart->max_rx_fifo_level = bytes_received;
1867
1868 return (bytes_received);
1869 }
1870
1871 /*******************************************************************************
1872 *
1873 * empty_rx_fifo
1874 *
1875 * Purpose : Read the RX FIFO.
1876 *
1877 * Arguments: In : uart: Pointer on the UART structure.
1878 * Out: none
1879 *
1880 * Returns : none
1881 *
1882 ******************************************************************************/
1883
1884 static void
1885 empty_rx_fifo (t_uart *uart)
1886 {
1887 SYS_UWORD16 bytes_in_rx_fifo;
1888 volatile SYS_UWORD8 dummy_byte;
1889
1890 bytes_in_rx_fifo = 0;
1891
1892 while (READ_UART_REGISTER (uart, LSR) & DR) {
1893
1894 dummy_byte = READ_UART_REGISTER (uart, RHR);
1895 bytes_in_rx_fifo++;
1896 }
1897
1898 if (bytes_in_rx_fifo > uart->max_rx_fifo_level)
1899 uart->max_rx_fifo_level = bytes_in_rx_fifo;
1900 }
1901
1902 /*******************************************************************************
1903 *
1904 * hisr_execute_rx_operations
1905 *
1906 * Purpose : If an escape sequence is detected or if a break in the detection
1907 * has occured RX FIFO bytes are written in the RX buffer.
1908 * If the software flow control is used bytes are analyzed to know
1909 * if a XON or a XOFF character is received to stop or start the
1910 * transmitter.
1911 * If a flow control is used and if the high watermark of the RX
1912 * buffer is reached the receiver is stopped.
1913 * If the RX threshold level is reached the callback mechanism is
1914 * activated.
1915 *
1916 * Arguments: In : none
1917 * Out: none
1918 *
1919 * Returns : none
1920 *
1921 ******************************************************************************/
1922
1923 static VOID
1924 hisr_execute_rx_operations (VOID)
1925 {
1926 SYS_UWORD16 bytes_free_in_rx_buffer;
1927 SYS_UWORD16 wrap_around_counter;
1928 SYS_UWORD16 bytes_in_rx_buffer;
1929 SYS_UWORD16 bytes_read;
1930 SYS_UWORD16 bytes_to_copy;
1931 SYS_UWORD8 *current_byte;
1932 SYS_UWORD8 xon_xoff_detected;
1933 t_uart *uart;
1934
1935 uart = &uart_parameters;
1936
1937 /*
1938 * Since new characters have been received, the sleep timer is reset then
1939 * restarted preventing the system to enter deep-sleep for a new period of
1940 * time.
1941 */
1942
1943 SER_restart_uart_sleep_timer ();
1944 uart_sleep_timer_enabled = 1;
1945
1946 #if TARGET_HAS_DTR_INPUT
1947 uart->index_hisr = (uart->index_hisr + 1) & 0x01; /* 0 or 1 */
1948 #endif
1949
1950 xon_xoff_detected = 0;
1951
1952 /*
1953 * Switch to the other buffer.
1954 */
1955
1956 current_byte = uart->rx_buffer_used_by_rx_hisr;
1957 if (current_byte == &(uart->rx_fifo_byte_1[0])) {
1958
1959 current_byte = &(uart->rx_fifo_byte_2[0]);
1960 bytes_read = uart->bytes_in_rx_buffer_2;
1961
1962 } else {
1963
1964 current_byte = &(uart->rx_fifo_byte_1[0]);
1965 bytes_read = uart->bytes_in_rx_buffer_1;
1966 }
1967
1968 uart->rx_buffer_used_by_rx_hisr = current_byte;
1969
1970 /*
1971 * All bytes are copied into the RX buffer only if an escape sequence has
1972 * been detected or a break in the detection has occured.
1973 */
1974
1975 if (!detect_escape_sequence (uart)) {
1976
1977 if (uart->rx_out > uart->rx_in)
1978 bytes_free_in_rx_buffer = (SYS_UWORD16) (uart->rx_out - uart->rx_in - 1);
1979 else
1980 bytes_free_in_rx_buffer =
1981 (SYS_UWORD16) (uart->buffer_size + uart->rx_out - uart->rx_in);
1982
1983 wrap_around_counter = uart->buffer_size + 1 -
1984 (SYS_UWORD16) (uart->rx_in - &(uart->rx_buffer[0]));
1985
1986 if (uart->flow_control_mode == fc_xoff) {
1987
1988 /*
1989 * For SW Flow Control, need to further investigate the processing
1990 * in order to improve the performance of the driver, and in order
1991 * to avoid managing the wrap around of the circular buffer each
1992 * time a character is copied.
1993 */
1994
1995 while (bytes_read && bytes_free_in_rx_buffer) {
1996
1997 /*
1998 * If the data received is XON or XOFF, the transmitter is
1999 * enabled (XON) or disabled (XOFF).
2000 */
2001
2002 if (*current_byte == uart->xoff_character) {
2003
2004 uart->tx_stopped_by_driver = 1;
2005 xon_xoff_detected = 1;
2006
2007 } else if (*current_byte == uart->xon_character) {
2008
2009 uart->tx_stopped_by_driver = 0;
2010 xon_xoff_detected = 1;
2011
2012 #if ((CHIPSET != 5) && (CHIPSET != 6))
2013 /*
2014 * Disable sleep mode.
2015 */
2016
2017 WRITE_UART_REGISTER (
2018 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
2019 #endif
2020
2021 /*
2022 * Unmask Tx interrupt.
2023 */
2024
2025 WRITE_UART_REGISTER (
2026 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
2027
2028 } else {
2029
2030 *(uart->rx_in++) = *current_byte;
2031
2032 wrap_around_counter--;
2033 if (!wrap_around_counter) {
2034
2035 uart->rx_in = &(uart->rx_buffer[0]);
2036 wrap_around_counter = uart->buffer_size + 1;
2037 }
2038
2039 bytes_free_in_rx_buffer--;
2040 }
2041
2042 current_byte++;
2043 bytes_read--;
2044 }
2045 } else { /* No Flow Control or HW Flow Control */
2046
2047 /*
2048 * Figure out the most restricting condition.
2049 */
2050
2051 bytes_to_copy =
2052 Min3 (bytes_free_in_rx_buffer, wrap_around_counter, bytes_read);
2053
2054 /*
2055 * Copy characters into the circular Rx buffer.
2056 */
2057
2058 memcpy (uart->rx_in, current_byte, bytes_to_copy);
2059
2060 /*
2061 * Update first the variables associated to blocking conditions:
2062 * if (bytes_read = 0) OR
2063 * (bytes_free_in_rx_buffer = 0) => No more characters to copy.
2064 */
2065
2066 bytes_free_in_rx_buffer -= bytes_to_copy;
2067 bytes_read -= bytes_to_copy;
2068
2069 wrap_around_counter -= bytes_to_copy;
2070 if (!wrap_around_counter)
2071 uart->rx_in = &(uart->rx_buffer[0]);
2072 else
2073 uart->rx_in += bytes_to_copy;
2074
2075 /*
2076 * Check if there are still some characters to copy.
2077 */
2078
2079 if (bytes_read && bytes_free_in_rx_buffer) {
2080
2081 /*
2082 * Update the remaining variables and figure out again the
2083 * most restricting condition. Since (bytes_read = 0) and
2084 * (bytes_free_in_rx_buffer = 0) are blocking conditions, if
2085 * we reach that point it means that the wrap around condition
2086 * has just occurred and it is not needed to manage it again.
2087 */
2088
2089 current_byte += bytes_to_copy;
2090 bytes_to_copy = Min (bytes_read, bytes_free_in_rx_buffer);
2091
2092 /*
2093 * Copy characters into the circular Rx buffer and update
2094 * current pointer.
2095 */
2096
2097 memcpy (uart->rx_in, current_byte, bytes_to_copy);
2098
2099 uart->rx_in += bytes_to_copy;
2100
2101 /*
2102 * bytes_free_in_rx_buffer not updated since not used anymore.
2103 */
2104 bytes_read -= bytes_to_copy;
2105
2106 }
2107 else {
2108 bytes_read = 0;
2109 }
2110 } /* end if (uart->flow_control_mode == fc_xoff) */
2111
2112
2113 /*
2114 * If the high watermark is reached, RTS is activated or XOFF is
2115 * sent according to the flow control mode.
2116 */
2117
2118 bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
2119
2120 if ((uart->flow_control_mode != fc_none) &&
2121 (bytes_in_rx_buffer >= RX_HIGH_WATERMARK (uart->buffer_size))) {
2122
2123 /*
2124 * Check if receipt must be stopped.
2125 */
2126
2127 if (!uart->rx_stopped_by_driver) {
2128
2129 uart->rx_stopped_by_driver = 1;
2130 if (!uart->rx_stopped_by_application)
2131 stop_receiver (uart);
2132 }
2133 }
2134
2135 /*
2136 * If a reading was suspended or if the callback function is installed,
2137 * it is called if one of these conditions is fulfiled:
2138 * - the RX threshold level is reached,
2139 * - a break has been detected,
2140 */
2141
2142 if ((!uart->rd_call_from_hisr_in_progress) &&
2143 (uart->reading_suspended ||
2144 (uart->rd_call_setup == rm_reInstall))) {
2145
2146 if ((bytes_in_rx_buffer >= uart->rx_threshold_level) ||
2147 #if TARGET_HAS_DTR_INPUT
2148 uart->dtr_change_detected[uart->index_hisr] ||
2149 #endif
2150 uart->break_received ||
2151 xon_xoff_detected) {
2152
2153
2154 uart->rd_call_from_hisr_in_progress = 1;
2155 update_reading_callback (uart, 3); /* 3: call from Rx HISR. */
2156
2157 uart->reading_suspended = 0;
2158 uart->break_received = 0;
2159 uart->esc_seq_received = 0;
2160 #if TARGET_HAS_DTR_INPUT
2161 uart->dtr_change_detected[uart->index_hisr] = 0;
2162 #endif
2163 }
2164 }
2165
2166 }
2167
2168
2169 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
2170
2171 /* Mask The Rx and Modem status interrupt */
2172 WRITE_UART_REGISTER (
2173 uart, IER, READ_UART_REGISTER (uart, IER) &
2174 ~(ERBI | EDSSI));
2175
2176 if ((uart->rx_buffer_used_by_rx_hisr) == &(uart->rx_fifo_byte_1[0]))
2177 uart->bytes_in_rx_buffer_1 = 0;
2178 else
2179 uart->bytes_in_rx_buffer_2 = 0;
2180
2181
2182 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
2183
2184 /* Unmask The Rx and Modem status interrupt*/
2185 WRITE_UART_REGISTER (
2186 uart, IER, READ_UART_REGISTER (uart, IER) |
2187 (ERBI | EDSSI));
2188
2189 if(uart->rx_stopped_by_lisr ) {
2190 if (!uart->rx_stopped_by_driver) {
2191
2192 uart->rx_stopped_by_lisr = 0;
2193
2194 /*
2195 * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
2196 */
2197 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
2198
2199
2200 /* UnMask The Rx interrupt */
2201 WRITE_UART_REGISTER (
2202 uart, IER, READ_UART_REGISTER (uart, IER) |
2203 (ERBI | EDSSI));
2204
2205 start_receiver (uart);
2206
2207 }
2208 }
2209
2210 }
2211
2212 /*******************************************************************************
2213 *
2214 * hisr_execute_v24_operations
2215 *
2216 * Purpose : The user's function is called if all conditions to call it are
2217 * fulfiled.
2218 *
2219 * Arguments: In : none
2220 * Out: none
2221 *
2222 * Returns : none
2223 *
2224 ******************************************************************************/
2225
2226 static VOID
2227 hisr_execute_v24_operations (VOID)
2228 {
2229 t_uart *uart;
2230
2231 uart = &uart_parameters;
2232
2233 /*
2234 * If a reading was suspended or if the callback function is installed,
2235 * it is called.
2236 */
2237
2238 if ((!DRIVER_DISABLED (uart)) &&
2239 (!uart->rd_call_from_hisr_in_progress) &&
2240 (uart->reading_suspended || (uart->rd_call_setup == rm_reInstall))) {
2241
2242 uart->rd_call_from_hisr_in_progress = 1;
2243 update_reading_callback (uart, 1); /* 1: call from HISR. */
2244 uart->reading_suspended = 0;
2245 uart->break_received = 0;
2246 uart->esc_seq_received = 0;
2247 }
2248
2249 }
2250
2251 /*******************************************************************************
2252 *
2253 * hisr_execute_tx_operations
2254 *
2255 * Purpose : Writes bytes from the TX buffer to the TX FIFO.
2256 * The user's function is called if all conditions to call it are
2257 * fulfiled.
2258 *
2259 * Arguments: In : none
2260 * Out: none
2261 *
2262 * Returns : none
2263 *
2264 ******************************************************************************/
2265
2266 static VOID
2267 hisr_execute_tx_operations (VOID)
2268 {
2269 SYS_UWORD16 bytes_in_tx_buffer;
2270 SYS_UWORD16 bytes_in_tx_fifo;
2271 SYS_UWORD16 wrap_around_counter;
2272 SYS_UWORD16 bytes_to_write;
2273 t_uart *uart;
2274 int counter;
2275
2276
2277 uart = &uart_parameters;
2278
2279 /*
2280 * A TX interrupt may have occured during the previous TX HISR. This case
2281 * may appear when a HISR having a higher priority has been activated when
2282 * the TX HISR was activated. When the next TX HISR is activated, the TX
2283 * FIFO may not be empty. Nothing is done until a TX interrupt will occur.
2284 * The RX HISR will be activated again and the TX FIFO will be empty.
2285 */
2286
2287 if (READ_UART_REGISTER (uart, LSR) & THRE) {
2288
2289 bytes_in_tx_fifo = 0;
2290
2291 /*
2292 * A request to send a XON/XOFF character may have been done by the
2293 * RX interrupt handler. The byte can be written because we are sure
2294 * that the TX FIFO is not full.
2295 */
2296
2297 if (uart->send_xon_xoff) {
2298
2299 WRITE_UART_REGISTER (uart, THR, uart->xon_xoff_to_send);
2300 uart->send_xon_xoff = 0;
2301 bytes_in_tx_fifo++;
2302 }
2303
2304 if ((!uart->tx_stopped_by_application) &&
2305 (!uart->tx_stopped_by_driver)) {
2306
2307 bytes_in_tx_buffer = get_bytes_in_tx_buffer (uart);
2308 wrap_around_counter =
2309 uart->buffer_size + 1 - (SYS_UWORD16) (uart->tx_out -
2310 &(uart->tx_buffer[0]));
2311
2312 /*
2313 * Figure out the most restricting condition.
2314 */
2315
2316 #if ((CHIPSET == 3) || (CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6))
2317 /*
2318 * Loading of only (FIFO_SIZE - 1) characters in the Tx FIFO to
2319 * avoid the generation of a spurious Tx FIFO almost empty
2320 * interrupt (Ulysse bug report #35).
2321 */
2322
2323 bytes_to_write =
2324 Min3 (bytes_in_tx_buffer, wrap_around_counter,
2325 (FIFO_SIZE - 1 - bytes_in_tx_fifo));
2326 #elif ((CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
2327 /*
2328 * Bug corrected on Calypso rev. A, rev. B, C035, Ulysse C035,
2329 * Calypso Lite & Calypso+.
2330 */
2331
2332 bytes_to_write =
2333 Min3 (bytes_in_tx_buffer, wrap_around_counter,
2334 (FIFO_SIZE - bytes_in_tx_fifo));
2335 #endif
2336
2337 /*
2338 * Write characters into the Tx FIFO.
2339 */
2340
2341 for (counter = 0; counter < bytes_to_write; counter++)
2342 WRITE_UART_REGISTER (uart, THR, *(uart->tx_out++));
2343
2344 /*
2345 * Update the variables associated to blocking conditions:
2346 * if (bytes_in_tx_buffer = 0) OR
2347 * (bytes_in_tx_fifo = FIFO_SIZE) => No more characters to copy.
2348 */
2349
2350 bytes_in_tx_buffer -= bytes_to_write;
2351 bytes_in_tx_fifo += bytes_to_write;
2352
2353 wrap_around_counter -= bytes_to_write;
2354 if (!wrap_around_counter)
2355 uart->tx_out = &(uart->tx_buffer[0]);
2356
2357 /*
2358 * Check if there are still some characters to write.
2359 */
2360
2361 if (bytes_in_tx_buffer &&
2362 #if ((CHIPSET == 3) || (CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6))
2363 (bytes_in_tx_fifo < (FIFO_SIZE - 1))) {
2364 #elif ((CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
2365 (bytes_in_tx_fifo < FIFO_SIZE)) {
2366 #endif
2367
2368 /*
2369 * Figure out again the most restricting condition. Since
2370 * (bytes_in_tx_buffer = 0) and (bytes_in_tx_fifo = FIFO_SIZE)
2371 * are blocking conditions, if we reach that point it means
2372 * that the wrap around condition has just occurred and it is
2373 * not needed to manage it again.
2374 */
2375
2376 #if ((CHIPSET == 3) || (CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6))
2377 bytes_to_write =
2378 Min (bytes_in_tx_buffer,
2379 (FIFO_SIZE - 1 - bytes_in_tx_fifo));
2380 #elif ((CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
2381 bytes_to_write =
2382 Min (bytes_in_tx_buffer,
2383 (FIFO_SIZE - bytes_in_tx_fifo));
2384 #endif
2385
2386 /*
2387 * Write characters into the Tx FIFO and update associated
2388 * variables.
2389 */
2390
2391 for (counter = 0; counter < bytes_to_write; counter++)
2392 WRITE_UART_REGISTER (uart, THR, *(uart->tx_out++));
2393
2394 bytes_in_tx_buffer += bytes_to_write;
2395 bytes_in_tx_fifo += bytes_to_write;
2396 }
2397
2398 /*
2399 * If a writing was suspended or if the callback function is
2400 * installed, it is called if the TX threshold level is reached.
2401 */
2402
2403 if ((!DRIVER_DISABLED (uart)) &&
2404 (!uart->wr_call_from_hisr_in_progress) &&
2405 (bytes_in_tx_buffer <= uart->tx_threshold_level) &&
2406 ((uart->wr_call_setup == rm_reInstall) ||
2407 uart->writing_suspended)) {
2408
2409 uart->writing_suspended = 0;
2410
2411 uart->wr_call_from_hisr_in_progress = 1;
2412 update_writing_callback (uart, 1); /* 1: call from HISR. */
2413 }
2414 } /* end if ((!uart->tx_stopped_by_application) && */
2415 /* (!uart->tx_stopped_by_driver)) */
2416
2417 if (bytes_in_tx_fifo)
2418
2419 /*
2420 * Unmask Tx interrupt.
2421 */
2422
2423 WRITE_UART_REGISTER (
2424 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
2425
2426 else {
2427
2428 if ((!bytes_in_tx_fifo) && (uart->break_to_send))
2429 bytes_in_tx_fifo = send_break (uart);
2430 }
2431
2432 #if ((CHIPSET != 5) && (CHIPSET != 6))
2433 /*
2434 * Re-enable the sleep mode.
2435 */
2436
2437 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
2438 /*
2439 WRITE_UART_REGISTER (
2440 uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
2441
2442 */
2443 #endif
2444 }
2445 }
2446
2447 /*******************************************************************************
2448 *
2449 * read_rx_fifo
2450 *
2451 * Purpose : Reads the RX FIFO. If the driver is enabled bytes are written in
2452 * an array to be analyzed by the RX HISR.
2453 *
2454 * Arguments: In : uart: Pointer on the UART structure.
2455 * Out: none
2456 *
2457 * Returns : none
2458 *
2459 ******************************************************************************/
2460
2461 static void
2462 read_rx_fifo (t_uart *uart)
2463 {
2464
2465 /*
2466 * If the driver is disabled the RX FIFO is read to acknoledge the
2467 * interrupt else bytes received are written into an array which will be
2468 * analyzed from the RX HISR.
2469 */
2470
2471 if (DRIVER_DISABLED (uart))
2472 empty_rx_fifo (uart);
2473
2474 else if (build_rx_fifo_array (uart)) {
2475 (void) NU_Activate_HISR (&(uart->rx_hisr_ctrl_block));
2476 }
2477
2478 }
2479
2480 /*******************************************************************************
2481 *
2482 * check_v24_input_lines
2483 *
2484 * Purpose : Check the V.24 input lines. According to the states of the input
2485 * lines and to the flow control mode selected, the transmitter is
2486 * enabled or disabled. The reading callback function is called if
2487 * it is installed and if all conditions are fulfiled.
2488 *
2489 * Arguments: In : uart: Pointer on the UART structure.
2490 * Out: none
2491 *
2492 * Returns : none
2493 *
2494 ******************************************************************************/
2495
2496 static void
2497 check_v24_input_lines (t_uart *uart)
2498 {
2499 SYS_BOOL v24_input_line_changed;
2500 volatile SYS_UWORD8 modem_status;
2501
2502 modem_status = READ_UART_REGISTER (uart, MSR);
2503 v24_input_line_changed = 0;
2504
2505 if (modem_status & DELTA_CTS) {
2506
2507 v24_input_line_changed = 1;
2508
2509 if (modem_status & MCTS)
2510 uart->rts_level = 0;
2511 else
2512 uart->rts_level = 1;
2513 }
2514
2515 #if (CHIPSET == 12)
2516 else if (modem_status & DELTA_DSR) {
2517 v24_input_line_changed = 1;
2518
2519 if (modem_status & MDSR)
2520 {
2521 uart->dtr_level = 0;
2522 if (uart->flow_control_mode != fc_dtr && uart->baudrate == baudrate_value[FD_BAUD_AUTO])
2523 UAF_SetComPar (UAF_UART_1, FD_BAUD_AUTO, bpc_8, sb_1, pa_none); /* switch back to autobaud */
2524 }
2525 else
2526 uart->dtr_level = 1;
2527
2528 /*
2529 * The reading callback function has to be called. But bytes received before
2530 * the change of state of DTR must be copied into the RX buffer before to
2531 * call it.
2532 */
2533
2534 if (READ_UART_REGISTER (uart, LSR) & DR) { /* If Rx FIFO is not empty */
2535
2536 /*
2537 * The Rx FIFO will be read to fill one of the two buffers and the Rx
2538 * HISR will be activated.
2539 */
2540
2541 uart->index_it = (uart->index_it + 1) & 0x01; /* 0 or 1 */
2542 uart->dtr_change_detected[uart->index_it] = 1;
2543 uart->dtr_level_saved[uart->index_it] = uart->dtr_level;
2544 read_rx_fifo (uart);
2545
2546 } else
2547 v24_input_line_changed = 1;
2548 }
2549 #endif
2550
2551 /*
2552 * When the hardware flow control is selected, if the RS 232 input signal is
2553 * deactivated (low), the transmitter is stopped.
2554 */
2555
2556 if (uart->flow_control_mode == fc_rts) {
2557
2558 if (uart->rts_level) {
2559 uart->tx_stopped_by_driver = 1;
2560 }
2561
2562 else {
2563
2564 uart->tx_stopped_by_driver = 0;
2565 #ifdef EXTHOST_WAKEUP_GPIO
2566 AI_ResetBit(EXTHOST_WAKEUP_GPIO);
2567 #endif
2568
2569 #if ((CHIPSET != 5) && (CHIPSET != 6))
2570 /*
2571 * Disable sleep mode.
2572 */
2573
2574 WRITE_UART_REGISTER (
2575 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
2576 #endif
2577
2578 /*
2579 * Unmask Tx interrupt.
2580 */
2581
2582 WRITE_UART_REGISTER (
2583 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
2584
2585 }
2586 }
2587
2588 if (v24_input_line_changed)
2589 (void) NU_Activate_HISR (&(uart->v24_hisr_ctrl_block));
2590 }
2591
2592 /*******************************************************************************
2593 *
2594 * fill_tx_fifo
2595 *
2596 * Purpose : If the TX buffer is not empty, and if there is no break in
2597 * progress, bytes are written into the TX FIFO until the TX FIFO is
2598 * full or the TX buffer is empty. Else, if there is a break to send
2599 * an all 0s character is written into the TX FIFO and a break is
2600 * declared in progress to avoid to fill the TX FIFO on the next
2601 * interrupt.
2602 * When the TX FIFO is empty and if a break is in progress, the break
2603 * length is programmed: all 0s characters are written into the TX
2604 * FIFO. The number of bytes has been defined previously with the
2605 * UAF_SetLineState function. The break condition is enabled.
2606 * When the TX FIFO and the transmitter shift register (TSR) are both
2607 * empty and if a break is in progress, the break condition is
2608 * disabled.
2609 * When bytes are written from the TX buffer to the TX FIFO, the
2610 * writing callback function is called if it is installed and if all
2611 * conditions are fulfiled.
2612 *
2613 * Arguments: In : uart: Pointer on the UART structure.
2614 * Out: none
2615 *
2616 * Returns : none
2617 *
2618 ******************************************************************************/
2619
2620 static void
2621 fill_tx_fifo (t_uart *uart)
2622 {
2623 #if ((CHIPSET != 5) && (CHIPSET != 6))
2624 /*
2625 * Disable sleep mode.
2626 */
2627
2628 WRITE_UART_REGISTER (
2629 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
2630 #endif
2631
2632 /*
2633 * Mask Tx interrupt.
2634 */
2635
2636 WRITE_UART_REGISTER (
2637 uart, IER, READ_UART_REGISTER (uart, IER) & ~ETBEI);
2638
2639 /*
2640 * If a break is in progress, bytes of the TX buffer are not written into
2641 * the TX FIFO.
2642 */
2643
2644 if (!uart->break_in_progress)
2645 (void) NU_Activate_HISR (&(uart->tx_hisr_ctrl_block));
2646
2647 else {
2648
2649 /*
2650 * The break HISR is activated and the break condition is cleared.
2651 */
2652
2653 WRITE_UART_REGISTER (
2654 uart, LCR, READ_UART_REGISTER (uart, LCR) & ~BREAK_CONTROL);
2655
2656 (void) NU_Activate_HISR (&(uart->break_hisr_ctrl_block));
2657 }
2658 }
2659
2660 /*******************************************************************************
2661 *
2662 * UAF_Init
2663 *
2664 * Purpose : Initializes the UART hardware and installs interrupt handlers.
2665 * The parameters are set to the default values:
2666 * - 19200 baud,
2667 * - 8 bits / character,
2668 * - no parity,
2669 * - 1 stop bit,
2670 * - no flow control.
2671 * All functionalities of the UART driver are disabled.
2672 *
2673 * Arguments: In : uartNo: Used UART.
2674 * Out: none
2675 *
2676 * Returns : FD_OK : Successful operation.
2677 * FD_NOT_SUPPORTED: Wrong UART number.
2678 * FD_INTERNAL_ERR : Internal problem.
2679 *
2680 ******************************************************************************/
2681
2682 T_FDRET
2683 UAF_Init (T_fd_UartId uartNo)
2684 {
2685 t_uart *uart;
2686 volatile SYS_UWORD8 status;
2687
2688 /*
2689 * Check UART number.
2690 * A return is used to simplify the code.
2691 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
2692 * flow control is not supported.
2693 * DCD and DTR are not supported on UART Irda on C & D-Sample.
2694 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
2695 */
2696
2697 if (uartNo != UAF_UART_1)
2698 return (FD_NOT_SUPPORTED);
2699
2700 uart = &uart_parameters;
2701
2702 /*
2703 * Create the 3 HISR actived in the RX/TX and V24 interrupt handlers.
2704 * A return is used to simplify the code if an error occurs.
2705 * All stacks are entirely filled with the pattern 0xFE.
2706 */
2707
2708 memset (&(uart->rx_hisr_stack[0]), 0xFE, RX_HISR_STACK_SIZE);
2709
2710 if (NU_Create_HISR (&(uart->rx_hisr_ctrl_block),
2711 "UAF_Rx",
2712 hisr_execute_rx_operations,
2713 RX_HISR_PRIORITY,
2714 &(uart->rx_hisr_stack[0]),
2715 RX_HISR_STACK_SIZE) != NU_SUCCESS)
2716
2717 return (FD_INTERNAL_ERR);
2718
2719 memset (&(uart->tx_hisr_stack[0]), 0xFE, TX_HISR_STACK_SIZE);
2720
2721 if (NU_Create_HISR (&(uart->tx_hisr_ctrl_block),
2722 "UAF_Tx",
2723 hisr_execute_tx_operations,
2724 TX_HISR_PRIORITY,
2725 &(uart->tx_hisr_stack[0]),
2726 TX_HISR_STACK_SIZE) != NU_SUCCESS)
2727
2728 return (FD_INTERNAL_ERR);
2729
2730 memset (&(uart->v24_hisr_stack[0]), 0xFE, V24_HISR_STACK_SIZE);
2731
2732 if (NU_Create_HISR (&(uart->v24_hisr_ctrl_block),
2733 "UAF_V24",
2734 hisr_execute_v24_operations,
2735 V24_HISR_PRIORITY,
2736 &(uart->v24_hisr_stack[0]),
2737 V24_HISR_STACK_SIZE) != NU_SUCCESS)
2738
2739 return (FD_INTERNAL_ERR);
2740
2741 /*
2742 * Create the HISR used to send a break.
2743 * A return is used to simplify the code if an error occurs.
2744 * The stack is entirely filled with the pattern 0xFE.
2745 */
2746
2747 memset (&(uart->break_hisr_stack[0]), 0xFE, BREAK_HISR_STACK_SIZE);
2748
2749 if (NU_Create_HISR (&(uart->break_hisr_ctrl_block),
2750 "UAF_Brk",
2751 hisr_start_break,
2752 BREAK_HISR_PRIORITY,
2753 &(uart->break_hisr_stack[0]),
2754 BREAK_HISR_STACK_SIZE) != NU_SUCCESS)
2755
2756 return (FD_INTERNAL_ERR);
2757
2758 /*
2759 * Create a timer used in the break HISR.
2760 * A return is used to simplify the code if an error occurs.
2761 */
2762
2763 if (NU_Create_Timer (&(uart->break_timer_ctrl_block),
2764 "Break",
2765 stop_break,
2766 0, /* Parameter supplied to the routine: not used. */
2767 1, /* This parameter is set when the timer is reset. */
2768 0, /* The timer expires once. */
2769 NU_DISABLE_TIMER) != NU_SUCCESS)
2770
2771 return (FD_INTERNAL_ERR);
2772
2773 /*
2774 * Create a timer used in the detection of the escape sequence.
2775 * A return is used to simplify the code if an error occurs.
2776 */
2777
2778 if (NU_Create_Timer (&(uart->guard_period_timer_ctrl_block),
2779 "Esc seq",
2780 analyze_guard_period_timer_expiration,
2781 0, /* Parameter supplied to the routine: not used. */
2782 1, /* This parameter is set when the timer is reset. */
2783 0, /* The timer expires once. */
2784 NU_DISABLE_TIMER) != NU_SUCCESS)
2785
2786 return (FD_INTERNAL_ERR);
2787
2788 /*
2789 * These data are used to send a break.
2790 * A character has: 8 data bits + 1 start bit + 1 stop bit = 10 bits.
2791 */
2792
2793 uart->baudrate = baudrate_value[FD_BAUD_19200];
2794 uart->autobauding = 0;
2795 uart->bits_per_char = 10;
2796
2797 /*
2798 * UART base address.
2799 */
2800
2801 uart->base_address = base_address[uartNo];
2802
2803 /*
2804 * Select the current array used to store received bytes.
2805 */
2806
2807 uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_2[0]);
2808 uart->rx_buffer_used_by_rx_hisr = &(uart->rx_fifo_byte_2[0]);
2809
2810 /*
2811 * RX and TX buffers.
2812 */
2813
2814 uart->buffer_size = FD_MAX_BUFFER_SIZE;
2815 uart->rx_threshold_level = 1;
2816 uart->tx_threshold_level = 0;
2817 uart->rx_in = &(uart->rx_buffer[0]);
2818 uart->rx_out = &(uart->rx_buffer[0]);
2819 uart->tx_in = &(uart->tx_buffer[0]);
2820 uart->tx_out = &(uart->tx_buffer[0]);
2821
2822 /*
2823 * Escape sequence.
2824 */
2825
2826 uart->esc_seq_modified = 0;
2827 uart->esc_seq_detection_state = INITIALIZATION;
2828 uart->esc_seq_character = DEFAULT_ESC_SEQ_CHARACTER;
2829 uart->guard_period = CONVERT_TIME_IN_TDMA (
2830 DEFAULT_GUARD_PERIOD);
2831
2832 /*
2833 * Flow control.
2834 */
2835
2836 uart->flow_control_mode = fc_none;
2837 uart->send_xon_xoff = 0;
2838 uart->rx_stopped_by_application = 1;
2839 uart->rx_stopped_by_driver = 0;
2840 uart->rx_stopped_by_lisr = 0;
2841 uart->tx_stopped_by_application = 1;
2842 uart->tx_stopped_by_driver = 0;
2843
2844 /*
2845 * Break.
2846 */
2847
2848 uart->break_received = 0;
2849 uart->break_to_send = 0;
2850 uart->break_in_progress = 0;
2851
2852 /*
2853 * Callback (UAF_ReadData and UAF_WriteData).
2854 */
2855
2856 uart->esc_seq_received = 0;
2857
2858 uart->reading_suspended = 0;
2859 uart->writing_suspended = 0;
2860 uart->rd_call_from_hisr_in_progress = 0;
2861 uart->wr_call_from_hisr_in_progress = 0;
2862 uart->rd_call_setup = rm_noInstall;
2863 uart->wr_call_setup = rm_noInstall;
2864
2865 /*
2866 * State defined in UAF_GetLineState.
2867 */
2868
2869 uart->state_1 = 0;
2870 uart->state_2 = 0;
2871 uart->state = &(uart->state_1);
2872
2873 /*
2874 * Errors counters.
2875 */
2876
2877 uart->framing_error = 0;
2878 uart->parity_error = 0;
2879 uart->overrun_error = 0;
2880 uart->spurious_interrupts = 0;
2881
2882 uart->max_rx_fifo_level = 0;
2883
2884 /*
2885 * Mask all interrupts causes and disable sleep mode and low power mode.
2886 */
2887
2888 WRITE_UART_REGISTER (uart, IER, 0x00);
2889
2890 /*
2891 * Reset UART mode configuration.
2892 */
2893
2894 WRITE_UART_REGISTER (uart, MDR1, RESET_DEFAULT_STATE |
2895 IR_SLEEP_DISABLED |
2896 SIR_TX_WITHOUT_ACREG2 |
2897 FRAME_LENGTH_METHOD);
2898
2899 /*
2900 * FIFO configuration.
2901 * EFR[4] = 1 to allow to program FCR[5:4] and MCR[7:5].
2902 */
2903
2904 WRITE_UART_REGISTER (uart, LCR, 0xBF);
2905 SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);
2906
2907 /*
2908 * Select the word length, the number of stop bits , the parity and set
2909 * LCR[7] (DLAB) to allow to program FCR, DLL and DLM.
2910 */
2911
2912 WRITE_UART_REGISTER (uart, LCR, WLS_8 | DLAB);
2913
2914 /*
2915 * Program the trigger levels.
2916 * MCR[6] must be set to 1.
2917 */
2918
2919 SET_BIT (uart, MCR, TCR_TLR_BIT);
2920 WRITE_UART_REGISTER (uart, TCR, 0x0F);
2921 WRITE_UART_REGISTER (uart, TLR, RX_FIFO_TRIGGER_LEVEL);
2922 RESET_BIT (uart, MCR, TCR_TLR_BIT);
2923
2924 /*
2925 * Force the generation of THR_IT on TX FIFO empty: SCR[3] = 1.
2926 */
2927
2928 WRITE_UART_REGISTER (
2929 uart, SCR, READ_UART_REGISTER (uart, SCR) | TX_EMPTY_CTL_IT);
2930
2931 /*
2932 * Program the FIFO control register. Bit 0 must be set when other FCR bits
2933 * are written to or they are not programmed.
2934 * FCR is a write-only register. It will not be modified.
2935 */
2936
2937 WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE |
2938 RX_FIFO_RESET | /* self cleared */
2939 TX_FIFO_RESET); /* self cleared */
2940
2941 /*
2942 * Program the baud generator.
2943 */
2944
2945 WRITE_UART_REGISTER (uart, DLL, dll[FD_BAUD_19200]);
2946 WRITE_UART_REGISTER (uart, DLM, dlh[FD_BAUD_19200]);
2947
2948 /*
2949 * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
2950 */
2951
2952 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
2953
2954 /*
2955 * Select UART mode.
2956 */
2957
2958 WRITE_UART_REGISTER (uart, MDR1, UART_MODE |
2959 IR_SLEEP_DISABLED |
2960 SIR_TX_WITHOUT_ACREG2 |
2961 FRAME_LENGTH_METHOD);
2962
2963 /*
2964 * Read the state of RTS (RTS on RS232, CTS on chipset).
2965 */
2966
2967 status = READ_UART_REGISTER (uart, MSR);
2968
2969 if (status & MCTS)
2970 uart->rts_level = 0;
2971 else
2972 uart->rts_level = 1;
2973
2974 #if TARGET_HAS_DTR_INPUT
2975 /*
2976 * On C & D-Sample, 2 I/O are used to control DCD and DTR on UART Modem.
2977 * DCD: I/O 2 (output)
2978 * DTR: I/O 3 (input)
2979 */
2980
2981 #define EXTENDED_MCU_REG (0xFFFEF006) /* Extended MCU register */
2982 #define ASIC_CONFIG_REG (0xFFFEF008) /* Asic Configuration register */
2983
2984 #define IO_DTR (10) /* I/O 3; bit 10 of Asic Configuration register */
2985 #define IO_DCD ( 6) /* I/O 2; bit 6 of Extended MCU register */
2986
2987 /*
2988 * Select I/O for DCD and configure it as output.
2989 * DCD should start HIGH (not asserted).
2990 */
2991
2992 *((volatile SYS_UWORD16 *) EXTENDED_MCU_REG) &= ~(1 << IO_DCD);
2993 AI_ConfigBitAsOutput (ARMIO_DCD);
2994 AI_SetBit (ARMIO_DCD);
2995
2996 /*
2997 * Select I/O for DTR and configure it as input.
2998 * An interrupt is used to detect a change of state of DTR. Falling edge
2999 * or rising edge is selected according to the state of DTR.
3000 */
3001
3002 *((volatile SYS_UWORD16 *) ASIC_CONFIG_REG) &= ~(1 << IO_DTR);
3003 AI_ConfigBitAsInput (ARMIO_DTR);
3004 uart->dtr_level = AI_ReadBit (ARMIO_DTR);
3005
3006 if (uart->dtr_level)
3007 AI_SelectIOForIT (ARMIO_DTR, ARMIO_FALLING_EDGE);
3008 else
3009 AI_SelectIOForIT (ARMIO_DTR, ARMIO_RISING_EDGE);
3010
3011 AI_UnmaskIT (ARMIO_MASKIT_GPIO);
3012
3013 /*
3014 * Reset the 2 indexes of the circular buffer of 2 elements.
3015 * The circular buffer does not need to be initialized.
3016 */
3017
3018 uart->index_it = 0;
3019 uart->index_hisr = 0;
3020 #elif (CHIPSET == 12)
3021 /*
3022 * DCD and DTR are directly handled by Calypso+.
3023 * Force DCD pin to HIGH
3024 */
3025
3026 WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) & ~MDCD);
3027
3028 /*
3029 * Read the state of DTR (DTR on RS232, DSR on chipset).
3030 */
3031
3032 status = READ_UART_REGISTER (uart, MSR);
3033
3034 if (status & MDSR)
3035 uart->dtr_level = 0;
3036 else
3037 uart->dtr_level = 1;
3038
3039 /*
3040 * Reset the 2 indexes of the circular buffer of 2 elements.
3041 * The circular buffer does not need to be initialized.
3042 */
3043
3044 uart->index_it = 0;
3045 uart->index_hisr = 0;
3046 #endif /* BOARD == 8, 9, 40 or 41, CHIPSET == 12 */
3047
3048 /*
3049 * Unmask RX interrupt and the modem status interrupt.
3050 */
3051
3052 WRITE_UART_REGISTER (uart, IER, ERBI | EDSSI);
3053
3054 #if (CHIPSET == 12)
3055 /*
3056 * Unmask DSR interrupt in order to detect a change of state of DTR.
3057 */
3058
3059 ENABLE_DSR_INTERRUPT (uart);
3060 #endif
3061
3062 return (FD_OK);
3063 }
3064
3065 /*******************************************************************************
3066 *
3067 * UAF_Enable
3068 *
3069 * Purpose : The functionalities of the UART driver are disabled or enabled.
3070 * In the deactivated state, all information about the communication
3071 * parameters should be stored and recalled if the driver is again
3072 * enabled. When the driver is enabled the RX and TX buffers are
3073 * cleared.
3074 *
3075 * Arguments: In : uartNo: Used UART.
3076 * : enable: 1: enable the driver
3077 * 0: disable the driver
3078 * Out: none
3079 *
3080 * Returns : FD_OK : Successful operation.
3081 * FD_NOT_SUPPORTED: Wrong UART number.
3082 * FD_INTERNAL_ERR : Internal problem with the hardware.
3083 *
3084 ******************************************************************************/
3085
3086 T_FDRET
3087 UAF_Enable (T_fd_UartId uartNo,
3088 SYS_BOOL enable)
3089 {
3090 t_uart *uart;
3091
3092 /*
3093 * Check UART number.
3094 * A return is used to simplify the code.
3095 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3096 * flow control is not supported.
3097 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3098 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3099 */
3100
3101 if (uartNo != UAF_UART_1)
3102 return (FD_NOT_SUPPORTED);
3103
3104 /*
3105 * There is no case where FD_INTERNAL_ERR may be returned.
3106 */
3107
3108 uart = &uart_parameters;
3109
3110 if (enable) {
3111
3112 uart->rx_stopped_by_driver = 0;
3113
3114 ENABLE_DRIVER (uart);
3115 start_receiver (uart);
3116
3117 } else {
3118
3119 DISABLE_DRIVER (uart);
3120 stop_receiver (uart);
3121
3122 uart->tx_in = &(uart->tx_buffer[0]);
3123 uart->rx_in = &(uart->rx_buffer[0]);
3124 uart->tx_out = uart->tx_in;
3125 uart->rx_out = uart->rx_in;
3126 }
3127
3128 return (FD_OK);
3129 }
3130
3131 /*******************************************************************************
3132 *
3133 * UAF_SetComPar
3134 *
3135 * Purpose : Sets up the communication parameters: baud rate, bits per
3136 * character, number of stop bits, parity.
3137 *
3138 * Arguments: In : uartNo : Used UART.
3139 * baudrate: Used baud rate.
3140 * bpc : Used bits per character.
3141 * sb : Used stop bits.
3142 * parity : Used parity.
3143 * Out: none
3144 *
3145 * Returns : FD_OK : Successful operation.
3146 * FD_NOT_SUPPORTED: The specified parameters don't fit to the
3147 * capabilities of the UART or wrong UART number.
3148 * FD_INTERNAL_ERR : Internal problem with the hardware.
3149 *
3150 ******************************************************************************/
3151
3152 T_FDRET
3153 UAF_SetComPar (T_fd_UartId uartNo,
3154 T_baudrate baudrate,
3155 T_bitsPerCharacter bpc,
3156 T_stopBits sb,
3157 T_parity parity)
3158 {
3159 t_uart *uart;
3160 volatile SYS_UWORD8 mcr_value;
3161 volatile SYS_UWORD8 status;
3162
3163 /*
3164 * Check UART number.
3165 * A return is used to simplify the code.
3166 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3167 * flow control is not supported.
3168 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3169 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3170 */
3171
3172 if (uartNo != UAF_UART_1)
3173 return (FD_NOT_SUPPORTED);
3174
3175 /*
3176 * There is no case where FD_INTERNAL_ERR may be returned.
3177 * pa_space is not supported. Some baudrates are not supported too.
3178 * A return is used to simplify the code.
3179 */
3180
3181 if ((!baudrate_value[baudrate]) ||
3182 (parity == pa_space))
3183
3184 return (FD_NOT_SUPPORTED);
3185
3186 uart = &uart_parameters;
3187
3188 /*
3189 * Mask all interrupts causes and disable sleep mode and low power mode.
3190 */
3191
3192 WRITE_UART_REGISTER (uart, IER, 0x00);
3193
3194 #if TARGET_HAS_DTR_INPUT
3195 AI_MaskIT (ARMIO_MASKIT_GPIO);
3196 #elif (CHIPSET == 12)
3197 DISABLE_DSR_INTERRUPT (uart);
3198 #endif
3199
3200 /*
3201 * Reset UART mode configuration.
3202 */
3203
3204 WRITE_UART_REGISTER (uart, MDR1, RESET_DEFAULT_STATE |
3205 IR_SLEEP_DISABLED |
3206 SIR_TX_WITHOUT_ACREG2 |
3207 FRAME_LENGTH_METHOD);
3208
3209 /*
3210 * FIFO configuration.
3211 * EFR[4] = 1 to allow to program FCR[5:4] and MCR[7:5].
3212 */
3213
3214 WRITE_UART_REGISTER (uart, LCR, 0xBF);
3215 SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);
3216
3217 /*
3218 * Select the word length, the number of stop bits , the parity and set
3219 * LCR[7] (DLAB) to allow to program FCR, DLL and DLM.
3220 */
3221
3222 uart->baudrate = baudrate_value[baudrate];
3223 uart->autobauding = (baudrate == FD_BAUD_AUTO); /* if autobauding enable trigger */
3224 uart->bits_per_char = 1; /* Start bit. */
3225 mcr_value = DLAB;
3226
3227 if (bpc == bpc_7) {
3228
3229 mcr_value |= WLS_7;
3230 uart->bits_per_char += 7;
3231
3232 } else {
3233
3234 mcr_value |= WLS_8;
3235 uart->bits_per_char += 8;
3236 }
3237
3238 if (sb == sb_2) {
3239
3240 mcr_value |= STB;
3241 uart->bits_per_char += 2;
3242
3243 } else
3244 uart->bits_per_char += 1;
3245
3246 switch (parity) {
3247
3248 case pa_even:
3249
3250 mcr_value |= (PEN | EPS);
3251 uart->bits_per_char += 1;
3252
3253 break;
3254
3255 case pa_odd:
3256
3257 mcr_value |= PEN;
3258 uart->bits_per_char += 1;
3259
3260 break;
3261
3262 default:
3263
3264 /*
3265 * There is nothing to do.
3266 */
3267
3268 break;
3269 }
3270
3271 WRITE_UART_REGISTER (uart, LCR, mcr_value);
3272
3273 /*
3274 * Program the trigger levels.
3275 * MCR[6] must be set to 1.
3276 */
3277
3278 SET_BIT (uart, MCR, TCR_TLR_BIT);
3279 WRITE_UART_REGISTER (uart, TCR, 0x0F);
3280 WRITE_UART_REGISTER (uart, TLR, RX_FIFO_TRIGGER_LEVEL);
3281 RESET_BIT (uart, MCR, TCR_TLR_BIT);
3282
3283 /*
3284 * Force the generation of THR_IT on TX FIFO empty: SCR[3] = 1.
3285 */
3286
3287 WRITE_UART_REGISTER (
3288 uart, SCR, READ_UART_REGISTER (uart, SCR) | TX_EMPTY_CTL_IT);
3289
3290 /*
3291 * Program the FIFO control register. Bit 0 must be set when other FCR bits
3292 * are written to or they are not programmed.
3293 * FCR is a write-only register. It will not be modified.
3294 */
3295
3296 WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE |
3297 RX_FIFO_RESET | /* self cleared */
3298 TX_FIFO_RESET); /* self cleared */
3299
3300 /*
3301 * Program the baud generator.
3302 */
3303
3304 WRITE_UART_REGISTER (uart, DLL, dll[baudrate]);
3305 WRITE_UART_REGISTER (uart, DLM, dlh[baudrate]);
3306
3307 /*
3308 * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
3309 */
3310
3311 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
3312
3313 /*
3314 * Select UART mode.
3315 */
3316
3317 WRITE_UART_REGISTER (uart, MDR1, ((baudrate==FD_BAUD_AUTO)?
3318 UART_MODE_AUTOBAUDING:
3319 UART_MODE) |
3320 IR_SLEEP_DISABLED |
3321 SIR_TX_WITHOUT_ACREG2 |
3322 FRAME_LENGTH_METHOD);
3323
3324 /*
3325 * Read the state of RTS (RTS on RS232, CTS on chipset).
3326 */
3327
3328 status = READ_UART_REGISTER (uart, MSR);
3329
3330 if (status & MCTS)
3331 uart->rts_level = 0;
3332 else
3333 uart->rts_level = 1;
3334
3335 #if TARGET_HAS_DTR_INPUT
3336 /*
3337 * Read the state of DTR and select the edge.
3338 */
3339
3340 uart->dtr_level = AI_ReadBit (ARMIO_DTR);
3341
3342 if (uart->dtr_level)
3343 AI_SelectIOForIT (ARMIO_DTR, ARMIO_FALLING_EDGE);
3344 else
3345 AI_SelectIOForIT (ARMIO_DTR, ARMIO_RISING_EDGE);
3346
3347 AI_UnmaskIT (ARMIO_MASKIT_GPIO);
3348 #elif (CHIPSET == 12)
3349 /*
3350 * Read the state of DTR - No need to reload MSR register since its value
3351 * is still stored in the "status" local variable.
3352 */
3353
3354 if (status & MDSR)
3355 uart->dtr_level = 0;
3356 else
3357 uart->dtr_level = 1;
3358 #endif
3359
3360 #if ((CHIPSET == 5) || (CHIPSET == 6))
3361 /*
3362 * Unmask RX and TX interrupts and the modem status interrupt.
3363 */
3364
3365 WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI);
3366 #elif (CHIPSET == 12)
3367 /*
3368 * Unmask RX and TX interrupts and the modem status interrupt...
3369 */
3370
3371 WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI);
3372
3373 /*
3374 * ... Then, unmask DSR interrupt...
3375 */
3376
3377 ENABLE_DSR_INTERRUPT (uart);
3378
3379 /*
3380 * ... And finally allow sleep mode.
3381 */
3382
3383 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
3384 /*
3385 WRITE_UART_REGISTER (uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
3386 */
3387 #else
3388 /*
3389 * Unmask RX and TX interrupts and the modem status interrupt
3390 * and allow sleep mode.
3391 */
3392 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
3393
3394 /* WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI | IER_SLEEP);*/
3395
3396 WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI);
3397 #endif
3398
3399
3400 return (FD_OK);
3401 }
3402
3403 /*******************************************************************************
3404 *
3405 * UAF_SetBuffer
3406 *
3407 * Purpose : Sets up the size of the circular buffers to be used in the UART
3408 * driver. This function may be called only if the UART is disabled
3409 * with UAF_Enable.
3410 *
3411 * Arguments: In : uartNo : Used UART.
3412 * bufSize : Specifies the size of the circular buffer.
3413 * rxThreshold: Amount of received bytes that leads to a call
3414 * to suspended read-out function which is passed
3415 * to the function UAF_ReadData.
3416 * txThreshold: Amount of bytes in the TX buffer to call the
3417 * suspended write-in function which is passed to
3418 * the function UAF_WriteData
3419 * Out: none
3420 *
3421 * Returns : FD_OK : Successful operation.
3422 * FD_NOT_SUPPORTED: bufSize exceeds the maximal possible
3423 * capabilities of the driver or the threshold
3424 * values don't correspond to the bufSize or
3425 * wrong UART number.
3426 * FD_INTERNAL_ERR : Internal problem with the hardware or the
3427 * function has been called while the UART is
3428 * enabled.
3429 *
3430 ******************************************************************************/
3431
3432 T_FDRET
3433 UAF_SetBuffer (T_fd_UartId uartNo,
3434 SYS_UWORD16 bufSize,
3435 SYS_UWORD16 rxThreshold,
3436 SYS_UWORD16 txThreshold)
3437 {
3438 T_FDRET result;
3439 t_uart *uart;
3440
3441 /*
3442 * Check UART number.
3443 * A return is used to simplify the code.
3444 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3445 * flow control is not supported.
3446 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3447 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3448 */
3449
3450 if (uartNo != UAF_UART_1)
3451 return (FD_NOT_SUPPORTED);
3452
3453 if ((bufSize > FD_MAX_BUFFER_SIZE) ||
3454 (rxThreshold > FD_MAX_BUFFER_SIZE) ||
3455 (txThreshold > FD_MAX_BUFFER_SIZE))
3456
3457 result = FD_NOT_SUPPORTED;
3458
3459 else {
3460
3461 uart = &uart_parameters;
3462
3463 if (!DRIVER_DISABLED (uart))
3464 result = FD_INTERNAL_ERR;
3465
3466 else if (RX_HIGH_WATERMARK (bufSize) < RX_LOW_WATERMARK (bufSize))
3467 result = FD_NOT_SUPPORTED;
3468
3469 else {
3470
3471 uart->buffer_size = bufSize;
3472 uart->rx_threshold_level = rxThreshold;
3473 uart->tx_threshold_level = txThreshold;
3474
3475 result = FD_OK;
3476 }
3477 }
3478
3479 return (result);
3480 }
3481
3482 /*******************************************************************************
3483 *
3484 * UAF_SetFlowCtrl
3485 *
3486 * Purpose : Changes the flow control mode of the UART driver.
3487 * If a flow control is activated, DTR is activated or XOFF is sent
3488 * if the RX buffer is not able to store the received characters else
3489 * DTR is deactivated or XON is sent.
3490 *
3491 * Arguments: In : uartNo: Used UART.
3492 * fcMode: flow control mode (none, DTR/DSR, RTS/CTS, XON/XOFF).
3493 * XON : ASCII code of the XON character.
3494 * XOFF : ASCII code of the XOFF character.
3495 * Out: none
3496 *
3497 * Returns : FD_OK : Successful operation.
3498 * FD_NOT_SUPPORTED: The flow control mode is not supported or wrong
3499 * UART number.
3500 * FD_INTERNAL_ERR : Internal problem with the hardware.
3501 *
3502 ******************************************************************************/
3503
3504 T_FDRET
3505 UAF_SetFlowCtrl (T_fd_UartId uartNo,
3506 T_flowCtrlMode fcMode,
3507 SYS_UWORD8 XON,
3508 SYS_UWORD8 XOFF)
3509 {
3510 T_FDRET result;
3511 t_uart *uart;
3512
3513 /*
3514 * Check UART number.
3515 * A return is used to simplify the code.
3516 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3517 * flow control is not supported.
3518 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3519 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3520 */
3521
3522 if (uartNo != UAF_UART_1)
3523 return (FD_NOT_SUPPORTED);
3524
3525 /*
3526 * There is no case where FD_INTERNAL_ERR may be returned.
3527 * The DTR/DSR protocol is not supported.
3528 */
3529
3530 if (fcMode == fc_dtr)
3531 result = FD_NOT_SUPPORTED;
3532
3533 else {
3534
3535 uart = &uart_parameters;
3536
3537 uart->tx_stopped_by_driver = 0;
3538
3539
3540 uart->xon_character = XON;
3541 uart->xoff_character = XOFF;
3542 uart->flow_control_mode = fcMode;
3543
3544 #if ((CHIPSET != 5) && (CHIPSET != 6))
3545 /*
3546 * Disable sleep mode.
3547 */
3548
3549 WRITE_UART_REGISTER (
3550 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
3551 #endif
3552
3553 WRITE_UART_REGISTER (
3554 uart, MCR, READ_UART_REGISTER (uart, MCR) | MRTS);
3555
3556 #if ((CHIPSET != 5) && (CHIPSET != 6))
3557 /*
3558 * Re-enable sleep mode.
3559 */
3560 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
3561 /*
3562 WRITE_UART_REGISTER (
3563 uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
3564 */
3565 #endif
3566
3567 if (fcMode == fc_rts) {
3568 #if 1 // Dmitriy: enable hardware assisted CTS
3569 volatile SYS_UWORD8 oldValue;
3570
3571 oldValue = READ_UART_REGISTER (uart, LCR);
3572
3573 // LCR value to allow acces to EFR
3574
3575 WRITE_UART_REGISTER (uart, LCR, 0xBF);
3576
3577 // enable hardware assisted CTS
3578
3579 SET_BIT (uart, EFR, AUTO_CTS_BIT);
3580
3581 WRITE_UART_REGISTER (uart, LCR, oldValue);
3582 #endif
3583 if (uart->rts_level)
3584 uart->tx_stopped_by_driver = 1;
3585 }
3586
3587 /*
3588 * If the high watermark is reached, RTS is activated or XOFF is sent
3589 * according to the flow control mode. Else, RTS is deactivated or XON
3590 * is sent.
3591 */
3592
3593 if (fcMode != fc_none) {
3594
3595 if (get_bytes_in_rx_buffer (uart) >= RX_HIGH_WATERMARK (
3596 uart->buffer_size)) {
3597
3598 uart->rx_stopped_by_driver = 1;
3599 stop_receiver (uart);
3600
3601 } else if (!DRIVER_DISABLED (uart)) {
3602
3603 uart->rx_stopped_by_driver = 0;
3604 start_receiver (uart);
3605 }
3606
3607 } else {
3608
3609 uart->rx_stopped_by_driver = 0;
3610 uart->tx_stopped_by_driver = 0;
3611 }
3612
3613 result = FD_OK;
3614 }
3615
3616 return (result);
3617 }
3618
3619 /*******************************************************************************
3620 *
3621 * UAF_SetEscape
3622 *
3623 * Purpose : To return to the command mode at the ACI while a data connection
3624 * is established, an escape sequence has to be detected.
3625 * To distinguish between user data and the escape sequence a
3626 * defined guard period is necessary before and after this sequence.
3627 *
3628 * Arguments: In: uartNo : Used UART.
3629 * escChar : ASCII character which could appear three times
3630 * as an escape sequence.
3631 * guardPeriod: Denotes the minimal duration of the rest before
3632 * the first and after the last character of the
3633 * escape sequence, and the maximal receiving
3634 * duration of the whole escape string. This value
3635 * is expressed in ms.
3636 * Out: none
3637 *
3638 * Returns : FD_OK : Successful operation.
3639 * FD_NOT_SUPPORTED: Wrong UART number.
3640 * FD_INTERNAL_ERR : Internal problem with the hardware.
3641 *
3642 ******************************************************************************/
3643
3644 T_FDRET
3645 UAF_SetEscape (T_fd_UartId uartNo,
3646 SYS_UWORD8 escChar,
3647 SYS_UWORD16 guardPeriod)
3648 {
3649 t_uart *uart;
3650
3651 /*
3652 * Check UART number.
3653 * A return is used to simplify the code.
3654 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3655 * flow control is not supported.
3656 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3657 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3658 */
3659
3660 if (uartNo != UAF_UART_1)
3661 return (FD_NOT_SUPPORTED);
3662
3663 /*
3664 * There is no case where FD_INTERNAL_ERR may be returned.
3665 */
3666
3667 uart = &uart_parameters;
3668
3669 uart->esc_seq_modified = 1;
3670 uart->esc_seq_character = escChar;
3671 uart->guard_period = CONVERT_TIME_IN_TDMA ((UNSIGNED) guardPeriod);
3672 uart->esc_seq_modified = 0; /* Set to 0 by the RX interrupt handler. */
3673
3674 return (FD_OK);
3675 }
3676
3677 /*******************************************************************************
3678 *
3679 * UAF_InpAvail
3680 *
3681 * Purpose : Returns the number of characters available in the RX buffer of the
3682 * driver. If the driver is disabled the function returns 0.
3683 *
3684 * Arguments: In : uartNo: Used UART.
3685 * Out: none
3686 *
3687 * Returns : >= 0 : The returned value is the amount of data in the
3688 * RX buffer.
3689 * FD_NOT_SUPPORTED: Wrong UART number.
3690 * FD_NOT_READY : The function is called while the callback of the
3691 * readOutFunc function is activated and still not
3692 * terminated.
3693 * FD_INTERNAL_ERR : Internal problem with the hardware.
3694 *
3695 ******************************************************************************/
3696
3697 T_FDRET
3698 UAF_InpAvail (T_fd_UartId uartNo)
3699 {
3700 T_FDRET result;
3701 t_uart *uart;
3702 SYS_UWORD16 bytes_read;
3703 SYS_UWORD16 bytes_in_rx_buffer;
3704
3705 /*
3706 * Check UART number.
3707 * A return is used to simplify the code.
3708 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3709 * flow control is not supported.
3710 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3711 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3712 */
3713
3714 if (uartNo != UAF_UART_1)
3715 return (FD_NOT_SUPPORTED);
3716
3717 /*
3718 * There is no case where FD_INTERNAL_ERR may be returned.
3719 */
3720
3721 uart = &uart_parameters;
3722
3723 if (uart->rd_call_setup == rm_notDefined)
3724 result = FD_NOT_READY;
3725
3726 else if (DRIVER_DISABLED (uart))
3727 result = 0;
3728
3729 else {
3730
3731 bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
3732
3733 /*
3734 * Update reading pointer of the RX buffer if a callback from LISR
3735 * has been done.
3736 */
3737
3738 if (uart->rd_call_from_hisr_in_progress) {
3739
3740 bytes_read = uart->rd_size_before_call[0] -
3741 uart->rd_size_after_call[0] +
3742 uart->rd_size_before_call[1] -
3743 uart->rd_size_after_call[1];
3744
3745 uart->rx_out += bytes_read;
3746
3747 if (uart->rx_out >= &(uart->rx_buffer[0]) + uart->buffer_size + 1)
3748 uart->rx_out = uart->rx_out - uart->buffer_size - 1;
3749
3750 /*
3751 * Check if the low watermark is reached to enable the receiver.
3752 */
3753
3754 bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
3755
3756 if ((uart->flow_control_mode != fc_none) &&
3757 (bytes_in_rx_buffer <= RX_LOW_WATERMARK (uart->buffer_size))) {
3758
3759 if ((!uart->rx_stopped_by_application) &&
3760 uart->rx_stopped_by_driver)
3761 start_receiver (uart);
3762
3763 uart->rx_stopped_by_driver = 0;
3764 }
3765
3766 uart->rd_call_from_hisr_in_progress = 0;
3767 }
3768
3769 result = (T_FDRET) bytes_in_rx_buffer;
3770 }
3771
3772 return (result);
3773 }
3774
3775 /*******************************************************************************
3776 *
3777 * UAF_OutpAvail
3778 *
3779 * Purpose : Returns the number of free characters in TX buffer of the driver.
3780 * If the driver is disabled the function returns 0.
3781 *
3782 * Arguments: In : uartNo: Used UART.
3783 * Out: none
3784 *
3785 * Returns : >= 0 : The returned value is the amount of data in the
3786 * TX buffer.
3787 * FD_NOT_SUPPORTED: Wrong UART number.
3788 * FD_NOT_READY : The function is called while the callback of the
3789 * writeInFunc function is activated and still not
3790 * terminated.
3791 * FD_INTERNAL_ERR : Internal problem with the hardware.
3792 *
3793 ******************************************************************************/
3794
3795 T_FDRET
3796 UAF_OutpAvail (T_fd_UartId uartNo)
3797 {
3798 T_FDRET result;
3799 t_uart *uart;
3800 SYS_UWORD16 bytes_written;
3801
3802 /*
3803 * Check UART number.
3804 * A return is used to simplify the code.
3805 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3806 * flow control is not supported.
3807 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3808 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3809 */
3810
3811 if (uartNo != UAF_UART_1)
3812 return (FD_NOT_SUPPORTED);
3813
3814 /*
3815 * There is no case where FD_INTERNAL_ERR may be returned.
3816 */
3817
3818 uart = &uart_parameters;
3819
3820 if (uart->wr_call_setup == rm_notDefined)
3821 result = FD_NOT_READY;
3822
3823 else if (DRIVER_DISABLED (uart))
3824 result = 0;
3825
3826 else {
3827
3828 /*
3829 * Update reading pointer of the TX buffer if a callback from LISR
3830 * has been done.
3831 */
3832
3833 if (uart->wr_call_from_hisr_in_progress) {
3834
3835 bytes_written = uart->wr_size_before_call[0] -
3836 uart->wr_size_after_call[0] +
3837 uart->wr_size_before_call[1] -
3838 uart->wr_size_after_call[1];
3839
3840 uart->tx_in += bytes_written;
3841
3842 if (uart->tx_in >= &(uart->tx_buffer[0]) + uart->buffer_size + 1)
3843 uart->tx_in = uart->tx_in - uart->buffer_size - 1;
3844
3845 uart->wr_call_from_hisr_in_progress = 0;
3846
3847 /*
3848 * if the TX FIFO is empty, unmask TX empty interrupt.
3849 */
3850
3851 if (!uart->tx_stopped_by_driver &&
3852 (READ_UART_REGISTER (uart, LSR) & THRE))
3853 {
3854 #if ((CHIPSET != 5) && (CHIPSET != 6))
3855 /*
3856 * Disable sleep mode.
3857 */
3858
3859 WRITE_UART_REGISTER (
3860 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
3861 #endif
3862
3863 /*
3864 * Unmask Tx interrupt.
3865 */
3866
3867 WRITE_UART_REGISTER (
3868 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
3869 }
3870 }
3871
3872 result = (T_FDRET) (uart->buffer_size - get_bytes_in_tx_buffer (uart));
3873 }
3874
3875 return (result);
3876 }
3877
3878 /*******************************************************************************
3879 *
3880 * UAF_EnterSleep
3881 *
3882 * Purpose : Checks if UART is ready to enter Deep Sleep. If ready, enables
3883 * wake-up interrupt.
3884 *
3885 * Arguments: In : uartNo: Used UART.
3886 * Out: none
3887 *
3888 * Returns : 0 : Deep Sleep is not possible.
3889 * >= 1 : Deep Sleep is possible.
3890 * FD_NOT_SUPPORTED: Wrong UART number.
3891 *
3892 * Warning: Parameters are not verified.
3893 *
3894 ******************************************************************************/
3895
3896 T_FDRET
3897 UAF_EnterSleep (T_fd_UartId uartNo)
3898 {
3899 t_uart *uart;
3900 SYS_BOOL deep_sleep;
3901 volatile SYS_UWORD8 status;
3902
3903 /*
3904 * Check UART number.
3905 * A return is used to simplify the code.
3906 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3907 * flow control is not supported.
3908 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3909 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3910 */
3911
3912 if (uartNo != UAF_UART_1)
3913 return (FD_NOT_SUPPORTED);
3914
3915 uart = &uart_parameters;
3916 deep_sleep = 0;
3917
3918 /*
3919 * Check if RX & TX FIFOs are both empty
3920 */
3921
3922 status = READ_UART_REGISTER (uart, LSR);
3923
3924 if (!(status & DR) &&
3925 (status & TEMT)) {
3926
3927 #if ((CHIPSET != 5) && (CHIPSET != 6))
3928 /*
3929 * Disable sleep mode.
3930 */
3931
3932 WRITE_UART_REGISTER (
3933 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
3934 #endif
3935
3936 #if (CHIPSET == 12)
3937 /*
3938 * Mask DSR interrupt.
3939 */
3940
3941 DISABLE_DSR_INTERRUPT (uart);
3942 #endif
3943
3944 /*
3945 * Mask RX, TX and the modem status interrupts.
3946 */
3947
3948 WRITE_UART_REGISTER (
3949 uart, IER, READ_UART_REGISTER (uart, IER) &
3950 ~(ERBI | ETBEI | EDSSI));
3951
3952 /*
3953 * Enable the wake-up interrupt.
3954 */
3955
3956 ENABLE_WAKEUP_INTERRUPT (uart);
3957
3958 deep_sleep = 1;
3959 }
3960
3961 return (deep_sleep);
3962 }
3963
3964 /*******************************************************************************
3965 *
3966 * UAF_WakeUp
3967 *
3968 * Purpose : Wakes up UART after Deep Sleep.
3969 *
3970 * Arguments: In : uartNo: Used UART.
3971 * Out: none
3972 *
3973 * Returns : FD_OK : Successful operation.
3974 * FD_NOT_SUPPORTED: Wrong UART number.
3975 *
3976 * Warning: Parameters are not verified.
3977 *
3978 ******************************************************************************/
3979
3980 T_FDRET
3981 UAF_WakeUp (T_fd_UartId uartNo)
3982 {
3983 t_uart *uart;
3984
3985 /*
3986 * Check UART number.
3987 * A return is used to simplify the code.
3988 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
3989 * flow control is not supported.
3990 * DCD and DTR are not supported on UART Irda on C & D-Sample.
3991 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
3992 */
3993
3994 if (uartNo != UAF_UART_1)
3995 return (FD_NOT_SUPPORTED);
3996
3997 uart = &uart_parameters;
3998
3999 /*
4000 * Disable the wake-up interrupt.
4001 */
4002
4003 DISABLE_WAKEUP_INTERRUPT (uart);
4004
4005 /*
4006 * Unmask RX and modem status interrupts.
4007 */
4008
4009 WRITE_UART_REGISTER (
4010 uart, IER, READ_UART_REGISTER (uart, IER) | (ERBI | EDSSI));
4011
4012 #if (CHIPSET == 12)
4013 /*
4014 * Unmask DSR interrupt.
4015 */
4016
4017 ENABLE_DSR_INTERRUPT (uart);
4018 #endif
4019
4020 #if ((CHIPSET != 5) && (CHIPSET != 6))
4021 /*
4022 * Allow sleep mode.
4023 */
4024 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
4025 /*
4026 WRITE_UART_REGISTER (
4027 uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
4028 */
4029 #endif
4030
4031 return (FD_OK);
4032 }
4033
4034 /*******************************************************************************
4035 *
4036 * UAF_ReadData
4037 *
4038 * Purpose : To read the received characters out of the RX buffer the address
4039 * of a function is passed. If characters are available, the driver
4040 * calls this function and pass the address and the amount of
4041 * readable characters. Because the RX buffer is circular, the
4042 * callback function may be called with more than one address of
4043 * buffer fragment.
4044 * The readOutFunc function modifies the contents of the size array
4045 * to return the driver the number of processed characters. Each
4046 * array entry is decremented by the number of bytes read in the
4047 * fragment.
4048 * If the UAF_ReadData is called while the RX buffer is empty, it
4049 * depends on the suspend parameter to suspend the call-back or to
4050 * leave without any operation. In the case of suspension, the
4051 * return value of UAF_ReadData is UAF_SUSPENDED. A delayed call-back
4052 * will be performed if:
4053 * - the RX buffer reachs the adjusted threshold (rxThreshold of
4054 * UAF_SetBuffer),
4055 * - the state of a V.24 input line has changed,
4056 * - a break is detected,
4057 * - an escape sequence is detected.
4058 * If no suspension is necessary the function returns the number of
4059 * processed bytes.
4060 *
4061 * Arguments: In : uartNo : Used UART.
4062 * suspend : mode of suspension in case of RX buffer empty.
4063 * readOutFunc: Callback function.
4064 * cldFromIrq: The driver sets this parameter to 1
4065 * if the callback function is called
4066 * from an interrupt service routine.
4067 * reInstall : The call-back function sets this
4068 * parameter to rm_reInstall if the
4069 * driver must call again the callback
4070 * function when the RX threshold level
4071 * is reached. Else it will be set to
4072 * rm_noInstall. Before to call the
4073 * readOutFunc function this parameter
4074 * is set to rm_notDefined.
4075 * nsource : Informed the callback function about
4076 * the number of fragments which are
4077 * ready to copy from the circular RX
4078 * buffer.
4079 * source : Array which contains the addresses
4080 * of the fragments.
4081 * size : Array which contains the sizes of
4082 * each fragments.
4083 * state : The state parameter is the status
4084 * of the V.24 lines and the break /
4085 * escape detection. The state
4086 * parameter is described in the
4087 * specification of UAF_GetLineState.
4088 * Out: none
4089 *
4090 * Returns : >= 0 : Succesful operation. Amount of processed bytes.
4091 * FD_NOT_SUPPORTED: Wrong UART number.
4092 * FD_SUSPENDED : The callback is suspended until the buffer or
4093 * state condition changed.
4094 * FD_NOT_READY : The function is called while the callback is
4095 * activated and still not terminated.
4096 * FD_INTERNAL_ERR : Internal problems with the hardware.
4097 *
4098 ******************************************************************************/
4099
4100 T_FDRET
4101 UAF_ReadData (T_fd_UartId uartNo,
4102 T_suspendMode suspend,
4103 void (readOutFunc (SYS_BOOL cldFromIrq,
4104 T_reInstMode *reInstall,
4105 SYS_UWORD8 nsource,
4106 SYS_UWORD8 *source[],
4107 SYS_UWORD16 size[],
4108 SYS_UWORD32 state)))
4109 {
4110 T_FDRET result;
4111 t_uart *uart;
4112 SYS_UWORD16 bytes_read;
4113 SYS_UWORD16 bytes_in_rx_buffer;
4114
4115 /*
4116 * Check UART number.
4117 * A return is used to simplify the code.
4118 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4119 * flow control is not supported.
4120 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4121 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4122 */
4123
4124 if (uartNo != UAF_UART_1)
4125 return (FD_NOT_SUPPORTED);
4126
4127 /*
4128 * There is no case where FD_INTERNAL_ERR may be returned.
4129 */
4130
4131 uart = &uart_parameters;
4132
4133 if (uart->rd_call_setup == rm_notDefined)
4134 result = FD_NOT_READY;
4135
4136 else if (get_bytes_in_rx_buffer (uart) || uart->esc_seq_received) {
4137
4138 uart->readOutFunc = readOutFunc;
4139 update_reading_callback (uart, 0); /* 0: call from application. */
4140
4141 bytes_read = uart->rd_size_before_call[0] -
4142 uart->rd_size_after_call[0] +
4143 uart->rd_size_before_call[1] -
4144 uart->rd_size_after_call[1];
4145
4146 uart->rx_out += bytes_read;
4147
4148 if (uart->rx_out >= &(uart->rx_buffer[0]) + uart->buffer_size + 1)
4149 uart->rx_out = uart->rx_out - uart->buffer_size - 1;
4150
4151 /*
4152 * Check if the low watermark is reached to enable the receiver.
4153 */
4154
4155 if ((uart->flow_control_mode != fc_none) &&
4156 (get_bytes_in_rx_buffer (uart) <= RX_LOW_WATERMARK (
4157 uart->buffer_size))) {
4158
4159 if ((!uart->rx_stopped_by_application) &&
4160 uart->rx_stopped_by_driver && (!uart->rx_stopped_by_lisr))
4161 start_receiver (uart);
4162
4163 uart->rx_stopped_by_driver = 0;
4164 }
4165
4166 uart->esc_seq_received = 0;
4167 result = (T_FDRET) bytes_read;
4168
4169 } else if (suspend == sm_suspend) {
4170
4171 uart->readOutFunc = readOutFunc;
4172 uart->reading_suspended = 1;
4173 result = FD_SUSPENDED;
4174
4175 } else {
4176
4177 /*
4178 * The previous callback function is deinstalled.
4179 */
4180
4181 uart->rd_call_setup = rm_noInstall;
4182 uart->reading_suspended = 0;
4183 result = 0; /* 0 byte read. */
4184 }
4185
4186 return (result);
4187 }
4188
4189 /*******************************************************************************
4190 *
4191 * UAF_WriteData
4192 *
4193 * Purpose : To write characters into the TX buffer the address of a function
4194 * is passed. If free space is available in the buffer, the driver
4195 * calls this function and passes the destination address and the
4196 * amount of space. Because the TX buffer is circular, the callback
4197 * function may be called with more than one address of buffer
4198 * fragment.
4199 * The writeInFunc function modifies the contents of the size array
4200 * to return the driver the number of processed bytes. Each array
4201 * entry is decremented by the number of bytes written in this
4202 * fragment.
4203 * If the UAF_WriteData function is called while the TX buffer is
4204 * full, it depends on the suspend parameter to suspend the
4205 * call-back or to leave this function without any operation. In the
4206 * case of suspension the returned value of the UAF_WriteData is
4207 * UAF_SUSPENDED. A delayed call-back will be performed if the TX
4208 * buffer reaches the adjusted threshold (txThreshold of
4209 * UAF_SetBuffer). If no suspension is necessary the function returns
4210 * the number of processed bytes.
4211 *
4212 * Arguments: In : uartNo : Used UART.
4213 * suspend : mode of suspension in case of TX buffer empty.
4214 * writeInFunc: Callback function.
4215 * cldFromIrq: The driver sets this parameter to 1
4216 * if the call-back function is called
4217 * from an interrupt service routine.
4218 * reInstall : The callback function sets this
4219 * parameter to rm_reInstall if the
4220 * driver must call again the callback
4221 * function when the TX threshold level
4222 * is reached. Else it will be set to
4223 * rm_noInstall. Before to call the
4224 * writeInFunc function this parameter
4225 * is set to rm_notDefined.
4226 * ndest : Informed the callback function about
4227 * the number of fragments which are
4228 * available in the TX buffer.
4229 * dest : Array which contains the addresses
4230 * of the fragments.
4231 * size : Array which contains the sizes of
4232 * each fragments.
4233 * Out: none
4234 *
4235 * Returns : >= 0 : Succesful operation. Amount of processed bytes.
4236 * FD_NOT_SUPPORTED: Wrong UART number.
4237 * FD_SUSPENDED : The callback is suspended until the buffer
4238 * condition changed.
4239 * FD_NOT_READY : The function is called while the callback is
4240 * activated and still not terminated.
4241 * FD_INTERNAL_ERR : Internal problems with the hardware.
4242 *
4243 ******************************************************************************/
4244
4245 T_FDRET
4246 UAF_WriteData (T_fd_UartId uartNo,
4247 T_suspendMode suspend,
4248 void (writeInFunc (SYS_BOOL cldFromIrq,
4249 T_reInstMode *reInstall,
4250 SYS_UWORD8 ndest,
4251 SYS_UWORD8 *dest[],
4252 SYS_UWORD16 size[])))
4253 {
4254 T_FDRET result;
4255 t_uart *uart;
4256 SYS_UWORD16 bytes_written;
4257
4258 /*
4259 * Check UART number.
4260 * A return is used to simplify the code.
4261 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4262 * flow control is not supported.
4263 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4264 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4265 */
4266
4267 if (uartNo != UAF_UART_1)
4268 return (FD_NOT_SUPPORTED);
4269
4270 /*
4271 * There is no case where FD_INTERNAL_ERR may be returned.
4272 */
4273
4274 uart = &uart_parameters;
4275
4276 if (uart->wr_call_setup == rm_notDefined)
4277 result = FD_NOT_READY;
4278
4279 else if ((!DRIVER_DISABLED (uart)) &&
4280 (get_bytes_in_tx_buffer (uart) < uart->buffer_size)) {
4281
4282 uart->writeInFunc = writeInFunc;
4283 update_writing_callback (uart, 0); /* 0: call from application. */
4284
4285 bytes_written = uart->wr_size_before_call[0] -
4286 uart->wr_size_after_call[0] +
4287 uart->wr_size_before_call[1] -
4288 uart->wr_size_after_call[1];
4289
4290 uart->tx_in += bytes_written;
4291
4292 if (uart->tx_in >= &(uart->tx_buffer[0]) + uart->buffer_size + 1)
4293 uart->tx_in = uart->tx_in - uart->buffer_size - 1;
4294
4295 /* If we have been stopped due to high RTS, we have to
4296 * wake up application processor by IRQ via IO1 -HW */
4297 #ifdef EXTHOST_WAKEUP_GPIO
4298 if (uart->tx_stopped_by_driver)
4299 AI_SetBit(EXTHOST_WAKEUP_GPIO);
4300 #endif
4301
4302 /*
4303 * If:
4304 * - there is no break to send,
4305 * - the flow control is not activated,
4306 * unmask the TX empty interrupt to be able to send characters.
4307 */
4308 if (!uart->break_to_send &&
4309 !uart->tx_stopped_by_driver)
4310 {
4311 #if ((CHIPSET != 5) && (CHIPSET != 6))
4312 /*
4313 * Disable sleep mode.
4314 */
4315
4316 WRITE_UART_REGISTER (
4317 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
4318 #endif
4319
4320 /*
4321 * Unmask Tx interrupt.
4322 */
4323
4324 WRITE_UART_REGISTER (
4325 uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
4326 }
4327
4328 result = (T_FDRET) bytes_written;
4329
4330 } else if (suspend == sm_suspend) {
4331
4332 uart->writeInFunc = writeInFunc;
4333 uart->writing_suspended = 1;
4334 result = FD_SUSPENDED;
4335
4336 } else {
4337
4338 /*
4339 * The previous callback function is deinstalled.
4340 */
4341
4342 uart->wr_call_setup = rm_noInstall;
4343 uart->writing_suspended = 0;
4344 result = 0;
4345 }
4346
4347 return (result);
4348 }
4349
4350 /*******************************************************************************
4351 *
4352 * UAF_StopRec
4353 *
4354 * Purpose : If a flow control mode is set, this function tells the terminal
4355 * equipment that no more data can be received.
4356 * XON/XOFF: XOFF is sent.
4357 * DTR/DSR : DTR is desactivated.
4358 * RTS/CTS : RTS is deactivated.
4359 *
4360 * Arguments: In : uartNo: Used UART.
4361 * Out: none
4362 *
4363 * Returns : FD_OK : Successful operation.
4364 * FD_NOT_SUPPORTED: Wrong UART number.
4365 * FD_INTERNAL_ERR : Internal problem with the hardware.
4366 *
4367 ******************************************************************************/
4368
4369 T_FDRET
4370 UAF_StopRec (T_fd_UartId uartNo)
4371 {
4372 t_uart *uart;
4373
4374 /*
4375 * Check UART number.
4376 * A return is used to simplify the code.
4377 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4378 * flow control is not supported.
4379 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4380 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4381 */
4382
4383 if (uartNo != UAF_UART_1)
4384 return (FD_NOT_SUPPORTED);
4385
4386 /*
4387 * There is no case where FD_INTERNAL_ERR may be returned.
4388 */
4389
4390 uart = &uart_parameters;
4391
4392 if (uart->flow_control_mode != fc_none)
4393 stop_receiver (uart);
4394
4395 uart->rx_stopped_by_application = 1;
4396
4397 return (FD_OK);
4398 }
4399
4400 /*******************************************************************************
4401 *
4402 * UAF_StartRec
4403 *
4404 * Purpose : If a flow control mode is set, this function tells the terminal
4405 * equipment that the receiver is again able to receive more data.
4406 * If the buffer has already reached the high water mark the driver
4407 * sends the signal only if the buffer drains to a low water mark.
4408 * XON/XOFF: XON is sent.
4409 * DTR/DSR : DTR is activated.
4410 * RTS/CTS : RTS is activated.
4411 *
4412 * Arguments: In : uartNo: Used UART.
4413 * Out: none
4414 *
4415 * Returns : FD_OK : Successful operation.
4416 * FD_NOT_SUPPORTED: Wrong UART number.
4417 * FD_INTERNAL_ERR : Internal problem with the hardware.
4418 *
4419 ******************************************************************************/
4420
4421 T_FDRET
4422 UAF_StartRec (T_fd_UartId uartNo)
4423 {
4424 t_uart *uart;
4425
4426 /*
4427 * Check UART number.
4428 * A return is used to simplify the code.
4429 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4430 * flow control is not supported.
4431 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4432 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4433 */
4434
4435 if (uartNo != UAF_UART_1)
4436 return (FD_NOT_SUPPORTED);
4437
4438 /*
4439 * There is no case where FD_INTERNAL_ERR may be returned.
4440 */
4441
4442 uart = &uart_parameters;
4443
4444 if ((uart->flow_control_mode != fc_none) && (!uart->rx_stopped_by_driver))
4445 start_receiver (uart);
4446
4447 uart->rx_stopped_by_application = 0;
4448
4449 return (FD_OK);
4450 }
4451
4452 /*******************************************************************************
4453 *
4454 * UAF_GetLineState
4455 *
4456 * Purpose : Returns the state of the V.24 lines, the flow control state and
4457 * the result of the break/escape detection process as a bit field.
4458 *
4459 * Arguments: In : uartNo: Used UART.
4460 * Out: state : State of the V.24 lines, the flow control state and
4461 * the result of the break/escape sequence detection
4462 * process as a bit field.
4463 *
4464 * Returns : FD_OK : Successful operation.
4465 * FD_NOT_SUPPORTED: Wrong UART number.
4466 * FD_NOT_READY : The function is called while the callback of
4467 * the readOutFunc function is activated and still
4468 * not terminated.
4469 * FD_INTERNAL_ERR : Internal problem with the hardware.
4470 *
4471 ******************************************************************************/
4472
4473 T_FDRET
4474 UAF_GetLineState (T_fd_UartId uartNo,
4475 SYS_UWORD32 *state)
4476 {
4477 T_FDRET result;
4478 t_uart *uart;
4479
4480 /*
4481 * Check UART number.
4482 * A return is used to simplify the code.
4483 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4484 * flow control is not supported.
4485 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4486 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4487 */
4488
4489 if (uartNo != UAF_UART_1)
4490 return (FD_NOT_SUPPORTED);
4491
4492 /*
4493 * There is no case where FD_INTERNAL_ERR may be returned.
4494 * Signals not supported are reported as 0.
4495 */
4496
4497 uart = &uart_parameters;
4498
4499 if (uart->rd_call_setup == rm_notDefined)
4500 result = FD_NOT_READY;
4501
4502 else {
4503
4504 /*
4505 * The field state_2 is used when state_1 is set to 0 to avoid to
4506 * lose events detected in the RX interrupt handler.
4507 * Fields BRK and BRKLEN are set when a break is detected.
4508 * The field ESC is set when an escape sequence is detected.
4509 */
4510
4511 *state = uart->state_2;
4512 uart->state_2 = 0;
4513 uart->state = &(uart->state_2);
4514
4515 *state |= uart->state_1;
4516 uart->state_1 = 0;
4517 uart->state = &(uart->state_1);
4518
4519 *state |= ((((SYS_UWORD32) uart->rts_level) << RTS) |
4520
4521 #if TARGET_HAS_DTR_INPUT
4522 (((SYS_UWORD32) uart->dtr_level) << DTR) |
4523 #endif
4524
4525 (((SYS_UWORD32) (uart->tx_stopped_by_application |
4526 uart->tx_stopped_by_driver)) << TXSTP) |
4527
4528 (((SYS_UWORD32) (uart->rx_stopped_by_application |
4529 uart->rx_stopped_by_driver)) << RXSTP) |
4530
4531 (((SYS_UWORD32) (uart->buffer_size -
4532 get_bytes_in_rx_buffer (uart))) << RXBLEV));
4533
4534 /*
4535 * Fields SA, SB and X are set according to the flow control:
4536 *
4537 * None RTS/CTS XON/XOFF
4538 * SA DTR DTR DTR
4539 * SB RTS 0 RTS
4540 * X 0 RTS XON:0 XOFF:1 (transmitter)
4541 *
4542 * DTR is supported on C, D & E-Sample.
4543 */
4544
4545 #if TARGET_HAS_DTR_INPUT
4546 *state |= (((SYS_UWORD32) uart->dtr_level) << SA);
4547 #endif
4548
4549 if (uart->flow_control_mode != fc_rts)
4550 *state |= (((SYS_UWORD32) uart->rts_level) << SB);
4551
4552 if (uart->flow_control_mode == fc_rts)
4553 *state |= (((SYS_UWORD32) uart->rts_level) << X);
4554
4555 else if ((uart->flow_control_mode == fc_xoff) &&
4556 (uart->tx_stopped_by_application ||
4557 uart->tx_stopped_by_driver))
4558 *state |= (1 << X);
4559
4560 result = FD_OK;
4561 }
4562
4563 return (result);
4564 }
4565
4566 /*******************************************************************************
4567 *
4568 * UAF_SetLineState
4569 *
4570 * Purpose : Sets the states of the V.24 status lines according to the bit
4571 * field of the parameter state.
4572 *
4573 * Arguments: In : uartNo: Used UART.
4574 * state : Bit field. Only the signals which are marked with
4575 * the 'set' access can be used to change the state of
4576 * the signal.
4577 * mask : Bit field with the same structure as state. Each bit
4578 * in state corresponds to a bit in mask. Settabled
4579 * bits marked by a 1 are manipulated by the driver.
4580 * Out: none
4581 *
4582 * Returns : FD_OK : Successful operation.
4583 * FD_NOT_SUPPORTED: Wrong UART number.
4584 * FD_INTERNAL_ERR : Internal problem with the hardware.
4585 *
4586 ******************************************************************************/
4587
4588 T_FDRET
4589 UAF_SetLineState (T_fd_UartId uartNo,
4590 SYS_UWORD32 state,
4591 SYS_UWORD32 mask)
4592 {
4593 t_uart *uart;
4594 UNSIGNED break_length;
4595
4596 /*
4597 * Check UART number.
4598 * A return is used to simplify the code.
4599 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4600 * flow control is not supported.
4601 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4602 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4603 */
4604
4605 if (uartNo != UAF_UART_1)
4606 return (FD_NOT_SUPPORTED);
4607
4608 uart = &uart_parameters;
4609
4610 /*
4611 * There is no case where FD_INTERNAL_ERR may be returned.
4612 * DCD is supported on C, D & E-Sample. The SA field is not supported because
4613 * DSR is not supported on all platforms.
4614 */
4615
4616 #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
4617 if (mask & (1 << SA))
4618 #else
4619 if ((mask & (1 << SA)) || (mask & (1 << DCD)))
4620 #endif
4621 return (FD_NOT_SUPPORTED); /* Return used to simplify the code */
4622
4623 /*
4624 * Check if a break has to be sent.
4625 */
4626
4627 uart->break_length = (UNSIGNED) ((state >> BRKLEN) & 0xFF);
4628
4629 if (state & (1 << BRK) && (mask & (1 << BRK))) {
4630
4631 if (uart->break_length > FIFO_SIZE)
4632 return (FD_NOT_SUPPORTED); /* Return used to simplify the code */
4633
4634 else {
4635
4636 uart->time_without_character =
4637 compute_break_time (uart->baudrate, uart->bits_per_char, 3);
4638
4639 uart->break_to_send = 1;
4640
4641 /*
4642 * If the TX FIFO is empty the break is send from this function
4643 * else the interrupt handler will send the break.
4644 */
4645
4646 if (READ_UART_REGISTER (uart, LSR) & TEMT)
4647 send_break(uart);
4648 }
4649 }
4650
4651 #if ((CHIPSET != 5) && (CHIPSET != 6))
4652 /*
4653 * Disable sleep mode.
4654 */
4655
4656 WRITE_UART_REGISTER (
4657 uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
4658 #endif
4659
4660 /*
4661 * The CTS field is ignored if the X bit in the mask is set. In this case
4662 * the X bit controls CTS.
4663 */
4664
4665 if (mask & (1 << CTS)) {
4666
4667 if (uart->flow_control_mode != fc_rts) {
4668
4669 /*
4670 * As the RTS/CTS flow control is not selected, the X bit does not
4671 * control CTS. CTS needs only to be activated or deactivated
4672 * according to the value of the CTS field.
4673 */
4674
4675 if (state & (1 << CTS))
4676 WRITE_UART_REGISTER (
4677 uart, MCR, READ_UART_REGISTER (uart, MCR) | MRTS);
4678
4679 else
4680 WRITE_UART_REGISTER (
4681 uart, MCR, READ_UART_REGISTER (uart, MCR) & ~MRTS);
4682
4683 } else if (!(mask & (1 << X))) {
4684
4685 /*
4686 * The RTS/CTS flow control is selected but the X bit in the mask
4687 * is null. Then the CTS bit controls CTS and the receiver must be
4688 * stopped or started according to the state of the CTS bit.
4689 * The receiver is started only if it was not stopped by the driver
4690 * and if it was stopped by the application.
4691 */
4692
4693 if (state & (1 << CTS)) {
4694
4695 if (!uart->rx_stopped_by_application) {
4696
4697 if (!uart->rx_stopped_by_driver)
4698 stop_receiver (uart);
4699
4700 uart->rx_stopped_by_application = 1;
4701 }
4702
4703 } else {
4704
4705 if ((!uart->rx_stopped_by_driver) &&
4706 uart->rx_stopped_by_application)
4707 start_receiver (uart);
4708
4709 uart->rx_stopped_by_application = 0;
4710 }
4711 }
4712 }
4713
4714 /*
4715 * The DCD field is ignored if the SB bit of the mask is set.
4716 */
4717
4718 #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
4719
4720 if (!(mask & (1 << SB)) && (mask & (1 << DCD))) {
4721
4722 if (state & (1 << DCD)) {
4723 /* Turn on DCD */
4724 #if (CHIPSET == 12)
4725 WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) | MDCD);
4726 #else
4727 AI_ResetBit (ARMIO_DCD);
4728 #endif
4729 } else {
4730 /* Turn off DCD */
4731 #if (CHIPSET == 12)
4732 WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) & ~MDCD);
4733 #else
4734 AI_SetBit (ARMIO_DCD);
4735 #endif
4736 }
4737 }
4738
4739 #endif /* BOARD 8 or 9 or 40 or 41 or CHIPSET 12 */
4740
4741 /*
4742 * Signals are set according to fields SA, SB and X states and flow
4743 * control:
4744 *
4745 * None RTS/CTS XON/XOFF
4746 * SA 0 (ns) 0 (ns) 0 (ns)
4747 * SB DCD DCD DCD
4748 * X ignore CTS XON:0 XOFF:1 (receiver)
4749 *
4750 * ns: signal not supported.
4751 * DCD is supported on C, D & E-Sample.
4752 */
4753
4754 #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
4755
4756 if (mask & (1 << SB)) {
4757
4758 if (state & (1 << SB)) {
4759 /* Turn on DCD */
4760 #if (CHIPSET == 12)
4761 WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) | MDCD);
4762 #else
4763 AI_ResetBit (ARMIO_DCD);
4764 #endif
4765 } else {
4766 /* Turn off DCD */
4767 #if (CHIPSET == 12)
4768 WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) & ~MDCD);
4769 #else
4770 AI_SetBit (ARMIO_DCD);
4771 #endif
4772 }
4773 }
4774
4775 #endif /* BOARD 8 or 9 or 40 or 41 or CHIPSET 12 */
4776
4777 if ((mask & (1 << X)) &&
4778 (uart->flow_control_mode != fc_none)) {
4779
4780 if (state & (1 << X)) {
4781
4782 if (!uart->rx_stopped_by_application) {
4783
4784 if (!uart->rx_stopped_by_driver)
4785 stop_receiver (uart);
4786
4787 uart->rx_stopped_by_application = 1;
4788 }
4789
4790 } else {
4791
4792 /*
4793 * The receiver is started only if it is not stopped by the driver
4794 * and if it is stopped by the application.
4795 */
4796
4797 if ((!uart->rx_stopped_by_driver) &&
4798 uart->rx_stopped_by_application)
4799 start_receiver (uart);
4800
4801 uart->rx_stopped_by_application = 0;
4802 }
4803 }
4804
4805 #if ((CHIPSET != 5) && (CHIPSET != 6))
4806 /*
4807 * Re-enable sleep mode.
4808 */
4809 /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
4810 /*
4811 WRITE_UART_REGISTER (
4812 uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
4813 */
4814 #endif
4815
4816 return (FD_OK);
4817 }
4818
4819 /*******************************************************************************
4820 *
4821 * UAF_InterruptHandler
4822 *
4823 * Purpose : Interrupt handler.
4824 *
4825 * Arguments: In : uart_id : origin of interrupt
4826 * interrupt_status: source of interrupt
4827 * Out: none
4828 *
4829 * Returns : none
4830 *
4831 ******************************************************************************/
4832
4833 void
4834 UAF_InterruptHandler (T_fd_UartId uart_id,
4835 SYS_UWORD8 interrupt_status)
4836 {
4837
4838 t_uart *uart;
4839
4840 /*
4841 * uart_id is not used.
4842 */
4843
4844 uart = &uart_parameters;
4845
4846 uart->current_time = NU_Retrieve_Clock ();
4847
4848 /*
4849 * Causes of interrupt:
4850 * - trigger level reached,
4851 * - character time-out indication,
4852 * - transmitter holding register empty,
4853 * - modem status.
4854 */
4855
4856 switch (interrupt_status) {
4857
4858 case RX_DATA:
4859
4860 #if TARGET_HAS_DTR_INPUT
4861 uart->index_it = (uart->index_it + 1) & 0x01; /* 0 or 1 */
4862 uart->dtr_change_detected[uart->index_it] = 0;
4863 uart->dtr_level_saved[uart->index_it] = uart->dtr_level;
4864 #endif
4865 read_rx_fifo (uart);
4866
4867 // Disable Autobaud and lock baudrate upon first received character
4868 if (uart->autobauding != 0)
4869 {
4870 /* MSMSMSMS */
4871 SYS_UWORD8 uasr;
4872 T_baudrate baudrate;
4873 T_bitsPerCharacter bpc;
4874 T_parity parity;
4875
4876 WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) | DLAB);
4877
4878
4879 uasr = READ_UART_REGISTER (uart, UASR);
4880
4881 switch (uasr & 0x1F)
4882 {
4883 case 0x01: baudrate = FD_BAUD_115200; break;
4884 case 0x02: baudrate = FD_BAUD_57600; break;
4885 case 0x03: baudrate = FD_BAUD_38400; break;
4886 case 0x04: baudrate = FD_BAUD_28800; break;
4887 case 0x05: baudrate = FD_BAUD_19200; break;
4888 case 0x06: baudrate = FD_BAUD_14400; break;
4889 case 0x07: baudrate = FD_BAUD_9600; break;
4890 case 0x08: baudrate = FD_BAUD_4800; break;
4891 case 0x09: baudrate = FD_BAUD_2400; break;
4892 case 0x0A: baudrate = FD_BAUD_1200; break;
4893 default: /* no baudrate detected, abort for now */
4894 return;
4895 }
4896
4897 switch (uasr>>5 & 0x01)
4898 {
4899 case 0x00: bpc = bpc_7; break;
4900 case 0x01: bpc = bpc_8; break;
4901 }
4902
4903 switch (uasr>>6 & 0x03)
4904 {
4905 case 0x00: parity = pa_none; break;
4906 case 0x01: parity = pa_space; break;
4907 case 0x02: parity = pa_even; break;
4908 case 0x03: parity = pa_odd; break;
4909 }
4910
4911 UAF_SetComPar (UAF_UART_1,
4912 baudrate,
4913 bpc,
4914 sb_1,
4915 parity);
4916
4917 uart->baudrate = baudrate_value[FD_BAUD_AUTO]; /* remember autobauding */
4918 }
4919
4920 break;
4921
4922 case TX_EMPTY:
4923
4924 fill_tx_fifo (uart);
4925 break;
4926
4927 case MODEM_STATUS:
4928
4929 check_v24_input_lines (uart);
4930 break;
4931 }
4932 }
4933
4934 /*******************************************************************************
4935 *
4936 * UAF_CheckXEmpty
4937 *
4938 * Purpose : Checks the empty condition of the Transmitter.
4939 *
4940 * Arguments: In : uartNo: Used UART.
4941 * Out: none
4942 *
4943 * Returns : FD_OK : Empty condition OK.
4944 * FD_NOT_SUPPORTED: Wrong UART number.
4945 * FD_NOT_READY : Empty condition not OK.
4946 * FD_INTERNAL_ERR : Internal problem with the hardware.
4947 *
4948 ******************************************************************************/
4949
4950 T_FDRET
4951 UAF_CheckXEmpty (T_fd_UartId uartNo)
4952 {
4953 T_FDRET result;
4954 t_uart *uart;
4955 SYS_UWORD8 status;
4956
4957 /*
4958 * Check UART number.
4959 * A return is used to simplify the code.
4960 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
4961 * flow control is not supported.
4962 * DCD and DTR are not supported on UART Irda on C & D-Sample.
4963 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
4964 */
4965
4966 if (uartNo != UAF_UART_1)
4967 return (FD_NOT_SUPPORTED);
4968
4969 /*
4970 * There is no case where FD_INTERNAL_ERR may be returned.
4971 */
4972
4973 result = FD_OK;
4974
4975 uart = &uart_parameters;
4976 status = READ_UART_REGISTER (uart, LSR);
4977
4978 /*
4979 * Checks if:
4980 * - the TX SW Buffer is empty,
4981 * - the TX HW FIFO is empty (THRE),
4982 * - the Transmitter Shift Register is empty (TEMT).
4983 */
4984
4985 if (!(TX_BUFFER_EMPTY (uart)) ||
4986 !(status & THRE) ||
4987 !(status & TEMT))
4988
4989 result = FD_NOT_READY;
4990
4991 return (result);
4992 }
4993
4994 #if TARGET_HAS_DTR_INPUT
4995 /*******************************************************************************
4996 *
4997 * UAF_DTRInterruptHandler
4998 *
4999 * Purpose : This function is only used on C & D-Sample. On this platform, the
5000 * DTR signal is controlled with an I/O. A change of state of this
5001 * signal is detected with an interrupt. This function is called when
5002 * this interrupt occurs.
5003 *
5004 * Arguments: In : none
5005 * Out: none
5006 *
5007 * Returns : none
5008 *
5009 ******************************************************************************/
5010
5011 void
5012 UAF_DTRInterruptHandler (void)
5013 {
5014 t_uart *uart;
5015
5016 uart = &uart_parameters;
5017
5018 /*
5019 * Read the state of DTR and change the edge to detect the next change
5020 * of DTR.
5021 */
5022
5023 uart->dtr_level = AI_ReadBit (ARMIO_DTR);
5024
5025 if (uart->dtr_level)
5026 {
5027 AI_SelectIOForIT (ARMIO_DTR, ARMIO_FALLING_EDGE);
5028 if (uart->flow_control_mode != fc_dtr && uart->baudrate == baudrate_value[FD_BAUD_AUTO])
5029 UAF_SetComPar (UAF_UART_1, FD_BAUD_AUTO, bpc_8, sb_1, pa_none);
5030 }
5031 else
5032 AI_SelectIOForIT (ARMIO_DTR, ARMIO_RISING_EDGE);
5033
5034 /*
5035 * The reading callback function has to be called. But bytes received before
5036 * the change of state of DTR must be copied into the RX buffer before to
5037 * call it.
5038 */
5039
5040 if (READ_UART_REGISTER (uart, LSR) & DR) { /* If Rx FIFO is not empty */
5041
5042 /*
5043 * The Rx FIFO will be read to fill one of the two buffers and the Rx
5044 * HISR will be activated.
5045 */
5046
5047 uart->index_it = (uart->index_it + 1) & 0x01; /* 0 or 1 */
5048 uart->dtr_change_detected[uart->index_it] = 1;
5049 uart->dtr_level_saved[uart->index_it] = uart->dtr_level;
5050 read_rx_fifo (uart);
5051
5052 } else
5053 (void) NU_Activate_HISR (&(uart->v24_hisr_ctrl_block));
5054
5055 }
5056 #endif /* BOARD 8 or 9 or 40 or 41 */
5057
5058 #if (defined BTEMOBILE && (CHIPSET != 12))
5059 /*******************************************************************************
5060 *
5061 * UAF_Exit
5062 *
5063 * Purpose :
5064 *
5065 * Arguments: In : uartNo: Used UART.
5066 * Out: none
5067 *
5068 * Returns : FD_OK : Successful operation.
5069 * FD_NOT_SUPPORTED: Wrong UART number.
5070 * FD_INTERNAL_ERR : Internal problem.
5071 *
5072 ******************************************************************************/
5073
5074 T_FDRET
5075 UAF_Exit (T_fd_UartId uartNo)
5076 {
5077 t_uart *uart;
5078
5079 /*
5080 * Check UART number.
5081 * A return is used to simplify the code.
5082 * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
5083 * flow control is not supported.
5084 * DCD and DTR are not supported on UART Irda on C & D-Sample.
5085 * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
5086 */
5087
5088 if (uartNo != UAF_UART_1)
5089 return (FD_NOT_SUPPORTED);
5090
5091 uart = &uart_parameters;
5092
5093 /*
5094 * Delete the 3 HISR actived in the RX/TX and V24 interrupt handlers.
5095 * A return is used to simplify the code if an error occurs.
5096 */
5097
5098 if (NU_Delete_HISR (&(uart->rx_hisr_ctrl_block)) != NU_SUCCESS)
5099 return (FD_INTERNAL_ERR);
5100
5101 if (NU_Delete_HISR (&(uart->tx_hisr_ctrl_block)) != NU_SUCCESS)
5102 return (FD_INTERNAL_ERR);
5103
5104 if (NU_Delete_HISR (&(uart->v24_hisr_ctrl_block)) != NU_SUCCESS)
5105 return (FD_INTERNAL_ERR);
5106
5107 /*
5108 * Delete the HISR used to send a break.
5109 * A return is used to simplify the code if an error occurs.
5110 */
5111
5112 if (NU_Delete_HISR (&(uart->break_hisr_ctrl_block)) != NU_SUCCESS)
5113 return (FD_INTERNAL_ERR);
5114
5115 /*
5116 * Disable and then delete the timer used in the break HISR
5117 * A return is used to simplify the code if an error occurs.
5118 */
5119
5120 (void) NU_Control_Timer (&(uart->break_timer_ctrl_block),
5121 NU_DISABLE_TIMER);
5122
5123 if (NU_Delete_Timer (&(uart->break_timer_ctrl_block)) != NU_SUCCESS)
5124 return (FD_INTERNAL_ERR);
5125
5126 /*
5127 * Disable and then delete the timer used in the detection of the escape
5128 * sequence. A return is used to simplify the code if an error occurs.
5129 */
5130
5131 (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
5132 NU_DISABLE_TIMER);
5133
5134 if (NU_Delete_Timer (&(uart->guard_period_timer_ctrl_block)) != NU_SUCCESS)
5135 return (FD_INTERNAL_ERR);
5136
5137 /*
5138 * At that point, all HISRs and Timers have been successfully deleted.
5139 */
5140
5141 return (FD_OK);
5142 }
5143 #endif /* (defined BTEMOBILE && (CHIPSET != 12)) */