comparison chipsetsw/drivers/drv_app/uart/uartfax.c @ 0:509db1a7b7b8

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