FreeCalypso > hg > freecalypso-sw
diff gsm-fw/g23m-aci/uart/uart_rxf.c @ 775:eedbf248bac0
gsm-fw/g23m-aci subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 12 Oct 2014 01:45:14 +0000 |
parents | |
children | f54080301c98 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/g23m-aci/uart/uart_rxf.c Sun Oct 12 01:45:14 2014 +0000 @@ -0,0 +1,815 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This modul is part of the entity UART and implements all +| procedures and functions as described in the +| SDL-documentation (RX-statemachine) ++----------------------------------------------------------------------------- +*/ + +#ifndef UART_RXF_C +#define UART_RXF_C +#endif /* !UART_RXF_C */ + +#define ENTITY_UART + +#ifndef FF_MULTI_PORT +/*==== INCLUDES =============================================================*/ + +#ifdef WIN32 +#include "nucleus.h" +#endif /* WIN32 */ +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include "macdef.h" /* to get a lot of macros */ +#include "custom.h" +#include "gsm.h" /* to get a lot of macros */ +#include "cnf_uart.h" /* to get cnf-definitions */ +#include "mon_uart.h" /* to get mon-definitions */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#ifdef DTILIB +#include "dti.h" /* to get dti lib */ +#endif /* DTILIB */ +#include "pei.h" /* to get PEI interface */ +#ifdef _TARGET_ +#include "uart/serialswitch.h" +#include "uart/traceswitch.h" +#else /* _TARGET_ */ +#include "serial_dat.h" /* to get definitions of serial driver */ +#endif /* _TARGET_ */ +#include "uart.h" /* to get the global entity definitions */ + +#ifdef _SIMULATION_ +#include <stdio.h> /* to get sprintf */ +#endif /* _SIMULATION_ */ +#include <string.h> /* JK, delete warnings: to get memcpy */ + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + + +/* ++------------------------------------------------------------------------------ +| Function : rx_proc_input ++------------------------------------------------------------------------------ +| Description : The function rx_proc_input() is the actual callback function +| to read data from the receive buffer. +| +| Parameters : uart_device - database for the affected UART device +| ++------------------------------------------------------------------------------ +*/ +LOCAL void rx_proc_input (T_UART_DATA* uart_device) +{ + USHORT i, len; + T_DLC *dlc; /* used Data Link Connection */ + UBYTE *source; /* Data source pointer */ + UBYTE *destination; /* Data destination pointer */ + UBYTE temp_field; /* multi purpose value */ + BOOL channels_complete; /* indicator of complete reception */ + SHORT error_code; /* error code returned from a function */ + + TRACE_FUNCTION( "rx_proc_input" ); + + /* + * read data only if we have read permission + */ + if(uart_device->rx.read_permission) + { + if(uart_device->rx.dlc_instance EQ UART_EMPTY_INSTANCE) + dlc = &uart_device->dlc_table[UART_CONTROL_INSTANCE]; + else + dlc = &uart_device->dlc_table[uart_device->rx.dlc_instance]; + destination = &dlc->receive_data->buffer[dlc->receive_pos]; +#ifdef _SIMULATION_ +{ + char buf[80]; + sprintf(buf,"uart_device->rx.dlc_instance: %d", uart_device->rx.dlc_instance); + TRACE_EVENT(buf); +} +#endif /* _SIMULATION_ */ + if(uart_device->rx.dlc_instance EQ UART_EMPTY_INSTANCE) + { + /* + * Raw data + */ + /* + * Is a data descriptor allocated and + * is the channel ready to receive + */ + if((dlc->receive_process EQ UART_RX_PROCESS_READY) && + (dlc->receive_data)) + { + for (i=0; i < uart_device->rx.nsource; i++) + { + /* + * are there still data in the ring buffer segment and + * are there still space in the data descriptor + */ + if ((uart_device->rx.size[i] > 0) && + (dlc->receive_size > dlc->receive_pos)) + { + len = dlc->receive_size - dlc->receive_pos; + if (len > uart_device->rx.size[i]) + len = uart_device->rx.size[i]; + + memcpy(&dlc->receive_data->buffer[dlc->receive_pos], + uart_device->rx.source[i], + len); + + uart_device->rx.size[i] -= len; + dlc->receive_pos += len; + dlc->receive_data->len = dlc->receive_pos; + } + } + dlc->receive_process = UART_RX_PROCESS_COMPLETE; + } + } + else + { + channels_complete = FALSE; + /* + * for each fragment + */ + for (i=0; i < uart_device->rx.nsource; i++) + { + /* + * while there is still data in buffer and + * not yet all channels are processed + */ + source = uart_device->rx.source[i]; + while((uart_device->rx.size[i] > 0) && (channels_complete NEQ TRUE)) + { + /* + * detect HDLC flag + */ + if(*source EQ UART_HDLC_FLAG) + { + switch(uart_device->rx.analyze_state) + { + case UART_RX_ERROR: + /* + * begin of frame detected + */ + uart_device->rx.analyze_state = UART_RX_BEGIN; + /* fall through */ + case UART_RX_BEGIN: + /* + * initialize new packet + */ + uart_device->rx.stored_len = 0; + uart_device->rx.address_field = 0; + uart_device->rx.fcs = UART_INITFCS; + uart_device->rx.escape = FALSE; + uart_device->rx.analyze_state = UART_RX_ADDRESS; + break; + + default: + /* + * detect HDLC flag + */ + if(uart_device->rx.stored_len > 0) + { + /* + * determine whether FCS already calculated + */ + if(uart_device->rx.analyze_state NEQ UART_RX_FCS) + { + /* + * UART_RX_INFORMATION_... + */ + destination--; +#ifdef _SIMULATION_ + uart_device->rx.fcs = *destination; +#else /* _SIMULATION_ */ + uart_device->rx.fcs = uart_device-> + fcstab[uart_device->rx.fcs ^ *destination]; +#endif /* _SIMULATION_ */ + /* + * remove FCS from data stream + */ + dlc->receive_pos--; + uart_data->rx.stored_len--; + } + if(uart_device->rx.fcs EQ UART_GOODFCS) + { + /* + * no error occured, frame complete + */ + dlc->receive_data->len = dlc->receive_pos; + dlc->receive_process = UART_RX_PROCESS_COMPLETE; + uart_device->rx.analyze_state = UART_RX_END; + break; + } + } + /* + * remove receiced frame because of an error + */ + switch(uart_device->rx.analyze_state) + { + case UART_RX_INFORMATION: + case UART_RX_FCS: + if(uart_data->rx.dlc_instance EQ UART_CONTROL_INSTANCE) + dlc->receive_pos-= 2; + dlc->receive_pos -= uart_data->rx.stored_len; + dlc->receive_process = UART_RX_PROCESS_READY; + break; + default: + /* + * Other states are not handeled here + */ + break; + } + uart_device->rx.analyze_state = UART_RX_END; + break; + } + } + else if((*source EQ UART_HDLC_ESCAPE) && + (uart_device->rx.escape NEQ TRUE)) + { + /* + * detect Control Escape octet + */ + uart_device->rx.escape = TRUE; + } + else + { + /* + * bit 5 complement for the octet followed by Control Escape + */ + if(uart_device->rx.escape EQ TRUE) + { + *source ^= 0x20; + uart_device->rx.escape = FALSE; + } + /* + * store the packet and determine the protocol + */ + switch(uart_device->rx.analyze_state) + { + case UART_RX_ERROR: + /* + * wait for next HDLC flag + */ + break; + + case UART_RX_ADDRESS: + if((*source & UART_EA) EQ UART_EA) + { + /* + * FCS calculation + */ +#ifdef _SIMULATION_ + uart_device->rx.fcs = *source; +#else /* _SIMULATION_ */ + uart_device->rx.fcs = uart_device-> + fcstab[uart_device->rx.fcs ^ *source]; +#endif /* _SIMULATION_ */ + /* + * store Address field + */ + uart_device->rx.address_field = *source; + uart_device->rx.analyze_state = UART_RX_CONTROL; + } + else + { + /* + * invalid frame detected + */ + uart_device->rx.analyze_state = UART_RX_ERROR; + } + break; + + case UART_RX_CONTROL: + switch(*source) + { + case UART_UIH_DATA_FRAME: + /* + * Data frame detected + */ + temp_field = uart_device->rx.address_field >> UART_DLCI_POS; + /* + * if it is an existing channel, but not control channel + */ + if((temp_field NEQ UART_DLCI_CONTROL) && + (uart_device->dlc_instance[temp_field] NEQ + UART_EMPTY_INSTANCE)) + { + uart_device->rx.dlc_instance = + uart_device->dlc_instance[temp_field]; + dlc = &uart_device->dlc_table[uart_device->rx.dlc_instance]; +#ifdef _SIMULATION_ + TRACE_EVENT_P2("Addressfield found DLCI: 0x%02X \ + (dlc_instance 0x%02X)", + temp_field, uart_device->rx.dlc_instance); +#endif /* _SIMULATION_ */ + if(dlc->receive_process EQ UART_RX_PROCESS_READY) + { + /* + * reception Data channel found + * FCS calculation + */ +#ifdef _SIMULATION_ + uart_device->rx.fcs = *source; +#else /* _SIMULATION_ */ + uart_device->rx.fcs = uart_device-> + fcstab[uart_device-> + rx.fcs ^ *source]; +#endif /* _SIMULATION_ */ + destination = &dlc->receive_data-> + buffer[dlc->receive_pos]; + uart_device->rx.analyze_state = UART_RX_INFORMATION; + break; + } + else if(dlc->receive_process EQ UART_RX_PROCESS_COMPLETE) + { + channels_complete = TRUE; + break; + } + } + /* fall through */ + case UART_SABM_FRAME: + case UART_UA_FRAME: + case UART_DM_DATA_FRAME: + case UART_DM_CONTROL_FRAME: + case UART_DISC_FRAME: + case UART_UIH_CONTROL_FRAME: + /* + * Control frame detected + */ + dlc = &uart_device->dlc_table[UART_CONTROL_INSTANCE]; + uart_device->rx.dlc_instance = UART_CONTROL_INSTANCE; + if(dlc->receive_process EQ UART_RX_PROCESS_READY) + { + /* + * reception Control channel found + * FCS calculation + */ +#ifdef _SIMULATION_ + uart_device->rx.fcs = *source; +#else /* _SIMULATION_ */ + uart_device->rx.fcs = uart_device-> + fcstab[uart_device-> + rx.fcs ^ *source]; +#endif /* _SIMULATION_ */ + destination = &dlc->receive_data-> + buffer[dlc->receive_pos]; + uart_device->rx.analyze_state = UART_RX_INFORMATION; + /* + * store Address and Control field + */ + *destination = uart_device->rx.address_field; + destination++; + dlc->receive_pos++; + *destination = *source; + destination++; + dlc->receive_pos++; + } + else if(dlc->receive_process EQ UART_RX_PROCESS_COMPLETE) + { + channels_complete = TRUE; + } + else + /* + * discard frame, because it is unexpected + */ + uart_device->rx.analyze_state = UART_RX_ERROR; + break; + default: + /* + * invalid frame detected + */ + uart_device->rx.analyze_state = UART_RX_ERROR; + break; + } + break; + + case UART_RX_INFORMATION: + if(uart_device->rx.stored_len < uart_device->n1) + { + *destination = *source; + /* + * increase destination pointer + */ + destination++; + uart_device->rx.stored_len++; + dlc->receive_pos++; + } + else + { + /* + * FCS calculation + */ +#ifdef _SIMULATION_ + uart_device->rx.fcs = *source; +#else /* _SIMULATION_ */ + uart_device->rx.fcs = uart_device-> + fcstab[uart_device->rx.fcs ^ *source]; +#endif /* _SIMULATION_ */ + uart_device->rx.analyze_state = UART_RX_FCS; + } + break; + + case UART_RX_FCS: + /* + * remove receiced packet because its to long + */ + if(uart_data->rx.dlc_instance EQ UART_CONTROL_INSTANCE) + dlc->receive_pos-= 2; + dlc->receive_pos -= uart_data->rx.stored_len; + dlc->receive_process = UART_RX_PROCESS_READY; + uart_device->rx.analyze_state = UART_RX_ERROR; + break; + + default: + /* + * wrong analyze state + */ + uart_device->rx.analyze_state = UART_RX_ERROR; + break; + } + } + if(uart_device->rx.analyze_state EQ UART_RX_END) + uart_device->rx.analyze_state = UART_RX_BEGIN; + /* + * don't move source pointer + * if each possible channel was processed + * In this case analyze_state should be UART_RX_CONTROL. + * The Control field must be analyzed again in next call of + * this function. + */ + else if(channels_complete NEQ TRUE) + { + /* + * increase source pointer + */ + source++; + uart_device->rx.size[i]--; + } + } + } + } + } + + PSIGNAL(hCommUART, UART_DRIVER_RECEIVED_IND, uart_device); + + *uart_device->rx.reInstall = rm_noInstall; + + /* + * update pointer in UART driver + */ + if((error_code = UF_InpAvail (uart_device->device)) < 0 ) + { + TRACE_ERROR_P2("UF Driver: DataPointerUpdate failed, [%d], uart_rxf.c(%d)", + error_code, __LINE__); + } +} /* rx_proc_input() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : rx_init ++------------------------------------------------------------------------------ +| Description : The function rx_init() initializes the RX service +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void rx_init () +{ +#ifndef _SIMULATION_ +#ifdef WIN32 +#ifndef _TARGET_ + char buf[80]; +#endif /* !_TARGET_ */ + STATUS sts; +#endif /* WIN32 */ +#endif /* !_SIMULATION_ */ + + TRACE_FUNCTION( "rx_init" ); + +#ifndef _SIMULATION_ +#ifdef WIN32 + sts = NU_Create_HISR (&uart_data->rx.rx_HISR, + "RX_HISR", + rx_proc_input, + 2, + uart_data->HISR_stack, + HISR_STACK_SIZE); +#ifndef _TARGET_ + sprintf (buf, "NU_Create_HISR(RX) = %d", sts); + TRACE_EVENT (buf); +#endif /* _TARGET_ */ +#endif /* WIN32 */ +#endif /* !_SIMULATION_ */ + + uart_data->rx.read_permission = FALSE; + uart_data->rx.prev_lines = 0; + uart_data->rx.dlc_instance = UART_EMPTY_INSTANCE; + uart_data->rx.escape = FALSE; + uart_data->rx.analyze_state = UART_RX_ERROR; + uart_data->rx.receive_state = UART_RX_NOT_RECEIVING; + uart_data->rx.fcs = UART_INITFCS; + uart_data->rx.address_field = 0; + uart_data->rx.stored_len = 0; + + INIT_STATE( UART_SERVICE_RX , RX_DEAD ); +} /* rx_init() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : rx_readOutFunc_0 ++------------------------------------------------------------------------------ +| Description : The function rx_readOutFunc_0() is the official callback +| function to read data from the receive buffer of UART device 0. +| It just copies the parameters and calls then the actual +| function. +| +| Parameters : cldFromIrq - called from interrupt +| reInstall - reinstallation mode +| nsource - number of source pointers +| source - array of source pointers +| size - array of sizes for every source pointer +| state - state of V.24 lines +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void rx_readOutFunc_0 (BOOL cldFromIrq, + T_reInstMode *reInstall, + UBYTE nsource, + UBYTE *source[], + USHORT *size, + ULONG state) +{ +#ifndef _SIMULATION_ +#ifndef _TARGET_ + char buf[40]; +#endif /* !_TARGET_ */ +#endif /* !_SIMULATION_ */ + T_UART_DATA* uart_device; + + TRACE_FUNCTION( "rx_readOutFunc_0" ); + + /* + * select UART device 0 + */ + uart_device = &(uart_data_base[0]); + + /* + * store parameters + */ + uart_device->rx.cldFromIrq = cldFromIrq; + uart_device->rx.nsource = nsource; + uart_device->rx.source[0] = source[0]; + uart_device->rx.source[1] = source[1]; + uart_device->rx.size = size; + uart_device->rx.lines = state; + uart_device->rx.reInstall = reInstall; + +#ifndef _SIMULATION_ +#ifdef WIN32 + if (cldFromIrq) + { + STATUS sts; + /* + * interrupt context of the UART driver -> activate the HISR + */ + sts = NU_Activate_HISR (&uart_device->rx.rx_HISR); +#ifndef _TARGET_ + sprintf (buf, "NU_Activate_HISR(RX) = %d", sts); + TRACE_EVENT (buf); +#endif /* !_TARGET_ */ + } + else +#endif /* WIN32 */ +#endif /* !_SIMULATION_ */ + { +#ifdef _SIMULATION_ + UBYTE* trace_source[2]; + USHORT trace_size[2]; + USHORT i; + USHORT pos; + char buf[90]; + + trace_source[0] = source[0]; + trace_source[1] = source[1]; + + trace_size[0] = size[0]; + trace_size[1] = size[1]; + + /* + * trace input + */ + if((nsource) && + (uart_device->rx.read_permission)) + { + + TRACE_EVENT("==== INRAW"); + i = 0; + pos = 0; + while(pos < trace_size[0]) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_source[0][pos]); + pos++; + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + else if(pos >= trace_size[0]) + { + TRACE_EVENT( buf ); + } + } + if(nsource > 1) + { + i = 0; + pos = 0; + while(pos < trace_size[1]) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_source[1][pos]); + pos++; + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + else if(pos >= trace_size[1]) + { + TRACE_EVENT( buf ); + } + } + } + } +#endif /* _SIMULATION_ */ + + /* + * normal callback from UF_ReadData + */ + rx_proc_input(uart_device); + } + +} /* rx_readOutFunc_0() */ + + + +#ifdef FF_TWO_UART_PORTS +/* ++------------------------------------------------------------------------------ +| Function : rx_readOutFunc_1 ++------------------------------------------------------------------------------ +| Description : The function rx_readOutFunc_1() is the official callback +| function to read data from the receive buffer of UART device 1. +| It just copies the parameters and calls then the actual +| function. +| +| Parameters : cldFromIrq - called from interrupt +| reInstall - reinstallation mode +| nsource - number of source pointers +| source - array of source pointers +| size - array of sizes for every source pointer +| state - state of V.24 lines +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void rx_readOutFunc_1 (BOOL cldFromIrq, + T_reInstMode *reInstall, + UBYTE nsource, + UBYTE *source[], + USHORT *size, + ULONG state) +{ +#ifndef _SIMULATION_ +#ifndef _TARGET_ + char buf[40]; +#endif /* !_TARGET_ */ +#endif /* !_SIMULATION_ */ + T_UART_DATA* uart_device; + + TRACE_FUNCTION( "rx_readOutFunc_1" ); + + /* + * select UART device 1 + */ + uart_device = &(uart_data_base[1]); + + /* + * store parameters + */ + uart_device->rx.cldFromIrq = cldFromIrq; + uart_device->rx.nsource = nsource; + uart_device->rx.source[0] = source[0]; + uart_device->rx.source[1] = source[1]; + uart_device->rx.size = size; + uart_device->rx.lines = state; + uart_device->rx.reInstall = reInstall; + +#ifndef _SIMULATION_ +#ifdef WIN32 + if (cldFromIrq) + { + STATUS sts; + /* + * interrupt context of the UART driver -> activate the HISR + */ + sts = NU_Activate_HISR (&uart_device->rx.rx_HISR); +#ifndef _TARGET_ + sprintf (buf, "NU_Activate_HISR(RX) = %d", sts); + TRACE_EVENT (buf); +#endif /* !_TARGET_ */ + } + else +#endif /* WIN32 */ +#endif /* !_SIMULATION_ */ + { +#ifdef _SIMULATION_ + UBYTE* trace_source[2]; + USHORT trace_size[2]; + USHORT i; + USHORT pos; + char buf[90]; + + trace_source[0] = source[0]; + trace_source[1] = source[1]; + + trace_size[0] = size[0]; + trace_size[1] = size[1]; + + /* + * trace input + */ + if((nsource) && + (uart_device->rx.read_permission)) + { + + TRACE_EVENT("==== INRAW"); + i = 0; + pos = 0; + while(pos < trace_size[0]) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_source[0][pos]); + pos++; + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + else if(pos >= trace_size[0]) + { + TRACE_EVENT( buf ); + } + } + if(nsource > 1) + { + i = 0; + pos = 0; + while(pos < trace_size[1]) + { + i+= sprintf(&buf[i], "0x%02x, ", trace_source[1][pos]); + pos++; + if(i > 80) + { + TRACE_EVENT( buf ); + i = 0; + } + else if(pos >= trace_size[1]) + { + TRACE_EVENT( buf ); + } + } + } + } +#endif /* _SIMULATION_ */ + + /* + * normal callback from UF_ReadData + */ + rx_proc_input(uart_device); + } + +} /* rx_readOutFunc_1() */ +#endif /* FF_TWO_UART_PORTS */ +#endif /* !FF_MULTI_PORT */