So the title may not fully reflect the content of this post, but I tried to keep it short
So I'm in the process of building out an 8 bit parallel display driver for the Teensy Micromod using FlexIO2. Data is transmitted on FlexIO2 pins 4:11 and the WR on pin 0.
I almost have a proof of concept working, but for some reason I am getting an empty pulse on the WR pin just before it shifts out the data from Shifter0
The configuration for the shifter and timer has been taken from a few NXP demo code files that have implemented the same protocol to drive a display - one for the imxrt1050 and another for the KL28. The FlexIO peripheral works the same across these series from what I read.
Below is an example sketch of the FlexIO2 setup, the shifter config, the timer config and a function to transmit the data 1 byte at a time.
As can be seen in the image above, the WR pin is sending out one pulse as soon as the shifter buffer is loaded, which it shouldn't. It should only send a pulse when the data moves from the shifter buffer to the shifter.
Looking for suggestions on how to correct this issue - any input is appriciated!
David
So I'm in the process of building out an 8 bit parallel display driver for the Teensy Micromod using FlexIO2. Data is transmitted on FlexIO2 pins 4:11 and the WR on pin 0.
I almost have a proof of concept working, but for some reason I am getting an empty pulse on the WR pin just before it shifts out the data from Shifter0
The configuration for the shifter and timer has been taken from a few NXP demo code files that have implemented the same protocol to drive a display - one for the imxrt1050 and another for the KL28. The FlexIO peripheral works the same across these series from what I read.
Below is an example sketch of the FlexIO2 setup, the shifter config, the timer config and a function to transmit the data 1 byte at a time.
Code:
#include <Arduino.h>
#include "FlexIO_t4.h"
//#include "DMAChannel.h"
FlexIOHandler *pFlex;
IMXRT_FLEXIO_t *p;
const FlexIOHandler::FLEXIO_Hardware_t *hw;
//DMAChannel myDMA;
//volatile uint32_t DMAMEM dataBuffer[2] __attribute__((aligned(32)));
uint8_t bufferData[4] = {0x17, 0x07, 0x19, 0x90};
void FlexIO_Init(){
/* Get a FlexIO channel */
pFlex = FlexIOHandler::flexIOHandler_list[1]; // use FlexIO2
/* Pointer to the port structure in the FlexIO channel */
p = &pFlex->port();
/* Pointer to the hardware structure in the FlexIO channel */
hw = &pFlex->hardware();
/* Basic pin setup */
pinMode(10, OUTPUT); // FlexIO2:0
pinMode(40, OUTPUT); // FlexIO2:4
pinMode(41, OUTPUT); // FlexIO2:5
pinMode(42, OUTPUT); // FlexIO2:6
pinMode(43, OUTPUT); // FlexIO2:7
pinMode(44, OUTPUT); // FlexIO2:8
pinMode(45, OUTPUT); // FlexIO2:9
pinMode(6, OUTPUT); // FlexIO2:10
pinMode(9, OUTPUT); // FlexIO2:11
/* High speed and drive strength configuration */
*(portControlRegister(10)) = 0xFF;
*(portControlRegister(40)) = 0xFF;
*(portControlRegister(41)) = 0xFF;
*(portControlRegister(42)) = 0xFF;
*(portControlRegister(43)) = 0xFF;
*(portControlRegister(44)) = 0xFF;
*(portControlRegister(45)) = 0xFF;
*(portControlRegister(6)) = 0xFF;
*(portControlRegister(9)) = 0xFF;
/* Set clock */
pFlex->setClockSettings(3, 0, 0); // 480 MHz
/* Set up pin mux */
pFlex->setIOPinToFlexMode(10);
pFlex->setIOPinToFlexMode(40);
pFlex->setIOPinToFlexMode(41);
pFlex->setIOPinToFlexMode(42);
pFlex->setIOPinToFlexMode(43);
pFlex->setIOPinToFlexMode(44);
pFlex->setIOPinToFlexMode(45);
pFlex->setIOPinToFlexMode(6);
pFlex->setIOPinToFlexMode(9);
/* claim Shifter 0 */
pFlex->claimShifter(0);
/* claim Timer 0 */
pFlex->claimTimer(0);
/* Enable the clock */
hw->clock_gate_register |= hw->clock_gate_mask;
/* Enable the FlexIO with fast access */
p->CTRL = FLEXIO_CTRL_FLEXEN | FLEXIO_CTRL_FASTACC;
}
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) << 8) /* 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)));
{
}
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.print(CrashReport);
Serial.println("Start setup");
delay(1000);
FlexIO_Init();
delay(10);
}
void loop() {
singleBeatWrite(bufferData,4);
Serial.println("sent data");
delay(500);
}
As can be seen in the image above, the WR pin is sending out one pulse as soon as the shifter buffer is loaded, which it shouldn't. It should only send a pulse when the data moves from the shifter buffer to the shifter.
Looking for suggestions on how to correct this issue - any input is appriciated!
David