FreeCalypso > hg > fc-tourmaline
view src/gpf/ccd/csn1_choice_x.c @ 268:f2e52cab0a73
abb_inth.c: check all interrupt causes, not just one
The original code used if - else if - else if etc constructs, thus
the first detected interrupt was the only one handled. However,
Iota ITSTATREG is a clear-on-read register, thus if we only handle
the first detected interrupt and skip checking the others, then the
other interrupts will be lost, if more than one interrupt happened
to occur in one ABB interrupt handling cycle - a form of rare race
condition. Change the code to check all interrupts that were read
in this cycle.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 13 Jun 2021 18:17:53 +0000 |
parents | 4e78acac3d88 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : CCD | Modul : csn1_choice_x.c +----------------------------------------------------------------------------- | 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 : Definition of encoding and decoding functions for CSN1_CHOICE2 | elements +----------------------------------------------------------------------------- */ /* * standard definitions like GLOBAL, UCHAR, ERROR etc. */ #include "typedefs.h" #include "header.h" /* * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only * look at ccdapi.h */ #undef USE_DRIVER #include "ccdapi.h" /* * Types and functions for bit access and manipulation */ #include "ccd_globs.h" #include "bitfun.h" /* * Prototypes of ccd internal functions */ #include "ccd.h" #include "ccd_codingtypes.h" /* * Declaration of coder/decoder tables */ #include "ccdtable.h" #include "ccddata.h" EXTERN T_FUNC_POINTER codec[MAX_CODEC_ID+1][2]; #ifndef RUN_INT_RAM /* Attention for RUN_...: static function */ static void decode_csn1_choice_alternative(const ULONG e_ref, T_ENUM union_tag, T_CCD_Globs *globs); static void encode_csn1_choice_alternative(const ULONG e_ref, T_ENUM union_tag, T_CCD_Globs *globs); #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* Attention for RUN_...: static function */ /* +--------------------------------------------------------------------+ | PROJECT : CCD (6144) MODULE : csn1_choice1 | | STATE : code ROUTINE : decode_csn1_choice_alternative | +--------------------------------------------------------------------+ PURPOSE : Decode a chosen alternative of a CSN.1 CHOICE type Use the parameter union_tag to read the CHOICE index. Because of union_tag it is easy to calculate the elemRef for the chosen element which is to be decoded. Then the appropriate decoding function for the chosen element is called. */ static void decode_csn1_choice_alternative(const ULONG e_ref, T_ENUM union_tag, T_CCD_Globs *globs) { ULONG elem_ref, mcomp_ref; UBYTE *act_structpos; mcomp_ref= melem[e_ref].elemRef; /* * Write the CHOICE tag value in the C-structure. * Calculate the elem_ref for the chosen element. */ *(T_ENUM *) (globs->pstruct+globs->pstructOffs) = union_tag; elem_ref = mcomp[mcomp_ref].componentRef + (ULONG) union_tag; #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "decode_csn1_choice_alternative()"); #else TRACE_CCD (globs, "decode_csn1_choice_alternative() %s", ccddata_get_alias((USHORT)e_ref, 1)); #endif #endif /* * Store the actual structure position. */ act_structpos = globs->pstruct; globs->pstruct += (globs->pstructOffs + sizeof(T_ENUM)); /* * Use the jump-table for selecting the decode function * Call the decode function for the chosen element. */ (void) codec[melem[elem_ref].codingType][DECODE_FUN] (mcomp_ref, elem_ref, globs); /* * Restore the write pointer to prepare decoding of the next element */ globs->pstruct = act_structpos; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* Attention for RUN_...: static function */ /* +--------------------------------------------------------------------+ | PROJECT : CCD (6144) MODULE : csn1_choice1 | | STATE : code ROUTINE : encode_csn1_choice_alternative | +--------------------------------------------------------------------+ PURPOSE : Encode a chosen alternative of a CSN.1 CHOICE type. Because of union_tag it is easy to calculate the e_ref for the chosen element to be encoded. Then the appropriate encoding function for the chosen element is called. */ static void encode_csn1_choice_alternative (const ULONG e_ref, T_ENUM union_tag, T_CCD_Globs *globs) { ULONG elem_ref, mcomp_ref; UBYTE *act_structpos; mcomp_ref= melem[e_ref].elemRef; /* * Calculate the elem_ref for the chosen element. */ elem_ref = mcomp[mcomp_ref].componentRef + (ULONG) union_tag; #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "encode_csn1_choice_alternative()"); #else TRACE_CCD (globs, "encode_csn1_choice_alternative() %s", ccddata_get_alias((USHORT)e_ref, 1)); #endif #endif /* * Store the actual structure position. */ act_structpos = globs->pstruct; globs->pstruct += (globs->pstructOffs + sizeof(T_ENUM)); /* * Use the jump-table for selecting the encode function * Call the encode function for the chosen element. */ (void) codec[melem[elem_ref].codingType][ENCODE_FUN] (mcomp_ref, elem_ref, globs); /* * Restore the write pointer to prepare decoding of the next element */ globs->pstruct = act_structpos; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM/* +-----------------------------------------------------------------------+ | PROJECT : CCD (6144) MODULE : CCD | | STATE : code ROUTINE : cdc_csn1_choice_x_decode | +-----------------------------------------------------------------------+ PURPOSE : Decode CSN.1 CHOICE type In the header file the structure containing an element of coding type CSN1_CHOICE is represented by a structure type declaration. This structure type is composed at least of a control item preceding an item of an union type. The control item indicates the CHOICE index. The item of the union type represents the CHOICE alternatives. The CHOICE index is "num" bits long. It is read from the message bit string and the result is written to the control item. CCD determes "elemRef" depending on this control item and processes the union element according to table entry of "elemRef" . */ SHORT cdc_csn1_choice_x_decode (const ULONG c_ref, const ULONG e_ref, ULONG num, T_CCD_Globs *globs) { ULONG union_tag, num_of_alt, num_of_comps; ULONG cix_ref, num_prolog_steps, prolog_step_ref; #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "cdc_csn1_choice1_decode()"); #else TRACE_CCD (globs, "cdc_csn1_choice1_decode() %s", ccddata_get_alias((USHORT)e_ref, 1)); #endif #endif cix_ref = melem[e_ref].calcIdxRef; num_prolog_steps = calcidx[cix_ref].numPrologSteps; prolog_step_ref = calcidx[cix_ref].prologStepRef; /* * If this element is conditional, check the condition. */ if (calcidx[cix_ref].numCondCalcs NEQ 0 AND ! ccd_conditionOK (e_ref, globs)) return 1; /* * If this element has a defined prologue * we have to process it before decoding the bitstream. */ if (num_prolog_steps) { ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); } globs->pstructOffs = melem[e_ref].structOffs; if (melem[e_ref].optional) { /* Postpone optional flag setting for non-code transparent * pointer types ('P', 'Q', 'R'). * For these types, the optional flag is the pointer itself. * These types cannot be set yet, as the pointer may be * preceeded by a counter octet, a union tag id octet etc. */ if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R') globs->pstruct[globs->pstructOffs++] = (UBYTE) TRUE; } /* * Get the number of alternatives from the C-structure. */ num_of_comps = mcomp[melem[e_ref].elemRef].numOfComponents; /* Determine number of possible alternatives */ num_of_alt = num <<1; /* read the bit representing the CHOICE index*/ union_tag = bf_getBits(num, globs); /* Check number of alternatives */ if (!num_of_comps) { /* Don't do anything for empty choices */ return 1; } else if (num_of_comps != num_of_alt) { /* if the number of components doesn't match to number of possible * examine whether the CHOICE index demands an impossible alternative */ if (union_tag > num_of_comps) { /* if CHOICE index demands an impossible alternative * return an error and break decoding */ ccd_recordFault (globs, ERR_CSN1_CHOICE, BREAK, (USHORT) e_ref, globs->pstruct+globs->pstructOffs); } else { ccd_recordFault (globs, ERR_CSN1_CHOICE, CONTINUE, (USHORT) e_ref, globs->pstruct+globs->pstructOffs); } } /* * Decode a chosen alternative of an CSN.1 CHOICE type */ decode_csn1_choice_alternative(e_ref, (T_ENUM) union_tag, globs); return 1; } #endif /* !RUN_INT_RAM */ #ifndef RUN_INT_RAM /* +----------------------------------------------------------------------+ | PROJECT : CCD (6144) MODULE : csn1_choice1 | | STATE : code ROUTINE : cdc_csn1_choice_x_encode | +----------------------------------------------------------------------+ PURPOSE : Encoding of CHOICE1 type for UMTS In the header file the structure containing an element of coding type CSN1_CHOICE is represented by a structure type declaration. This structure type is composed at least of a control item preceding an item of an union type. The control item indicates the CHOICE index. The item of the union type represents the CHOICE alternatives. The CHOICE index is "num" bit long. Tts value is read from the message structureand the result is written to the bit string. CCD determines "elemRef" depending on this index and processes the union element according to table entry of "elemRef" . */ SHORT cdc_csn1_choice_x_encode (const ULONG c_ref, const ULONG e_ref, ULONG num, T_CCD_Globs *globs) { ULONG union_tag, num_of_alt, num_of_comps; ULONG cix_ref, num_prolog_steps, prolog_step_ref; #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "cdc_csn1_choice_encode()"); #else TRACE_CCD (globs, "cdc_csn1_choice_encode() %s", mcomp[melem[e_ref].elemRef].name); #endif #endif cix_ref = melem[e_ref].calcIdxRef; num_prolog_steps = calcidx[cix_ref].numPrologSteps; prolog_step_ref = calcidx[cix_ref].prologStepRef; /* * If this element is conditional, check the condition. */ if (calcidx[cix_ref].numCondCalcs NEQ 0 AND ! ccd_conditionOK (e_ref, globs)) return 1; /* * If this element has a defined prologue * we have to process it before decoding the bitstream. */ if (num_prolog_steps) { ccd_performOperations (num_prolog_steps, prolog_step_ref, globs); } /* * Setup the offset into the C-structure for this element */ globs->pstructOffs = melem[e_ref].structOffs; if (melem[e_ref].optional) { /* * For optional elements check the valid-flag in the C-struct. * Postpone optional flag setting for non-code transparent * pointer types ('P', 'Q', 'R'). * For these types, the optional flag is the pointer itself. * These types cannot be set yet, as the pointer may be * preceeded by a counter octet, a union tag id octet etc. */ if (melem[e_ref].elemType < 'P' OR melem[e_ref].elemType > 'R') { if (globs->pstruct[globs->pstructOffs++] EQ FALSE) return 1; } } /* * Get the number of alternatives from the C-structure. */ num_of_comps = mcomp[melem[e_ref].elemRef].numOfComponents; /* Determine number of possible alternatives */ num_of_alt = num <<1; /* * Get the value of CHOICE index (= union controller) from the C-structure. * Check its correctness. Write it in the air message. * Afterwards encode the chosen CHOICE altervative. */ union_tag = (ULONG) globs->pstruct[globs->pstructOffs]; /* * Check its correctness. */ if (union_tag >= num_of_alt) { /* * CHOICE index goes beyond the number of alternatives determined by * selected coding type => return Error and break encoding process */ ccd_recordFault (globs, ERR_CSN1_CHOICE, BREAK, (USHORT) e_ref, globs->pstruct+globs->pstructOffs); } /* * Write the CHOICE tag value in the C-structure. */ bf_writeVal (union_tag, num, globs); /* Check number of alternatives */ if (!num_of_comps) { /* Don't do anything for empty choices */ return 1; } else if (num_of_comps != num_of_alt) { /* if the number of components doesn't match to number of possible alternatives return a warning */ ccd_recordFault (globs, ERR_CSN1_CHOICE, CONTINUE, (USHORT) e_ref, globs->pstruct+globs->pstructOffs); if (union_tag > num_of_comps) { /* if the CHOICE index demands an impossible one handle this choice as no_code element */ #ifdef DEBUG_CCD #ifndef CCD_SYMBOLS TRACE_CCD (globs, "cdc_No_encode()"); #else TRACE_CCD (globs, "cdc_No_encode() %s", ccddata_get_alias((USHORT) e_ref, 1)); #endif #endif return 1; } } /* * Encode a chosen alternative of an CSN.1 CHOICE type */ encode_csn1_choice_alternative (e_ref, (T_ENUM) union_tag, globs); return 1; } #endif /* !RUN_INT_RAM */