diff --git a/Targets/Bonito3a3000_7a/dev/ltc.c b/Targets/Bonito3a3000_7a/dev/ltc.c index cf44cb33..657cd0f5 100644 --- a/Targets/Bonito3a3000_7a/dev/ltc.c +++ b/Targets/Bonito3a3000_7a/dev/ltc.c @@ -1,5 +1,6 @@ /* - * This file is for DS1338 RTC. + * This file is for LTC2946 for LS7A 2 way. + * */ #include #include @@ -15,174 +16,337 @@ #define CR_REG 0x4 #define SR_REG 0x4 -#define ls7a_i2c_writeb(reg, val) outb(LS7A_I2C1_REG_BASE + reg, val) -#define ls7a_i2c_readb(reg) inb(LS7A_I2C1_REG_BASE + reg) +#define ls7a_i2c_writeb(reg, val) outb(LS7A_I2C1_REG_BASE + reg, val) +#define ls7a_i2c_readb(reg) inb(LS7A_I2C1_REG_BASE + reg) + +#define LTC_REG_COUNT 0x44 +//unit mV +#define LTC_DLTSNS_RESOLUTION 25 //uV +#define LTC_VIN_RESOLUTION 25 //mV +#define LTC_ADDIN_RESOLUTION 0.5 //mV +#define LTC_RSNS 5 //mO + +//#define LTC_DEBUG + +#ifdef LTC_DEBUG +#define _LTCVERBOSE 5 +#else +#define _LTCVERBOSE 0 +#endif +#define LTC_I2C_MASS_ADDR 0xcc + +int _ltcverbose = _LTCVERBOSE; +unsigned char ltc_mass_addr = LTC_I2C_MASS_ADDR; static void ls7a_i2c_stop(void) { again: - ls7a_i2c_writeb(CR_REG, CR_STOP); - ls7a_i2c_readb(SR_REG); - while (ls7a_i2c_readb(SR_REG) & SR_BUSY) - goto again; + ls7a_i2c_writeb(CR_REG, CR_STOP); + ls7a_i2c_readb(SR_REG); + while (ls7a_i2c_readb(SR_REG) & SR_BUSY) + goto again; } -static void i2c_init(void) +static void ls7a_i2c_init(void) { - delay(1000); - ls7a_i2c_writeb(CTR_REG, 0x0); - delay(1000); - ls7a_i2c_writeb(PRER_LO_REG, 0x71); - ls7a_i2c_writeb(PRER_HI_REG, 0x2); - ls7a_i2c_writeb(CTR_REG, 0x80); + //delay(1000); + ls7a_i2c_writeb(CTR_REG, 0x0); + //delay(1000); + ls7a_i2c_writeb(PRER_LO_REG, 0x71); + ls7a_i2c_writeb(PRER_HI_REG, 0x2); + ls7a_i2c_writeb(CTR_REG, 0x80); } static int i2c_tx_byte(u8 data, u8 opt) { - ls7a_i2c_writeb(TXR_REG, data); - ls7a_i2c_writeb(CR_REG, opt); - while (ls7a_i2c_readb(SR_REG) & SR_TIP) ; + ls7a_i2c_writeb(TXR_REG, data); + ls7a_i2c_writeb(CR_REG, opt); + while (ls7a_i2c_readb(SR_REG) & SR_TIP) ; - if (ls7a_i2c_readb(SR_REG) & SR_NOACK) { - printf("ltc has no ack, Pls check the hardware!\n"); - ls7a_i2c_stop(); - return -1; - } + if (ls7a_i2c_readb(SR_REG) & SR_NOACK) { + printf("ltc has no ack, Pls check the hardware!\n"); + ls7a_i2c_stop(); + return -1; + } - return 0; + return 0; } static int ltc_send_addr(u8 dev_addr ,u8 data_addr) { - if (i2c_tx_byte(dev_addr, CR_START | CR_WRITE) < 0) - return 0; - if (i2c_tx_byte(data_addr, CR_WRITE) < 0) - return 0; + if (i2c_tx_byte(dev_addr, CR_START | CR_WRITE) < 0) + return 0; + if (i2c_tx_byte(data_addr, CR_WRITE) < 0) + return 0; - return 1; + return 1; } int ltc_write(u8 dev_addr,u8 data_addr, u8 *buf, int count) { - u8 i; - if (!ltc_send_addr(dev_addr,data_addr)) - return 0; + u8 i; + if (!ltc_send_addr(dev_addr,data_addr)) + return 0; - for (i = 0; i < count; i++) - if (i2c_tx_byte(buf[i] & 0xff, CR_WRITE) < 0) - return 0; - ls7a_i2c_stop(); + for (i = 0; i < count; i++) + if (i2c_tx_byte(buf[i] & 0xff, CR_WRITE) < 0) + return 0; + ls7a_i2c_stop(); - return i; + return i; } static int ltc_read_cur(u8 dev_addr,u8 *buf, int count) { - u8 i; - dev_addr |= 0x1; + u8 i; + dev_addr |= 0x1; - if (i2c_tx_byte(dev_addr, CR_START | CR_WRITE) < 0) - return 0; + if (i2c_tx_byte(dev_addr, CR_START | CR_WRITE) < 0) + return 0; - for (i = 0; i < count; i++) { - ls7a_i2c_writeb(CR_REG, ((i == count - 1) ? - (CR_READ | CR_ACK) : CR_READ)); - while (ls7a_i2c_readb(SR_REG) & SR_TIP) ; - buf[i] = ls7a_i2c_readb(RXR_REG); - } + for (i = 0; i < count; i++) { + ls7a_i2c_writeb(CR_REG, ((i == count - 1) ? + (CR_READ | CR_ACK) : CR_READ)); + while (ls7a_i2c_readb(SR_REG) & SR_TIP) ; + buf[i] = ls7a_i2c_readb(RXR_REG); + } - ls7a_i2c_stop(); - return i; + ls7a_i2c_stop(); + return i; } -int ltc_read_rand(u8 dev_addr,u8 data_addr, u8 *buf,int count) +int ltc_read(u8 dev_addr,u8 data_addr, u8 *buf,int count) { - if (!ltc_send_addr(dev_addr,data_addr)) - return 0; + if (!ltc_send_addr(dev_addr,data_addr)) + return 0; - if (!ltc_read_cur(dev_addr,buf,count)) - return 0; - return 1; + if (ltc_read_cur(dev_addr,buf,count) != count) + return 0; + return 1; } -int ltc_test(u8 dev_addr) +#define MAX_LTC_NUM 4 +int ltc_init(ac, av) + int ac; + char *av[]; { - u8 buf[0xe8] = {0}; - u8 data_addr = 0; - int i; - u32 tmp; - unsigned int value, value_max, value_min, value1, value1_max, value1_min; - i2c_init(); - buf[0] = 0x10; - ltc_write(dev_addr,0,buf,1); - ltc_read_rand(dev_addr,data_addr,buf, 0xe8); - - for (i = 0; i < 0xe8; i++) { - if (!(i % 16)) - printf("\n"); - printf("%02x ", buf[i]); - } - printf("\n"); - - printf("result value should divide 10000 !\n"); - tmp = (buf[0x28] << 4) | (buf[0x29] >> 4); - value = ((tmp/2) - 500)*10000; - value = value/133; - printf("CPU VDD %d\n",value); - tmp = (buf[0x2a] << 4) | (buf[0x2b] >> 4); - value_max = ((tmp/2) - 500)*10000; - value_max = value_max/133; - printf("MAX CPU VDD %d\n",value_max); - tmp = (buf[0x2c] << 4) | (buf[0x2d] >> 4); - value_min = ((tmp/2) - 500) * 10000; - value_min /= 133; - printf("MIN CPU VDD %d\n",value_min); -#if 1 - tmp = (buf[0x14] << 4) | (buf[0x15] >> 4); - value1 = tmp * 0.50; - printf("PEST_1V1 %d\n",value1); - tmp = (buf[0x16] << 4) | (buf[0x17] >> 4); - value1_max = tmp * 0.50; - printf("MAX PEST_1V1 %d\n",value1_max); - tmp = (buf[0x18] << 4) | (buf[0x19] >> 4); - value1_min = tmp * 0.50; - printf("MIN PEST_1V1 %d\n",value1_min); + int i, j; + u8 dev_addr[MAX_LTC_NUM]; + u8 buf[LTC_REG_COUNT] = {0}; + int ltc_num = 0; + //get parameters + if(ac < 2){ + printf("usage: ltc_init i2c_addr\n"); + return 0; + } + for(i=0; i < MAX_LTC_NUM; i++){ + if(ac > i+1){ + dev_addr[i] = (unsigned char)strtoul(av[i+1], 0, 0); + printf("info: i2c_addr[%d]: 0x%x\n", i, dev_addr[i]); + ltc_num++; + } + } + if(ac > (MAX_LTC_NUM + 1)){ + printf("Warning: support %d LTC devices at the most.\n", MAX_LTC_NUM); + } + + ls7a_i2c_init(); + + for(i=0; i < ltc_num; i++){ + //check chip ID + if(!ltc_read(dev_addr[i], 0xe7, buf, 1)){ + printf("Error: ltc read ID e7 fail!\n"); + return 0; + }; + if(!ltc_read(dev_addr[i], 0xe8, &buf[1], 1)){ + printf("Error: ltc read ID e8 fail!\n"); + return 0; + }; + if(buf[0] != 0x60 || buf[1] != 0x01){ + printf("Info: ltc ID is: %02x %02x\n", buf[0], buf[1]); + printf("Error: ltc ID check fail!\n"); + return 0; + } + + printf("check ltc %d(addr 0x%02x) info success.\n", i, dev_addr[i]); + //read all registers out for test + if(_ltcverbose > 2){ + if(!ltc_read(dev_addr[i], 0, buf, LTC_REG_COUNT)){ + printf("Error: ltc read rand fail!\n"); + return 0; + }; + + //printf(""); + for (j = 0; j < LTC_REG_COUNT; j++) { + if (!(j % 8)) + printf("\n0x%02x: ", j); + printf("%02x ", buf[j]); + } + printf("\n"); + } + + //reset + buf[0] = (0x3 << 0); + ltc_write(dev_addr[i], 1, buf, 1); + //set initial MIN/MAX + buf[0] = 0x0; + buf[1] = 0x0; + buf[2] = 0x0; + + buf[4] = 0xff; + buf[5] = 0xff; + buf[6] = 0xff; + buf[7] = 0xf0; + //Power + ltc_write(dev_addr[i], 0x8, &buf[0], 3); + ltc_write(dev_addr[i], 0xb, &buf[4], 3); + + //deltaSense + ltc_write(dev_addr[i], 0x16, &buf[0], 2); + ltc_write(dev_addr[i], 0x18, &buf[6], 2); + + //VIN + ltc_write(dev_addr[i], 0x20, &buf[0], 2); + ltc_write(dev_addr[i], 0x22, &buf[6], 2); + + //ADIN + ltc_write(dev_addr[i], 0x2A, &buf[0], 2); + ltc_write(dev_addr[i], 0x2C, &buf[6], 2); + + //set threshold TODO + //enable alert TODO + //configure monitor mode + buf[0] = (0x3 << 0) | (0x3 << 3) | (0x2 << 5); + ltc_write(dev_addr[i], 0, buf, 1); + + printf("configure ltc %d(addr 0x%02x) success.\n", i, dev_addr[i]); + } + +} + +int ltc_result_proc(unsigned char *buf){ + unsigned int val_cur, val_max, val_min; + unsigned int volt_cur, volt_max, volt_min; +#if 1 //ADDIN + printf("ADDIN(mV), "); + val_cur = (buf[0x28 + 0] << 4) | (buf[0x28 + 1] >> 4); + val_max = (buf[0x28 + 2] << 4) | (buf[0x28 + 3] >> 4); + val_min = (buf[0x28 + 4] << 4) | (buf[0x28 + 5] >> 4); + + volt_cur = val_cur * LTC_ADDIN_RESOLUTION; + volt_max = val_max * LTC_ADDIN_RESOLUTION; + volt_min = val_min * LTC_ADDIN_RESOLUTION; + + printf("%d, %d, %d, \n", volt_cur, volt_max, volt_min); + if(_ltcverbose > 3){ + printf("%02x%02x, %02x%02x, %02x%02x, \n", buf[0x28 + 0], buf[0x28 + 1], buf[0x28 + 2], buf[0x28 + 3], buf[0x28 + 4], buf[0x28 + 5]); + } #endif -#if 0 - tmp = (buf[0x2a] << 4) | (buf[0x2b] >> 4); - value_max = ((tmp * 0.5)/1000 - 0.5)/0.133; - printf("MAX CPU VDD %lf\n",value_max); - tmp = (buf[0x2c] << 4) | (buf[0x2d] >> 4); - value_min = ((tmp * 0.5)/1000 - 0.5)/0.133; - printf("MIN CPU VDD %lf\n",value_min); - - tmp = (buf[0x14] << 4) | (buf[0x15] >> 4); - value1 = tmp * 0.000050; - printf("PEST_1V1 %lf\n",value1); - tmp = (buf[0x16] << 4) | (buf[0x17] >> 4); - value1_max = tmp * 0.000050; - printf("MAX PEST_1V1 %lf\n",value1_max); - tmp = (buf[0x18] << 4) | (buf[0x19] >> 4); - value1_min = tmp * 0.000050; - printf("MIN PEST_1V1 %lf\n",value1_min); +#if 1 //Vin + printf("Vin(mV), "); + val_cur = (buf[0x1E + 0] << 4) | (buf[0x1E + 1] >> 4); + val_max = (buf[0x1E + 2] << 4) | (buf[0x1E + 3] >> 4); + val_min = (buf[0x1E + 4] << 4) | (buf[0x1E + 5] >> 4); + + volt_cur = val_cur * LTC_VIN_RESOLUTION; + volt_max = val_max * LTC_VIN_RESOLUTION; + volt_min = val_min * LTC_VIN_RESOLUTION; + + printf("%d, %d, %d, \n", volt_cur, volt_max, volt_min); + if(_ltcverbose > 3){ + printf("%02x%02x, %02x%02x, %02x%02x, \n", buf[0x1E + 0], buf[0x1E + 1], buf[0x1E + 2], buf[0x1E + 3], buf[0x1E + 4], buf[0x1E + 5]); + } +#endif +#if 1 //deltaSense + printf("deltaSense(uV), "); + + val_cur = (buf[0x14 + 0] << 4) | (buf[0x14 + 1] >> 4); + val_max = (buf[0x14 + 2] << 4) | (buf[0x14 + 3] >> 4); + val_min = (buf[0x14 + 4] << 4) | (buf[0x14 + 5] >> 4); + + volt_cur = val_cur * LTC_DLTSNS_RESOLUTION; + volt_max = val_max * LTC_DLTSNS_RESOLUTION; + volt_min = val_min * LTC_DLTSNS_RESOLUTION; + + printf("%d, %d, %d, \n", volt_cur, volt_max, volt_min); + if(_ltcverbose > 3){ + printf("%02x%02x, %02x%02x, %02x%02x, \n", buf[0x14 + 0], buf[0x14 + 1], buf[0x14 + 2], buf[0x14 + 3], buf[0x14 + 4], buf[0x14 + 5]); + } #endif +#if 1 //Power + printf("Power(uW)(Rsns %d m ohm), ", LTC_RSNS); + val_cur = (buf[0x5 + 0] << 16) | (buf[0x5 + 1] << 8) | (buf[0x5 + 2]); + val_max = (buf[0x8 + 0] << 16) | (buf[0x8 + 1] << 8) | (buf[0x8 + 2]); + val_min = (buf[0xb + 0] << 16) | (buf[0xb + 1] << 8) | (buf[0xb + 2]); + + volt_cur = val_cur * LTC_VIN_RESOLUTION * LTC_DLTSNS_RESOLUTION / LTC_RSNS; + volt_max = val_max * LTC_VIN_RESOLUTION * LTC_DLTSNS_RESOLUTION / LTC_RSNS; + volt_min = val_min * LTC_VIN_RESOLUTION * LTC_DLTSNS_RESOLUTION / LTC_RSNS; + + printf("%d, %d, %d, \n", volt_cur, volt_max, volt_min); + if(_ltcverbose > 3){ + printf("%02x%02x%02x, ", buf[0x5 + 0], buf[0x5 + 1], buf[0x5 + 2]); + printf("%02x%02x%02x, ", buf[0x8 + 0], buf[0x8 + 1], buf[0x8 + 2]); + printf("%02x%02x%02x, ", buf[0xb + 0], buf[0xb + 1], buf[0xb + 2]); + printf("\n"); + } +#endif + + return 0; } -int ltc_read(void) +int ltc_check(ac, av) + int ac; + char *av[]; { - ltc_test(0xd8);//device addr - ltc_test(0xd2); - ltc_test(0xce); + int i; + u8 dev_addr[MAX_LTC_NUM]; + u8 buf[LTC_REG_COUNT] = {0}; + int ltc_num = 0; + //get parameters + if(ac < 2){ + printf("usage: ltc_init i2c_addr\n"); + return 0; + } + for(i=0; i < MAX_LTC_NUM; i++){ + if(ac > i+1){ + dev_addr[i] = (unsigned char)strtoul(av[i+1], 0, 0); + if(_ltcverbose > 10){ + printf("info: i2c_addr[%d]: 0x%x\n", i, dev_addr[i]); + } + ltc_num++; + } + } + if(ac > (MAX_LTC_NUM + 1)){ + printf("Warning: support %d LTC devices at the most.\n", MAX_LTC_NUM); + } + + //check fault TODO + + //read results + printf("voltage, cur, max, min,\n"); + for(i=0; i < ltc_num; i++){ + printf("readout ltc %d(addr 0x%02x) results:\n", i, dev_addr[i]); + if(!ltc_read(dev_addr[i], 0, buf, LTC_REG_COUNT)){ + printf("Error: read results fail!\n"); + return 0; + }else{ + ltc_result_proc(buf); + }; + } + } + static const Cmd Cmds[] = { - {"Misc"}, - {"ltc_test", "", NULL, "test the i2c rtc is ok?", ltc_read, 1, 5, 0}, - {0, 0} + {"Misc"}, + {"ltc_init", "i2c addr0 [addr1] [addr2] ...", 0, "ltc init", ltc_init, 1, 5, 0}, + {"ltc_check", "i2c addr0 [addr1] [addr2] ...", 0, "check ltc results", ltc_check, 1, 5, 0}, + {0, 0} }; static void init_cmd __P((void)) __attribute__ ((constructor)); static void init_cmd() { - cmdlist_expand(Cmds, 1); + cmdlist_expand(Cmds, 1); }