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.
Hello, I am looking for some example code for the UCD31xx that would allow me to talk to an EEPROM. The technical reference manual shows all of the registers needed for I2C master mode and nicely breaks them down. However, I am not able to find any examples how to use it. I have been experimenting writing various stuff to the PMBTXBUF register and PMBCTRL1, PMBCTRL3. Particularly SLAVE_EN and MASTER_EN. I have attached 1kohm pull-up resistors to pins 35 and 36 (I2C_DATA, I2C_CLK). The pull-ups are working (i.e. the signals are 3.3V with them attached) but I am getting no activity on the pins. Maybe I don't have the pins configured correctly or something? Maybe I have to configure some sort of clock source for the I2C master? It is not clear to me what specifically needs to be initialized or what particular steps cause the master to start clocking out data.
I am seeing that there is a demo board named "UCD3138A64OEVM-662", which apparently does have an I2C EEPROM onboard that can be enabled via jumpers (J50, J52). So that looks like it was intended to give a demo of precisely what I am trying to do. But I am not actually finding any documentation or sample code related to that. If anyone knows where I could find that, if it exists, that would be a great way for me to approach this.
From my perspective right now, I just want to get an address-write byte sent out and observe it happen with my scope. Once I have that first basic function like that I believe I could probably make a lot of progress from that point.
Hi Ben,
Thanks for choosing UCD!
You can obtain the programmer's manual via the link below.
In chapter 4, it talks about the I2C eeprom communication.
Hope this doc can help you out. Please give me further update if this doc can not help you, I will keep on supporting you.
Best Regards!
Jacob
Thank you Jacob; that is exactly what I was looking for and it is very helpful. I am still experiencing problems getting any life out of the I2C pins. I will walk through exactly what I have done, and I would really appreciate any comments as to what I may have done wrong.
First of all, I should say that we are adding an EEPROM chip to an existing product that uses the UCD3138064A for the purpose of running a control loop internal of a power supply. I removed the small control card from a power supply where I can safely experiment with it. We were not previously using the I2C_CLK (FAULT1) and I2C_DATA (FAULT0) pins, so I was able to attach an EEPROM chip to these pins directly for prototype purposes. I am monitoring the pins with my oscilloscope.
Following the programmer's manual that you shared, I added a new source file in the existing Code Composer project with only an init function for the EEPROM so far, heavily based on the EEPROM example code:
void bsp_eepromInit( void ) { // Select I2C function for the FAULT0 and FAULT1 pins: MiscAnalogRegs.IOMUX.bit.FAULT_01_MUX_SEL = 2; // Set I2C peripheral into master mode: PMBusRegs.PMBCTRL3.bit.SLAVE_EN = 0; PMBusRegs.PMBCTRL3.bit.MASTER_EN = 1; // Disable the PMBus timeout. This timeout is not applicable to I2C EEPROM interface. PMBusRegs.PMBCTRL3.bit.CLK_LO_DIS = 1; //@TODO - Set the I2C speed here. union I2CCTRL1_REG i2cctrl1_shadow; i2cctrl1_shadow.bit.SLAVE_ADDR = 0x50; // 7-bit slave address of the EEPROM chip. i2cctrl1_shadow.bit.BYTE_COUNT = 4;//130; // Send the 2-byte EEPROM offset plus 128 bytes. i2cctrl1_shadow.bit.RW = 0; // Perform a write transaction. uint16_t eeprom_address = 0x1000; // Address can't use the low 7 bits? uint32_t txbuf_shadow = ((eeprom_address & 0x80) << 8); //low byte of page address in second byte txbuf_shadow = txbuf_shadow + ((eeprom_address & 0xff00) >> 8); //high byte of page address in first byte. txbuf_shadow = txbuf_shadow + ((write_data[0x20]) << 16); //first byte of data to write in third byte. txbuf_shadow = txbuf_shadow + ((write_data[0x21]) << 24); //second byte of data to write in fourth byte. I2CRegs.I2CTXBUF.all = txbuf_shadow; I2CRegs.I2CCTRL1 = i2cctrl1_shadow; //start write while( 0 == I2CRegs.I2CST.bit.DATA_REQUEST ); }
I am still getting both pins rising directly up to 3.3V when I apply power, and the microcontroller is making no attempt to toggle either of the pins. I don't intend to actually send an I2C message in the init function but I am doing it this way just to try to get some life out of it at this point. I have not found anything that should be interfering elsewhere in the existing code, however we do use the analog front-end of this chip for running a control loop in a power supply. So in theory it may be trying to use FAULT0/FAULT1 functions in a way that I am not aware of? It seems doubtful. I know we are already using FAULT2 as a GPIO input and it works fine that way.
I noticed that there are 2 pairs of pins that appear to have I2C functionality on this chip:
I have hooked my EEPROM chip to pins 35 and 36 and am monitoring those pins with my scope. I am not attempting to use pins 15/16. The programmer's reference refers to FAULT0 and FAULT1, so I believe that my setup is consistent with that.
Looking at the UCD31xx Technical Reference Manual, Rev D, section 9.8.4, IOMUX register. I am confused by this section. The sample EEPROM code shows a field named "FAULT_01_MUX_SEL", however this section does not show it. And table 9-11 appears to be in direct conflict with everything else in this section. I am guessing that table 9-11 came from some other microcontroller by mistake, so I am presently disregarding that table. Looking at the header file where IOMUX_REG is defined, it does have FAULT_01_MUX_SEL defined at bits 12:11. Basically I have just copy/pasted from the EEPROM example where it sets this to 2, and have not poked at it or had any way to verify what 2 means. I am kind of guessing that it should be OK. Concerning PMBUS_MUX_SEL in this register; I am guessing that is for pins 15/16. Before I had the programmer's reference, I was playing with that bit. I am now leaving that untouched so it should have its default value, which does appear to be I2C per the technical reference section 9.8.4. Could that be causing a conflict to have both pairs set in I2C mode like that?
I tried 2 different UCD3138064A chips with the same results just to be sure I didn't have a damaged chip. How would one go about selecting between pins 15/16 vs. 35/36 for I2C? I would like to verify that I had done that correctly. Any ideas you have would really be appreciated. I would be very happy to try any experiments that you could come up with. The setup I am using is easily replaced and not installed in a power supply, so there is no worry about any damage from experimental code.
Hi Ben,
I will help you check on this, but it will take sometimes. I will feed back to you later.
Best Regards!
Jacob
Hi Ben,
Here are some example code, you can have a try.
Thank you Jacob. I reviewed your sample code carefully and I find the main difference is:
PMBus1Regs.PMBCTRL3.bit.I2C_MODE_EN = 1;
I was not doing that before. My existing device header file did not have that bit defined. I added it as bit 23. Unfortunately, it did not help. I still do not get any activity generated on the I2C clock or data lines.
I think that I should probably be starting from a more fresh starting point just to get things running. I am going ahead and ordering a UCD3138A64OEVM-662 demo board. Then I will start a brand new project in Code Composer that only ever attempts to be an I2C master with your sample code. This will eliminate a lot of variables and unknowns for us. If we can get that working it should be easier to transition integrating it into my existing micro and hardware. I will let you know an update when I get the demo board and start working with it.
Thanks,
Ben
Hi Ben,
Sorry the example code didn't help. Please reach out to UCD team if you need help with the demo board.
Best Regards!
Jacob