📄 sci_atom.c
字号:
t1 = SCI_ISO_T1_MIN; } if(sci_cb[sci_id].sci_modes.man_act == 1) { /* clear AUTO bit (manual) */ _clear_bits(sci_id, SCCTL3, AUTO); /* set SDFLT bit */ _set_bits(sci_id, SCCTL0, SDFLT); /* need 2 OPB cycles of delay */ time0 = MF_SPR(SPR_TBL); /* Enable VCC */ if(sci_drv_modes.vcc_polarity == ACTIVE_HIGH) { _set_bits(sci_id, SCCTL0, VCC); } else { _clear_bits(sci_id, SCCTL0, VCC); } /* Enable I/O (IO_EN) */ _set_bits(sci_id, SCCTL0, IO_EN); /* Enable clock (CLKEN) */ _set_bits(sci_id, SCCTL0, CLKEN); /* Clock must be high for > 400 SCCLK before asserting reset */ time0 = MF_SPR(SPR_TBL); do{ time1 = MF_SPR(SPR_TBL); if(time0 < time1) { time1 = time1 - time0; } else{ time1 = 0xFFFFFFFF - (time0 - time1); } } while(time1 < (t1 * 2 * _OS_INB(sci_cb[sci_id].scclk_cnt0))); /* Assert reset line (SCRST) */ _set_bits(sci_id, SCCTL0, SCRST); /* set AUTO/MAN bit (auto) */ _set_bits(sci_id, SCCTL3, AUTO); } else { /* activate the reader and reset the Smart Card */ _set_bits(sci_id, SCCTL3, CRESET); /* wait for h/w reset cycle to complete */ while(_check_bits(sci_id, SCCTL3, CRESET) == 1); } break; /* warm reset */ case WARM: _set_bits(sci_id, SCCTL0, RST); /* wait for h/w reset cycle to complete */ while(_check_bits(sci_id, SCCTL0, RST) == 1); break; }}/******************************************************************************* Function: sci_atom_clock_stop**** Purpose: Stop the SCI/Smart Card clock at a given polarity.**** Parameters: sci_id: zero-based number to identify smart card controller*****************************************************************************/void sci_atom_clock_stop(ULONG sci_id){ /* determine and set polarity */ if(sci_cb[sci_id].sci_parameters.clock_stop_polarity == SCI_CLOCK_STOP_LOW) { _clear_bits(sci_id, SCCTL3, CLKSTP); } else if(sci_cb[sci_id].sci_parameters.clock_stop_polarity == SCI_CLOCK_STOP_HIGH) { _set_bits(sci_id, SCCTL3, CLKSTP); } /* stop the clock */ _clear_bits(sci_id, SCCTL0, CLKEN);}/******************************************************************************* Function: sci_atom_clock_start**** Purpose: Start the SCI/Smart Card clock.**** Parameters: sci_id: zero-based number to identify smart card controller*****************************************************************************/void sci_atom_clock_start(ULONG sci_id){ _set_bits(sci_id, SCCTL0, CLKEN);}/****************************************************************************** Name: sci_atom_is_card_present**** Purpose: This checks the state of the detect line and the active** polarity of the card detect line, to determine if a card** is present in the reader.**** Parameters: sci_id: zero-based number to identify smart card controller**** Returns: 0: card is not present** 1: card is present****************************************************************************/INT sci_atom_is_card_present(ULONG sci_id){ INT rc; if(_check_bits(sci_id, SCCTL3, POLDET) == _check_bits(sci_id, SCSTAT, DET)) { /* card is present */ rc = 1; } else { /* card not present */ rc = 0; } return(rc);}/****************************************************************************** Name: sci_atom_is_HW_activated**** Purpose: This determines if the SCI hardware is activated.**** Parameters: sci_id: zero-based number to identify smart card controller**** Returns: 0: hardware is not actived** 1: hardware is actived*****************************************************************************/INT sci_atom_is_HW_activated(ULONG sci_id){ return(_check_bits(sci_id, SCCTL0, IO_EN));}/******************************************************************************* Function: sci_atom_deactivate**** Purpose: Deactivate the interface (enter deac state).**** Parameters: sci_id: zero-based number to identify smart card controller*****************************************************************************/void sci_atom_deactivate(ULONG sci_id){ /* set the interrupt mask to zero */ _OS_OUTW(sci_cb[sci_id].scinten, ENCDI); /* clear all the interrupts */ _OS_OUTW(sci_cb[sci_id].scint, BOI|REI|TUI|CHI|TSI|RFI|RXLEN|RFTHI|TFHI|RUI|PARI|LTXI|FRXI); /* clear the UIC status */ sci_atom_clear_UICSR(sci_id); /* Don't attempt deactivation if a panic deactivation has occoured */ if((sci_cb[sci_id].state != SCI_STATE_INIT) && (sci_cb[sci_id].atr_status == SCI_ATR_READY)) { /* clock must be running, else NDEACT bit with stay high */ if(_check_bits(sci_id, SCCTL0, CLKEN) != 1) { /* we must be in clock stop, so start the clock */ _set_bits(sci_id, SCCTL0, CLKEN); } /* initiate normal deactivation */ _set_bits(sci_id, SCCTL3, NDEACT); /* NDEACT is auto cleared by HW, it indicates deactivation finish */ while(_check_bits(sci_id, SCCTL3, NDEACT) == 1); }}/******************************************************************************* Function: sci_atom_tx_start**** Purpose: set transmit (tx) registers.**** Parameters: sci_id: zero-based number to identify smart card controller** num_bytes: number of bytes to write from out buffer*****************************************************************************/void sci_atom_tx_start(ULONG sci_id, ULONG num_bytes){ /* set FIFO to 32-byte Tx */ _set_bits (sci_id, SCCTL1, FIFO1); _clear_bits(sci_id, SCCTL1, FIFO2); /* reset Tx FIFO */ _set_bits(sci_id, SCCTL1, TFIFOR); /* reset Rx FIFO */ _set_bits(sci_id, SCCTL1, RFIFOR); /* set hardware registers */ /* set the interrupt mask to zero */ _OS_OUTW(sci_cb[sci_id].scinten, ENCDI); /* clear all the interrupts */ sci_atom_clear_interrupt_status(sci_id, BOI|REI|TUI|CHI|TSI|RFI|RXLEN|RFTHI|TFHI|RUI|PARI|LTXI|FRXI); /* clear the UIC status */ sci_atom_clear_UICSR(sci_id); /* set rxlen to max */ _OS_OUTW(sci_cb[sci_id].scrxlen, 0x1FF); _OS_OUTW(sci_cb[sci_id].sctxlen, num_bytes); /* enable Tx interrupts */ //_OS_OUTW(sci_cb[sci_id].scinten, (ENBOI|ENTUI|ENCDI|EPARI|ELTXI));}/******************************************************************************* Function: sci_atom_rx_start**** Purpose: set recieve (rx) registers.**** Parameters: sci_id: zero-based number to identify smart card controller*****************************************************************************/void sci_atom_rx_start(ULONG sci_id){ /* set FIFO to 32-byte Rx */ _set_bits (sci_id, SCCTL1, FIFO2); _clear_bits(sci_id, SCCTL1, FIFO1); /* set rx threshold for >=1/2 full */ _OS_OUTB(sci_cb[sci_id].scbmr, _OS_INB(sci_cb[sci_id].scbmr) | RFFT); /* reset Tx FIFO */ _set_bits(sci_id, SCCTL1, TFIFOR); /* reset Rx FIFO */ _set_bits(sci_id, SCCTL1, RFIFOR); /* set rxlen to max */ _OS_OUTW(sci_cb[sci_id].scrxlen, 0x1FF); /* set the interrupt mask to zero */ _OS_OUTW(sci_cb[sci_id].scinten, ENCDI); /* clear all the interrupts */ sci_atom_clear_interrupt_status(sci_id, BOI|REI|TUI|CHI|TSI|RFI|RXLEN|RFTHI|TFHI|RUI|PARI|LTXI|FRXI); /* enable Rx interrupts */ _OS_OUTW(sci_cb[sci_id].scinten, ENBOI|ENREI|ENTSI|ENRFI|ENCDI|ERFTHI|ERUI|EPARI|EFRXI);}/******************************************************************************* Function: sci_atom_write_fifo**** Purpose: Transmit certain numbers of bytes to the FIFO**** Parameters: sci_id: zero-based number to identify smart card controller** num_bytes: number of bytes to be witten** p_buffer_addr: intput pointer of the write buffer's address*****************************************************************************/void sci_atom_write_fifo(ULONG sci_id, ULONG num_bytes, UCHAR **p_buffer_addr){ UCHAR *p_buffer; int num_bytes_left; num_bytes_left = (int)num_bytes; p_buffer = *p_buffer_addr; if((_OS_INB(sci_cb[sci_id].scctl1) & FIFO0) == FIFO0) { /* word FIFO access */ while((num_bytes_left> 0) && (_check_bits(sci_id, SCCTL3, POLDET) == _check_bits(sci_id, SCSTAT, DET))) { _OS_OUTL(sci_cb[sci_id].scbuffs, *(ULONG *)p_buffer); p_buffer += 4; if(num_bytes_left >= 4) { num_bytes_left -= 4; } else { num_bytes_left = 0; } } } else { /* byte FIFO access */ while((num_bytes_left > 0) && (_check_bits(sci_id, SCCTL3, POLDET) == _check_bits(sci_id, SCSTAT, DET))) { _OS_OUTB(sci_cb[sci_id].scbuffs, *p_buffer); p_buffer ++; num_bytes_left --; } } *p_buffer_addr = p_buffer;}/****************************************************************************** Name: sci_atom_read_fifo**** Purpose: Read any pending data from FIFO**** Parameters: sci_id: zero-based number to identify smart card controller** p_buffer_addr: intput pointer of the read buffer's address*****************************************************************************/void sci_atom_read_fifo(ULONG sci_id, UCHAR **p_buffer_addr){ UCHAR validb; UCHAR *p_buffer; p_buffer = *p_buffer_addr; if((_OS_INB(sci_cb[sci_id].scctl1) & FIFO0) == FIFO0) { /* word FIFO access */ /* only attempt read if data is available */ while(((_OS_INB(sci_cb[sci_id].scstat) & RSTAT) != 0) && (_check_bits(sci_id, SCCTL3, POLDET) == _check_bits(sci_id, SCSTAT, DET))) { /* check for valid data on the OPB wall */ if((_OS_INB(sci_cb[sci_id].scstat) & RPEND) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -