Got this working with a few code changes: /* * read_wiper - returns the 2nd byte of a 2-byte read from the specified wiper * 'reg' contains the write command to read the required wiper */ uint8_t read_wiper(uint8_t reg) {
uint8_t dataByte; //initialise i2c2 device init_i2c(); //set I2C2_CNT register to 1 for initial write command I2C2_CNT = 1; while (I2C2_STATUSRAW & 0x1000); //poll 'busy bit' in I2C2_STATUSRAW register (bit 12) until it is zero //set transmit mode I2C2_CON = 0x8601; //load data register with write command I2C2_DATA = reg; while (!(I2C2_STATUSRAW & 0x0010)); //poll XRDY bit in I2C2_STATUSRAW register (bit 4) until it is non-zero //data has transmitted, write 1 to clear the interrupt I2C2_STATUSRAW |= 0x0010; while (!(I2C2_STATUSRAW & 0x0004)); //poll 'access ready' bit in I2C2_STATUSRAW register (bit 4) until it is non-zero //set byte count to 2 I2C2_CNT = 2; //set receive mode I2C2_CON = 0x8400; //set start and auto stop condition I2C2_CON |= 0x0003; while (!(I2C2_STATUSRAW & 0x0008)); //poll 'receive ready bit' in I2C2_STATUSRAW register (bit 3) until it is non-zero dataByte = I2C2_DATA; //first byte is always 0x00 //data has been received, write 1 to clear the interrupt I2C2_STATUSRAW |= 0x0008; while (!(I2C2_STATUSRAW & 0x0008)); //poll 'receive ready bit' in I2C2_STATUSRAW register (bit 3) until it is non-zero dataByte = I2C2_DATA; //second byte is the value we want //data has been received, write 1 to clear the interrupt I2C2_STATUSRAW |= 0x0008; while (!(I2C2_STATUSRAW & 0x0100)); //poll 'buss free' bit in I2C2_STATUSRAW register (bit 8) until it is non-zero //clear all pending interrupts I2C2_STATUS = 0x7FF; return dataByte; } Note the clearing of pending interrupts after each check and the final clear of the status register (not status_raw) at the end. 5 byte writes now working every time... On Thursday, 13 September 2018 14:39:04 UTC+1, lazarman wrote: > > I love the TRM documentation its very detailed best to follow its > recommended sequences and roll your own code using examples as a template. > > I'd look at the i2C slave data sheet carefully especially the timing/setup > diagrams. > you have the scope looks like your close.Another idea look for example > code for device even if another micro. Looking at it might give you a clue > what's wrong. Last attempt try something quick and simple if you have > available no OS barebones one processor I bet your code works on it. > Good Luck > > > Sent from Yahoo Mail on Android > <https://overview.mail.yahoo.com/mobile/?.src=Android> > > On Thu, Sep 13, 2018 at 8:06 AM, Hugh Frater > <hugh....@gmail.com <javascript:>> wrote: > Does anyone know the correct programming sequence for doing an I2C random > read from within the PRU? I've tried this nicely written driver: > > https://github.com/LinuxDroneLab/pru-i2c-lib > > It works less than my code does... > > My code works fine if I call my routine once, on the scope I see the write > followed by the read of the 2 bytes I want... Call my function again and > all I see is the read. > > Code and scope grabs attached - the documentation on the I2C module from > within the AM335xTRM pdf is shocking and this problem is driving me mad... > > /* > * read_wiper - returns the 2nd byte of a 2-byte read from the specified > wiper > * 'reg' contains the write command to read the required wiper > */ > uint8_t read_wiper(uint8_t reg) > { > > uint8_t dataByte; > > //initialise i2c2 device > init_i2c(); > > //set I2C2_CNT register to 1 for initial write command > I2C2_CNT = 1; > > while (!(I2C2_STATUSRAW & 0x0100)); > //poll 'buss free' bit in I2C2_STATUSRAW register (bit 8) until it > is non-zero > //set transmit mode > I2C2_CON = 0x8601; > //load data register with write command > I2C2_DATA = reg; > > while (!(I2C2_STATUSRAW & 0x0004)); > //poll 'access ready' bit in I2C2_STATUSRAW register (bit 4) until > it is non-zero > //set byte count to 2 > I2C2_CNT = 2; > //set receive mode > I2C2_CON = 0x8403; > > while (!(I2C2_STATUSRAW & 0x0008)); > //poll 'receive ready bit' in I2C2_STATUSRAW register (bit 3) > until it is non-zero > > dataByte = I2C2_DATA; //first byte is always 0x00 > > //zero the receive ready bit once we have read the 1st byte into our > local variable > I2C2_STATUSRAW |= 0x0008; > > while (!(I2C2_STATUSRAW & 0x0008)); > //poll 'receive ready bit' in I2C2_STATUSRAW register (bit 3) > until it is non-zero > > dataByte = I2C2_DATA; //second byte is the value we want > > //zero the receive ready bit once we have read the 2nd byte into our > local variable > I2C2_STATUSRAW |= 0x0008; > > while (!(I2C2_STATUSRAW & 0x0100)); > //poll 'buss free' bit in I2C2_STATUSRAW register (bit 8) until it > is non-zero > > return dataByte; > } > > void init_i2c() > { > /* Enable I2C2 clock signal generation */ > while (!(CM_PER_I2C2 & 0x2)) > CM_PER_I2C2 |= 0x2; > > /* > * set I2C2_PSC register to 0x0B > * set I2C2_SCCL register to 0x0D > * set I2C2_SCCH register to 0x0F > * set I2C2_CON register to 1000 0110 0000 0000 (0x8600) > * set I2C2_SA register to 0x2E (address of MCP4641) > */ > > I2C2_PSC = 0x000B; > I2C2_SCLL = 0x000D; > I2C2_SCLH = 0x000F; > I2C2_CON = 0x8600; > I2C2_SA = i2cPotAddress; > I2C2_BUF = 0x0000; > > } > > [image: 20180913135820.png] > > [image: 20180913135835.png] > > > > > -- > For more options, visit http://beagleboard.org/discuss > --- > You received this message because you are subscribed to the Google Groups > "BeagleBoard" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to beagleboard...@googlegroups.com <javascript:>. > To view this discussion on the web visit > https://groups.google.com/d/msgid/beagleboard/aeaee4b9-4b7f-41b1-b86c-48f1ade8b24e%40googlegroups.com > > <https://groups.google.com/d/msgid/beagleboard/aeaee4b9-4b7f-41b1-b86c-48f1ade8b24e%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > > -- For more options, visit http://beagleboard.org/discuss --- You received this message because you are subscribed to the Google Groups "BeagleBoard" group. To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/80a809e7-608b-4aea-836e-84f0ceb97558%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.