PICO I2C FW

Dependencies:   USBDevice

Revision:
9:36ba3626aab7
Parent:
6:96d8d823e292
Child:
10:148da21c297e
--- a/main.cpp	Fri Nov 17 20:59:27 2017 +0000
+++ b/main.cpp	Fri Jun 29 17:44:11 2018 +0000
@@ -1,29 +1,1196 @@
 #include "mbed.h"
-#include "max32630fthr.h"
 #include "SDFileSystem.h"
+#include "max32630fthr.h"
+#include "USBSerial.h"
 
-MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
+
+#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
+
+//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);
+
+
+// Virtual serial port over USB
+//USBSerial pc;
+USBSerial pc(0x0B6A, 0x0042, 0x0001, true);
+
+// 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 error_flag;
+int error_ticks;
+
+//LED  blink setup
 DigitalOut rLED(LED1);
 DigitalOut gLED(LED2);
+DigitalOut bLED(LED3);
 
-SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd");  // mosi, miso, sclk, cs
+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 take_data_flag_callback(){ // set data sample time flag
+    
+    take_data_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)
+        //db.printf("\r\nsearch next rom [%2d]",rom_count);
+                        
+        //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;     
+                    }
+ //                   pc.printf("sdx[%d] lz[%2d] byte[%d] mask[%02X] bn[%d] ROM[%02X %02X %02X]\n\r",search_dir,last_zero,byte_num,byte_mask, byte_num, rom_id[2], rom_id[1], rom_id[0]);
+                                    
+                                
+                }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                 
+                //db.printf(" -- rom id[ ");
+                for(i=7;i>=0;i--){
+                    rom_id_list[rom_count][i] = rom_id[i] ;
+                    //db.printf("%02X ",rom_id[i]); 
+                }    
+                //db.printf("]\r\n"); 
+                //db.printf("last_device[%2d]\r\n",last_device); 
+                //db.printf("last_zero[%2d]\r\n",last_zero); 
+                //db.printf("last_discrep[%2d]\r\n",last_discrep);                
+                
+                //clac_crc of rom ID
+                for (i=0;i<7;i++){
+                    crc = calc_crc8(crc, rom_id[i]);
+                }
+                //db.printf("crc8 = [%02X]\r\n",crc);
+                
+                                                                                              
+                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
 
-// main() runs in its own thread in the OS
-// (note the calls to Thread::wait below for delays)
+    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                 
+                //db.printf(" -- rom id[ ");
+                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
+    
+    // debug output
+    //for(i=0;i<n+2;i++) db.printf("read_OW_register - [%2d][%02X]\r\n",i,data[i]);
+    
+    
+    // --- 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 
+    //db.printf("get_temperature -- FIFO[%02X %02X] CRC[%02X %02X]\r\n",t[0],t[1],t[2],t[3]);
+    //calculate temperture from data     
+    count = (int)(t[0]*256 + t[1]);
+    if (count >= 32768)count = count - 65536;     // 2s comp
+    T = (double)count*0.005; 
+    
+    //db.printf("T = %f count[%5d]\r\n", T,count);
+    return T;    
+}// end get_temperature()
+
+
+//******************************************************************************
+//        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];  
+    
+    // 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; 
+    
+    //************* init ticker timer callbacks  ****************
+    timer_1.attach(&LED_blink_callback,1.0);        //start ticker, once per  sec.      
+    
+    
+    i2c.frequency(400000);      //set I2C clock to 100kHz     
+       
+    //wait(1);  //wait 1 sec for USB serial port to init.
+    
+    //db.printf("--- OT07 - Base Logger Firmware uisng DS2484 bridge V0.2 ---\r\ndaplink serial port\r\n");
+    //pc.printf("--- OT07 - Base Logger Firmware uisng DS2484 bridge V0.2 ---\r\nmicro USB serial port\r\n");
+    
+    rLED = LED_OFF;
     gLED = LED_ON;
-    rLED = 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); 
+    
+    //db.printf("DS2484 Reset --> status[%02X]\r\n",data[0]);    
+    
+    // ******************  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");
+    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");
+    } 
+    pc.printf("\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);
+        //db.printf("device[%2X] in test mode\r\n",j);
+    } 
+    
+    
+    rx_index = 0;               //character buffer index for input from PC
+    
+    button.fall(&btn_pressed);
+     
+    //db.printf("start Main loop\r\n");
+    //db.printf("tf[%d]\r\n",tick_flag);
+    while(1) {  // start main loop,  take data if logging, check for input, repeat   
+    
+    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
+            {
+                FILE *fp = fopen("/sd/MAX30207Log.csv", "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;
+        }  
+        button_flag = false;  
+    }
 
-    FILE *fp = fopen("/sd/myfile.txt", "w");
-    fprintf(fp, "Hello World!\n");
-    fclose(fp);
-    rLED = LED_OFF;
+      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();
+            //pc.putc(rx_buff[rx_index]);     //echo character 
+            //pc.printf("<[%02x] %c i[%d]>",rx_buff[i],rx_buff[i],i); //echo charater
+            
+                            
+            if(rx_buff[rx_index] == CR){
+                //db.printf("\r\n");
+                pc.printf("\r\n");                
+                rx_buff[++rx_index] = 0;
+                //db.printf("%s\r\n",rx_buff);
+                //pc.printf("%s\r\n",rx_buff);
+                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);
+                
+                //db.printf("c[%c] d[%d] a1[%x] a2[%x] n[%d]\r\n",c,device,arg1,arg2,n);  //echo values read in
+               //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 'f':   
+                        case 'F':   //f is for "flash" for microSD
+                                     if(!SDDetect)
+                                        pc.printf("y\r\n");
+                                    else
+                                        pc.printf("n\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;                                 
+                                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("/sd/MAX30207Log.csv", "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");
+                                    } 
+                                    //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]);                                 
+                                    //pc.printf("\r\n");
+                                }
+                                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));
+                                    }                             
+                                    //pc.printf("\r\n");
+                                }
+                            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                                                                       
+                                    //OW_read_byte(data,2);
+                                    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);
+                                        //db.printf("device[%2X] in test mode\r\n",j);
+                                    } 
+                            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  
 
-    while (true) {
-        gLED = !gLED;
-        Thread::wait(500);
-    }
+      }// 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){          
+            //pc.printf("tc{%5d] tts[%5d]\n\r",time_count,time_to_sample);                
+            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);            
+                }
+                /*
+                // print out time count and temperatures
+                pc.printf("%5d",time_count);
+                for(j=0;j<device_count;j++){
+                    pc.printf(", %7.3f",T[j]);
+                }
+                pc.printf("\r\n");
+                */
+                FILE *fp = fopen("/sd/MAX30207Log.csv", "a");
+                if (fp != NULL) 
+                {
+                    //fprintf(fp, "\n");
+                    fprintf(fp, "%5d",time_count);
+                    for(j=0;j<device_count;j++)
+                    {
+                        fprintf(fp,", %7.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)
 }