PICO I2C FW
Dependencies: USBDevice
main.cpp
- Committer:
- cyberjoey
- Date:
- 2018-07-06
- Revision:
- 15:61dce4bef44f
- Parent:
- 14:480f2398fe6a
- Child:
- 16:2f373d3c8214
File content as of revision 15:61dce4bef44f:
#include "mbed.h" #include "SDFileSystem.h" #include "max32630fthr.h" #include "USBSerial.h" #include <ctype.h> #define I2C_ADDRESS 0x30 // DS2484 I2C address #define DS2484_ADD 0x30 // DS2484 I2C write address #define PERIOD 10 // Logging period in seconds //DS2484 Status register bits #define OWB 0x01 // status reg, One Wire Busy #define PPD 0x02 // status reg, Presence Pulse Detected #define SD 0x04 // status reg, Short Detected #define LL 0x08 // status reg, Logic Level #define RST 0x10 // status reg, Device Reset (DS2484 Reset) #define SBR 0x20 // status reg, Single Bit Result #define TSB 0x40 // status reg, Triplet Second Bit #define DIR 0x80 // status reg, Branch Direction Taken //DS2484 Command bytes #define RESET 0xF0 // DS2484 Reset #define SRP 0xE1 // DS2484 Set Read Pointer #define WDC 0xD2 // DS2484 Write Device Configuration #define ACP 0xC3 // DS2484 Adjust one wire Control Port #define OW_RESET 0xB4 // DS2484 One Wire Reset #define OW_SB 0x87 // One Wire Single Bit (write or read) #define OWWB 0xA5 // One Wire Write Byte #define OWRB 0x96 // One Wire Read Byte #define OWT 0x78 // One Wire Triplet (read 2 bits, write 1 bit) //One Wire Commands #define OW_SEARCH 0xF0 // Search Rom #define OW_READ 0x33 // Read Rom #define OW_MATCH 0x55 // Match Rom #define OW_SKIP 0xCC // Skip Rom #define OW_OD_MATCH 0x69 // Match Rom #define OW_OD_SKIP 0x3C // Skip Rom #define OW_ALARM 0xEC // Alarm Search // OT07 OW commands #define OT07_OW_CONVERT 0x44 //OT07 OW convert temperature command #define OT07_OW_WRITE 0xCC // OT07 OW Write Register command #define OT07_OW_READ 0x33 // OT07 OW Read Register command #define OT07_OW_RESET 0x82 // OT07 OW Soft Reset command //OT07 Registers #define OT07_STATUS 0x00 // OT07 status regiter #define OT07_INT_EN 0x01 // OT07 Interrupt Enable #define OT07_FIFO_W 0x04 // OT07 FIFO Write Pointer #define OT07_FIFO_R 0x05 // OT07 FIFO Read Pointer #define OT07_FIFO_OF 0x06 // OT07 FIFO Overflow Counter #define OT07_FIFO_COUNT 0x07 // OT07 FIFO Data Count #define OT07_FIFO_DATA 0x08 // OT07 FIFO Data #define OT07_FIFO_CNFG1 0x09 // OT07 FIFO Configuration 1 (FIFO_A_FULL) #define OT07_FIFO_CNFG2 0x0A // OT07 FIFO Configuration 2 #define OT07_SYS 0x0C // OT07 System Configuration #define OT07_ALARM_HIGH_MSB 0x10 // OT07 Alarm High MSB #define OT07_ALARM_HIGH_LSB 0x11 // OT07 Alarm High LSB #define OT07_ALARM_LOW_MSB 0x12 // OT07 Alarm Low MSB #define OT07_ALARM_LOW_LSB 0x13 // OT07 Alarm LOW LSB #define OT07_ADC_BITS 0x14 // OT07 Temp Seneor Setup (ADC_RES[7:6]) #define OT07_GPIO_SETUP 0x20 // OT07 GPIO Setup, sets GPIO modes #define Ot07_GPIO_CTRL 0x21 // OT07 GPIO control #define OT07_ROM_ID 0x30 // OT07 ROM_ID address of LSB? #define MAX_DEVICES 64 // Maximum number of rom devices allowed #define ID_LENGTH 8 // Rom ID length in bytes #define BS 8 // ASCII Back Space #define CR 13 // ASCII Carriage Return const char* settings_file = "/sd/settings.txt"; const char* log_file = "/sd/MAX30207Log.csv"; //global variable //******************** init Feather Boared Hardware *********************** MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); //microSD logging file system setup SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd"); // mosi, miso, sclk, cs //SD card insertion detection pin DigitalIn SDDetect(P2_2, PullUp); InterruptIn SDInsert(P2_2); // Virtual serial port over USB USBSerial pc(0x0B6A, 0x0042, 0x0001, false); // I2C setup I2C i2c(P3_4,P3_5); // P3_4 -> I2C1_SDA, P3_5-> I2C1_SCL //Timer setup Ticker timer_1; // timer for blinking led heartbeat bool tick_flag; // used for counting seconds bool log_flag = false; bool led_toggle_flag = false; bool button_flag = false; bool sd_insert_flag = false; bool error_flag; int error_ticks; //LED blink setup DigitalOut rLED(LED1); DigitalOut gLED(LED2); DigitalOut bLED(LED3); InterruptIn button(SW1); void LED_blink_callback(){ // LED Heart beat led_toggle_flag = !led_toggle_flag; if(log_flag) //if logging { if(led_toggle_flag) { //toggle red led rLED = LED_ON; } else { rLED = LED_OFF; gLED = LED_OFF; bLED = LED_OFF; } } else if(error_flag) //if error (no sd card) { if(led_toggle_flag) { //toggle red led rLED = LED_ON; gLED = LED_ON; } else { rLED = LED_OFF; gLED = LED_OFF; bLED = LED_OFF; } error_ticks--; if(error_ticks <= 0) error_flag = false; } else { if(led_toggle_flag) { //toggle teal leds gLED = LED_ON; bLED = LED_ON; } else { rLED = LED_OFF; gLED = LED_OFF; bLED = LED_OFF; } } tick_flag = true; } void btn_pressed() //button pressed isr { button_flag = true; } void sd_insert() //sd_insert pressed isr { sd_insert_flag = true; } // ***************************************************************************** // Define CRC-8 Table // ***************************************************************************** static unsigned char crc_table[] = { 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; // ----------------------------------------------------------------------------- // Calculate the CRC8 of the byte value provided with the current total // calc_crc8(unsigned char, unsigned char) crc8 total, byte to add // pass crc8 total = 0 to start new crc sum. // Returns new crc8 total // ----------------------------------------------------------------------------- unsigned char calc_crc8(unsigned char crc8, unsigned char value){ return crc_table[crc8 ^ value]; } // ***************************************************************************** // OW_reset() // returns 0 no device present, 1 device present // ***************************************************************************** int OW_reset(){ char data[2]; // define as minimun array size so 'data' is a pointer data[0] = OW_RESET; // One Wire Reset 0xB4 i2c.write(DS2484_ADD,data,1,0); // write reset command to DS2484 wait_ms(1); do{ // poll OW-busy i2c.read(DS2484_ADD,data,1); // read back status byte from DS2484 }while(OWB & data[0]); if(PPD & data[0])return 1; // Presence Pulse Detected bit true? return 0; // else } // end OW_reset() // ***************************************************************************** // OW_write_byte(char) takes char to send over one wire // returns DS2484 status byte // ***************************************************************************** char OW_write_byte(char byte){ char data[2]; data[0] = 0xA5; data[1] = byte; i2c.write(DS2484_ADD,data,2,1); i2c.read(DS2484_ADD,data,1); // read status byte // db.printf("[%02X]",byte); wait_us(700); // assumes normal speed OW write return data[0]; // return DS2484 Status byte }// end OW_write_byte() // ***************************************************************************** // OW_read_byte(char *, int) char* (save data pointer) // int (number of bytes to read) // returns 0x00 // // assumes OW_reset, OW_match rom, and OW device register read address already sent. // // ***************************************************************************** char OW_read_byte(char* a, int n){ char data[2]; int i; //read n bytes of data i=0; do{ data[0] = OWRB; // send 0x96; DS2484 command, OW read byte i2c.write(DS2484_ADD,data,1,0); wait_us(600); do{ i2c.read(DS2484_ADD,data,1); // read status byte and test OW-busy? }while(data[0]&0x01 == 1); // status bit[0] set --> OW busy //get byte from DS2484 data[0] = SRP; // send 0xE1, set read pointer data[1] = 0xE1; // set read pointer address 0xE1 read OW data i2c.write(DS2484_ADD,data,2,1); i2c.read(DS2484_ADD,data,1); // read bytes from OW register a[i] = data[0]; i++; //pc.printf("[%02X] ",data[0]); }while(i<n); //for(i=0;i<n;i++) db.printf("OW_read_byte - [%2d][%02X]\r\n",i,a[i]); return 0x00; }// end OW_read_byte() // ***************************************************************************** // OW_match_rom(char *) pointer to device_id byte array // returns 0x00 // assumes OW_reset alread sent // ***************************************************************************** char OW_match_rom(char *device_id){ int i; //Match rom OW_write_byte(OW_MATCH); // send 0x55, match rom command //send rom code for device for(i=0;i<8;i++){ OW_write_byte(device_id[i]); //I2C write ow byte } return 0x00; }// end OW_macth_rom // ***************************************************************************** // search_rom(char *) pointer to start of 2D array rom_id_list // returns number of devices found // ***************************************************************************** int search_rom(char rom_id_list[MAX_DEVICES][ID_LENGTH]){ // searches for all device on OW bus, returns # found int bit_num; int byte_num; int last_zero; int last_discrep; int search_dir; int rom_count; char byte_mask; int last_device; int i; char rom_id[8]; //used in rom search char data[8]; char crc; //init for first search only last_device = 0; last_discrep = 0; rom_count = 0; for(i=0;i<8;i++)rom_id[i] = 0x00; //clear rom_id do{ // loop for each rom search (end when last_device = 1) //init variable for each search bit_num = 1; byte_num = 0; byte_mask = 1; last_zero = 0; //OW reset if(OW_reset()){ //returns 1 if at least one device present //test if last device found if(last_device!=1){ // more devices to find search_dir = 0; OW_write_byte(OW_SEARCH); //send 0xF0 over one wire to init search rom do{ //determine search direction if(bit_num < last_discrep){ //before last discrepancy if((rom_id[byte_num] & byte_mask) > 0){// use last rom path search_dir = 1; // last path was 1 }else{ search_dir = 0; // last path was 0 } }else{ // at or past last discrepancy if(bit_num == last_discrep){ // at last discrepancy search_dir = 1; //been here before so use 1 }else{ search_dir = 0; //past last discrepancy so use 0 } } //write direction bit and get reply data[0] = 0x78; data[1] = search_dir << 7; //sets bit 7 of status reg to search_dir i2c.write(DS2484_ADD,data,2,1); wait_us(250); //read in rom_id bits i2c.read(DS2484_ADD,data,1); // read status byte //(todo) check for no device error here //get search direction used by triplet command if(data[0]&0x80){ //true --> DIR bit = 1 search_dir = 1; }else{ search_dir = 0; } //test for discrepancy (both 0 and 1 present at current bit number)(TSB = 0 (1's present) and SBR = 0 (0's present)) if(!(data[0] & 0x60)){ // true --> discrepancy exist, both TSB and SBR = 0 if(search_dir == 0)last_zero = bit_num; } if(search_dir == 1){ // write search dir to rom bit rom_id[byte_num] |= byte_mask; }else{ rom_id[byte_num] &= ~byte_mask; } //increment bit_num and byte_num if needed bit_num++; byte_mask <<= 1; //rotate 1 bit left if(byte_mask == 0){ //if bit shifts out of byte set byte to 1 byte_num++; //also increnent byt num byte_mask = 1; } }while(bit_num<65); //bit nun started at 1 so end after 64 last_discrep = last_zero; if(last_discrep == 0)last_device = 1; //copy rom_id into rom_id_list and calc crc of first 7 bytes crc = 0x00; // reset crc8 total to 0 for(i=7;i>=0;i--){ rom_id_list[rom_count][i] = rom_id[i]; } //clac_crc of rom ID for (i=0;i<7;i++){ crc = calc_crc8(crc, rom_id[i]); } rom_count++; }//if(last_device..) }else{//if prescent -- if no device present rom count is 0 return 0; } }while(last_device == 0); return rom_count; }// end search_rom() // ***************************************************************************** // alarm_search(char *) pointer to start of 2D array rom_id_list // returns number of devices found with alarm triggered // ***************************************************************************** int alarm_search(char rom_id_list[MAX_DEVICES][ID_LENGTH]){ // searches for all devices with alarm triggered on OW bus, returns # found int bit_num; int byte_num; int last_zero; int last_discrep; int search_dir; int rom_count; char byte_mask; int last_device; int i; char rom_id[8]; //used in rom search char data[8]; char crc; //init for first search only last_device = 0; last_discrep = 0; rom_count = 0; for(i=0;i<8;i++)rom_id[i] = 0x00; //clear rom_id do{ // loop for each rom search (end when last_device = 1) //init variable for each search bit_num = 1; byte_num = 0; byte_mask = 1; last_zero = 0; //OW reset if(OW_reset()){ //returns 1 if at least one device present //test if last device found if(last_device!=1){ // more devices to find search_dir = 0; OW_write_byte(OW_ALARM); //send 0xEC over one wire to init alarm search do{ //determine search direction if(bit_num < last_discrep){ //before last discrepancy if((rom_id[byte_num] & byte_mask) > 0){// use last rom path search_dir = 1; // last path was 1 }else{ search_dir = 0; // last path was 0 } }else{ // at or past last discrepancy if(bit_num == last_discrep){ // at last discrepancy search_dir = 1; //been here before so use 1 }else{ search_dir = 0; //past last discrepancy so use 0 } } //write direction bit and get reply data[0] = 0x78; data[1] = search_dir << 7; //sets bit 7 of status reg to search_dir i2c.write(DS2484_ADD,data,2,1); wait_us(250); //read in rom_id bits i2c.read(DS2484_ADD,data,1); // read status byte //(todo) check for no device error here //get search direction used by triplet command if(data[0]&0x80){ //true --> DIR bit = 1 search_dir = 1; }else{ search_dir = 0; } //test for discrepancy (both 0 and 1 present at current bit number)(TSB = 0 (1's present) and SBR = 0 (0's present)) if(!(data[0] & 0x60)){ // true --> discrepancy exist, both TSB and SBR = 0 if(search_dir == 0)last_zero = bit_num; } if(search_dir == 1){ // write search dir to rom bit rom_id[byte_num] |= byte_mask; }else{ rom_id[byte_num] &= ~byte_mask; } //increment bit_num and byte_num if needed bit_num++; byte_mask <<= 1; //rotate 1 bit left if(byte_mask == 0){ //if bit shifts out of byte set byte to 1 byte_num++; //also increnent byt num byte_mask = 1; } }while(bit_num<65); //bit nun started at 1 so end after 64 last_discrep = last_zero; if(last_discrep == 0)last_device = 1; //copy rom_id into rom_id_list and calc crc of first 7 bytes crc = 0x00; // reset crc8 total to 0 for(i=7;i>=0;i--){ rom_id_list[rom_count][i] = rom_id[i]; } //clac_crc of rom ID for (i=0;i<7;i++){ crc = calc_crc8(crc, rom_id[i]); } rom_count++; }//if(last_device..) }else{//if prescent -- if no device present rom count is 0 return 0; } }while(last_device == 0); //check if rom_id from alarm search is all 1s (this means there was a presence pulse but no alarm is triggered) bool bad_rom_id = true; for(int i = 0; i < 7; i++) { if(rom_id_list[0][i] != 0xFF) bad_rom_id = false; //found a byte in the rom id that isn't all 1s } if(bad_rom_id) return 0; return rom_count; }// end alarm_search() // ******************** write_OW_register() ******************************** // write_OW_register(char*, int, int, char*) // char* pointer to rom_id // int start address // int number of bytes to write // char* pointer to write data location // returns 0 if CRC match data // returns -1 if CRC does not match data // // ***************************************************************************** int write_OW_register(char *device_ID, int start_add, int n, char *data){ int i; //select device OW_reset(); OW_match_rom(device_ID); //set start address OW_write_byte(OT07_OW_WRITE); // send 0xCC, OW write register command for OT07 OW_write_byte(start_add); // send write register start address OW_write_byte(n-1); // send length of bytes to write (00-> one byte) for(i=0;i<n;i++){ // send n bytes of data OW_write_byte(data[i]); } OW_read_byte(data,2); // read 2 byte CRC // --- todo ---- // calculate CRC of // Command + length + n bytes sent // compare with 2 bytes read return 0; }//end write_OW_register // ******************** read_OW_register() ******************************** // read_OW_register(char*, int, int, char*) // char* pointer to rom_id // int start address // int number of bytes to read, not including CRC bytes // char* pointer to save data location // returns 0 if CRC match data // returns -1 if CRC does not match data // // ***************************************************************************** int read_OW_register(char *device_ID, int start_add, int n, char *data){ //int i; //select device OW_reset(); OW_match_rom(device_ID); //set start address OW_write_byte(OT07_OW_READ); // send 0x33, OW read register command for OT07 OW_write_byte(start_add); // send read register start address OW_write_byte(n-1); // send length of bytes to read (0 -> 1 byte) OW_read_byte(data,n+2); // read n bytes plus 2 byte CRC // --- todo ---- // calculate CRC of // Command + length + n bytes // compare with last 2 bytes read return 0; }//end read_OW_register int set_test_mode(char *device_id){ char data[4]; // enter test mode OW_reset(); OW_match_rom(device_id); // match ROM OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0xFF); // device register address OW_write_byte(0x00); // number of bytes to write -1 OW_write_byte(0x54); // first half of test mode pass code OW_read_byte(data,2); // read 2 byte CRC OW_reset(); OW_match_rom(device_id); OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0xFF); // device register address OW_write_byte(0x00); // number of bytes to write -1 OW_write_byte(0x4D); // second half of test mode pass code OW_read_byte(data,2); // read 2 byte CRC // set ADC_ENABLED OW_reset(); OW_match_rom(device_id); OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0x81); // device register address OW_write_byte(0x00); // number of bytes to write -1 OW_write_byte(0x04); // ADC_ENABLED code OW_read_byte(data,2); // read 2 byte CRC OW_reset(); OW_match_rom(device_id); OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0x98); // device register address OW_write_byte(0x05); // number of bytes to write -1 OW_write_byte(0x40); // add 98 data 40 OW_write_byte(0xD4); // add 99 data D4 OW_write_byte(0xE0); // add 9A data E0 OW_write_byte(0xB3); // add 9B data B3 OW_write_byte(0x09); // add 9C data 09 OW_write_byte(0xBA); // add 9D data BA OW_read_byte(data,2); // read 2 byte CRC //OTP copy OW_reset(); OW_match_rom(device_id); OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0x80); // device register address OW_write_byte(0x00); // number of bytes to write -1 OW_write_byte(0x82); // OW_read_byte(data,2); // read 2 byte CRC OW_reset(); OW_match_rom(device_id); OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0x80); // device register address OW_write_byte(0x00); // number of bytes to write -1 OW_write_byte(0x02); // OW_read_byte(data,2); // read 2 byte CRC OW_reset(); OW_match_rom(device_id); OW_write_byte(OT07_OW_WRITE); // device write register command OW_write_byte(0xFF); // device register address OW_write_byte(0x00); // number of bytes to write -1 OW_write_byte(0x00); // exit Test mode OW_read_byte(data,2); // read 2 byte CRC return 0; }// end set_test_mode() // ******************** convert_temperature() ******************************** // convert_temperature() // returns 0 // dose not block for 0.75 seconds. // ***************************************************************************** int convert_temperature(){ // convert sent to all OW devices char data[8]; OW_reset(); OW_write_byte(OW_SKIP); // send 0xCC, skip rom command // activate strong pullup data[0] = WDC; // send 0xD2 Write Device Configuration data[1] = 0xA5; // 1010 0101 b strong and active pullup on i2c.write(DS2484_ADD,data,2,0); //convert command OW_write_byte(OT07_OW_CONVERT); // send 0x44, Convert Temperature OW_read_byte(data,2); // read 2 byte CRC return 0; } // ******************** convert_temperature() ******************************** // convert_temperature(char *) takes 8 byte rom_id as input // returns 0 // dose not block for 0.75 seconds. // ***************************************************************************** int convert_temperature(char *device_id){ char data[8]; OW_reset(); OW_match_rom(device_id); // send device id // activate strong pullup data[0] = WDC; // send 0xD2 Write Device Configuration data[1] = 0xA5; // 1010 0101 b strong and active pullup on i2c.write(DS2484_ADD,data,2,0); //convert command OW_write_byte(OT07_OW_CONVERT); // send 0x44, Convert Temperature OW_read_byte(data,2); // read 2 byte CRC return 0; } //************************ get_temperature() ********************************* // get_temperature(char *) takes 8 byte rom_id as input // returns double temperature in oC //****************************************************************************** double get_temperature(char *device_id){ char t[4]; double T; int count; // char data[2]; read_OW_register(device_id,OT07_FIFO_DATA,0x02,t); // Read temperature from FIFO, 2 bytes //calculate temperture from data count = (int)(t[0]*256 + t[1]); if (count >= 32768)count = count - 65536; // 2s comp T = (double)count*0.005; return T; }// end get_temperature() void write_settings_file(int interval, bool device_logged[MAX_DEVICES]) { FILE *fp = fopen(settings_file, "w"); if (fp != NULL) { fprintf(fp, "i %d\r\n", interval); fprintf(fp, "d"); for(int i = 0; i < MAX_DEVICES; i++) { if(device_logged[i] == true) { fprintf(fp," %d", i); } } fprintf(fp,"\r\n"); fclose(fp); } return; } bool print_settings_file() { FILE *fp = fopen(settings_file, "r"); if (fp != NULL) { pc.printf("*\r\n"); // Read contents from file char c = fgetc(fp); while (!feof(fp)) { pc.printf("%c", c); c = fgetc(fp); } pc.printf("*\r\n"); fclose(fp); } else { return false; } return true; } bool print_log_file() { FILE *fp = fopen(log_file, "r"); if (fp != NULL) { pc.printf("*\r\n"); // Read contents from file char c = fgetc(fp); while (!feof(fp)) { pc.printf("%c", c); c = fgetc(fp); } pc.printf("*\r\n"); fclose(fp); } else { return false; } return true; } int getline(char **lineptr, int *n, FILE *stream) { char *bufptr = NULL; char *p = bufptr; size_t size; int c; if (lineptr == NULL) { return -1; } if (stream == NULL) { return -1; } if (n == NULL) { return -1; } bufptr = *lineptr; size = *n; c = fgetc(stream); if (c == EOF) { return -1; } if (bufptr == NULL) { bufptr = (char *)malloc(128); if (bufptr == NULL) { return -1; } size = 128; } p = bufptr; while(c != EOF) { if ((p - bufptr) > (size - 1)) { size = size + 128; bufptr = (char *)realloc(bufptr, size); if (bufptr == NULL) { return -1; } } *p++ = c; if (c == '\n') { break; } c = fgetc(stream); } *p++ = '\0'; *lineptr = bufptr; *n = size; return p - bufptr - 1; } bool print_settings_file_2() { char * line = NULL; int len = 0; FILE *fp = fopen(settings_file, "r"); if (fp != NULL) { pc.printf("*\r\n"); // Read contents from file while ((getline(&line, &len, fp)) != -1) { pc.printf("%s", line); } pc.printf("*\r\n"); fclose(fp); } else { return false; } return true; } //returns true if settings file exists and is in the proper format bool apply_settings_file(bool (&logged_devices)[MAX_DEVICES], int& interval) { char * line = NULL; int len = 0; int line_number = 0; FILE *fp = fopen("/sd/settings.txt", "r"); if (fp != NULL) { //initialize devices to all false; for(int i = 0; i < MAX_DEVICES; i++) { logged_devices[i] = false; } // Read contents from file while ((getline(&line, &len, fp)) != -1) { line_number++; char i = 0; char c = line[i]; while(c != '\0') { int number; int n; sscanf((line+i), "%d%n", &number, &n); if(isdigit(c)) { if(line_number == 1) { interval = number; } else if(line_number == 2) { logged_devices[number] = true; } if(n > 1) i = i + (n - 1); } i++; c = line[i]; } } fclose(fp); } else { return false; } return true; } //****************************************************************************** // main() //****************************************************************************** int main() { char data[130]; int device_count = 0; // number of OW devices found by search_rom() int i; int j; int k; char device_id[ID_LENGTH]; //8 byte rom id of current slected device char rom_id_list[MAX_DEVICES][ID_LENGTH]; //List of rom id for each device on OW bus double T[MAX_DEVICES]; bool device_logged[MAX_DEVICES]; //initialize device_logged to all false; for(int i = 0; i < MAX_DEVICES; i++) { device_logged[i] = false; } // i/o variables char rx_buff[128]; // comport input buffer int rx_index; // rx_buffer pointer char c; // command type character int n; // argument count int arg1; // argumnet 1 int arg2; // argument 2 int device; // device argument int num_bytes; int time_count; int log_interval = PERIOD; int time_to_sample; apply_settings_file(device_logged, log_interval); //************* init ticker timer callbacks **************** timer_1.attach(&LED_blink_callback,0.5); //start ticker, once per sec. i2c.frequency(400000); //set I2C clock to 400kHz rLED = LED_OFF; gLED = LED_ON; bLED = LED_ON; // reset DS2484 data[0] = 0xE1; data[1] = 0xF0; i2c.write(DS2484_ADD,data,1,1); i2c.read(DS2484_ADD,data,1); // ****************** search for all OW devices on bus ***************** device_count = search_rom(rom_id_list); for(j=0;j<device_count;j++){ for(k=0;k<8;k++){ device_id[k] = rom_id_list[j][k]; // get device_id from rom_id_list } set_test_mode(device_id); } rx_index = 0; //character buffer index for input from PC button.fall(&btn_pressed); SDInsert.fall(&sd_insert); sd.disk_initialize(); //initialize sd card while(1) { // start main loop, take data if logging, check for input, repeat if(sd_insert_flag == true) { sd.disk_initialize(); sd_insert_flag = false; } if(button_flag == true) { if(log_flag == false){ //start logging if(SDDetect)//if SD card not detected { error_flag = true; error_ticks = 6; log_flag = false; } else { apply_settings_file(device_logged, log_interval); FILE *fp = fopen(log_file, "a"); if (fp != NULL) { fprintf(fp, "Time(s)"); for(j=0;j<device_count;j++) { if(device_logged[j]) fprintf(fp,", Device %d Temperature (C)",j); } fprintf(fp,"\r\n"); fclose(fp); } time_count = 0; time_to_sample = 0; // force sample at time = 0; tick_flag = true; // force sample at time = 0; log_flag = true; } }else{ log_flag = false; } button_flag = false; } while(tick_flag == false){ //check for input while waiting for next tick // ---------------------------------------------------------------------------- // test for charater input for USB com port // ---------------------------------------------------------------------------- //test if PC sent some charaters while(pc.readable()){ //characters in buffer, get them rx_buff[rx_index] = pc.getc(); if(rx_buff[rx_index] == CR){ rx_buff[++rx_index] = 0; rx_index = -1; // because i++ at end of while give i=0 on next loop device = 0; arg1 = 0; arg2 = 0; n = sscanf(rx_buff, " %c %d %x %x", &c, & device, &arg1, &arg2); //process input if(n > 0){//got input so process it switch(c){ case 'a': case 'A': // alarm search // ****************** search for all OW devices with alarm triggered on bus ***************** device_count = alarm_search(rom_id_list); pc.printf("%d devices:\r\n", device_count); for(j=0;j<device_count;j++){ pc.printf("device[%02X] rom id[",j); for(i=7;i>=0;i--){ pc.printf("%02X",rom_id_list[j][i]); } pc.printf("]\r\n"); } break; case 'c': case 'C': if(!SDDetect) pc.printf("y\r\n"); else pc.printf("n\r\n"); break; case 'd': case 'D': if(n==1) // if no device number is given { //clear device_logged array for(int i = 0; i < MAX_DEVICES; i++) { device_logged[i] = false; } write_settings_file(log_interval, device_logged); } if(n == 2) { device_logged[device] = true; write_settings_file(log_interval, device_logged); } break; case 'f': case 'F': //f is for "flash" for microSD if(!SDDetect) pc.printf("y\r\n"); else pc.printf("n\r\n"); /*apply_settings_file(device_logged, log_interval); pc.printf("Interval: %d\r\n", log_interval); bool no_devices = true; for(i = 0; i < MAX_DEVICES; i ++) { if(device_logged[i]) { pc.printf("Device %d is being logged.\r\n", i); no_devices = false; } } if(no_devices) pc.printf("No devices being logged.\r\n", i);*/ break; case 'g': case 'G': //0 means get config, 1 means get log if(n == 2) { bool fileExists = false; if(device == 0)//get config { fileExists = print_settings_file(); //fileExists = print_settings_file_2(); } if(device == 1)//get log { fileExists = print_log_file(); } if(!fileExists) { pc.printf("no_file\r\n"); } } break; case 'i': case 'I': //Set Logging sample intreval in seconds log_interval = device; if(log_interval < 1)log_interval = 1; if(log_interval > 60)log_interval = 60; write_settings_file(log_interval, device_logged); break; case 'l': case 'L': // Toggle logging if(log_flag == false){ //start logging if(SDDetect)//if SD card not detected { error_flag = true; error_ticks = 6; log_flag = false; } else { FILE *fp = fopen(log_file, "a"); if (fp != NULL) { fprintf(fp, "Time(s)"); for(j=0;j<device_count;j++) { fprintf(fp,", Device %d Temperature (C)",j); } fprintf(fp,"\r\n"); fclose(fp); } time_count = 0; time_to_sample = 0; // force sample at time = 0; tick_flag = true; // force sample at time = 0; log_flag = true; } }else{ //pc.printf("<stop logging>\r\n"); log_flag = false; } break; case 'P': case 'p': // power down One Wire buss if(n == 2){ if (device == 0){ // power down mode ON. data[0] = WDC; // 0xD2 Write Device Config data[1] = 0xD2; // 1101 0010 set 1WS = 0, SPU = 0, PDN = 1, APU = 0 i2c.write(DS2484_ADD,data,2,0); pc.printf("<Power down DQ>\r\n"); }else{ // power down mode OFF data[0] = WDC; // 0xD2 Write Device Config data[1] = 0xE1; // 1110 0001 set 1WS = 0, SPU = 0, PDN = 0, APU = 1 i2c.write(DS2484_ADD,data,2,0); pc.printf("<Power up DQ>\r\n"); } } break; case 'r': case 'R': //read register "r device radd.start radd.end" for(k=0;k<8;k++){ device_id[k] = rom_id_list[device][k]; // get device_id from rom_id_list } if(n==3){ //read single register from selected device read_OW_register(device_id,arg1,1,data); pc.printf("device[%02X] add[%02X] data[%02X] crc[%02X %02X]\r\n",device,arg1,data[0],data[1],data[2]); } if(n==4){ //read a range of regesters from selected device num_bytes = arg2-arg1 + 1; // calculate number of bytes to read if (num_bytes < 1) num_bytes = 1; // if arg2 <= arg 1 just read arg1 address. read_OW_register(device_id,arg1,num_bytes,data); for(i=0;i<num_bytes;i++){ pc.printf("\r\ndevice[%02X] add[%02X] data[%02X]",device,arg1+i,data[i]); } pc.printf(" crc[%02X %02X]\r\n",data[i],data[i+1]); } break; case 's': case 'S': // search rom // ****************** search for all OW devices on bus ***************** device_count = search_rom(rom_id_list); // print out rom codes found //pc.printf("\r\nsearch rom\r\n"); pc.printf("%d devices:\r\n", device_count); for(j=0;j<device_count;j++){ pc.printf("device[%02X] rom id[",j); for(i=7;i>=0;i--){ pc.printf("%02X",rom_id_list[j][i]); } pc.printf("]\r\n"); } break; case 'T': case 't': if(n == 2){//get temperatures from selected device for(k=0;k<8;k++){ device_id[k] = rom_id_list[device][k]; // get device_id from rom_id_list } convert_temperature(device_id); //send OW convert selected device wait(0.02); //wait 20 ms for convert temperature to complete T[0] = get_temperature(device_id); pc.printf("device[%02X] temperature[%.3f]\r\n",device,T[0]); } if(n == 3){ // "t 1 5" get temperature for devices 1 thru 5 convert_temperature(); //send OW convert to all devices wait(0.02); //wait 750 ms for convert temperature to complete for(j=device;j<=arg1;j++){ for(k=0;k<8;k++){ device_id[k] = rom_id_list[j][k]; // get device_id from rom_id_list } pc.printf("device[%02X] temperature[%.3f]\r\n",j,get_temperature(device_id)); } } break; case 'w': case 'W': //write register "w device w.addr data" for(k=0;k<8;k++){ device_id[k] = rom_id_list[device][k]; // get device_id from rom_id_list } data[0] = arg2; write_OW_register(device_id, arg1, 1, data); pc.printf("write -- device[%02X] add[%02X] data[%02X] ",device,arg1,arg2); // get CRC pc.printf("crc[%02X %02X]\r\n",data[0],data[1]); break; case 'x': case 'X': // experimental modes // ****************** set up ADC enabled in test mode***************** pc.printf("<set ADC_ENABLED in test mode>\r\n"); for(j=0;j<device_count;j++){ for(k=0;k<8;k++){ device_id[k] = rom_id_list[j][k]; // get device_id from rom_id_list } set_test_mode(device_id); } break; }//end switch(c) }//if(n>0) }//end if(CR) if(rx_buff[rx_index] == BS){//backspace received, back up buffer pointer if(rx_index>0)rx_index--;//remove last char from buffer if not at start. }else rx_index++; }//end while(pc.redable()) wait(0.1); // slow down polling }// end (while tick == false) tick_flag = false; // set to false for next time // only reached when tick_flag = true otherwise stuck in pc.readable() loop if(log_flag == true){ if(time_count >= time_to_sample){ //take next sample time_to_sample += log_interval; // calculate time for next sample // start conversion convert_temperature(); wait(0.02); //wait 20ms for convert to complete for(j=0;j<device_count;j++){ for(k=0;k<8;k++){ device_id[k] = rom_id_list[j][k]; // get device_id from rom_id_list } T[j] = get_temperature(device_id); } //open file for microSD logging FILE *fp = fopen(log_file, "a"); if (fp != NULL) { //fprintf(fp, "\n"); fprintf(fp, "%d",time_count); for(j=0;j<device_count;j++) { if(device_logged[j]) { fprintf(fp,", %.3f",T[j]); } } fprintf(fp,"\r\n"); fclose(fp); } }// end if(time_count >= time_to_sample) time_count ++; // }// end if(log_flag) }//end while(1) }