This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

i2c communication problems

Hi,

I have been having a lot of problems communicating with an Atmel SAM D09 as a slave, and an nrf51422 as a master.

I seem to have two problems, hopefully solving just one will get me where I need to be. but I can't seem to narrow it down. The first issue, I have been trying to use a slightly modified twi_sw_master.c to communicate with the slave, this has worked with plenty of other i2c devices out there, like EEPROMs Acelerometers, and PMICs however the Atmel won't ack. The reason I believe this to be a problem, is it doesn't run at exactly 100Khz (best i can get is 94Khz), this seems highly unlikely to me, but it is the only thing that is apparent as the Atmel is returning no error while polling the interrupt flags, and all the config is set as required. It is also pulling up both of its i2c pins, which would indicate that it is working. I have done plenty of debugging with uart, and all seems normal.

To get around this i have tried using twi_hw_master.c to work, and i do get 100Khz exactly, however the waveform i see on my scope looks wrong. To my understanding, there are 9 clock pulses on SCL, the last one being for an ack/nack, this was present on the sw version, but on the hw version it is not present and there also does not appear to be a valid stop condition, although no data is being transferred due to the lack of an ack. My aim is to use the self programming function of the Atmel SAM to update it OTA via the BLE on the nrf. the code on the Atmel is from the ASF, so i can be quite sure it works. Also worth noting that the Atmel chip is configured to respond to any address between 0-127 regardless. Unfortunately for me i am very restricted on GPIOs on the nrf, so using something else is out of the question. image description

  • Clicking that link takes me still to a 180x100 image, the title on the page is actually "scope.png (180x100)"! It's not clickable either, not that I can see, so there's no full-sized one I can see. Not that I suspect it would help much.

    I'm pretty sure the tw_hw_master works fine, it's even simpler than the sw one. I don't use it myself, I write the registers directly but it's the same thing in the end. The TWI hardware I've never had a problem with on the nrf51.

    The only example I see for the D20 is the D20 bootloader, shame there isn't a simpler I2C slave test, the unit tests only test master mode so they don't help. I can only suggest setting up the simplest I2C project you can, perhaps one of the other SAM boards has a version you can modify although I don't see much.

  • The reason that the stop condition is not clocked out is because of a PAN fix in twi_hw_master which shuts down the twi peripheral during the last clock cycle when an error is received (for example NACK). Adding a delay of about one clock cycle (10us) before the shut down will fix this, but the problem here is that the atmel chip is not sending ACK. Since the SW driver works with other i2c peripherals, the problem is with the atmel chip. Get this to work first.

    I also suggest to use nrf_drv_twi instead of twi_hw_master if it is possible, as the twi_hw_master is deprecated.

  • Thanks Ole, seems that the atmel is definately the perpetrator here. It is odd, as it seems to be configured and functioning correctly, it just never gets an address match. Looks like i will need to ask somewhere on an atmel forum. Although i am not sure how the Atmel could ack the nrf, if the 9th clock cycle is not present, but i have tried using a different master which has this 9th clock, and its still not working. I would like to use the newer driver, but based on our hardware and software requirements, and also the time, it is not possible for me to update the SDK and softdevice which is a shame. On newer things i will certainty be using the latest versions.

    I haven't yet tried the twi_hw_master on any other slaves yet only the sw version, perhaps i should also try this first!

  • After the master has clocked out the 8th bit and the clock is low, it just waits to see if the slave ACKs by pulling SDA low, it doesn't actually need to clock until it sees that, it can wait. This also gives slow slaves a little time to ACK. So a 9th clock pulse isn't necessary until SDA goes low for the ACK. In this case the Atmel doesn't pull low, so that's the end of the transaction.

    You said, right at the top, that the D09 is configured to accept any address. I still don't see an ASF example which does that. So you have ADDR 17..26 set to zero (that's ADDR.ADDRMASK), 1..10 set to 127 (that's ADDR.ADDR) and CTRLB.AMODE set to 0x02 to enable the range? Oh and 10bit addressing is off and GENCEN also off. If all those are the case then it should respond to any address. Most of the examples I've seen used a fixed address and there isn't even an I2C example for the D09 for some reason.

  • There is no example for the D09, but the hardware is there, and its near enough identical. I wish there was an example though. You are correct about the range, i have got it configured to address_mode_range, with mask as the bottom, and addr as the top, although i have tried both ways for the sake of it. even with a fixed address there is no ack. ten bit addressing is disabled, but i didn't think to check GENCEN, i will check that one later. There is no ASF example for this, i have modified it to do this. i am actually using a D10 currently, but there is very little difference between that and the D09 (an extra timer if i remember correctly), just there are no dev boards with the D09 yet, and all our boards will be using the D09 as it is cheaper. Thanks for clearing up the bit about the 9th clock, that was a bit confusing for me, as both the arduino and sw_master were producing it.

Related