FreeCalypso > hg > freecalypso-sw
diff gsm-fw/bsp/sim32.c @ 163:5e0e41cd7c9f
gsm-fw/bsp/sim*.c: initial import from the Leonardo semi-src
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 18 Nov 2013 01:37:19 +0000 |
parents | |
children | 1199cdf99c32 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/bsp/sim32.c Mon Nov 18 01:37:19 2013 +0000 @@ -0,0 +1,321 @@ +/* + * SIM32.C + * + * Pole Star SIM + * + * Target : ARM + * + * Copyright (c) Texas Instruments 1995 + * + */ + +#define SIM32_C 1 + +#include "chipset.cfg" + +#include "main/sys_types.h" +#include <assert.h> +#include "inth/iq.h" +#include "sim.h" + + +#ifdef SIM_DEBUG_TRACE +/* working buffer for NULL BYTE */ +extern SYS_UWORD8 SIM_dbg_null[]; +/* Nucleus variable given the current number of TDMA frames */ +extern SYS_UWORD32 IQ_FrameCount; +/* working variable to calculate the TDMA ecart */ +extern SYS_UWORD16 SIM_dbg_tdma_diff; +/* working variable storing the current number of TDMA frames elapsed */ +SYS_UWORD32 SIM_dbg_local_count; +#endif + +/* + * SIM_IntHandler + * + * Read cause of SIM interrupt : + * + * if receive buffer full, read char + * if transmitter empty, change direction, transmit a dummy char + * + */ +void SIM_IntHandler(void) +{ + volatile unsigned short it, i, stat, conf1; + volatile SYS_UWORD8 ins; + volatile SYS_UWORD8 rx; + volatile SYS_UWORD8 nack; + volatile SYS_UWORD8 nack1; + + + SIM_PORT *p; + + p = &(Sim[0]); + + p->rxParityErr = 0; + it = p->c->it; + + if ((it & SIM_IT_ITRX) && !(p->c->maskit & SIM_MASK_RX)) // int on reception + { + stat = p->c->rx; + conf1 = p->conf1; + +#ifdef SIM_DEBUG_TRACE + if ((IQ_FrameCount - SIM_dbg_local_count) > SIM_dbg_tdma_diff) { + SIM_dbg_tdma_diff = IQ_FrameCount - SIM_dbg_local_count; + } + SIM_dbg_local_count = IQ_FrameCount; +#endif + + // Check if reception parity is enable + if (((conf1 & SIM_CONF1_CHKPAR) && ((stat & SIM_DRX_STATRXPAR) != 0))\ + || ((conf1 & SIM_CONF1_CHKPAR) == 0)) + { + rx = (SYS_UWORD8) (stat & 0x00FF); + ins = p->xbuf[1] & p->hw_mask; + nack = (~p->xbuf[1]) & p->hw_mask; + + switch (p->moderx) + { + case 0: //mode of normal reception without proc char (like PTS proc) + p->rbuf[p->rx_index++] = rx; + break; + + case 1: //mode wait for ACK + if ((rx & p->hw_mask) == ins) + { + p->moderx = 2; + } + else if ((rx & p->hw_mask) == nack) + { + p->moderx = 4; + } + else if (((rx & 0xF0) == 0x60) || ((rx & 0xF0) == 0x90)) + { + if (rx != 0x60) //in case of error code (SW1/SW2) returned by sim card + { + p->rSW12[p->SWcount++] = rx; + p->moderx = 5; + } + else + { + p->null_received = 1; +#ifdef SIM_DEBUG_TRACE + SIM_dbg_null[0]++; +#endif + } + } + else + { + p->errorSIM = SIM_ERR_ABNORMAL_CASE2; + } + //if rx = 0x60 wait for ACK + break; + + case 2: //mode reception by block + p->rbuf[p->rx_index++] = rx; + + if(p->expected_data == 256) + { + if (p->rx_index == 0) + { + p->moderx = 5; + } + } + else + { + if (p->rx_index == p->expected_data) + { + p->moderx = 5; + } + } + break; + + case 3: //mode reception char by char. reception of proc char + if ((rx & p->hw_mask) == ins) + { + p->moderx = 2; + } + else if ((rx & p->hw_mask) == nack) + { + p->moderx = 4; + } //if rx = 0x60 wait for ACK + else if (rx == 0x60) + { + p->null_received == 1; +#ifdef SIM_DEBUG_TRACE + SIM_dbg_null[1]++; +#endif + } + + break; + + case 4: //mode reception char by char. reception of data + p->rbuf[p->rx_index++] = rx; + p->moderx = 3; //switch to receive proc char mode + + if(p->expected_data == 256) + { + if (p->rx_index == 0) + { + p->moderx = 5; + } + } + else + { + if (p->rx_index == p->expected_data) + { + p->moderx = 5; + } + } + break; + + case 5: //mode wait for procedure character except NULL + if ((rx != 0x60) || (p->SWcount != 0)) //treat NULL character only if arriving before SW1 SW2 + { + p->rSW12[p->SWcount++] = rx; + } + else + { + p->null_received = 1; +#ifdef SIM_DEBUG_TRACE + SIM_dbg_null[2]++; +#endif + } + + + break; + + case 6: //give the acknowledge char + if (((rx & 0xF0) == 0x60) || ((rx & 0xF0) == 0x90)) + { + if (rx != 0x60) //in case of error code (SW1/SW2) returned by sim card + { + p->rSW12[p->SWcount++] = rx; + p->moderx = 5; + } + else + { + p->null_received = 1; +#ifdef SIM_DEBUG_TRACE + SIM_dbg_null[3]++; +#endif + } + } + else + { + p->ack = rx; + } + } + } + else + { + p->rxParityErr = 1; + } + } + + if ((it & SIM_IT_ITTX) && !(p->c->maskit & SIM_MASK_TX)) + { +#ifdef SIM_DEBUG_TRACE + SIM_dbg_local_count = IQ_FrameCount; +#endif + // check the transmit parity + stat = p->c->stat; + + + if ((stat & SIM_STAT_TXPAR) || ((p->conf1 & SIM_CONF1_CHKPAR) == 0)) //parity disable + { + if (p->xOut != (p->xIn - 1)) //if only one char transmitted (already transmitted) + { //just need to have confirmation of reception + if (p->xOut == (p->xIn - 2)) + { + p->xOut++; + p->c->tx = *(p->xOut); // transmit + + p->conf1 &= ~SIM_CONF1_TXRX; // return the direction + p->c->conf1 = p->conf1; + } + + if (p->xOut < (p->xIn - 2)) + { + p->xOut++; + p->c->tx = *(p->xOut); // transmit + } + } + } + else + { + p->c->tx = *(p->xOut); // transmit same char + p->txParityErr++; // count number of transmit parity errors + } + + } + + // Handle errors + if ((it & SIM_IT_ITOV) && !(p->c->maskit & SIM_MASK_OV)) + { + p->errorSIM = SIM_ERR_OVF; + + } + if ((it & SIM_IT_WT) && !(p->c->maskit & SIM_MASK_WT)) + { + p->errorSIM = SIM_ERR_READ; + } + + // Reset the card in case of NATR to let the program continue + if ((it & SIM_IT_NATR) && !(p->c->maskit & SIM_MASK_NATR)) + { + p->c->cmd = SIM_CMD_STOP; + p->errorSIM = SIM_ERR_NATR; + } + +#if ((CHIPSET == 2) || (CHIPSET == 3)) + // SIM card insertion / extraction + if ((it & SIM_IT_CD) && !(p->c->maskit & SIM_MASK_CD)) + { + stat = p->c->stat; + if ((stat & SIM_STAT_CD) != SIM_STAT_CD) + { + (p->RemoveFunc)(); + p->errorSIM = SIM_ERR_NOCARD; + } + } +#endif +} + +#if ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) + /* + * SIM_CD_IntHandler + * + * Read cause of SIM interrupt : + * + */ + void SIM_CD_IntHandler(void) + { + volatile unsigned short it_cd, stat; + SIM_PORT *p; + + p = &(Sim[0]); + + p->rxParityErr = 0; + it_cd = p->c->it_cd; + + // SIM card insertion / extraction + if ((it_cd & SIM_IT_CD) && !(p->c->maskit & SIM_MASK_CD)) + { + stat = p->c->stat; + if ((stat & SIM_STAT_CD) != SIM_STAT_CD) + { + (p->RemoveFunc)(); + p->errorSIM = SIM_ERR_NOCARD; + } + } +} +#endif + + +// to force this module to be linked +SYS_UWORD16 SIM_Dummy(void) +{ + +}