I'm trying to get an 8080 MCU LCD working on the FlexIO interface on an IMXRT1050. It looks like data is clocking out correctly for the most part however I'm having trouble with the WR and RD pins. They are resting low, then rising just before clocking out data. So I'm getting extra zeros in my data stream. Any ideas?
I seem to be facing the exact same issue on a Teensy Micromod using an RT1062 - this is an Arduino friendly rt1062 by PJRC/SparkFun.
Although I am not using the official NXP demo code, I have based the configuration of the FlexIO module, shifter and timer in an identical manner to the HX8357 NXP example for the KL28/RT1050 (AN5313/AN12822), and I am also getting an early pulse on the WR as soon as the shifter is loaded on a single beat transmit
My code looks like so:
Shifter/timer setup:
void singleBeatWrite(uint8_t const * buffer, uint32_t const length){
p->CTRL &= ~FLEXIO_CTRL_FLEXEN;
//p->CTRL |= FLEXIO_CTRL_SWRST; //Software reset FlexIO registers enable
//p->CTRL &= ~FLEXIO_CTRL_SWRST; //Software reset FlexIO registers disable
/* Configure the shifters */
p->SHIFTCFG[0] =
FLEXIO_SHIFTCFG_INSRC /* Shifter input */
| FLEXIO_SHIFTCFG_SSTOP(0U) /* Shifter stop bit disabled */
| FLEXIO_SHIFTCFG_SSTART(0U) /* Shifter start bit disabled and loading data on enabled */
| FLEXIO_SHIFTCFG_PWIDTH(8U-1U); /* Bus width */
p->SHIFTCTL[0] =
FLEXIO_SHIFTCTL_TIMSEL(0U) /* Shifter's assigned timer index */
| (0<<23) //FLEXIO_SHIFTCTL_TIMPOL(0U) /* Shift on posedge of shift clock */
| FLEXIO_SHIFTCTL_PINCFG(3U) /* Shifter's pin configured as output */
| FLEXIO_SHIFTCTL_PINSEL(4U) /* Shifter's pin start index */
| (0<<7) //((uint32_t)(1<<7)) /* Shifter's pin active high */
| FLEXIO_SHIFTCTL_SMOD(2U); /* Shifter mode as transmit */
/* Configure the timer for shift clock */
p->TIMCMP[0] =
((1U * 2U - 1) << /* TIMCMP[15:8] = number of beats x 2 – 1 */
| (40U/2U - 1U); //(4U/2U - 1U) /* TIMCMP[7:0] = baud rate divider / 2 – 1 */
p->TIMCFG[0] =
FLEXIO_TIMCFG_TIMOUT(0U) /* Timer output logic one when enabled and not affected by reset */
| FLEXIO_TIMCFG_TIMDEC(0U) /* Timer decrement on FlexIO clock, shift clock equals timer output */
| FLEXIO_TIMCFG_TIMRST(0U) /* Timer never reset */
| FLEXIO_TIMCFG_TIMDIS(2U) /* Timer disabled on timer compare */
| FLEXIO_TIMCFG_TIMENA(2U) /* Timer enabled on trigger high */
| FLEXIO_TIMCFG_TSTOP(0U) /* Timer stop bit disabled */
| (0<<1); //((uint32_t)(0<<1)) //FLEXIO_TIMCFG_TSTART(0U); /* Timer start bit disabled */
p->TIMCTL[0] =
FLEXIO_TIMCTL_TRGSEL((((0U) << 2) | 1U)) /* Timer trigger selected as shifter's status flag */
| (1<<23) //FLEXIO_TIMCTL_TRGPOL(1U) /* Timer trigger polarity as active low */
| (1<<22)//FLEXIO_TIMCTL_TRGSRC(1U) /* Timer trigger source as internal */
| FLEXIO_TIMCTL_PINCFG(3U) /* Timer' pin configured as output */
| FLEXIO_TIMCTL_PINSEL(0) /* Timer' pin index: WR pin */
| (1<<7) //FLEXIO_TIMCTL_PINPOL(1U) /* Timer' pin active low */
| FLEXIO_TIMCTL_TIMOD(1U); /* Timer mode as dual 8-bit counters baud/bit */
/* Enable FlexIO */
p->CTRL |= FLEXIO_CTRL_FLEXEN;
if(length)
{
/* Use polling method for data transfer */
for(uint32_t i=0; i<length-1U; i++)
{
while(0 == (p->SHIFTSTAT & (1U << 0U)))
{
}
p->SHIFTBUF[0U] = *buffer++;
}
/* Write the last byte */
while(0 == (p->SHIFTSTAT & (1U << 0U)))
{
}
p->TIMSTAT |= (1U << 0U);
p->SHIFTBUF[0U] = *buffer++;
/*Wait for transfer to be completed */
while(0 == (p->TIMSTAT & (1U << 0U)));
{
}
}
}
I then call this function from my main loop ever 500ms by calling singleBeatWrite and passing the data
uint8_t bufferData[4] = {0x17, 0x07, 0x19, 0x90};
...
singleBeatWrite(bufferData,4);
Hi Luke,
This looks like a very custom approach. It will totally depend on your FlexIO configuration. I highly recommend you to check the below community document. Even though the document is for KL43 devices, the FlexIO modules works the same in RT devices.
https://community.nxp.com/docs/DOC-105640
Hope it helps!
Best regards,
Felipe
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
So what is causing my issue is that the value on my RW pin is changing when FLEXIO_MCULCD_SetSingleBeatWriteConfig(base) is called and then dropping again when FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base) is called.
One option I've tried is to refactor FLEXIO_MCULCD_WriteCommandBlocking to set the config first, the pin rises, then call FLEXIO_MCULCD_StartTransfer(base) so my CS pin gets set. Then do the opposite at the end of the function. This way my lcd driver should ignore those extra transitions on the WR line.
I would also need to do similar refactoring for the other read/write functions.
Although I should mention that I am measuring these signals straight out of the MCU and one of my coworkers mentioned that the LCD Driver may hold these lines up anyway and this whole issue will be moot.
Hi Luke,
There is some material that I can recommend you to take as reference. You can find driver and demo project in the SDK package of a board supports the demo, such as FRDM-K28F. Unfortunately, we do not have this example for RT1050 devices but you can take it as reference.
In addition, I suggest you to check this application note that explains how to use the FlexIO module to emulate 8080 bus interface. Also this link mentions the typical usage of FlexIO LCD APIs.
I hope this information helps you.
Best regards,
Felipe