06/21/18

Fork of rtos_threading_with_callback by mbed_example

Revision:
3:3e8c16b6620c
Child:
4:61f1412310af
diff -r c7229eac380b -r 3e8c16b6620c EasyFuse_Prog.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EasyFuse_Prog.cpp	Thu Jun 21 22:11:25 2018 +0000
@@ -0,0 +1,461 @@
+#include "mbed.h"
+
+extern Serial pc;
+extern int frequ; //unit kHz
+extern char dev_addr; //fixed
+
+char get_half_byte(int *); //defined in I2C_read.cpp
+ 
+
+char get_byte(int *flag) {
+    char cur_char;
+    char temp;
+    int flag1 = 0;
+    cur_char = get_half_byte(&flag1); 
+    if (flag1 == 1) {
+        cur_char = cur_char << 4;
+        temp = get_half_byte(&flag1);
+        cur_char = (cur_char | temp);
+    }
+    *flag = flag1;
+    return cur_char;
+}     
+
+void print_nvm_reg(uint8_t *max_Vout, uint8_t *max_Vout_trim, uint8_t *high_time, uint8_t *low_time, uint8_t *adc_samp_rate, 
+uint8_t *adc_range, uint8_t *adc_time_out, uint8_t *comp_offset, uint8_t *range_trim, uint8_t *PMOS_off, uint8_t *Driver2, uint8_t *Driver3, 
+uint8_t *DMOS, uint8_t *CCM_threshold, uint8_t *DMOS_ctrl_trim, uint8_t *adc_op_mode) {
+
+    pc.printf("\033[%dm ", 35);//change text color to red
+    pc.printf("\n\n\n\r\t    Register contents :\n\r\t   ");
+    for ( int i = 0; i<26; i++) pc.printf("\304"); 
+    pc.printf("\n\n\r\t    1. max_Vout        = 0x%2.2X",*max_Vout);
+    pc.printf("\n\n\r\t    2. max_Vout_trim   = 0x%2.2X",*max_Vout_trim);
+    pc.printf("\n\n\r\t    3. high_time       = 0x%2.2X",*high_time);
+    pc.printf("\n\n\r\t    4. low_time        = 0x%2.2X",*low_time);
+    pc.printf("\n\n\r\t    5. adc_samp_rate   = 0x%2.2X",*adc_samp_rate);
+    pc.printf("\n\n\r\t    6. adc_range       = 0x%2.2X",*adc_range);
+    pc.printf("\n\n\r\t    7. adc_time_out    = 0x%2.2X",*adc_time_out);
+    pc.printf("\n\n\r\t    8. comp_offset     = 0x%2.2X",*comp_offset);
+    pc.printf("\n\n\r\t    9. range_trim      = 0x%2.2X",*range_trim);
+    pc.printf("\n\n\r\t   10. PMOS_off        = 0x%2.2X",*PMOS_off);
+    pc.printf("\n\n\r\t   11. Driver2         = 0x%2.2X",*Driver2);
+    pc.printf("\n\n\r\t   12. Driver3         = 0x%2.2X",*Driver3);
+    pc.printf("\n\n\r\t   13. DMOS            = 0x%2.2X",*DMOS);
+    pc.printf("\n\n\r\t   14. CCM_threshold   = 0x%2.2X",*CCM_threshold);
+    pc.printf("\n\n\r\t   15. DMOS_ctrl_trim  = 0x%2.2X",*DMOS_ctrl_trim);
+    pc.printf("\n\n\r\t   16. adc_op_mode     = 0x%2.2X",*adc_op_mode);
+    pc.printf("\n\n\r\t   ");
+    for ( int i = 0; i<26; i++) pc.printf("\315");
+    pc.printf("\033[%dm", 32);//change text color to green
+    pc.printf("\n\r");    
+}   
+
+void edit_nvm_reg(uint8_t *max_Vout, uint8_t *max_Vout_trim, uint8_t *high_time, uint8_t *low_time, uint8_t *adc_samp_rate, 
+uint8_t *adc_range, uint8_t *adc_time_out, uint8_t *comp_offset, uint8_t *range_trim, uint8_t *PMOS_off, uint8_t *Driver2, uint8_t *Driver3, 
+uint8_t *DMOS, uint8_t *CCM_threshold, uint8_t *DMOS_ctrl_trim, uint8_t *adc_op_mode) {
+
+    char temp;
+    int flag1;
+    char count;
+    char reg_data;
+    
+    char reg_name[16][15] = {"max_Vout", "max_Vout_trim", "high_time", "low_time", "adc_samp_rate", 
+                            "adc_range", "adc_time_out", "comp_offset", "range_trim", "PMOS_off", "Driver2", "Driver3", 
+                            "DMOS", "CCM_threshold", "DMOS_ctrl_trim", "adc_op_mode" };
+
+    uint8_t *reg_addr[16] =  {   max_Vout, max_Vout_trim, high_time, low_time, adc_samp_rate, 
+                            adc_range, adc_time_out, comp_offset, range_trim, PMOS_off, Driver2, Driver3, 
+                            DMOS, CCM_threshold, DMOS_ctrl_trim, adc_op_mode};
+                            
+    pc.printf("\n\n\n \r\tDo you want to edit the registers? (y/n) : ");  
+    temp = 0;
+    while ( temp!='y' && temp!='n') {
+        temp = pc.getc();
+    }
+    if (temp == 'n') {
+        pc.printf("\n\n \r\tContinue with above contents");
+        return;
+    }
+    temp = 'y';
+    while (temp =='y') {
+            //get selection
+            flag1 = 0;
+            while (!flag1) {
+                    pc.printf("\n\n\n\r\tEnter (1 - 16) to select the register to edit and hit 'enter' key: ");
+                    temp = '0';
+                    count = 0;
+                    while (temp != '\r') {  //look for enter key
+                        count = (count * 10) + (temp - '0');  // converting to number
+                        temp = pc.getc();
+                        if ((temp < '0' || temp > '9') && temp !='\r') {
+                            pc.printf(" \n\r\t\033[%dm Invalid Chracter!! No worries, let us try again \033[%dm",41,40);
+                            break;
+                        }
+                    }
+                    if (count >= 1 && count <= 16 && temp == '\r') flag1 = 1;
+                    else if (temp == '\r') pc.printf(" \n\r\t\033[%dm Invalid Chracter!! No worries, let us try again \033[%dm",41,40);
+            }  
+            count = count - 1; //array starts from 0
+            //Read New Register Data
+            flag1 = 0;
+            while (!flag1) {
+                pc.printf("\n\n \r\tEnter new value in hex (00 to ff) for \033[%dm %s \033[%dm register : ",35,reg_name[count],32);
+                reg_data = get_half_byte(&flag1); 
+                if (flag1 == 1) {
+                    reg_data = reg_data << 4;
+                    temp = get_half_byte(&flag1);
+                    reg_data = (reg_data | temp);
+                }
+                if (flag1==0) pc.printf(" \033[%dm Invalid Chracter!! No worries, let us try again \033[%dm",41,40);
+            }       
+            *(reg_addr[count]) = reg_data;
+            
+            print_nvm_reg(  max_Vout, max_Vout_trim, high_time, low_time, adc_samp_rate, 
+                        adc_range, adc_time_out, comp_offset, range_trim, PMOS_off, Driver2, Driver3, 
+                        DMOS, CCM_threshold, DMOS_ctrl_trim, adc_op_mode);
+            
+            pc.printf("\n\n \r\tDo you want to make more changes? (y/n) : ");
+            temp = pc.getc();
+    }  //end of edit while loop
+}
+        
+void i2c_write_fn(I2C *i2c_obj, char ptr, char write_data) {
+    int flag1;
+    wait_us(10);
+    (*i2c_obj).start();
+    flag1 = (*i2c_obj).write(dev_addr);
+    if (flag1 != 1) pc.printf("\n\n\r\tNo Ack for dev addr :(");
+    flag1 = (*i2c_obj).write(ptr);
+    if (flag1 != 1) pc.printf("\n\n\r\tNo Ack reg pointer :(");    
+    flag1 = (*i2c_obj).write(write_data); 
+    if (flag1 != 1) pc.printf("\n\n\r\tNo Ack data :(");           
+    wait_us(5);
+    (*i2c_obj).stop();
+}
+
+char i2c_read_fn(I2C *i2c_obj, char ptr) {
+    int flag1;
+    char read_data;
+    wait_us(10);
+    (*i2c_obj).start();
+    flag1 = (*i2c_obj).write(dev_addr); 
+    if (flag1 != 1) pc.printf("\n\n\n\r\tNo Ack for dev addr :(");
+    flag1 = (*i2c_obj).write(ptr);
+    if (flag1 != 1) pc.printf("\n\n\r\tNo Ack reg pointer :(");
+    (*i2c_obj).stop();
+    wait_us(10);
+    (*i2c_obj).start();
+    flag1 = (*i2c_obj).write(dev_addr | 0x01); //lsb 1 for read
+    if (flag1 != 1) pc.printf("\n\n\r\tNo Ack for dev addr :(");         
+    read_data = (*i2c_obj).read(0); //0- donot send ack after read is done         
+    wait_us(5);
+    (*i2c_obj).stop();      
+    wait_us(120);
+    return read_data;
+}
+
+uint64_t EasyFuse_read(I2C *i2c_obj)    {
+    char reg_ptr = 0x00;
+    char reg_data[10];
+    char data;
+    uint8_t NVM_READ        = 0x70 ;  
+    uint8_t NVM_CTLR_ADR    = 0x0a ;  //Register address for NVM CTRL
+    uint64_t NVM_data = 0x0000000000000000;
+    
+    //Variables to store read data
+    uint8_t max_Vout;
+    uint8_t max_Vout_trim;
+    uint8_t high_time;
+    uint8_t low_time;
+    uint8_t adc_samp_rate;
+    uint8_t adc_range;
+    uint8_t adc_time_out;
+    uint8_t comp_offset;
+    uint8_t range_trim;
+    uint8_t PMOS_off;
+    uint8_t Driver2;
+    uint8_t Driver3;
+    uint8_t DMOS;
+    uint8_t CCM_threshold;
+    uint8_t DMOS_ctrl_trim;
+    uint8_t adc_op_mode;
+    
+    int i;
+    char temp;
+    
+    pc.printf("\n\n\n\r\t"); 
+    for ( i = 0; i<60; i++) pc.printf("\304");   
+    pc.printf("\n\n\n\r\tPerforming an NVM read and loading the contents to the register");
+    pc.printf("\n\n\r\tSwitching to faster clock before reading the NVM");    
+    i2c_write_fn(i2c_obj,0x02,0x01); //switching to faster clock for NVM read
+    i2c_write_fn(i2c_obj,0x03,0x01); //switching to faster clock for NVM read
+    wait_ms(1);
+    i2c_write_fn(i2c_obj,NVM_CTLR_ADR,NVM_READ); //Perform a complete read; will be sucessful only if NVM is not empty    
+    wait_ms(100);
+
+    //check if tm_nvm_read bit has cleared itself
+    temp = 0;
+    while (temp == 0){
+        data = i2c_read_fn(i2c_obj,NVM_CTLR_ADR);
+        data = data & 0x40;
+        if (data == 0x00) {
+                pc.printf("\n\n\r\ttm_nvm_read has cleared; so loading Register with NVM complete");
+                temp = 1;
+        }
+        else wait_ms(100);
+    }  
+
+    pc.printf("\n\n\n\r\tReading register 0x00 to 0x09");
+    for( reg_ptr = 0x00;  reg_ptr <= 0x09; reg_ptr = reg_ptr+1) {
+        reg_data[reg_ptr] = i2c_read_fn(i2c_obj,reg_ptr);
+    }           
+    
+    //Storing read data into variables
+    max_Vout        = reg_data[0] & 0x0f;
+    max_Vout_trim   = reg_data[1] & 0x1f;
+    high_time       = reg_data[2] & 0x7f;
+    low_time        = reg_data[3] & 0x7f;
+    adc_samp_rate   = reg_data[4]>>4;
+    adc_range       = (reg_data[4]>>2) & 0x03;
+    adc_time_out    = reg_data[4] & 0x03;
+    comp_offset     = reg_data[5] & 0x1f;
+    range_trim      = reg_data[6] & 0x1f;
+    PMOS_off        = reg_data[7] & 0x0f;
+    Driver2         = reg_data[8] & 0x0f;
+    Driver3         = (reg_data[8]>>4) & 0x0f;
+    DMOS            = (reg_data[9]>>7) & 0x01;
+    CCM_threshold   = (reg_data[7]>>4) & 0x0f;
+    DMOS_ctrl_trim  = reg_data[9] & 0x1f;
+    adc_op_mode     = (reg_data[5]>>7) & 0x01;
+
+    pc.printf("\n\n\r\tFollowing data was read from the Register");
+
+    print_nvm_reg(&max_Vout, &max_Vout_trim, &high_time, &low_time, &adc_samp_rate, 
+    &adc_range, &adc_time_out, &comp_offset, &range_trim, &PMOS_off, &Driver2, &Driver3, 
+    &DMOS, &CCM_threshold, &DMOS_ctrl_trim, &adc_op_mode);
+    
+    //push data into NVM_data
+    NVM_data = NVM_data | (max_Vout+1); //max_Vout(register) = max_Vout(NVM) - 1
+    NVM_data = (NVM_data<<5) | max_Vout_trim; 
+    NVM_data = (NVM_data<<7) | high_time; // <<x : x corresponds to no. of bits
+    NVM_data = (NVM_data<<7) | low_time;
+    NVM_data = (NVM_data<<4) | adc_samp_rate;
+    NVM_data = (NVM_data<<2) | adc_range;
+    NVM_data = (NVM_data<<2) | adc_time_out;
+    NVM_data = (NVM_data<<5) | comp_offset;
+    NVM_data = (NVM_data<<5) | range_trim;
+    NVM_data = (NVM_data<<4) | PMOS_off;
+    NVM_data = (NVM_data<<4) | Driver2;
+    NVM_data = (NVM_data<<4) | Driver3;
+    NVM_data = (NVM_data<<1) | DMOS;
+    NVM_data = (NVM_data<<4) | CCM_threshold;
+    NVM_data = (NVM_data<<5) | DMOS_ctrl_trim;
+    NVM_data = (NVM_data<<1) | adc_op_mode;    
+
+    pc.printf("\n\n\n\r\tReconstructed data read from NVM = 0x%016llX",NVM_data);   
+    return NVM_data;        
+}    
+
+
+void EasyFuse_prog() {
+    uint64_t NVM_data = 0x0000000000000000;
+    uint64_t NVM_read_data;
+    
+    // Register variables
+    uint8_t max_Vout = 0x07;
+    uint8_t max_Vout_trim = 0x00;
+    uint8_t high_time = 0x12;
+    uint8_t low_time = 0x29;
+    uint8_t adc_samp_rate = 0x06;
+    uint8_t adc_range = 0x01;
+    uint8_t adc_time_out = 0x02;
+    uint8_t comp_offset = 0x00;
+    uint8_t range_trim = 0x0f;
+    uint8_t PMOS_off = 0x08;
+    uint8_t Driver2 = 0x08;
+    uint8_t Driver3 = 0x08;
+    uint8_t DMOS = 0x01;
+    uint8_t CCM_threshold = 0x0f;
+    uint8_t DMOS_ctrl_trim = 0x0c;
+    uint8_t adc_op_mode = 0x01;
+
+    // NVM Register Control Bit locations; PWR_ON set in all the definitions
+    uint8_t NVM_RESET       = 0x31 ;
+    uint8_t NVM_PWE1        = 0x02 ;
+    uint8_t NVM_CLK1        = 0x34 ;
+    uint8_t NVM_PWR_ON      = 0x30 ;
+    uint8_t NVM_READ        = 0x70 ;
+    
+    uint8_t NVM_CTLR_ADR     = 0x0a ;  //Register address for NVM CTRL
+     
+    char reg_data = 0xaa;
+    char temp;
+    char high_time_prog = 0x04;
+    char low_time_prog = 0x04;
+    int flag1 = 0;
+    int i = 0;
+    
+    int delay1 = 20;
+    int delay2 = 2 * delay1;
+    
+    I2C i2c(p9,p10);
+    i2c.frequency((frequ/2)*1000);
+    LPC_PINCON->PINMODE_OD0 = (LPC_PINCON->PINMODE_OD0  | 0x0003); // To make p9 & P10 open_drain
+    i2c.stop(); //add a stop after hot-read 
+
+    pc.printf("\n\n\r\tFollowing are the default register data that will be programmed: \n\r ");
+    print_nvm_reg(&max_Vout, &max_Vout_trim, &high_time, &low_time, &adc_samp_rate, 
+    &adc_range, &adc_time_out, &comp_offset, &range_trim, &PMOS_off, &Driver2, &Driver3, 
+    &DMOS, &CCM_threshold, &DMOS_ctrl_trim, &adc_op_mode);    
+
+    edit_nvm_reg(&max_Vout, &max_Vout_trim, &high_time, &low_time, &adc_samp_rate, 
+    &adc_range, &adc_time_out, &comp_offset, &range_trim, &PMOS_off, &Driver2, &Driver3, 
+    &DMOS, &CCM_threshold, &DMOS_ctrl_trim, &adc_op_mode);       
+      
+    //push data into NVM_data
+    NVM_data = NVM_data | (max_Vout+1); //max_Vout(register) = max_Vout(NVM) - 1
+    NVM_data = (NVM_data<<5) | max_Vout_trim; 
+    NVM_data = (NVM_data<<7) | high_time; // <<x : x corresponds to no. of bits
+    NVM_data = (NVM_data<<7) | low_time;
+    NVM_data = (NVM_data<<4) | adc_samp_rate;
+    NVM_data = (NVM_data<<2) | adc_range;
+    NVM_data = (NVM_data<<2) | adc_time_out;
+    NVM_data = (NVM_data<<5) | comp_offset;
+    NVM_data = (NVM_data<<5) | range_trim;
+    NVM_data = (NVM_data<<4) | PMOS_off;
+    NVM_data = (NVM_data<<4) | Driver2;
+    NVM_data = (NVM_data<<4) | Driver3;
+    NVM_data = (NVM_data<<1) | DMOS;
+    NVM_data = (NVM_data<<4) | CCM_threshold;
+    NVM_data = (NVM_data<<5) | DMOS_ctrl_trim;
+    NVM_data = (NVM_data<<1) | adc_op_mode;
+    pc.printf("\n\n\n\r\tData to be written into NVM = 0x%016llX",NVM_data);
+    pc.printf("\n\n\r\tPlease note that max_Vout has been incremented. max_Vout(NVM) = max_Vout(register) + 1");  
+    pc.printf("\n\n\r\t"); 
+    for ( i = 0; i<80; i++) pc.printf("\304");  
+    pc.printf("\n\n\r\tContinue EasyFuse Programming? (y/n): ");  
+    temp = 0;
+    while ( temp!='y' && temp!='n') {
+        temp = pc.getc();
+    }
+    if (temp == 'n') {
+        pc.printf("\n\n\r\tAborting... :(");
+        return;
+    }
+    //EasyFuse Empty check
+    pc.printf("\n\n\r\tPerforming NVM Empty check by trying to load register with NVM contents");
+    i2c_write_fn(&i2c,0x02,0x01); //switching to faster clock for NVM read
+    i2c_write_fn(&i2c,0x03,0x01); //switching to faster clock for NVM read
+    wait_ms(1);
+    i2c_write_fn(&i2c,NVM_CTLR_ADR,NVM_READ); //Perform a complete read; will be sucessful only if NVM is not empty    
+    wait_ms(100);
+    
+    //check if tm_nvm_read bit has cleared itself
+    temp = 0;
+    while (temp == 0){
+        reg_data = i2c_read_fn(&i2c,NVM_CTLR_ADR);
+        reg_data = reg_data & 0x40;
+        if (reg_data == 0x00) {
+                pc.printf("\n\n\r\ttm_nvm_read has cleared; so loading Register with NVM complete");
+                temp = 1;
+        }
+        else wait_ms(100);
+    }   
+        
+    reg_data = i2c_read_fn(&i2c,0x02);
+    reg_data = reg_data<<4;
+    reg_data = reg_data | i2c_read_fn(&i2c,0x03);
+    if (reg_data == 0xff) pc.printf("  |\033[%dm  Register read might not be sucessfull \033[%dm ",45,40);
+    if (reg_data == 0x11) pc.printf("\n\n\r\t\033[%dm EasyFuse empty \033[%dm",44,40); //no change at address 0x02 & 0x03
+    else {
+        pc.printf("\n\n\r\t\033[%dm EasyFuse not empty \033[%dm",45,40);
+        pc.printf("\n\n\r\t Better to abort the test.. :(");
+        //return;
+    }         
+    
+    //added for debug.. delete later
+    pc.printf("\n\n\n\r\tWe will next configure the oscillator. Proceed? (y/n): ");  
+    temp = 0;
+    while ( temp!='y' && temp!='n') {
+        temp = pc.getc();
+    }
+    if (temp == 'n') {
+        pc.printf("\n\n\r\tAborting.. :(");
+        return;
+    }
+    pc.printf("\n\n\r\tEnabled 'fc_enable' & driver1. Monitor the oscillator at the output of comparator");     
+    i2c_write_fn(&i2c,0x0c,0x22);   
+osc_trim:
+    i2c_write_fn(&i2c,0x02,high_time_prog); //Recommended clocks period 
+    i2c_write_fn(&i2c,0x03,low_time_prog); // for programming is 10us
+    wait_ms(1);
+
+    pc.printf("\n\n\n\r\t\033[%dm", 44);//change backround to blue
+    pc.printf("Please check if Oscillator period is approx 10us (9.4us to 10.4us) \033[%dm\n\n\r\tPress 'y' to continue; Press 'm' to modify clock trim settings : ",40); 
+
+    temp = 0;
+    while ( temp!='y' && temp!='m' && temp!='m' ) {
+        temp = pc.getc();
+    }
+    if (temp == 'n') {
+        pc.printf("\n\n\r\tAborting.. :(");
+        return;
+    }
+    if (temp == 'm') {
+        pc.printf("\n\n\n\n\r\tCurrent high_time trim = 0x%2.2X  & low_time trim = 0x%2.2X",high_time_prog,low_time_prog);
+        flag1 = 0;
+        while (!flag1) {
+            pc.printf("\n\n\r\tEnter new high_time trim in hex (00 to ff): 0x");
+            high_time_prog = get_byte(&flag1);
+            if (flag1 == 0) pc.printf(" \033[%dm Invalid Chracter!! No worries, let us try again \033[%dm",41,40);
+        } 
+        flag1 = 0;
+        while (!flag1) {
+            pc.printf("\n\n\r\tEnter new low_time trim in hex (00 to ff) : 0x");
+            low_time_prog = get_byte(&flag1);
+            if (flag1 == 0) pc.printf(" \033[%dm Invalid Chracter!! No worries, let us try again \033[%dm",41,40);
+        }        
+        pc.printf("\n\n\r\tProgramming new high_time trim = 0x%2.2X  & new low_time trim = 0x%2.2X",high_time_prog,low_time_prog);
+        goto osc_trim;
+    }
+    
+    pc.printf("\n\n\r\tDisabled 'fc_enable' & driver1.");     
+    i2c_write_fn(&i2c,0x0c,0x00); 
+    wait_ms(delay2); 
+    pc.printf("\n\n\n\r\tAll set to program the EasyFuse, time to blow up some ploy fuses! ..**BOOOM**\n\n\r"); 
+    i2c_write_fn(&i2c,NVM_CTLR_ADR,NVM_PWR_ON); //turn ON supply to EasyFuse
+    wait_ms(100);    
+    i2c_write_fn(&i2c,NVM_CTLR_ADR,NVM_RESET); //turn ON supply to EasyFuse & RESETN = 1
+    wait_ms(1);
+    i2c_write_fn(&i2c,NVM_CTLR_ADR,NVM_PWR_ON); //RESETN = 0, Prog mode enabled: CKL1 = 0 during RESETN = 0,
+    temp = 0;
+    pc.printf("\n\n\n\r\tConnect PROG to 5V and press 'c' to continue"); 
+    while ( temp!='c') {
+        temp = pc.getc();
+    }    
+    wait_us(delay2);
+    i2c_write_fn(&i2c,NVM_CTLR_ADR,NVM_RESET);  //RESETN = 1,
+    wait_us(delay2);           
+    for ( i = 0; i < 64; i = i+1) {
+        temp =  NVM_RESET + (((NVM_data>>i) & 0x01)?(NVM_PWE1):0); //NVM_PWE1 if NVM_data[i]=1 & CLK1 de-asserted
+        i2c_write_fn(&i2c,NVM_CTLR_ADR,temp);
+        wait_us(delay2);
+        temp =  NVM_RESET;
+        i2c_write_fn(&i2c,NVM_CTLR_ADR,temp); //de-assert NVM_PWE1
+        wait_us(delay2);          
+        temp =  NVM_RESET + NVM_CLK1;
+        i2c_write_fn(&i2c,NVM_CTLR_ADR,temp); //assert CLK1
+        wait_us(delay2); 
+    }
+    pc.printf("\n\n\n\r\t\a\033[%dm", 44);//change backround to blue
+    pc.printf("Finished programming. Let us confirm if the NVM has been programmed correctly by reading the NVM. Proceed (y/n): ");
+    pc.printf("\033[%dm", 40);//change backround to black 
+          
+    temp = 0;
+    while ( temp!='y' ) {
+        temp = pc.getc();
+    }
+    NVM_read_data = EasyFuse_read(&i2c);
+    if ( NVM_data == NVM_read_data ) pc.printf("\n\n\r\tData written into NVM matches data read from NVM\n\n\n\r\t\033[%dm NVM PROGRAMMING SUCESSFULL. Hoorayyy!\a \033[%dm\n\r",44,40);
+    else  pc.printf("\n\n\r\tuh-oh.. Data written into NVM does not match data read from NVM\n\n\n\r\t\033[%dm NVM PROGRAMMING FAILED!\a \033[%dm\n\r",41,40);    
+}  
\ No newline at end of file