?? iccard.c
字號:
#pragma interrupt INTTM02 MD_INTTM02
#include "includes.h"
volatile Dummy_Comm485_ParameterS Cpu_card_comm;
uchar cd_data[ICCARD_MAX_DLEN];
uchar IC_ATR_DATA[8];
uchar IC_CPU_RAND_DATA[8];
uchar IC_CPU_ENCRYPT_DATA[8];
uchar IC_ESAM_RAND_DATA[8];
uchar IC_ESAM_ENCRYPT_DATA[8];
uchar IC_ESAM_KEY_BUFFER[24];
uchar IC_WRITE_BUFFER[80];
uchar recv_flag = 0;
uchar card_in_slot = 0;
uchar test_value = 0;
uchar IC_Card_flag = 0;
const uchar IC_SOUND_CLR[] = {SOUND_OF_CLR_CARD, SOUND_OF_INSERT, SOUND_OF_SYS_DEAL, SOUND_OF_WAIT};
const uchar IC_SOUND_BUY[] = {SOUND_OF_BUY_CARD, SOUND_OF_SYS_DEAL, SOUND_OF_WAIT};
const uchar IC_SOUND_BUY_OK[] = {SOUND_OF_BUY_OK};
const uchar IC_SOUND_BUY_ERR[] = {SOUND_OF_BUY_ERR};
const uchar IC_SOUND_CLR_OK[] = {SOUND_OF_CLR_FINISH};
const uchar IC_SOUND_NOT_IDENTIFY[] = {SOUND_OF_NOT_IDENTIFY_CARD};
void TM02Init(void)
{
CPUCARD_COMM_STOP();
PER0.0 = 1;
TS0L.2 = 0;
TMR02 = 0x0000;
TPS0L = 0x0044;
TDR02 = CLK_COUNT_9600;
}
__interrupt void MD_INTTM02( void )
{
TMIF02 = 0;
TS0L.2 = 0;
TDR02 = CLK_COUNT_9600;
TS0L.2 = 1;
Cpu_card_comm.BIT_Count++;
if( Cpu_card_comm.State_T_Or_R == TXDING )
{
CPU_card_send();
}
else
{
CPU_card_receive();
}
}
void CPU_card_start_tx(uchar frame_start_Pointer, uchar len)
{
_disable_interrupt();
Cpu_card_comm.Uart_Data = 0;
Cpu_card_comm.Len_Of_Need_To_Send = len;
Cpu_card_comm.FramePointer = frame_start_Pointer;
Cpu_card_comm.BIT_Count = 0;
Cpu_card_comm.State_T_Or_R = TXDING;
Cpu_card_comm.verify = 0;
MemsetZero( (uchar *)&Cpu_card_comm.Serial_Buffer[0], frame_start_Pointer );
if( !TS0L.2 ) TS0L.2 = 1;
TDR02 = CLK_COUNT_9600;
TMIF02 = 0;
CPUCARD_COMM_START();
_enable_interrupt();
}
void CPU_card_receive(void)
{
uchar temp_bit;
IC_IO_DIR(IC_IO_DIR_INPUT);
if( Cpu_card_comm.selectDevice == SEL_CARD )
{
temp_bit = CPU_CARD_IO;
}
else
{
temp_bit = ESAM_IO_PIN;
}
switch( Cpu_card_comm.BIT_Count )
{
case 9:
if( Cpu_card_comm.verify != temp_bit )
{
Cpu_card_comm.verify |= VERIFY_ERROR;
}
else
{
Cpu_card_comm.verify = 0;
}
break;
case 10:
recv_flag = 0;
TS0L.2 = 0;
CPUCARD_COMM_STOP();
if( 0 == ( Cpu_card_comm.verify & VERIFY_ERROR ) )
{
if( Cpu_card_comm.FramePointer < sizeof( Cpu_card_comm.Serial_Buffer ) )
{
Cpu_card_comm.Serial_Buffer[Cpu_card_comm.FramePointer++] = Cpu_card_comm.Uart_Data;
}
}
break;
default:
Cpu_card_comm.Uart_Data >>= 1;
if( temp_bit )
{
Cpu_card_comm.Uart_Data |= 0x80;
}
Cpu_card_comm.verify ^= temp_bit;
break;
}
}
void CPU_card_send(void)
{
IC_IO_DIR(IC_IO_DIR_OUTPUT);
if( Cpu_card_comm.Uart_Data & 0x01 )
{
IC_IO(1);
Cpu_card_comm.verify=~Cpu_card_comm.verify;
}
else
{
IC_IO(0);
}
switch( Cpu_card_comm.BIT_Count )
{
case 1:
Cpu_card_comm.Uart_Data = Cpu_card_comm.Serial_Buffer[Cpu_card_comm.FramePointer];
Cpu_card_comm.Serial_Buffer[Cpu_card_comm.FramePointer] = 0;
break;
case 9:
Cpu_card_comm.Uart_Data = Cpu_card_comm.verify;
break;
case 10:
Cpu_card_comm.Uart_Data = 0x01;
break;
case 11:
if( 0 == --Cpu_card_comm.Len_Of_Need_To_Send )
{
CPUCARD_COMM_STOP();
Cpu_card_comm.verify = 0;
Cpu_card_comm.BIT_Count = 0;
Cpu_card_comm.Uart_Data = 0;
}
break;
case 12:
case 13:
case 14:
break;
case 15:
Cpu_card_comm.FramePointer++;
Cpu_card_comm.verify = 0;
Cpu_card_comm.BIT_Count = 0;
Cpu_card_comm.Uart_Data = 0;
break;
default:
Cpu_card_comm.Uart_Data>>=1;
break;
}
}
void CPU_card_start_rx(void)
{
_disable_interrupt();
IC_IO_DIR(IC_IO_DIR_INPUT);
Cpu_card_comm.State_T_Or_R = RXDING;
Cpu_card_comm.FramePointer = 0;
Cpu_card_comm.BIT_Count = 0;
Cpu_card_comm.verify = 0;
_enable_interrupt();
}
void CPU_card_comm_init(void)
{
Cpu_card_comm.FramePointer %= sizeof( Cpu_card_comm.Serial_Buffer );
MemsetZero( &Cpu_card_comm.Serial_Buffer[0], Cpu_card_comm.FramePointer );
CPU_card_start_rx();
}
void CPUCardReset()
{
if( Cpu_card_comm.selectDevice == SEL_CARD )
{
CPU_RST(0);
Delay(400);
CPU_RST(1);
}
else
{
ESAM_RST(0);
Delay(400);
ESAM_RST(1);
}
}
void CPU_card_read_response(uchar read_len)
{
ushort ii = 0,old_IE0,old_IE1,old_IE2;
uchar temp_bit;
old_IE0 = MK0;
old_IE1 = MK1;
old_IE2 = MK2;
MK0 = 0xFFFF;
MK1 = 0xFFFF;
MK2 = 0xFFFF;
CPU_card_start_rx();
while( Cpu_card_comm.FramePointer < read_len )
{
if( Cpu_card_comm.selectDevice == SEL_CARD )
temp_bit = CPU_CARD_IO;
else
temp_bit = ESAM_IO_PIN;
if( ( !temp_bit ) && ( recv_flag == 0 ) )
{
CPUCARD_COMM_STOP();
recv_flag = 1;
Cpu_card_comm.BIT_Count = 0;
Cpu_card_comm.verify = 0;
Cpu_card_comm.State_T_Or_R = RXDING;
TDR02 = CLK_COUNT_9600;
TMIF02 = 0;
TS0L.2 = 1;
CPUCARD_COMM_START();
ii = 0;
}
ii++;
if( Cpu_card_comm.FramePointer > 1 )
{
if( ii > 6000 ) break;
}
else
{
if( ii > 60000 ) break;
}
}
CPUCARD_COMM_STOP();
MK0 = old_IE0;
MK1 = old_IE1;
MK2 = old_IE2;
}
void CPU_card_send_command(uchar s_pos, uchar send_len)
{
ushort ii = 0, old_IE0, old_IE1, old_IE2;
old_IE0 = MK0;
old_IE1 = MK1;
old_IE2 = MK2;
MK0 = 0xFFFF;
MK1 = 0xFFFF;
MK2 = 0xFFFF;
CPU_card_start_tx( s_pos, send_len );
while( !TMMK02 )
{
ClrWdt();
Delay(2);
if( ii++ > 60000 ) break;
}
if( !TMMK02 )
{
CPUCARD_COMM_STOP();
}
MK0 = old_IE0;
MK1 = old_IE1;
MK2 = old_IE2;
}
/*
* 清零卡:
* 由生產廠家制作和使用,
* 1.用于IC卡電度表進行"復位"操作,使IC卡電度表復位成生產狀態(tài).
* 2.強制進行繼電器的開關操作.
* 內容:68H+11H+00H+CSUM+16H (CSUM=校驗和)
*/
uchar ic_setting(void)
{
ulong new_buy;
uchar *recv_buf = cd_data;
uchar fn_data,temp[4];
memcpy( recv_buf, &Cpu_card_comm.Serial_Buffer[1], 0x19 );
memcpy( temp, recv_buf+3, 4 );
ExchangeData(temp);
// 購電底數(shù)
new_buy = *((ulong *)(temp));
new_buy = Hex2BcdLong( new_buy );
// 購電次數(shù)清零
MemsetZeroWriteE2prom( DB_GDCS, 4 );
// 剩余電量
PrePayData.BalanceSum = new_buy;
FramWrite( DB_SYDL, (uchar *)&new_buy, POWER_DATA_LEN );
// 累計購電量
PrePayData.CumulateBuySum = new_buy;
FramWrite( DB_LJGDL, (uchar *)&new_buy, POWER_DATA_LEN );
// 累計用電量
PrePayData.CumulatePaySum = 0;
FramWrite( DB_LJDL, (uchar *)&PrePayData.CumulatePaySum, POWER_DATA_LEN );
// 過零電量
PrePayData.OverZeroSum = 0;
FramWrite( DB_GLDL, (uchar *)&PrePayData.OverZeroSum, POWER_DATA_LEN );
// 最后購電量
FramWrite( DB_ZHGDL, (uchar *)&new_buy, POWER_DATA_LEN );
// 重置狀態(tài)字
fn_data = (~USED_METER);
save_data( &fn_data, DB_ST, 1 );
if( RELAYPARA.EnableFlag & BIT0 )
{
RELAY0_ON();
RELAY1_ON();
RELAYPARA.Status &=~ BIT0;
}
#if 0
if( RELAYPARA.EnableFlag & BIT1 )
{
RELAY1_ON();
RELAYPARA.Status &=~ BIT1;
}
#endif
FramWrite( ADDR_OF_RELAY_PARA+OFFSET_RELAY_STATUS, &RELAYPARA.Status, 1 );
return OK;
}
uchar ic_checking(void)
{
uchar *recv_buf, rec_num;
recv_buf = &Cpu_card_comm.Serial_Buffer[1];
if( OK != IC_read_file( SEL_CARD, 2, 0, 1 ) )
{
return(EPM_E__5);
}
rec_num = recv_buf[0];
if( rec_num >= 15 )
{
return(EPM_E__19);
}
//選擇反寫文件
if( OK != IC_select_file( SEL_TYPE_EF, 2 ) )
{
return EPM_E__14;
}
if( OK != IC_checking_writeback(rec_num) )
{
return EPM_E__15;
}
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR] = rec_num + 1;
if( OK != IC_write_file( SEL_CARD, 2, 0, 1 ) )
{
return EPM_E__20;
}
Delay20ms(20);
return(OK);
}
uchar ic_updating_pwd(void)
{
uchar key_num = 0, ii ;
if( OK != IC_read_file( SEL_CARD, FILE_ID_MODIFY_PASSWORD, 2, 1 ) )
{
return(EPM_E__5);
}
key_num = ( Cpu_card_comm.Serial_Buffer[1]/IC_KEY_LEN );
if( ( key_num > MAX_PWD_NUM ) || ( key_num == 0 ) )
{
return EPM_E__27;
}
for( ii = 0 ; ii < key_num; ii++ )
{
if( OK != IC_read_file(SEL_CARD, FILE_ID_MODIFY_PASSWORD, 4 + ii * IC_KEY_LEN, IC_KEY_LEN ) )
{
return(EPM_E__5);
}
memcpy( IC_ESAM_KEY_BUFFER, Cpu_card_comm.Serial_Buffer + 1, IC_KEY_LEN );
if( OK != ESAM_update_key() )
{
return(EPM_E__28);
}
}
return OK;
}
uchar ic_refill_writeback(uchar *meterAddr, ulong * buy_times, uchar card_sn)
{
unsigned char fn_data[50];
load_data( IC_WRITE_BUFFER, DB_SYDL, 20 );
ExchangeData( IC_WRITE_BUFFER );
ExchangeData( IC_WRITE_BUFFER+8 );
ExchangeData( IC_WRITE_BUFFER+12 );
ExchangeData( IC_WRITE_BUFFER+16 );
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR] = 0x68;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 1] = 0x80;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 2] = 0x22;
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 3], IC_WRITE_BUFFER, 20 );
//save buy times
memcpy( &Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 7], (unsigned char *)buy_times, 4 );
// 非法插卡次數(shù)清零
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 23] = 0;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 24] = 0;
// 電能表狀態(tài)字
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 25] = 0;
// 電表表號
memcpy(&Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 26], meterAddr, USER_METER_LEN);
// 卡序號
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 36] = card_sn;
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x25] = GetSum(&Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 1], 0x24);
Cpu_card_comm.Serial_Buffer[IC_WRITE_START_ADDR + 0x26] = 0x16;
if( OK != IC_write_file( SEL_ESAM, 2, 0, 0x27 ) )
{
return ERROR;
}
if( OK != IC_get_rand_data( SEL_CARD, 4 ) )
{
return ERROR;
}
if( OK != ESAM_read_MAC( 2, 0, 0x27 ) )
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -