/* ** =================================================================== ** Method : EE241_ReadBlock (component 24AA_EEPROM) ** Description : ** Read a block of memory. ** Parameters : ** NAME - DESCRIPTION ** addr - Address where to read the memory ** * data - Pointer to a buffer where to store the ** data ** dataSize - Size of buffer the data pointer ** is pointing to ** Returns : ** --- - Error code, possible values ** ERR_OK - OK ** otherwise it can return an error code of ** the underlying communication protocol. ** =================================================================== */ byte EE241_ReadBlock(EE241_Address addr, byte *data, word dataSize) { uint8_t res; #if EE241_DEVICE_ID==EE241_DEVICE_ID_8 uint8_t addr8; addr8 = (uint8_t)(addr&0xff); #else uint8_t addr16[2]; /* big endian address on I2C bus needs to be 16bit */ addr16[0] = (uint8_t)(addr>>8); /* 16 bit address must be in big endian format */ addr16[1] = (uint8_t)(addr&0xff); #endif res = GI2C1_SelectSlave(EE241_DEVICE_ADDR(addr)); if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } #if EE241_DEVICE_ID==EE241_DEVICE_ID_8 res = GI2C1_WriteBlock(&addr8, 1, GI2C1_DO_NOT_SEND_STOP); /* send 8bit address */ #else res = GI2C1_WriteBlock(addr16, 2, GI2C1_DO_NOT_SEND_STOP); /* send 16bit address */ #endif if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } res = GI2C1_ReadBlock(data, dataSize, GI2C1_SEND_STOP); if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } return GI2C1_UnselectSlave(); }
/* Single Write DAC Input Register (EEPROM not updated) */ uint8_t MCP4728_FastWriteDAC(uint8_t channel, uint16_t val) { uint8_t res; uint8_t data[3]; /* 01000|DAC1|DAC0|UDAC VREF|PD1|PD0|Gx|D11-D0 */ if (channel>3) { return ERR_FAILED; /* only channel 0-3 allowed */ } data[0] = 0x40|((channel&0x3)<<1); /* UDAC zero */ data[1] = (uint8_t)((val>>8)&0x0F); /* VREF, PD1, PD2 and Gx zero */ data[2] = (uint8_t)(val&0xff); /* low byte */ res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS); if (res!=ERR_OK) { return res; } res = GI2C1_WriteBlock(&data[0], sizeof(data), GI2C1_SEND_STOP); if (res!=ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } res = GI2C1_UnselectSlave(); if (res!=ERR_OK) { return res; } return ERR_OK; }
/* Single Write DAC Input Register and EEPROM */ uint8_t MCP4728_WriteDACandEE(uint8_t channel, uint16_t val) { uint8_t res; uint8_t data[3]; /* 01011|DAC1|DAC0|UDAC VREF|PD1|PD0|Gx|D11-D0 */ if (channel>3) { return ERR_FAILED; /* only channel 0-3 allowed */ } data[0] = 0x58|((channel&0x3)<<1); /* UDAC zero */ data[1] = (uint8_t)((val>>8)&0x0F); /* VREF, PD1, PD2 and Gx zero */ data[2] = (uint8_t)(val&0xff); /* low byte */ res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS); if (res!=ERR_OK) { return res; } res = GI2C1_WriteBlock(&data[0], sizeof(data), GI2C1_SEND_STOP); if (res!=ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } res = GI2C1_UnselectSlave(); if (res!=ERR_OK) { return res; } #if PL_CONFIG_HAS_MCP4728_RDY while(MCP4728_IsBusy()) { WAIT1_WaitOSms(10); /* wait until data is written */ } #else WAIT1_WaitOSms(500); /* give EEPROM time to write data */ #endif return ERR_OK; }
/* Fast Mode Write: updates all 4 channels, but does not update EEPROM */ uint8_t MCP4728_FastWriteAllDAC(uint16_t dac[4], size_t dacSize, uint8_t pd[4], size_t pdSize) { uint8_t res; uint8_t data[4*2], *p; int i; /* DAC contains PD1|PD0|D11..D0 */ if (dacSize!=4*sizeof(uint16_t) || pdSize!=4) { return ERR_FAILED; } p = &data[0]; for(i=0;i<4;i++) { *p = (pd[i]&0x3)<<4; *p |= (dac[i]>>8)&0x0F; p++; *p = (uint8_t)(dac[i]&0xFF); p++; } res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS); if (res!=ERR_OK) { return res; } res = GI2C1_WriteBlock(data, sizeof(data), GI2C1_SEND_STOP); if (res!=ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } res = GI2C1_UnselectSlave(); if (res!=ERR_OK) { return res; } return ERR_OK; }
/* ** =================================================================== ** Method : EE241_WriteByte (component 24AA_EEPROM) ** Description : ** Writes a single byte to specified address ** Parameters : ** NAME - DESCRIPTION ** addr - The address inside the EEPROM ** data - The data value to write ** Returns : ** --- - Error code, possible values ** ERR_OK - OK ** otherwise it can return an error code of ** the underlying communication protocol. ** =================================================================== */ byte EE241_WriteByte(EE241_Address addr, byte data) { uint8_t res, block[3]; res = GI2C1_SelectSlave(EE241_DEVICE_ADDR(addr)); if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } #if EE241_DEVICE_ID==EE241_DEVICE_ID_8 block[0] = (uint8_t)(addr&0xff); /* low byte of address */ block[1] = data; /* switch to read mode */ res = GI2C1_WriteBlock(block, 2, GI2C1_SEND_STOP); /* send address and data */ #else block[0] = (uint8_t)(addr>>8); /* high byte of address */ block[1] = (uint8_t)(addr&0xff); /* low byte of address */ block[2] = data; /* switch to read mode */ res = GI2C1_WriteBlock(block, sizeof(block), GI2C1_SEND_STOP); /* send address and data */ #endif if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } #if EE241_DO_ACKNOWLEDGE_POLLING /* do acknowledge polling */ block[0] = 0xff; /* dummy value */ do { WAIT1_WaitOSms(EE241_PAGE_WRITE_TIME_MS); res = GI2C1_ProbeACK(block, 1, GI2C1_SEND_STOP, EE241_ACK_POLLING_TIME_US); /* send address and data */ } while(res!=ERR_OK); /* wait until we get an ACK */ #endif /* EE241_DO_ACKNOWLEDGE_POLLING */ if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } return GI2C1_UnselectSlave(); }
/*! * \brief General Call to reset, wake-up, sofware update or read address bits. */ static uint8_t MCP4728_GeneralCall(uint8_t cmd) { uint8_t res; res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS); if (res!=ERR_OK) { return res; } res = GI2C1_WriteBlock(&cmd, sizeof(cmd), GI2C1_SEND_STOP); if (res!=ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } res = GI2C1_UnselectSlave(); if (res!=ERR_OK) { return res; } return ERR_OK; }
uint8_t MPC4728_SingleWrite(uint8_t channel, uint16_t val) { uint8_t res; uint8_t data[3]; /* 01011|DAC1|DAC0|UDAC VREF|PD1|PD0|Gx|D11-D0 */ data[0] = 0xB0|((channel&0x3)<<1); data[1] = (uint8_t)(val>>8); data[2] = (uint8_t)(val&0xff); res = GI2C1_SelectSlave(MPC4728_I2C_ADDRESS); if (res!=ERR_OK) { return res; } res = GI2C1_WriteBlock(&data[0], sizeof(data), GI2C1_SEND_STOP); if (res!=ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } res = GI2C1_UnselectSlave(); if (res!=ERR_OK) { return res; } return ERR_OK; }
byte EE241_WriteBlockPage(EE241_Address addr, byte *data, word dataSize) { uint8_t res, i, *p, block[EE241_BLOCK_BUF_SIZE+2]; /* additional 2 bytes for the address */ uint16_t eepromPage = (uint16_t)(addr/EE241_PAGE_SIZE); uint8_t offset = (uint8_t)(addr%EE241_PAGE_SIZE); if (dataSize==0 || dataSize>EE241_BLOCK_BUF_SIZE) { return ERR_OVERFLOW; /* you may increase the buffer size in the properties? */ } if (dataSize>EE241_PAGE_SIZE) { uint16_t size; size = (uint16_t)(EE241_PAGE_SIZE-offset); if (size!=0) { res = EE241_WriteBlock(addr, data, size); /* first page write */ if (res != ERR_OK) { return res; } data += size; /* increment data pointer */ addr += size; /* increment address */ dataSize -= size; /* reduce size */ } /* write multiple block of PAGE_SIZE */ while (dataSize>EE241_PAGE_SIZE) { res = EE241_WriteBlock(addr, data, EE241_PAGE_SIZE); if (res != ERR_OK) { return res; } data += EE241_PAGE_SIZE; /* increment data pointer */ addr += EE241_PAGE_SIZE; /* increment address */ dataSize -= EE241_PAGE_SIZE; /* reduce size */ } /* write remainder (if any) */ if (dataSize>0) { return EE241_WriteBlock(addr, data, dataSize); } return ERR_OK; } if (offset+dataSize <= EE241_PAGE_SIZE) { /* no page boundary crossing */ res = GI2C1_SelectSlave(EE241_DEVICE_ADDR(addr)); if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } #if EE241_DEVICE_ID==EE241_DEVICE_ID_8 /* 8 bit address byte, high byte of address have been place in SelectSlave(addr) */ block[0] = (uint8_t)(addr&0xff); /* low byte of address */ p = &block[1]; i = (uint8_t)dataSize; #else /* 16 bit address byte */ block[0] = (uint8_t)(addr>>8); /* high byte of address */ block[1] = (uint8_t)(addr&0xff); /* low byte of address */ p = &block[2]; i = (uint8_t)dataSize; #endif /* copy block */ while(i>0) { *p++ = *data++; i--; } res = GI2C1_WriteBlock(block, dataSize+((EE241_DEVICE_ID==EE241_DEVICE_ID_8)? 1:2), GI2C1_SEND_STOP); /* send address and data */ if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } #if EE241_DO_ACKNOWLEDGE_POLLING /* do acknowledge polling */ block[0] = 0xff; /* dummy value */ do { WAIT1_WaitOSms(EE241_PAGE_WRITE_TIME_MS); res = GI2C1_ProbeACK(block, 1, GI2C1_SEND_STOP, EE241_ACK_POLLING_TIME_US); /* send address and data */ } while(res!=ERR_OK); /* wait until we get an ACK */ if (res != ERR_OK) { (void)GI2C1_UnselectSlave(); return res; } #endif /* EE241_DO_ACKNOWLEDGE_POLLING */ return GI2C1_UnselectSlave(); } else { /* crossing page boundaries: make two page writes */