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

Garbled I2C unless printf is used

Hi,

I have a very odd problem but one which is consistent.

As part of my lcd library I send several ''packets' of data interleaved with spacing from a timer. It typically looks like -

6 bytes - 50us - 6 bytes - 50us - 6 bytes ...

A second timer works in counter mode and is used to stop the transmission once the requisite amount of bytes are sent. It works well.

Now, the command that kicks such a process off (the data is held in a buffer) is this -

void lcdTransactionEnd (void) {
  
  if (dmaBuffer.writeBuffer->writeLocked) {
    dmaBuffer.writeBuffer->writeLocked = 0;
  }
  if (dmaBuffer.transferBuffer->size && ! dmaBuffer.transferBuffer->txLocked) {
    printf("transfering \n");
    __startTransfer();
  }
}


and startTransfer is

static void __startTransfer (void) {

  dmaBuffer.transferBuffer->txLocked = 1;
  CFG_TWIM_LCD_TX->TXD.PTR = (uint32_t) &dmaBuffer.transferBuffer->data[0];
  CFG_TWIM_LCD_TX->TXD.MAXCNT = dmaBuffer.transferBuffer->packetSize;
  CFG_TIMER_LCD_COUNTER->CC[0] = dmaBuffer.transferBuffer->size / dmaBuffer.transferBuffer->packetSize;
  //printf("tx %d, %d \n", dmaBuffer.transferBuffer->size, dmaBuffer.transferBuffer->packetSize);
  CFG_TWIM_LCD_TX->TASKS_STARTTX = 1;
}


Now here's the thing. In the ledTransactionEnd there is a printf statement. If I remove this statement I get garbage (or data corruption) over I2C. I thought maybe I have a timing issue, so I replaced it with various nrf_delay_ms values and that had no effect. I have absolutely no idea how using printf can cause this to happen but it's repeating every time.

Any ideas most welcome!

Parents
  • Hi

    One thing to check is whether or not the data buffer provided to the TWIM PTR register is static or global, or if it is an automatic stack variable that could be overwritten by other data once you return from the function where it was defined. 

    This could explain why the printf call solves the issue, since it might delay the time before you return from the function so that the data is written to the I2C bus before the stack memory gets reused. 

    Best regards
    Torbjørn

Reply
  • Hi

    One thing to check is whether or not the data buffer provided to the TWIM PTR register is static or global, or if it is an automatic stack variable that could be overwritten by other data once you return from the function where it was defined. 

    This could explain why the printf call solves the issue, since it might delay the time before you return from the function so that the data is written to the I2C bus before the stack memory gets reused. 

    Best regards
    Torbjørn

Children
Related