LPC4370 SGPIO one-shot madness.

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

LPC4370 SGPIO one-shot madness.

479 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by David Lee on Fri Jun 06 13:53:29 MST 2014
I've configured a few slices to generate a custom serial interface. It has typical stuff like CHIP_SELECT, SERIAL_CLOCK, DATA, etc.
It runs in one-shot mode, sending a data payload of 24 bits. The single transmission is controlled according to the documentation
in the user manual (UM10503.PDF) Sec. 19.6.17.

It worked solid as a rock during testing with a simple data pattern like 0x00AA00AA.

So I decided to test it by sending random data payloads and I noticed on my scope that infrequently, the slices fail
to stop after 1 "cycle". That is to say, I see two transmission sequences back to back. Yuck! The failure is data dependent!!!???

I am starting the slices like this:


Quote:
// Start SGPIO operation by enabling slice clocks.
LPC_SGPIO->CTRL_ENABLED = m_controlMask;
//We only want 1 countdown cycle (1 transmission) so this will stop when POS reaches zero.
LPC_SGPIO->CTRL_DISABLED = m_controlMask;



This is the recommended process from Sec. 19.6.17.

In desperation, I tried reversing the order, in contradiction to Sec. 19.6.17:

Quote:
//Try setting CTRL_DISABLE BEFORE CTRL_ENABLE. This contradicts 19.6.17 in user manual!
//We only want 1 countdown cycle (1 transmission) so this will stop when POS reaches zero.
LPC_SGPIO->CTRL_DISABLED = m_controlMask;
// Start SGPIO operation by enabling slice clocks.
LPC_SGPIO->CTRL_ENABLED = m_controlMask;



The result is rock solid transmission with NO observable anomalous transmissions.

I would be grateful for help with this issue. I really, really do not like getting code to work by swapping the order
of commands willy nilly. Especially when it directly contradicts the documentation.

A little help?

Cheers,
David

Note. There's a typo in Sec 19.6.17:

Quote:
this register should always be cleared. If
only on POSi countdown is needed



should read:

Quote:
this register should always be cleared. If
only one POSi countdown is needed

Labels (1)
0 Kudos
4 Replies

402 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by David Lee on Mon Jun 09 06:52:53 MST 2014
JohnR,
Right! That reminds me, I may have swapped the recommended order of the register setups at the initialization stage too.
I'll look at my code and follow up. Thanks for the reply!

DPeters,
Good point. The re-transmissions I'm seeing are not data-dependent (that would be evil) but are, as you imply, timing dependent.
Nice insight. I will play with the timing of my loop, and perhaps disable interrupts to verify.

xianghuiwang,
Thank you for the reply. Errors in the User Manual are inevitable. But when all work together, as in this forum, we produce
better tools, products, and a better community. Nicely done, sir.

Cheers,
David
0 Kudos

402 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DPeters on Sat Jun 07 22:44:19 MST 2014
The documentation was confusing for me too.

If the recommended order is followed, there is a chance the CPU will get interrupted by IRQ, or if a pre-emptive OS task swap happens between:

LPC_SGPIO->CTRL_ENABLED = m_controlMask;

and:

LPC_SGPIO->CTRL_DISABLED = m_controlMask;

Then, if the SGPIO is clocking with any speed at all, POS reaches zero before the second instruction is executed while the CPU is off doing something else.  I think this is what David was experiencing with the double transmissions.  To me, it makes more sense to reverse the instructions, despite user manual explicitly stating in UM Rev 1.8 sec 19.6.17, Slice count disable register :


Quote:
When starting COUNTi (by setting CTRL_ENi), this register should always be cleared. If
only on POSi countdown is needed (when only one slice should be processed), then [CTRL_DISi]
register should be set after COUNTi is started with register CTRL_ENi.

(bold emphasis and [ ] mine)

But maybe there is some reason for the recommended order that has to do with internal workings of the peripheral.  But it would be very beneficial for our current project to get confirmation from NXP that reversing the instruction order is OK.
0 Kudos

402 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by JohnR on Sat Jun 07 05:44:54 MST 2014
Hi David,

More or less by chance some time ago, I came up with the same solution as yours.

Thus in my SGPIO_POS_IRQHandler():

SGPIO_POS_IRQHandler()
{
LPC_SGPIO->CTR_STATUS_1 = 1<<D;
while(LPC_SGPIO->STATUS_1 & 1<<D);// wait for status to clear

LPC_SGPIO->CTRL_ENABLED = 0;
       LPC_SGPIO->CTRL_DISABLED = 0;

// >REG[H chip select
LPC_SGPIO->REG[H] = 0x20001;

// REG[N] data
LPC_SGPIO->REG[N]  =    ;
......................................
.......................................

LPC_SGPIO->SET_EN_1 =  (1L <<  D);
LPC_SGPIO->CTRL_ENABLED =  (1L <<  H) | (1L <<  D) | (1L <<  N);
LPC_SGPIO->CTRL_DISABLED = (1L <<  H) | (1L <<  D) | (1L <<  N);
}

I have never understood why both registers need to be updated and in this order. Maybe NXP could provide the reason.

John.

0 Kudos

402 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by xianghuiwang on Fri Jun 06 18:23:05 MST 2014
Hi, David,
Your observation makes sense if you want to do single shot. We will do some more validation and update the user manual in this regard.
Thanks,
0 Kudos