comparison src/cs/drivers/drv_app/uart/uartfax.c @ 0:4e78acac3d88

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