Final Jacaranda Program; updated during Harald's visit; In NVM program, set tm_en_vout_mon =1 before updating the oscillator frequency.

EasyFuse_Prog.cpp

Committer:
CactusSemi
Date:
2020-04-02
Revision:
4:8afc50e5a7bc
Parent:
3:3e8c16b6620c

File content as of revision 4:8afc50e5a7bc:

#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(20);
    (*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(20);
    (*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_PWR_ON      = 0x20 ;
    uint8_t NVM_READ        = 0x90 ; 
    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
    i2c_write_fn(i2c_obj,NVM_CTLR_ADR,NVM_PWR_ON);
    wait_ms(1);
    i2c_write_fn(i2c_obj,NVM_CTLR_ADR,(NVM_PWR_ON + 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 = 0x04;
    uint8_t max_Vout_trim = 0x00;
    uint8_t high_time = 0x0A;
    uint8_t low_time = 0x53;
    uint8_t adc_samp_rate = 0x01;
    uint8_t adc_range = 0x01;
    uint8_t adc_time_out = 0x02;
    uint8_t comp_offset = 0x01;
    uint8_t range_trim = 0x10;
    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 = 0x00;

    // NVM Register Control Bit locations; PWR_ON set in all the definitions
    uint8_t NVM_RESET       = 0x01 ;
    uint8_t NVM_PWE1        = 0x02 ;
    uint8_t NVM_CLK1        = 0x04 ;
    uint8_t NVM_PWR_ON      = 0x20 ;
    uint8_t NVM_READ        = 0x90 ;//unpdated in Rev1.0
    
    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. Connect 4.5V at PROG pin");
    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 + NVM_PWR_ON)); //Force NVM load    
    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 & 0x80; //updated in Rev1.0; checking for tm_ld_shdw
        if (reg_data == 0x00) {
                pc.printf("\n\n\r\ttm_ld_shdw has cleared; so loading Register with NVM contents 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 == 0x00) pc.printf("\n\n\r\t\033[%dm EasyFuse empty \033[%dm",44,40); //address 0x02 & 0x03 changed to 0
    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;
    }
    i2c_write_fn(&i2c,0x00,0x08); //setting Vout_max to 4.6
    pc.printf("\n\n\r\tEnabled 'fc_enable' & driver1. Set VINP to 4.0V. Monitor the oscillator at the output of comparator");     
    i2c_write_fn(&i2c,0x0c,0x22);   
    i2c_write_fn(&i2c,0x0b,0x08);      
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 + NVM_PWR_ON)); //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 4.5V & VINP to 5V and press 'c' to continue"); 
    while ( temp!='c') {
        temp = pc.getc();
    }    
    pc.printf("\n\n\n\r\t");
    wait_us(delay2);
    i2c_write_fn(&i2c,NVM_CTLR_ADR,(NVM_RESET + NVM_PWR_ON));  //RESETN = 1,
    wait_us(delay2);           
    for ( i = 0; i < 64; i = i+1) {
        if ( ((NVM_data>>i) & 0x0000000000000001) == 1 ) {
            temp = NVM_PWE1;
            pc.printf("1");
        }
        else { 
            temp = 0x00;
            pc.printf("0");
        }
        temp =  (temp | NVM_RESET | NVM_PWR_ON); //NVM_PWE1 if NVM_data[i]=1 & CLK1 de-asserted
        pc.printf("\n\n\n\n\r\ttemp = 0x%2.2X",temp);
        i2c_write_fn(&i2c,NVM_CTLR_ADR,temp);
        wait_us(delay2);
        temp =  (NVM_RESET | NVM_PWR_ON);
        i2c_write_fn(&i2c,NVM_CTLR_ADR,temp); //de-assert NVM_PWE1
        wait_us(delay2);          
        temp =  (NVM_RESET | NVM_CLK1 | NVM_PWR_ON);
        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);    
}