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.

DM6437 I2C: Run Non-Blocking (ASYNC) mode

Hello:

I am communicating with an I2C expander using the DSP/BIOS i2c driver.  My code is derived from pspdrivers_1_10_03\packages\ti\sdo\pspdrivers\system\dm6437\bios\evmDM6437\i2c

  GIO_AppCallback BlinkledCbk;
   if (m_isAsyncMode) {
     BlinkledCbk.fxn = (GIO_TappCallback)BlinkLedCalback;
     BlinkledCbk.arg = NULL;
   }
   Uint8 start=0u;
   buf.i2cTrans.buffer    = &start;
   buf.i2cTrans.bufLen    = 1u;
   buf.i2cTrans.flags     = PSP_I2C_DEFAULT_WRITE | PSP_I2C_RESTART;
   buf.i2cTrans.param     = NULL;
   buf.i2cTrans.slaveAddr = m_slaveAddress;
   buf.timeout            = SYS_FOREVER;
   size                   = (size_t)buf.i2cTrans.bufLen;
   if (!m_isAsyncMode)  
     retCode = GIO_submit(m_i2cHandle,IOM_WRITE,&buf,&size,NULL);
   else
     retCode = GIO_submit(m_i2cHandle,IOM_WRITE,&buf,&size,&BlinkledCbk);

The code / driver works for me when I execute it in blocking mode but does not work when I run it in non-blocking (async) mode.

The call to GIO_submit() returns 1 (PENDING?),  whereas the blocking mode returns 0. 

The callback function that I pass in is never called.

Any ideas what may be happening?  Do I need to set up interrupts or something?

Thanks

--B

  • Hi:

    I noticed the following LOG message in the when running the GIO_SUBMIT.  I am running this from the echo TSK just like the example code.  However I have changed the files to be C++?

    • 0 TSK: ready dynamic TSK (0x81024dd4)
    • 1 TSK: ready echoTask (0x81024e34)
    • 2 SWI: begin KNL_swi (TSK scheduler) (0x81024f98)
    • 3 TSK: running echoTask (0x81024e34)
    • 4 SWI: end KNL_swi (TSK scheduler) (0x81024f98) state = done
    • 5 SEM: post <unknown handle> (0x8101fcfc) count = 0
    • 6 SEM: post <unknown handle> (0x8101fcfc) count = 0
    • 7 SEM: post <unknown handle> (0x8101fcfc) count = 0
    • 8 SEM: post <unknown handle> (0x8101fcfc) count = 0
    • 9 CLK: current time = 1 (0x00000001)
    • 10 PRD: tick count = 1 (0x00000001)
    • 11 SWI: post KNL_swi (TSK scheduler) (0x81024f98)
    • 12 SWI: begin KNL_swi (TSK scheduler) (0x81024f98)
    • 13 SWI: end KNL_swi (TSK scheduler) (0x81024f98) state = done
    • 14 CLK: current time = 2 (0x00000002)
    • 15 PRD: tick count = 2 (0x00000002)
    • 16 SWI: post KNL_swi (TSK scheduler) (0x81024f98)
    • 17 CLK: current time = 3 (0x00000003)
    • 18 PRD: tick count = 3 (0x00000003)
    • 19 CLK: current time = 4 (0x00000004)
    • 20 PRD: tick count = 4 (0x00000004)
    • 21 CLK: current time = 5 (0x00000005)
    • 22 PRD: tick count = 5 (0x00000005)
    • 23 CLK: current time = 6 (0x00000006)
    • 24 PRD: tick count = 6 (0x00000006)
    • 25 SYS abort called with message '*** MEM lock NOT CALLED IN TSK CONTEXT'

     

  • Hi Bandeg,

     

    The Sample application which comes with the PSP package, executes in non-blocking(async) mode by default. Have you tried running this sample application directly?. If not, please try this.

    Secondly, Are you using a EVM or a custom board?. Are you communicating with the same slave device the I2c PSP sample app is communicating?.

     

     

    Thanks & regards,

    Raghavendra

  • Okay.

    I may have fixed that problem with the SYS Abort.  I had added a "printf" statement inside the callback that BIOS must not be happy with. 

    Back to the original question.

    "The code / driver works for me when I execute it in blocking mode but does not work when I run it in non-blocking (async) mode"

    My code seems to operate correctly when running on the EVM (blocking and non-blocking)

    When I run in non-blocking mode on our own Hardware, which uses the NXP PCA9674A as slave, I don't seem to get a callback.

    (I suspect that the blocking call to the driver is flakey since I have seen it also stall on occasion).

    http://ics.nxp.com/products/pca/all/~PCA9674A/

    Thanks

    --B

  • Hi Bandeg,

     

    Since you are using your own hardware, can you please check if you are Initialization all the parameters appropriately in the i2cParams_evmdm6437.c file?. 

     

    Bandeg said:
    (I suspect that the blocking call to the driver is flakey since I have seen it also stall on occasion)

    So, the sync mode does not work?

     

     

    Well, I would like to suggest two experiments here:

    1. Try placing a breakpoint in the DDC_i2cIntrHandler(...) function placed in ddc_i2c.c file and check if this hits when run in both async and sync mode.

    2. When calling GIO_submit, set some timeout value instead of "SYS_FOREVER" and check its behaviour.

     

    Please try this, and let me know the results..

     

    Thanks & regards,

    Raghavendra

  • Thanks

    Looking at this closer I realized that I may have a problem with timing between calls.

    The first call does complete successfully.  There is a problem with the next call.   On my system the I2C operation is sending more data than one byte as in the blink LED example.  So my attempts to extend the blink delay were not sufficiently long enough.

    So I rewrote the non-blocking case to have the callback free a binary semaphore (SEM_post()) and the next call pend that semaphore.

    It seems to be working, I will continue to test.    Here is one last question on this topic.  

    Is it okay (with BIOS) to have the callback modify a semaphore using SEM_post() or do I need to find some other way to do this.   Is there documentation about what can and what cannot be called from a callback from the GIO drivers?   { no printf()s etc}

    Regards,


    --B

  • Hi Bandeg,

     

    Bandeg said:
    s it okay (with BIOS) to have the callback modify a semaphore using SEM_post()

    Yes, It should be ok..

     

    Thanks & regards,

    Raghavendra