SAI demo in MQX

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SAI demo in MQX

Jump to solution
1,134 Views
kalden_srcinc
Contributor IV

Hello,

 

I am trying to get the SAI demo code running within an MQX task on a TWR-K64F120M.  The normal demo works fine, but in my own project which includes MQX, the first I2C register write causes a problem.  Stepping through with the debugger it just hangs at I2C_DRV_SendAddress.  Inside this function, the first call to I2C_HAL_WriteByte succeeds, but the second hangs.  interrupting in the debugger just shows it somewhere in the kernel.

 

Breakpoint 2, I2C_DRV_SendAddress (instance=0, device=0x1fff10a0 <g_codecHandler+4>, cmdBuff=0x1fff8e40 "", cmdSize=2,

    direction=kI2CSend, timeout_ms=4294967295)

    at KSDK_1.2.0/platform/drivers/src/i2c/fsl_i2c_master_driver.c:508

508         assert(instance < I2C_INSTANCE_COUNT);

(gdb) n

510         I2C_Type * base = g_i2cBase[instance];

(gdb) n

512         i2c_master_state_t * master = (i2c_master_state_t *)g_i2cStatePtr[instance];

(gdb) n

516         uint8_t addrBuff[2] = {0};

(gdb) n

517         uint8_t addrSize = 0;

(gdb) n

518         bool isMainXferBlocking = master->isBlocking;

(gdb) n

521         master->isRequesting = true;

(gdb) n

522         master->isBlocking = true;

(gdb) n

527         directionBit = (direction == kI2CReceive) ? 0x1U : 0x0U;

(gdb) n

530         is10bitAddr = ((device->address >> 10U) == 0x1EU) ? true : false;

(gdb) n

533         if (is10bitAddr)

(gdb) n

540             addrByte1 = (uint8_t)device->address;

(gdb) n

546         addrByte1 = addrByte1 << 1U;

(gdb) n

549         addrByte1 |= (uint8_t)((is10bitAddr || cmdBuff) ? 0U : directionBit);

(gdb) n

552         addrBuff[addrSize++] = addrByte1;

(gdb) n

554         if (is10bitAddr)

(gdb) n

561         master->txBuff = addrBuff;

(gdb) n

562         master->txSize = addrSize;

(gdb) n

565         I2C_HAL_WriteByte(base, addrBuff[0]);

(gdb) n

568         I2C_DRV_MasterWait(instance, timeout_ms);

(gdb) n

571         if ((master->status == kStatus_I2C_Success) && cmdBuff)

(gdb) n

573             master->txBuff = cmdBuff;

(gdb) n

574             master->txSize = cmdSize;

(gdb) n

577             I2C_HAL_WriteByte(base, *cmdBuff);

(gdb) n

580             I2C_DRV_MasterWait(instance, timeout_ms);

(gdb) n

^C

Program received signal SIGTRAP, Trace/breakpoint trap.

0x00014f76 in _int_default_isr (vector_number=0x3 <__isr_vector+3>)

    at KSDK_1.2.0/rtos/mqx/mqx/source/kernel/int.c:64

64          _GET_KERNEL_DATA(kernel_data);

 

I have also traced this through from the IRQ side.  I see I2C0_IRQHandler get called.  This makes it all the way down through I2C_DRV_CompleteTransfer and ultimately hangs inside OSA_SemaPost.  Diving into OSA_SemaPost leads me down into _lwsem_post where everything seems to work until it gets to _INT_ENABLE() and hangs.

 

I'm not really sure where to go from here, so any advice would be appreciated.

 

Thanks

Labels (1)
0 Kudos
1 Solution
739 Views
fnaeem
Contributor I

Renaming the ISR is what I believe you're supposed to do per this writeup:

How To: Using Interrupt Handlers in MQX with KSDK

View solution in original post

0 Kudos
4 Replies
739 Views
kalden_srcinc
Contributor IV

So I did the same thing with edma and i2s ISRs and now things seem to work.  It wasn't enough just to define my own copies of thes functions and not compile in the built in SDK versions.  I had to actually rename the ISR before things would start working.

I'm glad it works, but it doesn't seem like the proper fix.  Does anyone know what is really going on here?

0 Kudos
740 Views
fnaeem
Contributor I

Renaming the ISR is what I believe you're supposed to do per this writeup:

How To: Using Interrupt Handlers in MQX with KSDK

0 Kudos
739 Views
kalden_srcinc
Contributor IV

"However, when using MQX this is no longer possible as the MQX kernel requires those IRQHandler names for its own interrupt handling. It is therefore necessary for the application developer to use a different name for the peripheral driver IRQ handler. The convention used in KSDK is pre-append the IRQHandler name with MQX"

Well, I guess I need to read more of the MQX documentation.  Thanks for pointing me to that.

0 Kudos
739 Views
kalden_srcinc
Contributor IV

So it seems to be related to the interrupt handler.  I was using the I2C handlers defined in drivers/i2c/fsl_i2c_irq.c. I was able to get breakpoints to hit in these calls, so they seemed to be correct and even tried adding OSA_InstallIntHandler(I2C0_IRQn, I2C0_IRQHandler); for good measure.  Basically, If I compile in fsl_i2c_irq.c, no matter what I do, nothing works.

My solution was to create my own functionally equivalent copy of the interrupt handler and register it with manually:

void MQX_I2C0_IRQHandler(void) { I2C_DRV_IRQHandler(I2C0_IDX); }

...

OSA_InstallIntHandler(I2C0_IRQn, MQX_I2C0_IRQHandler);

This got me past configuration, but now I get a hangup on DMA.  I'm going to try manually registering those ISRs next.

0 Kudos