comparison src/cs/drivers/drv_core/uart/serialswitch_core.c @ 0:b6a5e36de839

src/cs: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:39:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:b6a5e36de839
1 /*******************************************************************************
2 *
3 * SERIALSWITCH_CORE.C
4 *
5 * This module allows managing the use of the serial ports of TI GSM Evaluation
6 * Boards.
7 * An application may have to send several serial data flows. The board on which
8 * the application is running may have one or several devices. The purpose of
9 * this module is to establish connections between the serial data flows and the
10 * serial devices at runtime, when the application is started.
11 *
12 * (C) Texas Instruments 1999 - 2003
13 *
14 ******************************************************************************/
15 /*
16 * 17/12/03
17 * Duplication of serialswitch.c for L1 standalone only
18 *
19 ******************************************************************************/
20
21 #define __SERIALSWITCH_CORE_C__
22
23 #define __STANDARD_H__ /* Avoid to define UBYTE, SYS_UWORD16 and UINT32. */
24
25 #include "l1sw.cfg"
26 #include "chipset.cfg"
27
28
29 #if (OP_L1_STANDALONE == 0)
30 #include "main/sys_types.h"
31 #else
32 #include "sys_types.h"
33 #endif
34
35 #include "nucleus.h"
36
37 #include "traceswitch.h"
38 #include "serialswitch_core.h"
39
40 #include "uart/uart.h"
41
42 #include "memif/mem.h"
43
44 #define DUMMY_DEVICE (0)
45
46 #define IIR (0x02) /* UART interrupt ident. register - Read only */
47 #define SCR (0x10) /* UART suppl. control register - Read/Write */
48 #define SSR (0x11) /* UART suppl. status register - Read only */
49
50 /*
51 * Interrupt identification register.
52 * Bit 0 is set to 0 if an IT is pending.
53 * Bits 1 and 2 are used to identify the IT.
54 */
55
56 #define IIR_BITS_USED (0x07)
57 #define IT_NOT_PENDING (0x01)
58
59 /*
60 * Supplementary Control Register
61 */
62
63 #define RX_CTS_WAKE_UP_ENABLE_BIT (4)
64
65 /*
66 * Supplementary Status Register
67 */
68
69 #define RX_CTS_WAKE_UP_STS (0x02) /* Wake-up interrupt occurred */
70
71 /*
72 * This macro allows to read an UART register.
73 */
74
75 #define READ_UART_REGISTER(UART,REG) \
76 *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))
77
78
79 /*
80 * This macro allows to disable the UART's wake-up interrupt.
81 */
82
83 #define DISABLE_WAKE_UP_INTERRUPT(UART) \
84 *((volatile SYS_UWORD8 *) ((UART)->base_address + SCR)) &= \
85 ~(1 << (RX_CTS_WAKE_UP_ENABLE_BIT));
86
87 /*
88 * Wake-up time duration in seconds and in number of TDMAs.
89 * 1 TDMA = (6 / 1300) s = 0.004615 s (= 4.615 ms).
90 */
91
92 #define WAKE_UP_TIME_DURATION (10) /* 10 seconds */
93 #define WAKE_UP_TIME_IN_TDMA (WAKE_UP_TIME_DURATION * 1300 / 6)
94
95
96 /*
97 * Global uartswitch variable as read from FFS.
98 * It is supposed that NUMBER_OF_TR_UART, NUMBER_OF_FD_UART
99 * and NUMBER_OF_BT_UART have the same values.
100 */
101
102 #define DUMMY ('0')
103 #define G23_PANEL ('G')
104 #define RIVIERA_TRACE_MUX ('R')
105 #define FD_AT_COMMAND ('D')
106 #define BLUETOOTH_HCI ('B')
107
108 #if (CHIPSET == 12)
109 char ser_cfg_info[NUMBER_OF_TR_UART] = {DUMMY, DUMMY, DUMMY};
110 #else
111 char ser_cfg_info[NUMBER_OF_TR_UART] = {DUMMY, DUMMY};
112 #endif
113 static SYS_UWORD16 serial_cfg = 0x0048; /* All dummies */
114
115 /*
116 * Types of flows supported.
117 */
118
119 typedef enum {
120 TRACE_FLOW
121 #if (OP_L1_STANDALONE == 0)
122 , FAX_DATA_FLOW,
123 BLUETOOTH_HCI_FLOW
124 #endif
125 } t_flow_type;
126
127 /*
128 * For each serial data flow, a set of function pointers allows calling the
129 * functions associated to a serial device.
130 */
131
132 typedef struct s_tr_functions {
133
134 T_tr_UartId device;
135
136 void (*tr_Init) (T_tr_UartId device,
137 T_tr_Baudrate baudrate,
138 void (callback_function (void)));
139
140 SYS_UWORD32 (*tr_ReadNChars) (T_tr_UartId device,
141 char *buffer,
142 SYS_UWORD32 chars_to_read);
143
144 SYS_UWORD32 (*tr_ReadNBytes) (T_tr_UartId device,
145 char *buffer,
146 SYS_UWORD32 chars_to_read,
147 SYS_BOOL *eof_detected);
148
149 SYS_UWORD32 (*tr_WriteNChars) (T_tr_UartId device,
150 char *buffer,
151 SYS_UWORD32 chars_to_write);
152
153 SYS_UWORD32 (*tr_EncapsulateNChars) (T_tr_UartId device,
154 char *buffer,
155 SYS_UWORD32 chars_to_write);
156
157 SYS_UWORD32 (*tr_WriteNBytes) (T_tr_UartId device,
158 SYS_UWORD8 *buffer,
159 SYS_UWORD32 chars_to_write);
160
161 void (*tr_WriteChar) (T_tr_UartId device,
162 char character);
163
164 void (*tr_WriteString) (T_tr_UartId device,
165 char *buffer);
166
167 SYS_BOOL (*tr_EnterSleep) (T_tr_UartId device);
168
169 void (*tr_WakeUp) (T_tr_UartId device);
170
171 } t_tr_functions;
172
173
174 /*
175 * Prototypes of dummy functions.
176 * Dummy functions for Trace.
177 */
178
179 static void dummy_tr_Init (T_tr_UartId device,
180 T_tr_Baudrate baudrate,
181 void (callback_function (void)));
182
183 static SYS_UWORD32 dummy_tr_ReadNChars (T_tr_UartId device,
184 char *buffer,
185 SYS_UWORD32 chars_to_read);
186
187 static SYS_UWORD32 dummy_tr_ReadNBytes (T_tr_UartId device,
188 char *buffer,
189 SYS_UWORD32 chars_to_read,
190 SYS_BOOL *eof_detected);
191
192 static SYS_UWORD32 dummy_tr_WriteNChars (T_tr_UartId device,
193 char *buffer,
194 SYS_UWORD32 chars_to_write);
195
196 static SYS_UWORD32 dummy_tr_EncapsulateNChars (T_tr_UartId device,
197 char *buffer,
198 SYS_UWORD32 chars_to_write);
199
200 static SYS_UWORD32 dummy_tr_WriteNBytes (T_tr_UartId device,
201 SYS_UWORD8 *buffer,
202 SYS_UWORD32 chars_to_write);
203
204 static void dummy_tr_WriteChar (T_tr_UartId device,
205 char character);
206
207 static void dummy_tr_WriteString (T_tr_UartId device,
208 char *buffer);
209
210 static SYS_BOOL dummy_tr_EnterSleep (T_tr_UartId device);
211
212 static void dummy_tr_WakeUp (T_tr_UartId device);
213
214
215
216
217 /*
218 * Constants tables representing the various possible configurations
219 * for Trace, Fax & Data and Bluetooth HCI according to the different devices.
220 * Constant table for Trace using no device.
221 */
222
223 static const t_tr_functions dummy_trace = {
224
225 (T_tr_UartId) DUMMY_DEVICE,
226 dummy_tr_Init,
227 dummy_tr_ReadNChars,
228 dummy_tr_ReadNBytes,
229 dummy_tr_WriteNChars,
230 dummy_tr_EncapsulateNChars,
231 dummy_tr_WriteNBytes,
232 dummy_tr_WriteChar,
233 dummy_tr_WriteString,
234 dummy_tr_EnterSleep,
235 dummy_tr_WakeUp
236 };
237
238 /*
239 * Constant table for Trace using UART IrDA.
240 */
241
242 static const t_tr_functions uart_irda_trace = {
243
244 UA_UART_0,
245 UA_Init,
246 UA_ReadNChars,
247 UA_ReadNBytes,
248 UA_WriteNChars,
249 UA_EncapsulateNChars,
250 UA_WriteNBytes,
251 UA_WriteChar,
252 UA_WriteString,
253 UA_EnterSleep,
254 UA_WakeUp
255 };
256
257 /*
258 * Constant table for Trace using UART Modem.
259 */
260
261 static const t_tr_functions uart_modem_trace = {
262
263 UA_UART_1,
264 UA_Init,
265 UA_ReadNChars,
266 UA_ReadNBytes,
267 UA_WriteNChars,
268 UA_EncapsulateNChars,
269 UA_WriteNBytes,
270 UA_WriteChar,
271 UA_WriteString,
272 UA_EnterSleep,
273 UA_WakeUp
274 };
275
276 #if (CHIPSET == 12)
277 /*
278 * Constant table for Trace using UART Modem2.
279 */
280
281 static const t_tr_functions uart_modem2_trace = {
282
283 UA_UART_2,
284 UA_Init,
285 UA_ReadNChars,
286 UA_ReadNBytes,
287 UA_WriteNChars,
288 UA_EncapsulateNChars,
289 UA_WriteNBytes,
290 UA_WriteChar,
291 UA_WriteString,
292 UA_EnterSleep,
293 UA_WakeUp
294 };
295 #endif
296
297
298
299 /*
300 * UART structure used for UARTs.
301 */
302
303 typedef struct s_uart {
304
305 SYS_UWORD32 base_address;
306 SYS_BOOL device_used;
307 SYS_BOOL deep_sleep_set_up;
308 t_flow_type flow_type;
309 SYS_WORD16 flow_id;
310 void (*interrupt_handler) (int uart_id,
311 SYS_UWORD8 interrupt_status);
312
313 } t_uart;
314
315 static const t_tr_functions *tr_functions[SER_MAX_NUMBER_OF_FLOWS];
316
317
318 /*
319 * Timer used for duration control when UARTs are waked up by an interrupt or
320 * each time any new incoming characters are received; This timer prevents the
321 * system to enter deep sleep mode.
322 */
323
324 static NU_TIMER uart_sleep_timer;
325 SYS_BOOL uart_sleep_timer_enabled;
326
327 /*
328 * HISR used to reset and restart the sleep timer from an UART use by a Trace
329 * flow in case of incoming characters.
330 */
331
332 #define TIMER_HISR_PRIORITY (2)
333 #define TIMER_HISR_STACK_SIZE (512) /* Bytes. */
334
335 static NU_HISR timer_hisr_ctrl_block;
336 static char timer_hisr_stack[TIMER_HISR_STACK_SIZE];
337
338 /*
339 * For next arrays, it is supposed that NUMBER_OF_TR_UART, NUMBER_OF_FD_UART
340 * and NUMBER_OF_BT_UART have the same values.
341 * An index on an internal uart for trace, fax & data or bluetooth hci reffers
342 * to the same uart device.
343 */
344
345 static t_uart int_uart[NUMBER_OF_TR_UART];
346
347 #if ((CHIPSET == 2) || (CHIPSET == 3))
348 static SYS_UWORD32 uart_spurious_interrupts;
349 #elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
350 static SYS_UWORD32 uart_modem_spurious_interrupts;
351 static SYS_UWORD32 uart_irda_spurious_interrupts;
352 #endif
353 #if (CHIPSET == 12)
354 static SYS_UWORD32 uart_modem2_spurious_interrupts;
355 #endif
356
357 static const SYS_UWORD32 uart_base_address[NUMBER_OF_TR_UART] =
358 {
359 MEM_UART_IRDA,
360 MEM_UART_MODEM
361 #if (CHIPSET == 12)
362 , MEM_UART_MODEM2
363 #endif
364 };
365
366
367 /*******************************************************************************
368 *
369 * dummy_tr_Init
370 *
371 * Purpose: No action.
372 *
373 * Parameters: See SER_tr_Init.
374 *
375 * Return: none
376 *
377 ******************************************************************************/
378
379 static void
380 dummy_tr_Init (T_tr_UartId device,
381 T_tr_Baudrate baudrate,
382 void (callback_function (void)))
383 {
384 /*
385 * No action.
386 */
387 }
388
389 /*******************************************************************************
390 *
391 * dummy_tr_ReadNChars
392 *
393 * Purpose: No action.
394 *
395 * Parameters: See SER_tr_ReadNChars.
396 *
397 * Return: 0
398 *
399 ******************************************************************************/
400
401 static SYS_UWORD32
402 dummy_tr_ReadNChars (T_tr_UartId device,
403 char *buffer,
404 SYS_UWORD32 chars_to_read)
405 {
406 return (0);
407 }
408
409 /*******************************************************************************
410 *
411 * dummy_tr_ReadNBytes
412 *
413 * Purpose: No action.
414 *
415 * Parameters: See SER_tr_ReadNBytes.
416 *
417 * Return: 0
418 *
419 ******************************************************************************/
420
421 static SYS_UWORD32
422 dummy_tr_ReadNBytes (T_tr_UartId device,
423 char *buffer,
424 SYS_UWORD32 chars_to_read,
425 SYS_BOOL *eof_detected)
426 {
427 return (0);
428 }
429
430 /*******************************************************************************
431 *
432 * dummy_tr_WriteNChars
433 *
434 * Purpose: No action.
435 *
436 * Parameters: See SER_tr_WriteNChars.
437 *
438 * Return: The number of character to write.
439 *
440 ******************************************************************************/
441
442 static SYS_UWORD32
443 dummy_tr_WriteNChars (T_tr_UartId device,
444 char *buffer,
445 SYS_UWORD32 chars_to_write)
446 {
447 return (chars_to_write);
448 }
449
450 /*******************************************************************************
451 *
452 * dummy_tr_EncapsulateNChars
453 *
454 * Purpose: No action.
455 *
456 * Parameters: See SER_tr_EncapsulateNChars.
457 *
458 * Return: The number of character to write.
459 *
460 ******************************************************************************/
461
462 static SYS_UWORD32
463 dummy_tr_EncapsulateNChars (T_tr_UartId device,
464 char *buffer,
465 SYS_UWORD32 chars_to_write)
466 {
467 return (chars_to_write);
468 }
469
470 /*******************************************************************************
471 *
472 * dummy_tr_WriteNBytes
473 *
474 * Purpose: No action.
475 *
476 * Parameters: See SER_tr_WriteNBytes.
477 *
478 * Return: The number of byte to write.
479 *
480 ******************************************************************************/
481
482 static SYS_UWORD32
483 dummy_tr_WriteNBytes (T_tr_UartId device,
484 SYS_UWORD8 *buffer,
485 SYS_UWORD32 chars_to_write)
486 {
487 return (chars_to_write);
488 }
489
490 /*******************************************************************************
491 *
492 * dummy_tr_WriteChar
493 *
494 * Purpose: No action.
495 *
496 * Parameters: See SER_tr_WriteChar.
497 *
498 * Return: none
499 *
500 ******************************************************************************/
501
502 static void
503 dummy_tr_WriteChar (T_tr_UartId device,
504 char character)
505 {
506 /*
507 * No action.
508 */
509 }
510
511 /*******************************************************************************
512 *
513 * dummy_tr_WriteString
514 *
515 * Purpose: No action.
516 *
517 * Parameters: See SER_tr_WriteString.
518 *
519 * Return: none
520 *
521 ******************************************************************************/
522
523 static void
524 dummy_tr_WriteString (T_tr_UartId device,
525 char *buffer)
526 {
527 /*
528 * No action.
529 */
530 }
531
532 /*******************************************************************************
533 *
534 * dummy_tr_EnterSleep
535 *
536 * Purpose: No action.
537 *
538 * Parameters: See SER_tr_EnterSleep.
539 *
540 * Return: 1
541 *
542 ******************************************************************************/
543
544 static SYS_BOOL
545 dummy_tr_EnterSleep (T_tr_UartId device)
546 {
547 return (1);
548 }
549
550 /*******************************************************************************
551 *
552 * dummy_tr_WakeUp
553 *
554 * Purpose: No action.
555 *
556 * Parameters: See SER_tr_WakeUp.
557 *
558 * Return: none
559 *
560 ******************************************************************************/
561
562 static void
563 dummy_tr_WakeUp (T_tr_UartId device)
564 {
565 /*
566 * No action.
567 */
568 }
569
570
571
572 /*******************************************************************************
573 *
574 * analyze_uart_sleep_timer_expiration
575 *
576 * Purpose : The timer has just expired. If requested, UARTs can again be set
577 * up to enter Deep Sleep.
578 *
579 * Arguments: In : id: parameter not used.
580 * Out: none
581 *
582 * Returns : none
583 *
584 ******************************************************************************/
585
586 static VOID
587 analyze_uart_sleep_timer_expiration (UNSIGNED id)
588 {
589 /*
590 * Timer has expired.
591 * UARTs can again be set up for Deep Sleep.
592 */
593
594 (void) NU_Control_Timer (&uart_sleep_timer,
595 NU_DISABLE_TIMER);
596
597 uart_sleep_timer_enabled = 0;
598 }
599
600 /*******************************************************************************
601 *
602 * start_uart_sleep_timer
603 *
604 * Purpose : Starts the sleep timer once UARTs have been waked-up by an
605 * interrupt or if new incoming characters have been received.
606 *
607 * Arguments: In : none
608 * Out: none
609 *
610 * Returns : none
611 *
612 ******************************************************************************/
613
614 static void
615 start_uart_sleep_timer (void)
616 {
617 /*
618 * UART sleep timer is started.
619 * UARTs can't no more be set up for Deep Sleep until the timer expires.
620 */
621
622 (void) NU_Reset_Timer (&uart_sleep_timer,
623 &analyze_uart_sleep_timer_expiration,
624 WAKE_UP_TIME_IN_TDMA,
625 0, /* The timer expires once. */
626 NU_DISABLE_TIMER);
627
628 (void) NU_Control_Timer (&uart_sleep_timer,
629 NU_ENABLE_TIMER);
630 }
631
632 /*******************************************************************************
633 *
634 * set_flow_functions
635 *
636 * Purpose: Initializes a serial data flow functions set with the set of
637 * functions of the selected device.
638 *
639 * Parameters: In : flow : index of the serial data flow
640 * serial_driver: allows knowing which set of functions must
641 * be selected
642 * Out: none
643 *
644 * Return: none
645 *
646 ******************************************************************************/
647
648 static void
649 set_flow_functions (int flow,
650 T_SerialDriver serial_driver)
651 {
652
653 switch (serial_driver) {
654
655 case UART_IRDA_TRACE:
656 case UART_MODEM_TRACE:
657 #if (CHIPSET == 12)
658 case UART_MODEM2_TRACE:
659 #endif
660
661 if (serial_driver == UART_IRDA_TRACE)
662 tr_functions[flow] = &uart_irda_trace;
663 else {
664 #if (CHIPSET == 12)
665 if (serial_driver == UART_MODEM2_TRACE)
666 tr_functions[flow] = &uart_modem2_trace;
667 else
668 #endif
669 tr_functions[flow] = &uart_modem_trace;
670 }
671
672 int_uart[tr_functions[flow]->device].device_used = 1;
673 int_uart[tr_functions[flow]->device].flow_type = TRACE_FLOW;
674 int_uart[tr_functions[flow]->device].flow_id = flow;
675 int_uart[tr_functions[flow]->device].interrupt_handler =
676 UA_InterruptHandler;
677 break;
678
679 case DUMMY_TRACE:
680
681 tr_functions[flow] = &dummy_trace;
682 break;
683
684 }
685 }
686
687 /*******************************************************************************
688 *
689 * SER_InitSerialConfig
690 *
691 * Purpose: The parameter serial_info allows knowing all serial information
692 * necessary to set up the serial configuration of an application.
693 * From this information, the function is able to determine if the
694 * current serial configuration read out from the flash memory is
695 * valid. If it does not correspond to an allowed configuration, the
696 * default configuration is selected. This function must be called at
697 * the application's initialization, but never after.
698 *
699 * Parameters: In : serial_info: application serial information like the default
700 * configuration and all allowed configurations.
701 * Out: none
702 *
703 * Return: none
704 *
705 ******************************************************************************/
706
707 void
708 SER_InitSerialConfig (T_AppliSerialInfo *serial_info)
709 {
710 int uart_id;
711 int flow;
712 T_SerialDriver serial_driver;
713 SYS_UWORD16 *allowed_config;
714 SYS_UWORD8 nb_allowed_config;
715 SYS_BOOL valid_config_selected;
716 SYS_BOOL uart_used;
717 SYS_BOOL uart_used_for_trace;
718 SYS_UWORD16 current_config;
719 SYS_UWORD16 *pt_current_config = &(current_config);
720
721 /*
722 * Basic UARTs initializations.
723 */
724
725 for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
726
727 int_uart[uart_id].base_address = uart_base_address[uart_id];
728 int_uart[uart_id].device_used = 0;
729 int_uart[uart_id].deep_sleep_set_up = 0;
730 }
731
732 #if ((CHIPSET == 2) || (CHIPSET == 3))
733 uart_spurious_interrupts = 0;
734 #elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
735 uart_modem_spurious_interrupts = 0;
736 uart_irda_spurious_interrupts = 0;
737 #endif
738 #if (CHIPSET == 12)
739 uart_modem2_spurious_interrupts = 0;
740 #endif
741 uart_sleep_timer_enabled = 0;
742
743 /*
744 * Compute the current serial configuration.
745 */
746
747 for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
748
749 switch (ser_cfg_info[uart_id]) {
750
751 case G23_PANEL:
752 serial_cfg = serial_cfg +
753 ((uart_id + 1) << (12 - (4 * SER_PROTOCOL_STACK)));
754 break;
755
756 case RIVIERA_TRACE_MUX:
757 serial_cfg = serial_cfg +
758 ((uart_id + 1) << (12 - (4 * SER_LAYER_1)));
759 break;
760
761 case FD_AT_COMMAND:
762 serial_cfg = serial_cfg +
763 ((uart_id + 1) << (12 - (4 * SER_FAX_DATA)));
764 break;
765
766 case BLUETOOTH_HCI:
767 serial_cfg = serial_cfg +
768 ((uart_id + 1) << (12 - (4 * SER_BLUETOOTH_HCI)));
769 break;
770
771 case DUMMY:
772 break;
773 }
774 }
775
776 current_config = serial_cfg;
777 valid_config_selected = 0;
778 nb_allowed_config = serial_info->num_config;
779
780 /*
781 * Checks if the current serial config is one of the allowed.
782 */
783
784 while ((nb_allowed_config > 0) && !valid_config_selected) {
785
786 nb_allowed_config--;
787 allowed_config = (SYS_UWORD16 *)
788 &(serial_info->allowed_config[nb_allowed_config]);
789
790 if (*pt_current_config == *allowed_config)
791 valid_config_selected = 1;
792 }
793
794 /*
795 * If not, the default configuration is selected.
796 */
797
798 if (!valid_config_selected) {
799
800 pt_current_config = (SYS_UWORD16 *)&(serial_info->default_config);
801
802 }
803
804 /*
805 * The serial data flow functions set is initialized.
806 */
807
808 flow = 0;
809 while (flow < SER_MAX_NUMBER_OF_FLOWS) {
810
811 serial_driver = (T_SerialDriver)
812 (((*pt_current_config) >> (12 - flow * 4)) & 0x000F);
813
814 set_flow_functions (flow, serial_driver);
815 flow++;
816 }
817
818 /*
819 * Checks if both UARTs are used.
820 * If not, performs minimum initialization including Sleep Mode.
821 * Checks also if at least one UART is used by a Trace flow.
822 * If so, create a HISR in order to reset and restart the sleep timer
823 * in case of incoming characters.
824 */
825
826 uart_used = 0;
827 uart_used_for_trace = 0;
828 for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
829
830 if (!(int_uart[uart_id].device_used))
831 initialize_uart_sleep ((T_tr_UartId) uart_id);
832
833 else { /* if (int_uart[uart_id].device_used) */
834
835 uart_used = 1; /* At least one UART is used */
836
837 if (int_uart[uart_id].flow_type == TRACE_FLOW) {
838
839 /* At least one UART used by a Trace flow */
840 uart_used_for_trace = 1;
841 }
842 }
843 }
844
845 /*
846 * If at least one uart is used, create a timer to figure out if the system
847 * can enter deep sleep mode regarding the UARTs.
848 */
849
850 if (uart_used) {
851
852 (void) NU_Create_Timer (
853 &uart_sleep_timer,
854 "Sleep",
855 &analyze_uart_sleep_timer_expiration,
856 0, /* Parameter supplied to the routine: not used. */
857 WAKE_UP_TIME_IN_TDMA,
858 0, /* The timer expires once. */
859 NU_DISABLE_TIMER);
860
861 /*
862 * If at least one uart is used by a Trace flow, create a HISR to reset
863 * and restart the sleep timer.
864 */
865
866 if (uart_used_for_trace) {
867
868 /*
869 * The HISR entry function is the same function than the one called
870 * by the Rx HISR of the UARTFAX, since the only aim is to reset
871 * and restart the sleep timer in case of incoming characters on
872 * the Trace UART.
873 */
874
875 (void) NU_Create_HISR (
876 &timer_hisr_ctrl_block,
877 "Tim_HISR",
878 SER_restart_uart_sleep_timer,
879 TIMER_HISR_PRIORITY,
880 &(timer_hisr_stack[0]),
881 TIMER_HISR_STACK_SIZE);
882 }
883 }
884 }
885
886
887
888 /*******************************************************************************
889 *
890 * All functions SER_tr_xxx and SER_fd_xxx call a function of the UART trace
891 * driver or the UART fax & data driver.
892 * All functions SER_bt_xxx call a function of the UART Bluetooth HCI driver.
893 * See the function call for parameters and return values.
894 *
895 ******************************************************************************/
896
897 void
898 SER_tr_Init (int serial_data_flow,
899 T_tr_Baudrate baudrate,
900 void (callback_function (void)))
901 {
902 tr_functions[serial_data_flow]->tr_Init (
903 tr_functions[serial_data_flow]->device, baudrate, callback_function);
904 }
905
906 SYS_UWORD32
907 SER_tr_ReadNChars (int serial_data_flow,
908 char *buffer,
909 SYS_UWORD32 chars_to_read)
910 {
911 return (tr_functions[serial_data_flow]->tr_ReadNChars (
912 tr_functions[serial_data_flow]->device, buffer, chars_to_read));
913 }
914
915 SYS_UWORD32
916 SER_tr_ReadNBytes (int serial_data_flow,
917 char *buffer,
918 SYS_UWORD32 chars_to_read,
919 SYS_BOOL *eof_detected)
920 {
921 return (tr_functions[serial_data_flow]->tr_ReadNBytes (
922 tr_functions[serial_data_flow]->device, buffer, chars_to_read, eof_detected));
923 }
924
925 SYS_UWORD32
926 SER_tr_WriteNChars (int serial_data_flow,
927 char *buffer,
928 SYS_UWORD32 chars_to_write)
929 {
930 return (tr_functions[serial_data_flow]->tr_WriteNChars (
931 tr_functions[serial_data_flow]->device, buffer, chars_to_write));
932 }
933
934 SYS_UWORD32
935 SER_tr_EncapsulateNChars (int serial_data_flow,
936 char *buffer,
937 SYS_UWORD32 chars_to_write)
938 {
939 return (tr_functions[serial_data_flow]->tr_EncapsulateNChars (
940 tr_functions[serial_data_flow]->device, buffer, chars_to_write));
941 }
942
943 SYS_UWORD32
944 SER_tr_WriteNBytes (int serial_data_flow,
945 SYS_UWORD8 *buffer,
946 SYS_UWORD32 chars_to_write)
947 {
948 return (tr_functions[serial_data_flow]->tr_WriteNBytes (
949 tr_functions[serial_data_flow]->device, buffer, chars_to_write));
950 }
951
952 void
953 SER_tr_WriteChar (int serial_data_flow,
954 char character)
955 {
956 tr_functions[serial_data_flow]->tr_WriteChar (
957 tr_functions[serial_data_flow]->device, character);
958 }
959
960 void
961 SER_tr_WriteString (int serial_data_flow,
962 char *buffer)
963 {
964 tr_functions[serial_data_flow]->tr_WriteString (
965 tr_functions[serial_data_flow]->device, buffer);
966 }
967
968 SYS_BOOL
969 SER_tr_EnterSleep (int serial_data_flow)
970 {
971 return (tr_functions[serial_data_flow]->tr_EnterSleep (
972 tr_functions[serial_data_flow]->device));
973 }
974
975 void
976 SER_tr_WakeUp (int serial_data_flow)
977 {
978 tr_functions[serial_data_flow]->tr_WakeUp (
979 tr_functions[serial_data_flow]->device);
980 }
981
982
983
984 /*******************************************************************************
985 *
986 * SER_UartSleepStatus
987 *
988 * Purpose: This function checks if both UARTs are ready to enter Deep Sleep.
989 *
990 * Parameters: In : none
991 * Out: none
992 *
993 * Return: 0 : Deep Sleep is not possible.
994 * >= 1 : Deep Sleep is possible.
995 *
996 ******************************************************************************/
997
998 SYS_BOOL
999 SER_UartSleepStatus (void)
1000 {
1001 t_uart *uart;
1002 int uart_id;
1003 SYS_BOOL status;
1004
1005 /*
1006 * Check first if the sleep timer is active or if a Dynamic Switch is
1007 * being processed. A return is used to simplify the code.
1008 */
1009
1010 if (uart_sleep_timer_enabled)
1011 return (0);
1012
1013 /*
1014 * Check if both UARTs are ready to enter Deep Sleep.
1015 */
1016
1017 status = 1;
1018 uart_id = 0;
1019 while ((uart_id < NUMBER_OF_TR_UART) &&
1020 (status)) {
1021
1022 uart = &(int_uart[uart_id]);
1023
1024 /*
1025 * Check if the specified UART is actually used.
1026 */
1027
1028 if (uart->device_used) {
1029
1030 /*
1031 * Check if the specified UART is used by a Trace or
1032 * by a Fax & Data flow.
1033 */
1034
1035 if (uart->flow_type == TRACE_FLOW)
1036 status = SER_tr_EnterSleep (uart->flow_id);
1037
1038 else
1039 status = 0;
1040
1041 if (status) {
1042
1043 /*
1044 * The specified UART is now set up for Deep Sleep.
1045 */
1046
1047 uart->deep_sleep_set_up = 1;
1048
1049 }
1050 }
1051
1052 uart_id++;
1053 }
1054
1055 /*
1056 * Check if Deep Sleep is finally possible.
1057 * If not revert eventual Deep Sleep settings.
1058 */
1059
1060 if (!status) {
1061
1062 for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
1063
1064 uart = &(int_uart[uart_id]);
1065
1066 /*
1067 * If the specified used UART has already been set up for
1068 * Deep Sleep, revert these settings.
1069 */
1070
1071 if ((uart->device_used) &&
1072 (uart->deep_sleep_set_up)) {
1073
1074 /*
1075 * Check if the specified UART is used by a Trace or
1076 * by a Fax & Data flow.
1077 * Bluetooth HCI can not yet handled Deep Sleep Mode.
1078 */
1079
1080 if (uart->flow_type == TRACE_FLOW)
1081 SER_tr_WakeUp (uart->flow_id);
1082
1083 uart->deep_sleep_set_up = 0;
1084
1085 }
1086 }
1087 }
1088
1089 return (status);
1090 }
1091
1092
1093 /*******************************************************************************
1094 *
1095 * SER_WakeUpUarts
1096 *
1097 * Purpose: This function wakes up used UARTs after Deep Sleep.
1098 *
1099 * Parameters: In : none
1100 * Out: none
1101 *
1102 * Return: none
1103 *
1104 ******************************************************************************/
1105
1106 void
1107 SER_WakeUpUarts (void)
1108 {
1109 t_uart *uart;
1110 int uart_id;
1111
1112 if (uart_sleep_timer_enabled)
1113 start_uart_sleep_timer ();
1114
1115 for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
1116
1117 uart = &(int_uart[uart_id]);
1118
1119 /*
1120 * Check if the specified UART is actually used, and has not yet
1121 * been waked up.
1122 */
1123
1124 if ((uart->device_used) &&
1125 (uart->deep_sleep_set_up)) {
1126
1127 /*
1128 * Check if the specified UART is used by a Trace or
1129 * by a Fax & Data flow.
1130 * Bluetooth HCI can not yet handled Deep Sleep Mode.
1131 */
1132
1133 if (uart->flow_type == TRACE_FLOW)
1134 SER_tr_WakeUp (uart->flow_id);
1135
1136 /*
1137 * The specified UART is no more set up for Deep Sleep.
1138 */
1139
1140 uart->deep_sleep_set_up = 0;
1141
1142 }
1143 }
1144 }
1145
1146
1147 /*******************************************************************************
1148 *
1149 * SER_restart_uart_sleep_timer
1150 *
1151 * Purpose : Resets and restarts the sleep timer each time some characters are
1152 * received.
1153 *
1154 * Arguments: In : none
1155 * Out: none
1156 *
1157 * Returns : none
1158 *
1159 ******************************************************************************/
1160
1161 void
1162 SER_restart_uart_sleep_timer (void)
1163 {
1164 /*
1165 * First disable the timer.
1166 */
1167
1168 (void) NU_Control_Timer (&uart_sleep_timer,
1169 NU_DISABLE_TIMER);
1170
1171 /*
1172 * Then start again this timer for a new period.
1173 */
1174
1175 start_uart_sleep_timer ();
1176 }
1177
1178
1179 /*******************************************************************************
1180 *
1181 * SER_activate_timer_hisr
1182 *
1183 * Purpose : Activates the timer HISR to reset and restart the sleep timer
1184 * each time some characters are received.
1185 *
1186 * Arguments: In : none
1187 * Out: none
1188 *
1189 * Returns : none
1190 *
1191 ******************************************************************************/
1192
1193 void
1194 SER_activate_timer_hisr (void)
1195 {
1196 (void) NU_Activate_HISR (&timer_hisr_ctrl_block);
1197 }
1198
1199
1200 #if ((CHIPSET == 2) || (CHIPSET == 3))
1201
1202 /*******************************************************************************
1203 *
1204 * SER_uart_handler
1205 *
1206 * Purpose : UART interrupt handler.
1207 *
1208 * Arguments: In : none
1209 * Out: none
1210 *
1211 * Returns : none
1212 *
1213 ******************************************************************************/
1214
1215 void
1216 SER_uart_handler (void)
1217 {
1218 SYS_UWORD8 interrupt_status;
1219 t_uart *uart;
1220 int uart_id;
1221 SYS_BOOL it_identified;
1222
1223 it_identified = 0;
1224
1225 /*
1226 * Check first for a wake-up interrupt.
1227 */
1228
1229 uart_id = 0;
1230 while ((uart_id < NUMBER_OF_TR_UART) &&
1231 (!it_identified)) {
1232
1233 uart = &(int_uart[uart_id]);
1234 interrupt_status = READ_UART_REGISTER (uart, SSR);
1235
1236 if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */
1237
1238 it_identified = 1;
1239 uart_sleep_timer_enabled = 1;
1240 DISABLE_WAKE_UP_INTERRUPT (uart);
1241 }
1242
1243 uart_id++;
1244 }
1245
1246 /*
1247 * If no wake-up interrupt has been detected, check then systematically
1248 * both UARTs for other interrupt causes.
1249 */
1250
1251 if (!it_identified) {
1252
1253 for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
1254
1255 uart = &(int_uart[uart_id]);
1256 interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
1257
1258 if (!(interrupt_status & IT_NOT_PENDING)) {
1259
1260 it_identified = 1;
1261 (*(uart->interrupt_handler)) (uart_id, interrupt_status);
1262
1263 } else {
1264
1265 if ((uart_id == UA_UART_1) && (!it_identified))
1266 uart_spurious_interrupts++;
1267 }
1268 }
1269 }
1270 }
1271
1272 #elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
1273
1274 /*******************************************************************************
1275 *
1276 * SER_uart_modem_handler
1277 *
1278 * Purpose : UART MODEM interrupt handler.
1279 *
1280 * Arguments: In : none
1281 * Out: none
1282 *
1283 * Returns : none
1284 *
1285 ******************************************************************************/
1286
1287 void
1288 SER_uart_modem_handler (void)
1289 {
1290 SYS_UWORD8 interrupt_status;
1291 t_uart *uart;
1292 SYS_BOOL it_wakeup_identified;
1293
1294 it_wakeup_identified = 0;
1295 uart = &(int_uart[UA_UART_1]);
1296
1297 /*
1298 * Check first for a wake-up interrupt.
1299 */
1300
1301 interrupt_status = READ_UART_REGISTER (uart, SSR);
1302
1303 if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */
1304
1305 it_wakeup_identified = 1;
1306 uart_sleep_timer_enabled = 1;
1307 DISABLE_WAKE_UP_INTERRUPT (uart);
1308 }
1309
1310 /*
1311 * If no wake-up interrupt has been detected, check UART for other
1312 * interrupt causes.
1313 */
1314
1315 if (!it_wakeup_identified) {
1316
1317 interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
1318
1319 if (!(interrupt_status & IT_NOT_PENDING))
1320 (*(uart->interrupt_handler)) (UA_UART_1, interrupt_status);
1321
1322 else
1323 uart_modem_spurious_interrupts++;
1324 }
1325 }
1326
1327
1328 /*******************************************************************************
1329 *
1330 * SER_uart_irda_handler
1331 *
1332 * Purpose : UART IrDA interrupt handler.
1333 *
1334 * Arguments: In : none
1335 * Out: none
1336 *
1337 * Returns : none
1338 *
1339 ******************************************************************************/
1340
1341 void
1342 SER_uart_irda_handler (void)
1343 {
1344 SYS_UWORD8 interrupt_status;
1345 t_uart *uart;
1346 SYS_BOOL it_wakeup_identified;
1347
1348 it_wakeup_identified = 0;
1349 uart = &(int_uart[UA_UART_0]);
1350
1351 /*
1352 * Check first for a wake-up interrupt.
1353 */
1354
1355 interrupt_status = READ_UART_REGISTER (uart, SSR);
1356
1357 if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */
1358
1359 it_wakeup_identified = 1;
1360 uart_sleep_timer_enabled = 1;
1361 DISABLE_WAKE_UP_INTERRUPT (uart);
1362 }
1363
1364 /*
1365 * If no wake-up interrupt has been detected, check UART for other
1366 * interrupt causes.
1367 */
1368
1369 if (!it_wakeup_identified) {
1370
1371 interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
1372
1373 if (!(interrupt_status & IT_NOT_PENDING))
1374 (*(uart->interrupt_handler)) (UA_UART_0, interrupt_status);
1375
1376 else
1377 uart_irda_spurious_interrupts++;
1378 }
1379 }
1380
1381 #endif
1382
1383 #if (CHIPSET == 12)
1384 /*******************************************************************************
1385 *
1386 * SER_uart_modem2_handler
1387 *
1388 * Purpose : UART IrDA interrupt handler.
1389 *
1390 * Arguments: In : none
1391 * Out: none
1392 *
1393 * Returns : none
1394 *
1395 ******************************************************************************/
1396
1397 void
1398 SER_uart_modem2_handler (void)
1399 {
1400 SYS_UWORD8 interrupt_status;
1401 t_uart *uart;
1402 SYS_BOOL it_wakeup_identified;
1403
1404 it_wakeup_identified = 0;
1405 uart = &(int_uart[UA_UART_2]);
1406
1407 /*
1408 * Check first for a wake-up interrupt.
1409 */
1410
1411 interrupt_status = READ_UART_REGISTER (uart, SSR);
1412
1413 if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */
1414
1415 it_wakeup_identified = 1;
1416 uart_sleep_timer_enabled = 1;
1417 DISABLE_WAKE_UP_INTERRUPT (uart);
1418 }
1419
1420 /*
1421 * If no wake-up interrupt has been detected, check UART for other
1422 * interrupt causes.
1423 */
1424
1425 if (!it_wakeup_identified) {
1426
1427 interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
1428
1429 if (!(interrupt_status & IT_NOT_PENDING))
1430 (*(uart->interrupt_handler)) (UA_UART_2, interrupt_status);
1431
1432 else
1433 uart_modem2_spurious_interrupts++;
1434 }
1435 }
1436
1437 #endif
1438
1439 /*
1440 * Temporary functions.
1441 */
1442
1443 void
1444 UT_Init (int device_id,
1445 T_tr_Baudrate baudrate,
1446 void (callback_function (void)))
1447 {
1448 SER_tr_Init (SER_PROTOCOL_STACK, baudrate, callback_function);
1449 }
1450
1451 SYS_UWORD32
1452 UT_ReadNChars (int device_id,
1453 char *buffer,
1454 SYS_UWORD32 chars_to_read)
1455 {
1456 return (SER_tr_ReadNChars (SER_PROTOCOL_STACK, buffer, chars_to_read));
1457 }
1458
1459 SYS_UWORD32
1460 UT_WriteNChars (int device_id,
1461 char *buffer,
1462 SYS_UWORD32 chars_to_write)
1463 {
1464 return (SER_tr_WriteNChars (SER_PROTOCOL_STACK, buffer, chars_to_write));
1465 }
1466
1467 void
1468 UT_WriteChar (int device_id,
1469 char character)
1470 {
1471 SER_tr_WriteChar (SER_PROTOCOL_STACK, character);
1472 }
1473
1474 void
1475 UT_WriteString (int device_id,
1476 char *buffer)
1477 {
1478 SER_tr_WriteString (SER_PROTOCOL_STACK, buffer);
1479 }