This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28377D: I2c interrupt

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hi,

I use the i2c module of the 28377D and to avoid polling I use interrupts. It seems all work fine but sometimes appens that reading the the i2c interrupt source register I get 0 (NO_SRC)!! Why this appens? If in the interrupt procedure I signals the the i2c operation is aborted whitout do nothing the next operation is ok and the module continues to work.

Regards

 

  • i2ca.h

    /* =============================================================================
        PROJECT NAME:
        ITEM TYPE:
        ITEM NAME:
        ITEM REFERENCE:
        CURRENT VERSION:
        DATE:
        ITEM DESCRIPTION:
        DOC REFERENCES:
        AUTHOR(S):
        COPYRIGHT:
        REVISION HISTORY:
    ============================================================================= */
    
    #define I2CA_GLOBALS
    #include "includes.h"
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    void SetUpI2CA(void)
    {
    
    	GPIO_SetupPinMux(SCLA_GPIO, GPIO_MUX_CPU1, SCLA_PHER);
        GPIO_SetupPinOptions(SCLA_GPIO, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        GPIO_SetupPinMux(SDAA_GPIO, GPIO_MUX_CPU1, SDAA_PHER);
        GPIO_SetupPinOptions(SDAA_GPIO, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        //	Reset the module
        I2caRegs.I2CMDR.all = 0;
        //	200MHz/(19+1) = 10MHz
        I2caRegs.I2CPSC.bit.IPSC = 19;
        //	Minimum low time for slave is 1.3us (program 1.5us)
        I2caRegs.I2CCLKL = 15;
        //	Minimum high time for slave is 0.6us (program 1us)
        I2caRegs.I2CCLKH = 10;
        //	Module stops in breakpoint
        I2caRegs.I2CMDR.bit.FREE = 1;
        //	Module operate as master
        I2caRegs.I2CMDR.bit.MST = 1;
        //	Enables interrupts
        I2caRegs.I2CIER.bit.ARDY = 1;
        I2caRegs.I2CIER.bit.NACK = 1;
        I2caRegs.I2CIER.bit.RRDY = 1;
        I2caRegs.I2CIER.bit.SCD = 1;
        I2caRegs.I2CIER.bit.XRDY = 1;
        //	Remove module from reset condition
        I2caRegs.I2CMDR.bit.IRS = 1;
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    void i2ca_start_transfer(int16_t sadd, int16_t n_wr, int16_t n_rd, int16_t op)
    {
    union I2CMDR_REG cmdr;
    
        i2ca.stop = false;
        i2ca.nack = false;
        i2ca.done = false;
        i2ca.sar = sadd;
        i2ca.n_writes = n_wr;
        i2ca.n_reads = n_rd;
    
        DELAY_US(1);
    
        cmdr.all = 0;
        cmdr.bit.IRS = 1;
        cmdr.bit.MST = 1;
        switch( op )
        {
        case I2C_WRITE:
            i2ca.state = I2C_WRITING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_wr;
            cmdr.bit.TRX = 1;
            cmdr.bit.STP = 1;
            cmdr.bit.STT = 1;
            break;
    
        case I2C_WRITE_READ:
            i2ca.state = I2C_WRITING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_wr;
            cmdr.bit.TRX = 1;
            cmdr.bit.STP = 0;
            cmdr.bit.STT = 1;
            break;
    
        case I2C_READ:
            i2ca.state = I2C_READING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_rd;
            cmdr.bit.TRX = 0;
            cmdr.bit.STP = 1;
            cmdr.bit.STT = 1;
            break;
    
        case I2C_POLLING:
            i2ca.state = EEPROM_POLLING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_wr;
            cmdr.bit.TRX = 1;
            cmdr.bit.STP = 1;
            cmdr.bit.STT = 1;
            break;
    
        default:
            break;
        }
    
        I2caRegs.I2CMDR.all = cmdr.all;
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool i2ca_tx_rx(uint16_t sadd, int16_t n_writes, int16_t n_reads)
    {
    bool esito;
    
        if( n_reads == 0 )
        {
            //  Start write only transfer
            i2ca_start_transfer(sadd, n_writes, n_reads, I2C_WRITE);
        }
        else
        {
            if( n_writes == 0 )
            {
                //  start read only transfer
                i2ca_start_transfer(sadd, n_writes, n_reads, I2C_READ);
            }
            else
            {
                //  start a read after write transfer
                i2ca_start_transfer(sadd, n_writes, n_reads, I2C_WRITE_READ);
            }
        }
    
        //  wait for end of operation
        while( !i2ca.done );
        if( i2ca.nack )
        {
            esito = false;
        }
        else
        {
            esito = true;
        }
    
        return ( esito );
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    interrupt void i2ca_isr(void)
    {
    // Set interrupt priority:
    volatile uint16_t TempPIEIER = PieCtrlRegs.PIEIER8.all;
    uint16_t tmp;
    
        IER |= M_INT8;
        IER &= MINT8;
        PieCtrlRegs.PIEIER8.all &= MG8_1;
        PieCtrlRegs.PIEACK.all = 0xFFFF;
        asm(" NOP");
        EINT;
    
        // Insert ISR Code here.......
        tmp = I2caRegs.I2CISRC.all;
        switch ( tmp  )
        {
        case I2C_NO_ISRC:
            tmp = 0;
            break;
    
        case I2C_ARB_ISRC:
            tmp = 0;
            break;
    
        case I2C_NACK_ISRC:
            i2ca.nack = true;
            break;
    
        case I2C_ARDY_ISRC:
            if( (i2ca.state == EEPROM_POLLING) || i2ca.nack )
            {
                i2ca.done = true;
            }
            else
            {
                if( i2ca.state == I2C_WRITING )
                {
                    i2ca_start_transfer(i2ca.sar, 0, i2ca.n_reads, I2C_READ);
                }
            }
            break;
    
        case I2C_RX_ISRC:
            i2ca.rx_buf[i2ca.trx_ptr++] = I2caRegs.I2CDRR.bit.DATA;
            I2caRegs.I2CSTR.bit.RRDY = 1;
            break;
    
        case I2C_TX_ISRC:
            I2caRegs.I2CSTR.bit.XRDY = 1;
            I2caRegs.I2CDXR.bit.DATA = i2ca.tx_buf[i2ca.trx_ptr++];
            break;
    
        case I2C_SCD_ISRC:
            i2ca.state = I2C_NOP;
            i2ca.stop = true;
            i2ca.done = true;
            break;
    
        case I2C_AAS_ISRC:
            tmp = 0;
            break;
    
        default:
            tmp = 0;
            break;
        }
    
        // Restore registers saved:
        DINT;
        PieCtrlRegs.PIEIER8.all = TempPIEIER;
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    uint16_t set_cmdr(bool rm, bool start, bool trx, bool stop)
    {
    union I2CMDR_REG cmdr_img;
    
        cmdr_img.all = 0;
        cmdr_img.bit.FREE = 1;
        cmdr_img.bit.IRS = 1;
        cmdr_img.bit.MST = 1;
        cmdr_img.bit.RM = rm;
        cmdr_img.bit.TRX = trx;
        cmdr_img.bit.STT = start;
        cmdr_img.bit.STP = stop;
    
        return (cmdr_img.all);
    }
    

  • hi ,

    If the interrupt source is showing no source it could be due to the interrupt getting cleared or something to do with the levels set for triggering the interrupts etc 

    Can you take a look at the below example ? This may use loopback but will give you an idea on how to configure the FIFOs etc .

    C2000Ware\driverlib\f2837xd\examples\cpu1\i2ci2c_ex1_loopback.c

    Regards.

  • I'm not using the FIFO interrupts but the normal i2c interrupt vector.
  • Hi luca mattonai,

    Were you able to resolve the issue? Do you need further help?
  • Hi Meghana

    I solve the problem but not in clear mode... When I receive a wrong interrupt I behave as it was a not ack and all seems to work.

    Regards

  • Could you share your source code, please?
  • 8611.i2ca.h

    /* =============================================================================
        PROJECT NAME:
        ITEM TYPE:
        ITEM NAME:
        ITEM REFERENCE:
        CURRENT VERSION:
        DATE:
        ITEM DESCRIPTION:
        DOC REFERENCES:
        AUTHOR(S):
        COPYRIGHT:
        REVISION HISTORY:
    ============================================================================= */
    
    #define I2CA_GLOBALS
    #include "includes.h"
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    void SetUpI2CA(void)
    {
    
    	GPIO_SetupPinMux(SCLA_GPIO, GPIO_MUX_CPU1, SCLA_PHER);
        GPIO_SetupPinOptions(SCLA_GPIO, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        GPIO_SetupPinMux(SDAA_GPIO, GPIO_MUX_CPU1, SDAA_PHER);
        GPIO_SetupPinOptions(SDAA_GPIO, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        //	Reset the module
        I2caRegs.I2CMDR.all = 0;
        //	200MHz/(19+1) = 10MHz
        I2caRegs.I2CPSC.bit.IPSC = 19;
        //	Minimum low time for slave is 1.3us (program 1.5us)
        I2caRegs.I2CCLKL = 15;
        //	Minimum high time for slave is 0.6us (program 1us)
        I2caRegs.I2CCLKH = 10;
        //	Module stops in breakpoint
        I2caRegs.I2CMDR.bit.FREE = 1;
        //	Module operate as master
        I2caRegs.I2CMDR.bit.MST = 1;
        //	Enables interrupts
        I2caRegs.I2CIER.bit.ARDY = 1;
        I2caRegs.I2CIER.bit.NACK = 1;
        I2caRegs.I2CIER.bit.RRDY = 1;
        I2caRegs.I2CIER.bit.SCD = 1;
        I2caRegs.I2CIER.bit.XRDY = 1;
        //	Remove module from reset condition
        I2caRegs.I2CMDR.bit.IRS = 1;
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    void i2ca_start_transfer(int16_t sadd, int16_t n_wr, int16_t n_rd, int16_t op)
    {
    union I2CMDR_REG cmdr;
    
        i2ca.stop = false;
        i2ca.nack = false;
        i2ca.done = false;
        i2ca.sar = sadd;
        i2ca.n_writes = n_wr;
        i2ca.n_reads = n_rd;
    
    //    DELAY_US(20);
    
        cmdr.all = 0;
        cmdr.bit.IRS = 1;
        cmdr.bit.MST = 1;
        switch( op )
        {
        case I2C_WRITE:
            i2ca.state = I2C_WRITING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_wr;
            cmdr.bit.TRX = 1;
            cmdr.bit.STP = 1;
            cmdr.bit.STT = 1;
            break;
    
        case I2C_WRITE_READ:
            i2ca.state = I2C_WRITING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_wr;
            cmdr.bit.TRX = 1;
            cmdr.bit.STP = 0;
            cmdr.bit.STT = 1;
            break;
    
        case I2C_READ:
            i2ca.state = I2C_READING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_rd;
            cmdr.bit.TRX = 0;
            cmdr.bit.STP = 1;
            cmdr.bit.STT = 1;
            break;
    
        case I2C_POLLING:
            i2ca.state = EEPROM_POLLING;
            i2ca.trx_ptr = 0;
            I2caRegs.I2CSAR.bit.SAR = sadd;
            I2caRegs.I2CCNT = n_wr;
            cmdr.bit.TRX = 1;
            cmdr.bit.STP = 1;
            cmdr.bit.STT = 1;
            break;
    
        default:
            break;
        }
    
        I2caRegs.I2CMDR.all = cmdr.all;
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool i2ca_tx_rx(uint16_t sadd, int16_t n_writes, int16_t n_reads)
    {
    bool esito;
    
        if( n_reads == 0 )
        {
            //  Start write only transfer
            i2ca_start_transfer(sadd, n_writes, n_reads, I2C_WRITE);
        }
        else
        {
            if( n_writes == 0 )
            {
                //  start read only transfer
                i2ca_start_transfer(sadd, n_writes, n_reads, I2C_READ);
            }
            else
            {
                //  start a read after write transfer
                i2ca_start_transfer(sadd, n_writes, n_reads, I2C_WRITE_READ);
            }
        }
    
        //  wait for end of operation
        while( !(i2ca.done /*|| i2ca.nack*/) );
        if( i2ca.nack )
        {
            esito = false;
        }
        else
        {
            esito = true;
        }
    
        return ( esito );
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    interrupt void i2ca_isr(void)
    {
    // Set interrupt priority:
    volatile uint16_t TempPIEIER = PieCtrlRegs.PIEIER8.all;
    uint16_t tmp;
    union I2CMDR_REG cmdr;
    
        IER |= M_INT8;
        IER &= MINT8;
        PieCtrlRegs.PIEIER8.all &= MG8_1;
        PieCtrlRegs.PIEACK.all = 0xFFFF;
        asm(" NOP");
        EINT;
    
        // Insert ISR Code here.......
        tmp = I2caRegs.I2CISRC.all;
        switch ( tmp  )
        {
        case I2C_NO_ISRC:
    //        i2ca.nack = true;
            break;
    
        case I2C_ARB_ISRC:
            tmp = 0;
            break;
    
        case I2C_NACK_ISRC:
        	//	generate a stop
        	cmdr.all = I2caRegs.I2CMDR.all;
        	cmdr.bit.STP = 1;
        	I2caRegs.I2CMDR.all = cmdr.all;
        	//
        	i2ca.nack_count++;
            i2ca.nack = true;
            break;
    
        case I2C_ARDY_ISRC:
            if( (i2ca.state == EEPROM_POLLING) || i2ca.nack )
            {
                i2ca.done = true;
            }
            else
            {
                if( i2ca.state == I2C_WRITING )
                {
                    i2ca_start_transfer(i2ca.sar, 0, i2ca.n_reads, I2C_READ);
                }
            }
            break;
    
        case I2C_RX_ISRC:
            i2ca.rx_buf[i2ca.trx_ptr++] = I2caRegs.I2CDRR.bit.DATA;
            I2caRegs.I2CSTR.bit.RRDY = 1;
            break;
    
        case I2C_TX_ISRC:
            I2caRegs.I2CSTR.bit.XRDY = 1;
            I2caRegs.I2CDXR.bit.DATA = i2ca.tx_buf[i2ca.trx_ptr++];
            break;
    
        case I2C_SCD_ISRC:
            i2ca.state = I2C_NOP;
            i2ca.stop = true;
            i2ca.done = true;
            break;
    
        case I2C_AAS_ISRC:
            tmp = 0;
            break;
    
        default:
            tmp = 0;
            break;
        }
    
        // Restore registers saved:
        DINT;
        PieCtrlRegs.PIEIER8.all = TempPIEIER;
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    uint16_t set_cmdr(bool rm, bool start, bool trx, bool stop)
    {
    union I2CMDR_REG cmdr_img;
    
        cmdr_img.all = 0;
        cmdr_img.bit.FREE = 1;
        cmdr_img.bit.IRS = 1;
        cmdr_img.bit.MST = 1;
        cmdr_img.bit.RM = rm;
        cmdr_img.bit.TRX = trx;
        cmdr_img.bit.STT = start;
        cmdr_img.bit.STP = stop;
    
        return (cmdr_img.all);
    }
    
    eeprom.h
    /* =============================================================================
        PROJECT NAME:
        ITEM TYPE:
        ITEM NAME:
        ITEM REFERENCE:
        CURRENT VERSION:
        DATE:
        ITEM DESCRIPTION:
        DOC REFERENCES:
        AUTHOR(S):
        COPYRIGHT:
        REVISION HISTORY:
    ============================================================================= */
    
    #define EEPROM_GLOBALS
    #include "includes.h"
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_write(uint32_t address, int16_t n_writes, uint16_t *data)
    {
    int16_t i;
    bool esito;
    
        //  Prepare SAR
        i2ca.sar = (address & 0x3FFFF) >> 16;
        i2ca.sar = i2ca.sar << 1;
        i2ca.sar = (i2ca.sar | DSC_MUSK) >> 1;
        //
        i2ca.tx_buf[0] = (address >> 8) & 0xFF;
        i2ca.tx_buf[1] = address & 0xFF;
        //
        for (i=0; i<n_writes; i++)
        {
            i2ca.tx_buf[EEPROM_ADD_LEN+i] = data[i];
        }
        //
        esito = i2ca_tx_rx(i2ca.sar, n_writes+2, 0);
        //
        return (esito);
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_read(uint32_t address, int16_t n_reads, uint16_t *data)
    {
    int16_t i;
    bool esito;
    
        //  Prepare SAR
        i2ca.sar = (address & 0x3FFFF) >> 16;
        i2ca.sar = i2ca.sar << 1;
        i2ca.sar = (i2ca.sar | DSC_MUSK) >> 1;
        //
        i2ca.tx_buf[0] = (address >> 8) & 0xFF;
        i2ca.tx_buf[1] = address & 0xFF;
        //
        esito = i2ca_tx_rx(i2ca.sar, 2, n_reads);
        //
        if ( esito && (data != NULL) )
        {
            for (i=0; i<n_reads; i++)
            {
                data[i] = i2ca.rx_buf[i];
            }
        }
        //
        return (esito);
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_polling(void)
    {
    bool esito = false;
    
    /*
        i2ca.retry = 0;
        do
        {
            //
            i2ca.retry++;
            //
            i2ca.tx_buf[0] = 0;
            i2ca.tx_buf[1] = 0;
            i2ca_start_transfer(DSC_MUSK >> 1, 2, 0, I2C_POLLING);
            while( !i2ca.done );
            if ( i2ca.stop )
            {
                esito = true;
                i2ca.done = false;
                i2ca.stop = false;
            }
        } while( !esito );
    */
    
    	do
    	{
    		esito = eeprom_read(0, 1, NULL);
    	} while(! esito);
    
        return( esito );
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    uint16_t byte_to_word(uint16_t *add)
    {
    int16_t i;
    uint16_t res = 0;
    
    	add = add + 1;
    	for(i=0; i<2; i++)
    	{
    		res = (res << 8) | *add--;
    	}
    
    	return( res );
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    void word_to_byte(uint16_t ulval, uint16_t *add)
    {
    int16_t i;
    
    	for(i=0; i<2; i++)
    	{
    		*add++ = ulval & 0xFF;
    		ulval = ulval >> 8;
    	}
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_get_param(void)
    {
    bool esito = true;
    uint16_t utmp;
    int16_t i;
    
    	esito = esito && eeprom_read(EEP_PAR_PAGE, 256, r_data);
    	if( esito )
    	{
    		for(i=0; i<NWLR; i++)
    		{
    			eeimg[i] = byte_to_word(&r_data[i*2]);
    		}
    		utmp = 0;
    		for(i=0; i<NWLR; i++)
    		{
    			utmp += eeimg[i];
    		}
    		esito = esito && (utmp == 0);
    		if( esito )
    		{
    			for(i=0; i<NWLR; i++)
    				Wlr[i] = eeimg[i];
    		}
    	}
    
    	return( esito );
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_write_param(void)
    {
    int16_t i;
    uint16_t utmp;
    uint16_t chk = 0;
    bool esito = true;
    
    	//	clear eeimg
    	for(i=0; i<NWLR; i++)
    	{
    		eeimg[i] = 0;
    	}
    
    	//	copy data to be saved from Wlr to eeimg and compute checksum
    	for(i=0; i<NPAR-1; i++)
    	{
    		utmp = Wlr[i];
    		eeimg[i] = utmp;
    		chk += utmp;
    	}
    	eeimg[NWLR-1] = -chk;
    
    	//	converts to bytes
    	for(i=0; i<NWLR; i++)
    	{
    		word_to_byte(eeimg[i], &w_data[i*2]);
    	}
    	//	write byte data to eeprom
    	esito = esito && eeprom_write(EEP_PAR_PAGE, 256, w_data);
    	//	wait for programming end
    	esito = esito && eeprom_polling();
    
    	return( esito );
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_read_adjust(void)
    {
    int16_t i;
    uint16_t utmp;
    uint16_t chk = 0;
    bool esito = true;
    
    	esito = esito && eeprom_read(FLASH_OFFSET, FLASH_LEN*2, r_data);
    	for(i=0; i<FLASH_LEN; i++)
    	{
    		utmp = byte_to_word(&r_data[i*2]);
    		flash.img[i] = utmp;
    		chk += utmp;
    	}
    	esito = esito && (chk == 0);
    
    	if( esito )
    	{
    	}
    	else
    	{
    		for(i=0; i<FLASH_LEN; i++)
    		{
    			flash.img[i] = 0;
    		}
    		esito = false;
    	}
    
    	return (esito);
    }
    
    /* ============================================================================
        FUNCTION NAME:
        PURPOSE:
        DESCRIPTION:
        DOMAIN:
        ACCURACY:
        NOTES:
     ============================================================================ */
    bool eeprom_write_adjust(void)
    {
    int16_t i;
    uint16_t chk = 0;
    bool esito = true;
    
    	//	Compute checksum
    	for(i=0; i<FLASH_LEN-1; i++)
    	{
    		chk += flash.img[i];
    	}
    	flash.img[FLASH_LEN-1] = -chk;
    
    	//	convert to bytes
    	for(i=0; i<FLASH_LEN; i++)
    	{
    		word_to_byte(flash.img[i], &w_data[i*2]);
    	}
    	//	write data to eeprom
    	esito = esito && eeprom_write(FLASH_OFFSET, FLASH_LEN*2, w_data);
    	esito = esito && eeprom_polling();
    
    	return (esito);
    }
    

  • Hi Minh
    Here the related code