📄 sci_atom.c
字号:
/*---------------------------------------------------------------------------+| This source code has been made available to you by IBM on an AS-IS| basis. Anyone receiving this source is licensed under IBM| copyrights to use it in any way he or she deems fit, including| copying it, modifying it, compiling it, and redistributing it either| with or without modifications. No license under IBM patents or| patent applications is to be implied by the copyright license.|| Any user of this software should understand that IBM cannot provide| technical support for this software and will not be responsible for| any consequences resulting from the use of this software.|| Any person who transfers this source code or any derivative work| must include the IBM copyright notice, this paragraph, and the| preceding two paragraphs in the transferred software.|| COPYRIGHT I B M CORPORATION 1997, 1999, 2001| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author: Mike Lepore| Component: sci| File: sci_atom.c| Purpose: Atom functions for smart card interface control| Changes:|| Date: Author Comment:| ---------- ---------------- -----------------------------------------------| 03/22/2001 MAL Initial check-in.| 03/26/2001 Zongwei Liu Port to Linux| 09/26/2001 Zongwei Liu Port to pallas| 10/10/2001 Zongwei Liu Port to OS-Adaption layer| 12/13/2001 MAL, Zongwei Liu Added EMV2000 support/ 04/21/2003 Detrick, Mark Fixed bug in sci_atom_write_fifo./ If the num_bytes was not on a word boundry ,/ num_bytes would decrement below 0 and a machine/ check would occor also added int num_bytes_left/ to make sure we didn't receive a negative number+----------------------------------------------------------------------------*/#include "sci_atom.h"#include "sci_local.h"#include "os/os-types.h"#include "os/os-io.h"#include "hw/hardware.h"extern SCI_CONTROL_BLOCK sci_cb[SCI_NUMBER_OF_CONTROLLERS];extern SCI_DRV_MODES sci_drv_modes;/* prototype of local functions */static void _set_bits (ULONG sci_id, ULONG reg, UCHAR bits);static void _clear_bits (ULONG sci_id, ULONG reg, UCHAR bits);static INT _check_bits (ULONG sci_id, ULONG reg, UCHAR bits);/****************************************************************************** Function: sci_atom_assign_reg_address**** Purpose: assign the register addresses**** Parameters: sci_id: zero-based number to identify smart card controller****************************************************************************/void sci_atom_assign_reg_address(ULONG sci_id){ sci_cb[sci_id].scbuffs = (ULONG *) (sci_cb[sci_id].sci_base_address + SCBUFFS); sci_cb[sci_id].scctl0 = (UCHAR *) (sci_cb[sci_id].sci_base_address + SCCTL0); sci_cb[sci_id].scctl1 = (UCHAR *) (sci_cb[sci_id].sci_base_address + SCCTL1); sci_cb[sci_id].scinten = (USHORT *)(sci_cb[sci_id].sci_base_address + SCINTEN0); sci_cb[sci_id].scint = (USHORT *)(sci_cb[sci_id].sci_base_address + SCINT0); sci_cb[sci_id].scstat = (UCHAR *) (sci_cb[sci_id].sci_base_address + SCSTAT); sci_cb[sci_id].scbmr = (UCHAR *) (sci_cb[sci_id].sci_base_address + SCBMR); sci_cb[sci_id].scclk_cnt0= (UCHAR *) (sci_cb[sci_id].sci_base_address + SCCLK_CNT0); sci_cb[sci_id].scctl3 = (UCHAR *) (sci_cb[sci_id].sci_base_address + SCCTL3); sci_cb[sci_id].scetu = (USHORT *)(sci_cb[sci_id].sci_base_address + SCETU0); sci_cb[sci_id].scrxlen = (USHORT *)(sci_cb[sci_id].sci_base_address + SCRXLEN); sci_cb[sci_id].sctxlen = (USHORT *)(sci_cb[sci_id].sci_base_address + SCTXLEN); sci_cb[sci_id].sccwt = (USHORT *)(sci_cb[sci_id].sci_base_address + SCCWT0); sci_cb[sci_id].scegt = (UCHAR *) (sci_cb[sci_id].sci_base_address + SCEGT); sci_cb[sci_id].scbwt = (ULONG *) (sci_cb[sci_id].sci_base_address + SCBWT0);}/******************************************************************************* Function: sci_atom_reg_init**** Purpose: Initialize the registers of Smart Card Interface**** Parameters: sci_id: zero-based number to identify smart card controller*****************************************************************************/void sci_atom_reg_init(ULONG sci_id){ /* active-low detect;active-low VCC;clock stop low;auto mode */ _OS_OUTB(sci_cb[sci_id].scctl3, AUTO); if(sci_drv_modes.vcc_polarity == ACTIVE_HIGH) { /* active-high VCC */ _set_bits(sci_id, SCCTL3, POLVCC); } else { /* active-low VCC */ _clear_bits(sci_id, SCCTL3, POLVCC); } if(sci_drv_modes.detect_polarity == ACTIVE_HIGH) { /* active-high detect */ _set_bits(sci_id, SCCTL3, POLDET); } else { /* active-low detect */ _clear_bits(sci_id, SCCTL3, POLDET); } if(sci_drv_modes.vcc_polarity == ACTIVE_HIGH) { /* VCC off(low);all lines disabled;direct */ _OS_OUTB(sci_cb[sci_id].scctl0, DEACT); } else { /* VCC off(high);all lines disabled;direct */ _OS_OUTB(sci_cb[sci_id].scctl0, (DEACT|VCC)); } /* LRC;T=0;FIFOs disabled */ _OS_OUTB(sci_cb[sci_id].scctl1, 0); /* set the interrupt mask to zero */ _OS_OUTW(sci_cb[sci_id].scinten, 0); /* clear all the interrupts */ _OS_OUTW(sci_cb[sci_id].scint, BOI|REI|TUI|CHI|TSI|RFI|RXLEN|CDI|RFTHI|TFHI|RUI|PARI|LTXI|FRXI); /* clear the UIC status */ sci_atom_clear_UICSR(sci_id); /* set the interrupt mask to zero, except card detect */ _OS_OUTW(sci_cb[sci_id].scinten, ENCDI); /* DMA disabled;Rx FIFO not empty:Tx FIFO < half full */ _OS_OUTB(sci_cb[sci_id].scbmr, TFFT); /* set rxlen to max */ _OS_OUTW(sci_cb[sci_id].scrxlen, 0x1FF); _OS_OUTW(sci_cb[sci_id].sctxlen, 0);}/****************************************************************************** Function: sci_atom_set_chip_connection**** Purpose: Configure the register control the chip internal connection****************************************************************************/void sci_atom_set_chip_connection(void){#if defined (__DRV_FOR_VESTA__) MT_DCR(CICSEL3, MF_DCR(CICSEL3) | 0x60000000);#elif defined (__DRV_FOR_PALLAS__) MT_DCR(CICCR, MF_DCR(CICCR) | 0x80);#elif defined (__DRV_FOR_VULCAN__)#endif}/****************************************************************************** Name: sci_atom_clear_UICSR**** Purpose: clear the UIC status****************************************************************************/void sci_atom_clear_UICSR(ULONG sci_id){ MT_DCR(UICSR, MF_DCR(UICSR) & (~sci_cb[sci_id].sci_interrupt_mask));}/****************************************************************************** Name: sci_atom_get_interrupt_status**** Purpose: get the status of interrrupt**** Parameters: sci_id: zero-based number to identify smart card controller**** Returns the value of interrupt status register****************************************************************************/USHORT sci_atom_get_interrupt_status(ULONG sci_id){ return(_OS_INW(sci_cb[sci_id].scint));}/****************************************************************************** Name: sci_atom_clear_interrupt_status**** Purpose: clear the specified bits of interrrupt**** Parameters: sci_id: zero-based number to identify smart card controller** bits: bit mask****************************************************************************/void sci_atom_clear_interrupt_status(ULONG sci_id, USHORT bits){ _OS_OUTW(sci_cb[sci_id].scint, bits);}/****************************************************************************** Name: sci_atom_check_rx_data_pending**** Purpose: check any pending recieve data **** Parameters: sci_id: zero-based number to identify smart card controller**** Returns 0: if no data available** 1: if any recieve data is pending****************************************************************************/INT sci_atom_check_rx_data_pending(ULONG sci_id){ return(_check_bits(sci_id, SCSTAT, RPEND));}/****************************************************************************** Name: sci_atom_check_tx_fifo_half_full**** Purpose: check the status of TX FIFO if under half full**** Parameters: sci_id: zero-based number to identify smart card controller**** Returns 0: if FIFO < 1/2 full** 1: if FIFO >= 1/2 full****************************************************************************/INT sci_atom_check_tx_fifo_half_full(ULONG sci_id){ return(_check_bits(sci_id, SCSTAT, 0x20));}/****************************************************************************** Name: sci_atom_enable_tx_interrupts**** Purpose: enable Tx related interrupts**** Parameters: sci_id: zero-based number to identify smart card controller****************************************************************************/void sci_atom_enable_tx_interrupts(ULONG sci_id){ /* enable Tx interrupts */ _OS_OUTW(sci_cb[sci_id].scinten, (ENBOI|ENTUI|ENCDI|EPARI|ELTXI));}/****************************************************************************** Name: sci_atom_enable_tx_threshold_interrupts**** Purpose: enable Tx threshold interrupts**** Parameters: sci_id: zero-based number to identify smart card controller****************************************************************************/void sci_atom_enable_tx_threshold_interrupts(ULONG sci_id){ _set_bits(sci_id, SCINTEN1, ETFHI);}/****************************************************************************** Name: sci_atom_disable_tx_threshold_interrupts**** Purpose: disable Tx threshold interrupts**** Parameters: sci_id: zero-based number to identify smart card controller****************************************************************************/void sci_atom_disable_tx_threshold_interrupts(ULONG sci_id){ _clear_bits(sci_id, SCINTEN1, ETFHI);}/****************************************************************************** Name: sci_atom_set_rx_threshold_interrupts**** Purpose: Set Rx threshold interrupts according to num_bytes**** Parameters: sci_id: zero-based number to identify smart card controller** num_bytes: number of bytes to be read****************************************************************************/void sci_atom_set_rx_threshold_interrupts(ULONG sci_id, ULONG num_bytes){ if(num_bytes < 16) { /* set RX threshold for not empty */ _clear_bits(sci_id, SCBMR, RFFT); //outbyte(sci_cb[sci_id].scbmr,inbyte(sci_cb[sci_id].scbmr)&~RFFT); } else { /* set RX threshold for >=1/2 full */ _set_bits(sci_id, SCBMR, RFFT); //outbyte(sci_cb[sci_id].scbmr,inbyte(sci_cb[sci_id].scbmr)|RFFT); }}/****************************************************************************** Function: sci_atom_HW_reset**** Purpose: Initiate a hard ware reset**** Parameters: sci_id: zero-based number to identify smart card controller****************************************************************************/void sci_atom_HW_reset(ULONG sci_id, SCI_RESET_TYPE reset_type){ ULONG time0 = 0; ULONG time1 = 0; ULONG t1 = 0; switch(reset_type) { /* cold reset */ case COLD: if(sci_cb[sci_id].sci_modes.emv2000 == 1) { _set_bits(sci_id, SCCTL3, SCIEMV); t1 = SCI_EMV_T1_MIN; } else { _clear_bits(sci_id, SCCTL3, SCIEMV);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -