comparison serial/debug-chases/uartfax.c @ 0:75a11d740a02

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