I2C comms interfering with float sprintf?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
AmCi_3754291
Level 2
Level 2

I'm having this weird issue in which my float prints get messed up when I print after running I2C commands! I've done the heap changes [now set 0x1000] and set the -u_printf thing to true. When I simply try to print out a float value it works fine, but when I add my I2C functions my float prints get messed up.

Please See attached pictures of what I'm seeing when I run just printing out floats vs printing out float after receiving I2C data packet (the I2C data packet has nothing to do with the float I'm spitting out).

I've also attached my project. The difference between the 2 terminal outputs are coming from commenting and uncommenting the BNO080_dataAvailable function

Has anyone seen this before? Is there anything I'm missing?

Thanks

Amilcar

0 Likes
1 Solution
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Amilcar,

I've tried to run the project you've provided.  I have to comment out in main():

BNO080_begin(0x4B);

BNO080_enableRotationVector(50);

otherwise the code gets stuck.

With this change the code:

sprintf(Buff,"changed acceleration=%f\r",x);

UART_PutString(Buff);

get executed with no issue as you described.

Without actually having the BNO080 with the i2C interface, it will be difficult for the community to actually run the code with the issue.

First off,  you are always using UART_PutString(Buff) to communicate with the comm device.  This is fine.  It is a "blocking" function as you are using it.  This means that if the Buff has one byte or 1000 bytes to transfer, it will stay in this code until the last byte is transferred from Buff.  However, it does not prevent interrupts from being serviced.  Therefore the fact that the comm output is aborted early, makes me think either the code in UART_PtuString() is being fooled that the string transfer is completed or Buff is being modified by the I2C code to see a '\0' (NULL) which is the official string termination.

UART_PutString() snippet:

/* This is a blocking function, it will not exit until all data is sent */

while(string[bufIndex] != (char8) 0)

Suggestion #1:

Since the issue appears and the output appears to be 'clipped' consistently with "changed acceleration=0xFF", there appears to be a timing related issue going on here.  I suspect the 100KHz frequency operation of your I2C is effectively cross-synchronizing with the UART operation.

If this is true, then changing the base frequency of the I2C or the UART will NOT fix the problem but produce a change in the comm output.

For example, change the UART baud rate from 9600 to 115200.  If I'm correct, more of the comm output will come out correctly because the comm will process the Buff faster before it 'collides' with the I2C operation causing the issue.  (Note:  If ALL the comm output is corrected by increasing the baud rate,  do not be lulled into think the issue is fixed. it is NOT.  Since you are using UART_PutString() as a blocking function, whatever is 'corrupting' the comm output potentially still exists.)

Conversely, if you lower the UART baud rate to 4800, the comm output issue should appear sooner and the output will corrupt earlier.  You can chose to lower the I2C frequency from 100KHz, it should give the equivalent of increasing the UART baud rate.  I think you get the pattern.

Personally, since you are using UART_PutString() in a blocking mode, I'm suspecting the issue is being caused a the interrupt level probably the I2C component.  This is based on the fact that if the I2C is active: ISSUE.  If the I2C is inactive: NO ISSUE.

Using this suggestion hopefully will quickly isolate the issue to cross-synchronicity between the UART and I2C components.  It doesn't t solve the issue but should reduce the sections of code to debug.

Suggestion #2 is a bit more complicated but may aid in finding the root cause of the issue.

Suggestion #2:

Since I (and others) will have difficulty actually running your application, I recommend you place some debugging code that uses pin signalling.  For example, if using the comm port is not practical (or already in use), I use a "framing" technique.  The "framing" technique is where you assign an output pin to go high when entering a function and go low when exiting the function.  This allows the designer to view the timing of a function with a scope.

With the "framing" technique, you can toggle the signal pin when you reach a specific place in the code.  You can also allocate many output pins for different places in the code.

The PSoC has the ability to route internal HW signals directly to pins.  For example, the UART can be set to set a tx_interrupt on:

pastedImage_4.png

Chose one at a time and set the tx_interrupt to an output pin.  Monitor the output pin to verify proper operation.  For example, using UART_PutString()

TX -On Tx Complete should only occur when UART_PutString() returns when ALL Buff is transferred on the port.

TX - On FIFO Empty should only occur when the LAST BYTE of Buff is about to be transferred.

TX - On FIFO Full should go on when the first four bytes of Buff are placed in the Tx FIFO.  It should toggle every time a byte is being transferred on the comm line.  It should turn off when the last four bytes of Buff are to be transferred on the comm line.

TX - On FIFO Not Full is effectively the inverse logic of TX - On FIFO Full.

The process of debugging to find the root cause of any issue can be time-consuming.  However, I personally find it rewarding because in the process of a systematic execution of debugging, I learn more about my design, the design contributed by others (Cypress components for example) and overall System design.  The end result should be finding the root cause and becoming a better engineer.  All my previous debugging exercises have informed my future designs.  It allows me to better predict potential issues better before placing the design on paper.  It informs me better of the limitations and "traps" in certain design choices.

Amilcar, I realize this issue is a hassle.  My experience indicates that the PSoC5 is a very solid product with great functionality.  I applaud your choice.  Stick it out in the debugging process.  We in the community will help you if possible.  However, with out having your specific design, it does poses a challenge.

To the Community:

For us in the community, can someone can suggest a way to 'simulate' the I2C device (BNO080 = https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=2ahUKEwjFwMj3yunkAhVRiqwKHb22Dmc... with functional stubs to reproduce Amilcar's issue?

Len

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
10 Replies