FreeCalypso > hg > fc-magnetite
view src/cs/drivers/drv_app/sim/sim32.c @ 478:5e39123540e6
hybrid fw: Openmoko-mimicking AT@BAND command implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 14 Jun 2018 06:04:54 +0000 |
parents | 945cf7f506b2 |
children |
line wrap: on
line source
/* * 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) { }