+bool I2C_is_available(void) {
+ I2C_init();
+ I2C_Reset_EnterMainProgram();
+ if (!I2C_Start()) // some other device is active on the bus
+ return true;
+ I2C_SendByte(I2C_DEVICE_ADDRESS_MAIN & 0xFE);
+ if (!I2C_WaitAck()) { // no response from smartcard reader
+ I2C_Stop();
+ return false;
+ }
+ I2C_Stop();
+ return true;
+}
+
+#ifdef WITH_SMARTCARD
+// ¸´Î»½øÈëÒýµ¼Ä£Ê½
+// Reset the SIM_Adapter, then enter the bootloader program
+// Reserve£ºFor firmware update.
+static void I2C_Reset_EnterBootloader(void) {
+ I2C_SetResetStatus(0, 1, 1); // ÀµÍ¸´Î»Ïß
+ SpinDelay(100);
+ I2C_SetResetStatus(1, 1, 1); // ½â³ý¸´Î»
+ SpinDelay(10);
+}
+
+// Wait max 300ms or until SCL goes LOW.
+// Which ever comes first
+static bool WaitSCL_L_300ms(void) {
+ volatile uint16_t delay = 310;
+ while ( delay-- ) {
+ // exit on SCL LOW
+ if (!SCL_read)
+ return true;
+
+ SpinDelay(1);
+ }
+ return (delay == 0);
+}
+
+static bool I2C_WaitForSim() {
+ // variable delay here.
+ if (!WaitSCL_L_300ms())
+ return false;
+
+ // 8051 speaks with smart card.
+ // 1000*50*3.07 = 153.5ms
+ // 1byte transfer == 1ms with max frame being 256bytes
+ if (!WaitSCL_H_delay(10 * 1000 * 50))
+ return false;
+
+ return true;
+}
+
+// Send i2c ACK
+static void I2C_Ack(void) {
+ SCL_L; I2C_DELAY_2CLK;
+ SDA_L; I2C_DELAY_2CLK;
+ SCL_H; I2C_DELAY_2CLK;
+ if (!WaitSCL_H()) return;
+ SCL_L; I2C_DELAY_2CLK;
+}
+
+// Send i2c NACK
+static void I2C_NoAck(void) {
+ SCL_L; I2C_DELAY_2CLK;
+ SDA_H; I2C_DELAY_2CLK;
+ SCL_H; I2C_DELAY_2CLK;
+ if (!WaitSCL_H()) return;
+ SCL_L; I2C_DELAY_2CLK;
+}
+
+static int16_t I2C_ReadByte(void) {
+ uint8_t bits = 8, b = 0;