FreeCalypso > hg > fc-magnetite
diff src/cs/drivers/drv_core/uart/serialswitch_core.c @ 0:945cf7f506b2
src/cs: chipsetsw import from tcs211-fcmodem
binary blobs and LCD demo files have been excluded,
all line endings are LF only
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Sep 2016 22:50:11 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/drivers/drv_core/uart/serialswitch_core.c Sun Sep 25 22:50:11 2016 +0000 @@ -0,0 +1,1479 @@ +/******************************************************************************* + * + * SERIALSWITCH_CORE.C + * + * This module allows managing the use of the serial ports of TI GSM Evaluation + * Boards. + * An application may have to send several serial data flows. The board on which + * the application is running may have one or several devices. The purpose of + * this module is to establish connections between the serial data flows and the + * serial devices at runtime, when the application is started. + * + * (C) Texas Instruments 1999 - 2003 + * + ******************************************************************************/ +/* + * 17/12/03 + * Duplication of serialswitch.c for L1 standalone only + * + ******************************************************************************/ + +#define __SERIALSWITCH_CORE_C__ + +#define __STANDARD_H__ /* Avoid to define UBYTE, SYS_UWORD16 and UINT32. */ + +#include "l1sw.cfg" +#include "chipset.cfg" + + +#if (OP_L1_STANDALONE == 0) + #include "main/sys_types.h" +#else + #include "sys_types.h" +#endif + +#include "nucleus.h" + +#include "traceswitch.h" +#include "serialswitch_core.h" + +#include "uart/uart.h" + +#include "memif/mem.h" + +#define DUMMY_DEVICE (0) + +#define IIR (0x02) /* UART interrupt ident. register - Read only */ +#define SCR (0x10) /* UART suppl. control register - Read/Write */ +#define SSR (0x11) /* UART suppl. status register - Read only */ + +/* + * Interrupt identification register. + * Bit 0 is set to 0 if an IT is pending. + * Bits 1 and 2 are used to identify the IT. + */ + +#define IIR_BITS_USED (0x07) +#define IT_NOT_PENDING (0x01) + +/* + * Supplementary Control Register + */ + +#define RX_CTS_WAKE_UP_ENABLE_BIT (4) + +/* + * Supplementary Status Register + */ + +#define RX_CTS_WAKE_UP_STS (0x02) /* Wake-up interrupt occurred */ + +/* + * This macro allows to read an UART register. + */ + +#define READ_UART_REGISTER(UART,REG) \ + *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG))) + + +/* + * This macro allows to disable the UART's wake-up interrupt. + */ + +#define DISABLE_WAKE_UP_INTERRUPT(UART) \ + *((volatile SYS_UWORD8 *) ((UART)->base_address + SCR)) &= \ + ~(1 << (RX_CTS_WAKE_UP_ENABLE_BIT)); + +/* + * Wake-up time duration in seconds and in number of TDMAs. + * 1 TDMA = (6 / 1300) s = 0.004615 s (= 4.615 ms). + */ + +#define WAKE_UP_TIME_DURATION (10) /* 10 seconds */ +#define WAKE_UP_TIME_IN_TDMA (WAKE_UP_TIME_DURATION * 1300 / 6) + + +/* + * Global uartswitch variable as read from FFS. + * It is supposed that NUMBER_OF_TR_UART, NUMBER_OF_FD_UART + * and NUMBER_OF_BT_UART have the same values. + */ + +#define DUMMY ('0') +#define G23_PANEL ('G') +#define RIVIERA_TRACE_MUX ('R') +#define FD_AT_COMMAND ('D') +#define BLUETOOTH_HCI ('B') + +#if (CHIPSET == 12) + char ser_cfg_info[NUMBER_OF_TR_UART] = {DUMMY, DUMMY, DUMMY}; +#else + char ser_cfg_info[NUMBER_OF_TR_UART] = {DUMMY, DUMMY}; +#endif +static SYS_UWORD16 serial_cfg = 0x0048; /* All dummies */ + +/* + * Types of flows supported. + */ + +typedef enum { + TRACE_FLOW +#if (OP_L1_STANDALONE == 0) + , FAX_DATA_FLOW, + BLUETOOTH_HCI_FLOW +#endif +} t_flow_type; + +/* + * For each serial data flow, a set of function pointers allows calling the + * functions associated to a serial device. + */ + +typedef struct s_tr_functions { + + T_tr_UartId device; + + void (*tr_Init) (T_tr_UartId device, + T_tr_Baudrate baudrate, + void (callback_function (void))); + + SYS_UWORD32 (*tr_ReadNChars) (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_read); + + SYS_UWORD32 (*tr_ReadNBytes) (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_read, + SYS_BOOL *eof_detected); + + SYS_UWORD32 (*tr_WriteNChars) (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_write); + + SYS_UWORD32 (*tr_EncapsulateNChars) (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_write); + + SYS_UWORD32 (*tr_WriteNBytes) (T_tr_UartId device, + SYS_UWORD8 *buffer, + SYS_UWORD32 chars_to_write); + + void (*tr_WriteChar) (T_tr_UartId device, + char character); + + void (*tr_WriteString) (T_tr_UartId device, + char *buffer); + + SYS_BOOL (*tr_EnterSleep) (T_tr_UartId device); + + void (*tr_WakeUp) (T_tr_UartId device); + +} t_tr_functions; + + +/* + * Prototypes of dummy functions. + * Dummy functions for Trace. + */ + +static void dummy_tr_Init (T_tr_UartId device, + T_tr_Baudrate baudrate, + void (callback_function (void))); + +static SYS_UWORD32 dummy_tr_ReadNChars (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_read); + +static SYS_UWORD32 dummy_tr_ReadNBytes (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_read, + SYS_BOOL *eof_detected); + +static SYS_UWORD32 dummy_tr_WriteNChars (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_write); + +static SYS_UWORD32 dummy_tr_EncapsulateNChars (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_write); + +static SYS_UWORD32 dummy_tr_WriteNBytes (T_tr_UartId device, + SYS_UWORD8 *buffer, + SYS_UWORD32 chars_to_write); + +static void dummy_tr_WriteChar (T_tr_UartId device, + char character); + +static void dummy_tr_WriteString (T_tr_UartId device, + char *buffer); + +static SYS_BOOL dummy_tr_EnterSleep (T_tr_UartId device); + +static void dummy_tr_WakeUp (T_tr_UartId device); + + + + +/* + * Constants tables representing the various possible configurations + * for Trace, Fax & Data and Bluetooth HCI according to the different devices. + * Constant table for Trace using no device. + */ + +static const t_tr_functions dummy_trace = { + + (T_tr_UartId) DUMMY_DEVICE, + dummy_tr_Init, + dummy_tr_ReadNChars, + dummy_tr_ReadNBytes, + dummy_tr_WriteNChars, + dummy_tr_EncapsulateNChars, + dummy_tr_WriteNBytes, + dummy_tr_WriteChar, + dummy_tr_WriteString, + dummy_tr_EnterSleep, + dummy_tr_WakeUp +}; + +/* + * Constant table for Trace using UART IrDA. + */ + +static const t_tr_functions uart_irda_trace = { + + UA_UART_0, + UA_Init, + UA_ReadNChars, + UA_ReadNBytes, + UA_WriteNChars, + UA_EncapsulateNChars, + UA_WriteNBytes, + UA_WriteChar, + UA_WriteString, + UA_EnterSleep, + UA_WakeUp +}; + +/* + * Constant table for Trace using UART Modem. + */ + +static const t_tr_functions uart_modem_trace = { + + UA_UART_1, + UA_Init, + UA_ReadNChars, + UA_ReadNBytes, + UA_WriteNChars, + UA_EncapsulateNChars, + UA_WriteNBytes, + UA_WriteChar, + UA_WriteString, + UA_EnterSleep, + UA_WakeUp +}; + +#if (CHIPSET == 12) + /* + * Constant table for Trace using UART Modem2. + */ + + static const t_tr_functions uart_modem2_trace = { + + UA_UART_2, + UA_Init, + UA_ReadNChars, + UA_ReadNBytes, + UA_WriteNChars, + UA_EncapsulateNChars, + UA_WriteNBytes, + UA_WriteChar, + UA_WriteString, + UA_EnterSleep, + UA_WakeUp + }; +#endif + + + +/* + * UART structure used for UARTs. + */ + +typedef struct s_uart { + + SYS_UWORD32 base_address; + SYS_BOOL device_used; + SYS_BOOL deep_sleep_set_up; + t_flow_type flow_type; + SYS_WORD16 flow_id; + void (*interrupt_handler) (int uart_id, + SYS_UWORD8 interrupt_status); + +} t_uart; + +static const t_tr_functions *tr_functions[SER_MAX_NUMBER_OF_FLOWS]; + + +/* + * Timer used for duration control when UARTs are waked up by an interrupt or + * each time any new incoming characters are received; This timer prevents the + * system to enter deep sleep mode. + */ + +static NU_TIMER uart_sleep_timer; + SYS_BOOL uart_sleep_timer_enabled; + +/* + * HISR used to reset and restart the sleep timer from an UART use by a Trace + * flow in case of incoming characters. + */ + +#define TIMER_HISR_PRIORITY (2) +#define TIMER_HISR_STACK_SIZE (512) /* Bytes. */ + +static NU_HISR timer_hisr_ctrl_block; +static char timer_hisr_stack[TIMER_HISR_STACK_SIZE]; + +/* + * For next arrays, it is supposed that NUMBER_OF_TR_UART, NUMBER_OF_FD_UART + * and NUMBER_OF_BT_UART have the same values. + * An index on an internal uart for trace, fax & data or bluetooth hci reffers + * to the same uart device. + */ + +static t_uart int_uart[NUMBER_OF_TR_UART]; + +#if ((CHIPSET == 2) || (CHIPSET == 3)) + static SYS_UWORD32 uart_spurious_interrupts; +#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) + static SYS_UWORD32 uart_modem_spurious_interrupts; + static SYS_UWORD32 uart_irda_spurious_interrupts; +#endif +#if (CHIPSET == 12) + static SYS_UWORD32 uart_modem2_spurious_interrupts; +#endif + +static const SYS_UWORD32 uart_base_address[NUMBER_OF_TR_UART] = +{ + MEM_UART_IRDA, + MEM_UART_MODEM + #if (CHIPSET == 12) + , MEM_UART_MODEM2 + #endif +}; + + +/******************************************************************************* + * + * dummy_tr_Init + * + * Purpose: No action. + * + * Parameters: See SER_tr_Init. + * + * Return: none + * + ******************************************************************************/ + +static void +dummy_tr_Init (T_tr_UartId device, + T_tr_Baudrate baudrate, + void (callback_function (void))) +{ + /* + * No action. + */ +} + +/******************************************************************************* + * + * dummy_tr_ReadNChars + * + * Purpose: No action. + * + * Parameters: See SER_tr_ReadNChars. + * + * Return: 0 + * + ******************************************************************************/ + +static SYS_UWORD32 +dummy_tr_ReadNChars (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_read) +{ + return (0); +} + +/******************************************************************************* + * + * dummy_tr_ReadNBytes + * + * Purpose: No action. + * + * Parameters: See SER_tr_ReadNBytes. + * + * Return: 0 + * + ******************************************************************************/ + +static SYS_UWORD32 +dummy_tr_ReadNBytes (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_read, + SYS_BOOL *eof_detected) +{ + return (0); +} + +/******************************************************************************* + * + * dummy_tr_WriteNChars + * + * Purpose: No action. + * + * Parameters: See SER_tr_WriteNChars. + * + * Return: The number of character to write. + * + ******************************************************************************/ + +static SYS_UWORD32 +dummy_tr_WriteNChars (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_write) +{ + return (chars_to_write); +} + +/******************************************************************************* + * + * dummy_tr_EncapsulateNChars + * + * Purpose: No action. + * + * Parameters: See SER_tr_EncapsulateNChars. + * + * Return: The number of character to write. + * + ******************************************************************************/ + +static SYS_UWORD32 +dummy_tr_EncapsulateNChars (T_tr_UartId device, + char *buffer, + SYS_UWORD32 chars_to_write) +{ + return (chars_to_write); +} + +/******************************************************************************* + * + * dummy_tr_WriteNBytes + * + * Purpose: No action. + * + * Parameters: See SER_tr_WriteNBytes. + * + * Return: The number of byte to write. + * + ******************************************************************************/ + +static SYS_UWORD32 +dummy_tr_WriteNBytes (T_tr_UartId device, + SYS_UWORD8 *buffer, + SYS_UWORD32 chars_to_write) +{ + return (chars_to_write); +} + +/******************************************************************************* + * + * dummy_tr_WriteChar + * + * Purpose: No action. + * + * Parameters: See SER_tr_WriteChar. + * + * Return: none + * + ******************************************************************************/ + +static void +dummy_tr_WriteChar (T_tr_UartId device, + char character) +{ + /* + * No action. + */ +} + +/******************************************************************************* + * + * dummy_tr_WriteString + * + * Purpose: No action. + * + * Parameters: See SER_tr_WriteString. + * + * Return: none + * + ******************************************************************************/ + +static void +dummy_tr_WriteString (T_tr_UartId device, + char *buffer) +{ + /* + * No action. + */ +} + +/******************************************************************************* + * + * dummy_tr_EnterSleep + * + * Purpose: No action. + * + * Parameters: See SER_tr_EnterSleep. + * + * Return: 1 + * + ******************************************************************************/ + +static SYS_BOOL +dummy_tr_EnterSleep (T_tr_UartId device) +{ + return (1); +} + +/******************************************************************************* + * + * dummy_tr_WakeUp + * + * Purpose: No action. + * + * Parameters: See SER_tr_WakeUp. + * + * Return: none + * + ******************************************************************************/ + +static void +dummy_tr_WakeUp (T_tr_UartId device) +{ + /* + * No action. + */ +} + + + +/******************************************************************************* + * + * analyze_uart_sleep_timer_expiration + * + * Purpose : The timer has just expired. If requested, UARTs can again be set + * up to enter Deep Sleep. + * + * Arguments: In : id: parameter not used. + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +static VOID +analyze_uart_sleep_timer_expiration (UNSIGNED id) +{ + /* + * Timer has expired. + * UARTs can again be set up for Deep Sleep. + */ + + (void) NU_Control_Timer (&uart_sleep_timer, + NU_DISABLE_TIMER); + + uart_sleep_timer_enabled = 0; +} + +/******************************************************************************* + * + * start_uart_sleep_timer + * + * Purpose : Starts the sleep timer once UARTs have been waked-up by an + * interrupt or if new incoming characters have been received. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +static void +start_uart_sleep_timer (void) +{ + /* + * UART sleep timer is started. + * UARTs can't no more be set up for Deep Sleep until the timer expires. + */ + + (void) NU_Reset_Timer (&uart_sleep_timer, + &analyze_uart_sleep_timer_expiration, + WAKE_UP_TIME_IN_TDMA, + 0, /* The timer expires once. */ + NU_DISABLE_TIMER); + + (void) NU_Control_Timer (&uart_sleep_timer, + NU_ENABLE_TIMER); +} + +/******************************************************************************* + * + * set_flow_functions + * + * Purpose: Initializes a serial data flow functions set with the set of + * functions of the selected device. + * + * Parameters: In : flow : index of the serial data flow + * serial_driver: allows knowing which set of functions must + * be selected + * Out: none + * + * Return: none + * + ******************************************************************************/ + +static void +set_flow_functions (int flow, + T_SerialDriver serial_driver) +{ + + switch (serial_driver) { + + case UART_IRDA_TRACE: + case UART_MODEM_TRACE: + #if (CHIPSET == 12) + case UART_MODEM2_TRACE: + #endif + + if (serial_driver == UART_IRDA_TRACE) + tr_functions[flow] = &uart_irda_trace; + else { + #if (CHIPSET == 12) + if (serial_driver == UART_MODEM2_TRACE) + tr_functions[flow] = &uart_modem2_trace; + else + #endif + tr_functions[flow] = &uart_modem_trace; + } + + int_uart[tr_functions[flow]->device].device_used = 1; + int_uart[tr_functions[flow]->device].flow_type = TRACE_FLOW; + int_uart[tr_functions[flow]->device].flow_id = flow; + int_uart[tr_functions[flow]->device].interrupt_handler = + UA_InterruptHandler; + break; + + case DUMMY_TRACE: + + tr_functions[flow] = &dummy_trace; + break; + + } +} + +/******************************************************************************* + * + * SER_InitSerialConfig + * + * Purpose: The parameter serial_info allows knowing all serial information + * necessary to set up the serial configuration of an application. + * From this information, the function is able to determine if the + * current serial configuration read out from the flash memory is + * valid. If it does not correspond to an allowed configuration, the + * default configuration is selected. This function must be called at + * the application's initialization, but never after. + * + * Parameters: In : serial_info: application serial information like the default + * configuration and all allowed configurations. + * Out: none + * + * Return: none + * + ******************************************************************************/ + +void +SER_InitSerialConfig (T_AppliSerialInfo *serial_info) +{ + int uart_id; + int flow; + T_SerialDriver serial_driver; + SYS_UWORD16 *allowed_config; + SYS_UWORD8 nb_allowed_config; + SYS_BOOL valid_config_selected; + SYS_BOOL uart_used; + SYS_BOOL uart_used_for_trace; + SYS_UWORD16 current_config; + SYS_UWORD16 *pt_current_config = &(current_config); + + /* + * Basic UARTs initializations. + */ + + for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) { + + int_uart[uart_id].base_address = uart_base_address[uart_id]; + int_uart[uart_id].device_used = 0; + int_uart[uart_id].deep_sleep_set_up = 0; + } + +#if ((CHIPSET == 2) || (CHIPSET == 3)) + uart_spurious_interrupts = 0; +#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) + uart_modem_spurious_interrupts = 0; + uart_irda_spurious_interrupts = 0; +#endif +#if (CHIPSET == 12) + uart_modem2_spurious_interrupts = 0; +#endif + uart_sleep_timer_enabled = 0; + + /* + * Compute the current serial configuration. + */ + + for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) { + + switch (ser_cfg_info[uart_id]) { + + case G23_PANEL: + serial_cfg = serial_cfg + + ((uart_id + 1) << (12 - (4 * SER_PROTOCOL_STACK))); + break; + + case RIVIERA_TRACE_MUX: + serial_cfg = serial_cfg + + ((uart_id + 1) << (12 - (4 * SER_LAYER_1))); + break; + + case FD_AT_COMMAND: + serial_cfg = serial_cfg + + ((uart_id + 1) << (12 - (4 * SER_FAX_DATA))); + break; + + case BLUETOOTH_HCI: + serial_cfg = serial_cfg + + ((uart_id + 1) << (12 - (4 * SER_BLUETOOTH_HCI))); + break; + + case DUMMY: + break; + } + } + + current_config = serial_cfg; + valid_config_selected = 0; + nb_allowed_config = serial_info->num_config; + + /* + * Checks if the current serial config is one of the allowed. + */ + + while ((nb_allowed_config > 0) && !valid_config_selected) { + + nb_allowed_config--; + allowed_config = (SYS_UWORD16 *) + &(serial_info->allowed_config[nb_allowed_config]); + + if (*pt_current_config == *allowed_config) + valid_config_selected = 1; + } + + /* + * If not, the default configuration is selected. + */ + + if (!valid_config_selected) { + + pt_current_config = (SYS_UWORD16 *)&(serial_info->default_config); + + } + + /* + * The serial data flow functions set is initialized. + */ + + flow = 0; + while (flow < SER_MAX_NUMBER_OF_FLOWS) { + + serial_driver = (T_SerialDriver) + (((*pt_current_config) >> (12 - flow * 4)) & 0x000F); + + set_flow_functions (flow, serial_driver); + flow++; + } + + /* + * Checks if both UARTs are used. + * If not, performs minimum initialization including Sleep Mode. + * Checks also if at least one UART is used by a Trace flow. + * If so, create a HISR in order to reset and restart the sleep timer + * in case of incoming characters. + */ + + uart_used = 0; + uart_used_for_trace = 0; + for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) { + + if (!(int_uart[uart_id].device_used)) + initialize_uart_sleep ((T_tr_UartId) uart_id); + + else { /* if (int_uart[uart_id].device_used) */ + + uart_used = 1; /* At least one UART is used */ + + if (int_uart[uart_id].flow_type == TRACE_FLOW) { + + /* At least one UART used by a Trace flow */ + uart_used_for_trace = 1; + } + } + } + + /* + * If at least one uart is used, create a timer to figure out if the system + * can enter deep sleep mode regarding the UARTs. + */ + + if (uart_used) { + + (void) NU_Create_Timer ( + &uart_sleep_timer, + "Sleep", + &analyze_uart_sleep_timer_expiration, + 0, /* Parameter supplied to the routine: not used. */ + WAKE_UP_TIME_IN_TDMA, + 0, /* The timer expires once. */ + NU_DISABLE_TIMER); + + /* + * If at least one uart is used by a Trace flow, create a HISR to reset + * and restart the sleep timer. + */ + + if (uart_used_for_trace) { + + /* + * The HISR entry function is the same function than the one called + * by the Rx HISR of the UARTFAX, since the only aim is to reset + * and restart the sleep timer in case of incoming characters on + * the Trace UART. + */ + + (void) NU_Create_HISR ( + &timer_hisr_ctrl_block, + "Tim_HISR", + SER_restart_uart_sleep_timer, + TIMER_HISR_PRIORITY, + &(timer_hisr_stack[0]), + TIMER_HISR_STACK_SIZE); + } + } +} + + + +/******************************************************************************* + * + * All functions SER_tr_xxx and SER_fd_xxx call a function of the UART trace + * driver or the UART fax & data driver. + * All functions SER_bt_xxx call a function of the UART Bluetooth HCI driver. + * See the function call for parameters and return values. + * + ******************************************************************************/ + +void +SER_tr_Init (int serial_data_flow, + T_tr_Baudrate baudrate, + void (callback_function (void))) +{ + tr_functions[serial_data_flow]->tr_Init ( + tr_functions[serial_data_flow]->device, baudrate, callback_function); +} + +SYS_UWORD32 +SER_tr_ReadNChars (int serial_data_flow, + char *buffer, + SYS_UWORD32 chars_to_read) +{ + return (tr_functions[serial_data_flow]->tr_ReadNChars ( + tr_functions[serial_data_flow]->device, buffer, chars_to_read)); +} + +SYS_UWORD32 +SER_tr_ReadNBytes (int serial_data_flow, + char *buffer, + SYS_UWORD32 chars_to_read, + SYS_BOOL *eof_detected) +{ + return (tr_functions[serial_data_flow]->tr_ReadNBytes ( + tr_functions[serial_data_flow]->device, buffer, chars_to_read, eof_detected)); +} + +SYS_UWORD32 +SER_tr_WriteNChars (int serial_data_flow, + char *buffer, + SYS_UWORD32 chars_to_write) +{ + return (tr_functions[serial_data_flow]->tr_WriteNChars ( + tr_functions[serial_data_flow]->device, buffer, chars_to_write)); +} + +SYS_UWORD32 +SER_tr_EncapsulateNChars (int serial_data_flow, + char *buffer, + SYS_UWORD32 chars_to_write) +{ + return (tr_functions[serial_data_flow]->tr_EncapsulateNChars ( + tr_functions[serial_data_flow]->device, buffer, chars_to_write)); +} + +SYS_UWORD32 +SER_tr_WriteNBytes (int serial_data_flow, + SYS_UWORD8 *buffer, + SYS_UWORD32 chars_to_write) +{ + return (tr_functions[serial_data_flow]->tr_WriteNBytes ( + tr_functions[serial_data_flow]->device, buffer, chars_to_write)); +} + +void +SER_tr_WriteChar (int serial_data_flow, + char character) +{ + tr_functions[serial_data_flow]->tr_WriteChar ( + tr_functions[serial_data_flow]->device, character); +} + +void +SER_tr_WriteString (int serial_data_flow, + char *buffer) +{ + tr_functions[serial_data_flow]->tr_WriteString ( + tr_functions[serial_data_flow]->device, buffer); +} + +SYS_BOOL +SER_tr_EnterSleep (int serial_data_flow) +{ + return (tr_functions[serial_data_flow]->tr_EnterSleep ( + tr_functions[serial_data_flow]->device)); +} + +void +SER_tr_WakeUp (int serial_data_flow) +{ + tr_functions[serial_data_flow]->tr_WakeUp ( + tr_functions[serial_data_flow]->device); +} + + + +/******************************************************************************* + * + * SER_UartSleepStatus + * + * Purpose: This function checks if both UARTs are ready to enter Deep Sleep. + * + * Parameters: In : none + * Out: none + * + * Return: 0 : Deep Sleep is not possible. + * >= 1 : Deep Sleep is possible. + * + ******************************************************************************/ + +SYS_BOOL +SER_UartSleepStatus (void) +{ + t_uart *uart; + int uart_id; + SYS_BOOL status; + + /* + * Check first if the sleep timer is active or if a Dynamic Switch is + * being processed. A return is used to simplify the code. + */ + + if (uart_sleep_timer_enabled) + return (0); + + /* + * Check if both UARTs are ready to enter Deep Sleep. + */ + + status = 1; + uart_id = 0; + while ((uart_id < NUMBER_OF_TR_UART) && + (status)) { + + uart = &(int_uart[uart_id]); + + /* + * Check if the specified UART is actually used. + */ + + if (uart->device_used) { + + /* + * Check if the specified UART is used by a Trace or + * by a Fax & Data flow. + */ + + if (uart->flow_type == TRACE_FLOW) + status = SER_tr_EnterSleep (uart->flow_id); + + else + status = 0; + + if (status) { + + /* + * The specified UART is now set up for Deep Sleep. + */ + + uart->deep_sleep_set_up = 1; + + } + } + + uart_id++; + } + + /* + * Check if Deep Sleep is finally possible. + * If not revert eventual Deep Sleep settings. + */ + + if (!status) { + + for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) { + + uart = &(int_uart[uart_id]); + + /* + * If the specified used UART has already been set up for + * Deep Sleep, revert these settings. + */ + + if ((uart->device_used) && + (uart->deep_sleep_set_up)) { + + /* + * Check if the specified UART is used by a Trace or + * by a Fax & Data flow. + * Bluetooth HCI can not yet handled Deep Sleep Mode. + */ + + if (uart->flow_type == TRACE_FLOW) + SER_tr_WakeUp (uart->flow_id); + + uart->deep_sleep_set_up = 0; + + } + } + } + + return (status); +} + + +/******************************************************************************* + * + * SER_WakeUpUarts + * + * Purpose: This function wakes up used UARTs after Deep Sleep. + * + * Parameters: In : none + * Out: none + * + * Return: none + * + ******************************************************************************/ + +void +SER_WakeUpUarts (void) +{ + t_uart *uart; + int uart_id; + + if (uart_sleep_timer_enabled) + start_uart_sleep_timer (); + + for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) { + + uart = &(int_uart[uart_id]); + + /* + * Check if the specified UART is actually used, and has not yet + * been waked up. + */ + + if ((uart->device_used) && + (uart->deep_sleep_set_up)) { + + /* + * Check if the specified UART is used by a Trace or + * by a Fax & Data flow. + * Bluetooth HCI can not yet handled Deep Sleep Mode. + */ + + if (uart->flow_type == TRACE_FLOW) + SER_tr_WakeUp (uart->flow_id); + + /* + * The specified UART is no more set up for Deep Sleep. + */ + + uart->deep_sleep_set_up = 0; + + } + } +} + + +/******************************************************************************* + * + * SER_restart_uart_sleep_timer + * + * Purpose : Resets and restarts the sleep timer each time some characters are + * received. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +void +SER_restart_uart_sleep_timer (void) +{ + /* + * First disable the timer. + */ + + (void) NU_Control_Timer (&uart_sleep_timer, + NU_DISABLE_TIMER); + + /* + * Then start again this timer for a new period. + */ + + start_uart_sleep_timer (); +} + + +/******************************************************************************* + * + * SER_activate_timer_hisr + * + * Purpose : Activates the timer HISR to reset and restart the sleep timer + * each time some characters are received. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +void +SER_activate_timer_hisr (void) +{ + (void) NU_Activate_HISR (&timer_hisr_ctrl_block); +} + + +#if ((CHIPSET == 2) || (CHIPSET == 3)) + +/******************************************************************************* + * + * SER_uart_handler + * + * Purpose : UART interrupt handler. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +void +SER_uart_handler (void) +{ + SYS_UWORD8 interrupt_status; + t_uart *uart; + int uart_id; + SYS_BOOL it_identified; + + it_identified = 0; + + /* + * Check first for a wake-up interrupt. + */ + + uart_id = 0; + while ((uart_id < NUMBER_OF_TR_UART) && + (!it_identified)) { + + uart = &(int_uart[uart_id]); + interrupt_status = READ_UART_REGISTER (uart, SSR); + + if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */ + + it_identified = 1; + uart_sleep_timer_enabled = 1; + DISABLE_WAKE_UP_INTERRUPT (uart); + } + + uart_id++; + } + + /* + * If no wake-up interrupt has been detected, check then systematically + * both UARTs for other interrupt causes. + */ + + if (!it_identified) { + + for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) { + + uart = &(int_uart[uart_id]); + interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED; + + if (!(interrupt_status & IT_NOT_PENDING)) { + + it_identified = 1; + (*(uart->interrupt_handler)) (uart_id, interrupt_status); + + } else { + + if ((uart_id == UA_UART_1) && (!it_identified)) + uart_spurious_interrupts++; + } + } + } +} + +#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) + +/******************************************************************************* + * + * SER_uart_modem_handler + * + * Purpose : UART MODEM interrupt handler. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +void +SER_uart_modem_handler (void) +{ + SYS_UWORD8 interrupt_status; + t_uart *uart; + SYS_BOOL it_wakeup_identified; + + it_wakeup_identified = 0; + uart = &(int_uart[UA_UART_1]); + + /* + * Check first for a wake-up interrupt. + */ + + interrupt_status = READ_UART_REGISTER (uart, SSR); + + if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */ + + it_wakeup_identified = 1; + uart_sleep_timer_enabled = 1; + DISABLE_WAKE_UP_INTERRUPT (uart); + } + + /* + * If no wake-up interrupt has been detected, check UART for other + * interrupt causes. + */ + + if (!it_wakeup_identified) { + + interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED; + + if (!(interrupt_status & IT_NOT_PENDING)) + (*(uart->interrupt_handler)) (UA_UART_1, interrupt_status); + + else + uart_modem_spurious_interrupts++; + } +} + + +/******************************************************************************* + * + * SER_uart_irda_handler + * + * Purpose : UART IrDA interrupt handler. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + +void +SER_uart_irda_handler (void) +{ + SYS_UWORD8 interrupt_status; + t_uart *uart; + SYS_BOOL it_wakeup_identified; + + it_wakeup_identified = 0; + uart = &(int_uart[UA_UART_0]); + + /* + * Check first for a wake-up interrupt. + */ + + interrupt_status = READ_UART_REGISTER (uart, SSR); + + if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */ + + it_wakeup_identified = 1; + uart_sleep_timer_enabled = 1; + DISABLE_WAKE_UP_INTERRUPT (uart); + } + + /* + * If no wake-up interrupt has been detected, check UART for other + * interrupt causes. + */ + + if (!it_wakeup_identified) { + + interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED; + + if (!(interrupt_status & IT_NOT_PENDING)) + (*(uart->interrupt_handler)) (UA_UART_0, interrupt_status); + + else + uart_irda_spurious_interrupts++; + } +} + +#endif + +#if (CHIPSET == 12) + /******************************************************************************* + * + * SER_uart_modem2_handler + * + * Purpose : UART IrDA interrupt handler. + * + * Arguments: In : none + * Out: none + * + * Returns : none + * + ******************************************************************************/ + + void + SER_uart_modem2_handler (void) + { + SYS_UWORD8 interrupt_status; + t_uart *uart; + SYS_BOOL it_wakeup_identified; + + it_wakeup_identified = 0; + uart = &(int_uart[UA_UART_2]); + + /* + * Check first for a wake-up interrupt. + */ + + interrupt_status = READ_UART_REGISTER (uart, SSR); + + if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */ + + it_wakeup_identified = 1; + uart_sleep_timer_enabled = 1; + DISABLE_WAKE_UP_INTERRUPT (uart); + } + + /* + * If no wake-up interrupt has been detected, check UART for other + * interrupt causes. + */ + + if (!it_wakeup_identified) { + + interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED; + + if (!(interrupt_status & IT_NOT_PENDING)) + (*(uart->interrupt_handler)) (UA_UART_2, interrupt_status); + + else + uart_modem2_spurious_interrupts++; + } + } + +#endif + +/* + * Temporary functions. + */ + +void +UT_Init (int device_id, + T_tr_Baudrate baudrate, + void (callback_function (void))) +{ + SER_tr_Init (SER_PROTOCOL_STACK, baudrate, callback_function); +} + +SYS_UWORD32 +UT_ReadNChars (int device_id, + char *buffer, + SYS_UWORD32 chars_to_read) +{ + return (SER_tr_ReadNChars (SER_PROTOCOL_STACK, buffer, chars_to_read)); +} + +SYS_UWORD32 +UT_WriteNChars (int device_id, + char *buffer, + SYS_UWORD32 chars_to_write) +{ + return (SER_tr_WriteNChars (SER_PROTOCOL_STACK, buffer, chars_to_write)); +} + +void +UT_WriteChar (int device_id, + char character) +{ + SER_tr_WriteChar (SER_PROTOCOL_STACK, character); +} + +void +UT_WriteString (int device_id, + char *buffer) +{ + SER_tr_WriteString (SER_PROTOCOL_STACK, buffer); +}