Call to arms | Teensy + SDRAM = true

Just received the sdram development board today:D I ran through all of the test programs that I know about without a problem. I need to make sure I have all of the pinout info for this board. It is a version 4 board.
DevBoard.jpg


I thought I would start out simple and get the 4-bit VGA working first. More to learn I guess😋
 
Awesome it arrived and works! V4.0 is the same so far as all else here.

See this post on prior page: https://forum.pjrc.com/index.php?threads/call-to-arms-teensy-sdram-true.73898/post-340933

If you get any SDRAM integrity issues that lone cap 'above' the MCU can come off. Mine came off quickly so not sure it interferes at spec speed if running at 166 MHz?
Thanks, I do have that document. I ran the oneScanCaps.ino sketch and most of the frequencies had no errors. Interestingly enough 166MHz had one error. I am not sure which cap DQS has on the board. I can barely see it even with a magnifying glass:D Amazed you guys could change it...
 
In the pic above it is the SPEC below the red squiggle here over the 1062
1712630522984.png
1712630645505.png

Not so small if you zoom in :) - next to organic sugar and Kosher salt.

Add flux or put solder blob on solder tip maybe and it should wipe away easily enough and then 166 MHz should come out good with oneScanCaps.ino.
 
The solder paste used on these boards are high temp 260c, it's actually very good solder. But to get something off you need a good iron and some flux. Or add a little more solder paste from a siringe (the latter is the best and easiest option).

Plus side: Components sit really well and gives a good quality and life.
Down side: A pain to solder.
 
First simple experiment on SDRAM board works. Adapted my 4-bit VGA library based on @jmarsh's driver to the dev board. Just had to change two pin defines for FlexIo2 for HSYNC and VSYNC which is used in several places in the FlexIO begin method. The RGBI pins are the same for the T41, MicroMod and dev board.
SDRAM_Board_4bit_VGA.jpg


I setup some defines for the pin defines in the config file to make it easier to change to the different boards.
Code:
//=====================================
// Physical pin and FlexIO pin Defines.
// Defined for T41, MicroMod and SDRAM
// dev board V4.0.
//=====================================
// Common Pins
#define RED_PIN 11
#define GRN_PIN 12
#define BLU_PIN 10
#define INTENSITY_PIN 13

// FlexIO2 Pins
#if defined(ARDUINO_TEENSY41)
#define VSYNC_PIN 34
#define HSYNC_PIN 35
#define FLEX_VSYNC_PIN 29
#define FLEX_HSYNC_PIN 28
#else // MicroMod and Dev Board V4.0
#define VSYNC_PIN 8
#define HSYNC_PIN 7
#define FLEX_VSYNC_PIN 16
#define FLEX_HSYNC_PIN 17
#endif
//=====================================

Next step is testing use of the SDRAM as a frame buffer...
 
I setup some defines for the pin defines in the config file to make it easier to change to the different boards.
I ended up just "brute forcing" the pin mux initializations using the IMXRT pin names, so it doesn't matter what their Teensy pin numbers are:
Code:
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_02 = 4; // FLEXIO2_D2    RED
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_01 = 4; // FLEXIO2_D1    GREEN
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_00 = 4; // FLEXIO2_D0    BLUE
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 4; // FLEXIO2_D3    INTENSITY
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_13 = 4; // FLEXIO2_D29   VSYNC
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_12 = 4; // FLEXIO2_D28   HSYNC

There is one thing that the micromod / devboard can do that isn't possible on a regular Teensy: the low-intensity "yellow" color (red+green) is actually meant to be brown, which would be red + green intensity (no green though). This requires the green channel to have its own separate intensity output, controlled by a shifter stage in logic mode. Logic shifters can only output on FlexIO pins 4-7,12-15 so they're not usable on a regular Teensy.
 
Last edited:
I also tried getting the monitor's EDID info over DDC (which is just I2C), to auto-choose the best resolution... turns out VGA monitors have 5V pull-ups built-in meaning voltage shifters are needed, and mine didn't want to work properly at the time so I gave up on that.
 
I also tried getting the monitor's EDID info over DDC (which is just I2C), to auto-choose the best resolution... turns out VGA monitors have 5V pull-ups built-in meaning voltage shifters are needed, and mine didn't want to work properly at the time so I gave up on that.
Thanks for the info and link above. I now have it working with external sdram. It seems to work ok up to 270MHz with a 1280x720 frame buffer.
1280x768_Random_8x16.jpg


Excuse my shakey picture:) I still am not using double buffering like in your original sketch but it is setup to use it.
Code:
#if defined(USE_SDRAM_DEV)
SDRAM_t4 sdram;
static uint8_t *frameBuffer0 = (uint8_t*)sdram_malloc((MAX_HEIGHT+1)*(MAX_WIDTH+STRIDE_PADDING) * sizeof(uint8_t));
static uint8_t *frameBuffer1 = (uint8_t*)sdram_malloc((MAX_HEIGHT+1)*(MAX_WIDTH+STRIDE_PADDING) * sizeof(uint8_t));
static uint8_t* const s_frameBuffer[2] = {frameBuffer0, frameBuffer1};
#else
DMAMEM uint8_t frameBuffer0[(MAX_HEIGHT+1)*(MAX_WIDTH+STRIDE_PADDING)];
static uint8_t* const s_frameBuffer[1] = {frameBuffer0};
#endif

I added enough pins on my VGA adapter board to be able to access the EDID pins but did not route them. Good to know about the 5V pull-ups. Could have fried a Teensy😬 Can't remember if I downloaded "SDRAM_EXTMEM" library or not. Will have to check.

Now for more exploring...

EDIT - This is also nice to see:
Code:
Memory Usage on Teensy MicroMod:
  FLASH: code:58800, data:16380, headers:8784   free for files:16431108
   RAM1: variables:19072, code:40504, padding:25032   free for local variables:439680
   RAM2: variables:16512  free for malloc/new:507776
 
Last edited:
@jmarsh - Tested the elcdif sketches. Impressive:D Did not realize the mandelbrot sketch was animated.

elcdif_dev_board.jpg


Now to hook up the 10.1" LCD and test...

EDIT: By the way the T41 on the breadboard is the first T41 I got from PJRC. It has the white jumper wire fix for the 3.3V pin.
 
seems to work ok up to 270MHz
Running the SDRAM at 270 MHz?

For T_3.6 there was a PCB here wired with resistors to VGA - wonder if it works with the current scheme?

What SDRAM Lib is in use? The one derived from Paul's work on the @mjs513 github or the work @jmarsh did that split off from that and wasn't tested here at all.
 
Running the SDRAM at 270 MHz?

For T_3.6 there was a PCB here wired with resistors to VGA - wonder if it works with the current scheme?

What SDRAM Lib is in use? The one derived from Paul's work on the @mjs513 github or the work @jmarsh did that split off from that and wasn't tested here at all.
Hi Defragster - I am using @jmarsh's SDRAM_EXTMEM library. I only had to modify one sketch that was setup for the T41. The rest of them work out of the box. The sketch that I modified was "flexio_vga.ino" which basically just changed the VSYNC and HSYNC pins from 34 and 35 to 16 and 16 on the dev board. Here is the pinout:
Code:
//==============================================
// Original version of the 4 bit VGA DAC ladder.
//==============================================
/* R2R ladder:
 *
 * GROUND <------------- 536R ----*---- 270R -----*---------> VGA PIN: Red pin 1
 *                                |               |
 * INTENSITY (13) <---536R -------/               |
 *                                                |
 * T4-11 <---536R --------------------------------/
 *
 * GROUND <------------- 536R ----*---- 270R -----*---------> VGA PIN: Green pin 2
 *                                |               |
 * INTENSITY (13) <---536R -------/               |
 *                                                |
 * T4-12 <---536R --------------------------------/
 *
 * GROUND <------------- 536R ----*---- 270R -----*---------> VGA PIN: Blue pin3
 *                                |               |
 * INTENSITY (13) <---536R -------/               |
 *                                                |
 * T4-10 <---536R --------------------------------/
 *
 * VSYNC (16) <---------------68R---------------------------> VGA PIN 14 - T4 pin 16
 *
 * HSYNC (17) <---------------68R---------------------------> VGA PIN 13 - T4 pin 17
 */

The other sketches use this pinout:
Code:
/* R2R ladder:
 *
 * GROUND <------------- 536R ----*---- 270R ---*-----------> VGA PIN (1/2/3)
 *                                |             |
 * INTENSITY (7/8/7) <---536R ----/             |
 *                                              |
 * COLOR (6/32/9)  <-----536R-------------------/
 */

which is a condensed version of the above pinout but with different pin numbers used on the DEV board. I cloned and modified the library and it can be found here.
The other Library of mine can be found here but has not been updated yet for the DEV board. Will update it tomorrow.

I am now working on getting The 10.1" ER-TFTM101-1 lcd working with the DEV board in 8080 16-bit mode with DMA:)

@all concerned, does this pinout look right for thee DEV board?:

Code:
FlexIO2         Dev Board         ER-TFTM101-1 Pin
2:00 -----------> B0_00 -----------> D0 ----> 15
2:01 -----------> B0_01 -----------> D0 ----> 16
2:02 -----------> B0_01 -----------> D0 ----> 17
2:03 -----------> B0_01 -----------> D0 ----> 18
2:04 -----------> B0_01 -----------> D0 ----> 19
2:05 -----------> B0_01 -----------> D0 ----> 20
2:06 -----------> B0_01 -----------> D0 ----> 21
2:07 -----------> B0_01 -----------> D0 ----> 22
2:08 -----------> B0_01 -----------> D0 ----> 23
2:09 -----------> B0_01 -----------> D0 ----> 24
2:10 -----------> B0_01 -----------> D0 ----> 25
2:11 -----------> B0_01 -----------> D0 ----> 26
2:12 -----------> B0_01 -----------> D0 ----> 27
2:13 -----------> B0_13 -----------> D0 ----> 28
2:14 -----------> B0_14 -----------> D0 ----> 29
2:15 -----------> B0_15 -----------> D0 ----> 30
2:16 -----------> B1_00 -----------> /WR ---> 05
2:17 -----------> B1_01 -----------> /RD ---> 06
2:18 -----------> B1_02 -----------> /CS ---> 07
2:19 -----------> B1_03 ----------->  RS ---> 08
2:20 -----------> B1_04 -----------> WINT --> 09
2:21 -----------> B1_05 -----------> /RST --> 11
2:22 -----------> B1_06
2:23 -----------> B1_07
2:24 -----------> B1_08
                                     BL_CTL -> 14
                                     GND ----> 1,2,13,31,39,40
                                      5V ----> 3,4,37,38

Thanks
 
The sketch that I modified was "flexio_vga.ino" which basically just changed the VSYNC and HSYNC pins from 34 and 35 to 16 and 16 on the dev board.
I'm not really sure why this is necessary? Both boards have B1_12 & B1_13 and they're not referred to by Teensy pin number (only their pin matrix code and FlexIO ID), so making them dependent on the platform doesn't make much sense to me.

Ideally, what should be used:
- HSYNC output on B0_02 (FLEXIO2_02 / ELCDIF_HSYNC)
- VSYNC output on B0_03 (FLEXIO2_03 / ELCDIF_VSYNC)
- RED output on B1_00 (FLEXIO2_16 / ELCDIF_DATA12)
- GREEN output on B1_01 (FLEXIO2_17 / ELCDIF_DATA13)
- BLUE output on B1_02 (FLEXIO2_18 / ELCDIF_DATA14)
- INTENSITY output on B1_03 (FLEXIO2_19 / ELCDIF_DATA15)

This config would enable programs to use either FlexIO2 or eLCDIF to produce 4-bit VGA output without any rewiring, and both T4.1 and micromod/devboard have all the pins required.
 
I'm not really sure why this is necessary? Both boards have B1_12 & B1_13 and they're not referred to by Teensy pin number (only their pin matrix code and FlexIO ID), so making them dependent on the platform doesn't make much sense to me.

Ideally, what should be used:
- HSYNC output on B0_02 (FLEXIO2_02 / ELCDIF_HSYNC)
- VSYNC output on B0_03 (FLEXIO2_03 / ELCDIF_VSYNC)
- RED output on B1_00 (FLEXIO2_16 / ELCDIF_DATA12)
- GREEN output on B1_01 (FLEXIO2_17 / ELCDIF_DATA13)
- BLUE output on B1_02 (FLEXIO2_18 / ELCDIF_DATA14)
- INTENSITY output on B1_03 (FLEXIO2_19 / ELCDIF_DATA15)

This config would enable programs to use either FlexIO2 or eLCDIF to produce 4-bit VGA output without any rewiring, and both T4.1 and micromod/devboard have all the pins required.
Unless I missed something both B0_12 (35) and B0_13 (34) did not respond to a pin check with and LED connected to them. Just rechecked and they are not connected as well as pin B1_02 (36) and B1_03 (37). The only pin that is labeled as a T41 pin that seems to be working is pin B0_12 (32). If this is the case with pins 36 and 37 then I will not be able to use FlexIO2 in 16-bitt mode:confused: Hopefully I am missing something...

EDIT: Just re-wired back to original pin B0_12 (34) and B0_13 (35) tested with a fresh copy of flexio_vga.ino. No Go. Enough for tonight...
 
Last edited:
Made an interesting discovery: it's possible to initialize the SDRAM even before any code gets executed, by filling out a DCD (Device Configuration Data) struct. The ROM processes it and takes care of programming all the SEMC registers when the device boots, so the SDRAM is enabled already by the time ResetHandler() is executed.
This works without any modifications to cores (defining a new ImageVectorTable inserts it in the image before the existing one defined in bootdata.c which is a bit dirty but gets the job done) and seems to make the MPU setup a lot more stable - it now works without the NOPs and I've moved things around a bit without any random lockups happening.

In theory this would make it easier to put initialized data into SDRAM, since it could just be copied from flash the same way the _stext and _sdata sections are. But that would still require a modified linker script.
 
Not having good results with the SDRAM board and RA8876 in 16-bit 8080 mode. It's very unstable results:( Been playing with delays with no predictable results even at 2MHz. If I switch to 8-bit mode all of the examples in the Ra8876LiteTeensy library will work up to 4MHz. which is a lot lower speed than the T41. Possibly signal line length? Don't know yet. Going to switch back to the T41 in 16-bit mode and optimize it first then switch back and test with the SDRAM board. It's easier to monitor the signals with the T41 on a breadboard.

Almost have all of the connections memorized from switching back and forth:)
 
@Rezo maybe you know more? You ran RGB at 24 bits.
16 bits...
Code:
  lcdRegWrite(RA8876_CCR);//01h
#if defined(USE_8080_IF)
  if(BUS_WIDTH == 16) {
    lcdDataWrite(RA8876_PLL_ENABLE<<7|RA8876_WAIT_NO_MASK<<6|RA8876_KEY_SCAN_DISABLE<<5|RA8876_TFT_OUTPUT24<<3
    |RA8876_I2C_MASTER_DISABLE<<2|RA8876_SERIAL_IF_DISABLE<<1 | ---> RA8876_HOST_DATA_BUS_16BIT <---); // 16 bit
  } else {
    lcdDataWrite(RA8876_PLL_ENABLE<<7|RA8876_WAIT_NO_MASK<<6|RA8876_KEY_SCAN_DISABLE<<5|RA8876_TFT_OUTPUT24<<3
    |RA8876_I2C_MASTER_DISABLE<<2|RA8876_SERIAL_IF_DISABLE<<1  | ---> RA8876_HOST_DATA_BUS_8BIT <---); // 8 bit
  }
You can see that if the BUS_WIDTH is 16 then the host data bus is 16 bit else if 8 then the host bus is 8 bit. The TFT panel IF is 24 bits.
With SPI bus IF The TFT panel IF is also 24 bits.
 
@wwatson
Are you trying 16 bit FlexIO on the dev board?

If you have it working on a 4.1, then the config should be almost identical, but you need to make sure of the following changes:
  1. Set the relevant pins to output mode, and set the MUX to FlexIO2
  2. Set the FlexIO registers accordingly - pin numbers for the WR/RD pin and the 1st Data pin need to be the FlexIO pin number (0-31) and not the Teensy pin number
 
@Rezo
Here is the FlexIO2 pin usage I am using:
FlexIO2------- Dev Board-------- ER-TFTM101-1 Pin
2:00 -----------> B0_00 -----------> /WR ---> 05
2:01 -----------> B0_01 -----------> /RD ---> 06
2:02 -----------> B0_02 ----------->
2:03 -----------> B0_03 ----------->
2:04 -----------> B0_04 -----------> D0 ----> 15
2:05 -----------> B0_05 -----------> D1 ----> 16
2:06 -----------> B0_06 -----------> D2 ----> 17
2:07 -----------> B0_07 -----------> D3 ----> 18
2:08 -----------> B0_08 -----------> D4 ----> 19
2:09 -----------> B0_09 -----------> D5 ----> 20
2:10 -----------> B0_10 -----------> D6 ----> 21
2:11 -----------> B0_11 -----------> D7 ----> 22
2:12 -----------> B0_12 -----------> D8 ----> 23
2:13 -----------> B0_13 -----------> D9 ----> 24
2:14 -----------> B0_14 -----------> D10 ----> 25
2:15 -----------> B0_15 -----------> D11 ----> 26
2:16 -----------> B1_00 -----------> D12 ----> 27
2:17 -----------> B1_01 -----------> D13 ----> 28
2:18 -----------> B1_02 -----------> D14 ----> 29
2:19 -----------> B1_03 -----------> D15 ----> 30

Finally have a stable and predictable setup on the T4.1. The maximum effective speeed is 20 MHz.
It is limited by the speed of the RA8876 2D engine. The only problem left with the T4.1 is 8-bit
memory reads. It still returns inconsistent values. 8/16 reads and write are good. 16-bit reads
are also good. It's just 8-bit reads that are not consistent.

An 8-bit read:
Code:
 Teensy 4.1 and RA8876 parallel 8080 mode testing (8/16)

Bus speed: 2 MHZ
Bus Width: 8-bits

lcdDataread16(): Dummy 0x00ff, data 0x00ff
rslt = 0xFFFF <---------- incorrect value
Press anykey to continue
lcdDataread16(): Dummy 0x0001, data 0x00ff
rslt = 0x01FF <---------- correct value
Press anykey to continue
lcdDataread16(): Dummy 0x0001, data 0x00ff
rslt = 0x01FF <---------- correct value
Press anykey to continue
lcdDataread16(): Dummy 0x0001, data 0x0001
rslt = 0x0101 <---------- incorrect value
Press anykey to continue

A 16-bit read:
Code:
 Teensy 4.1 and RA8876 parallel 8080 mode testing (8/16)

Bus speed: 2 MHZ
Bus Width: 16-bits

lcdDataread16(): Dummy 0x0100, data 0xff01
rslt = 0x01FF <---------- correct value
Press anykey to continue
lcdDataread16(): Dummy 0xff01, data 0xff01
rslt = 0x01FF <---------- correct value
Press anykey to continue
lcdDataread16(): Dummy 0xff01, data 0xff01
rslt = 0x01FF <---------- correct value
Press anykey to continue
lcdDataread16(): Dummy 0xff01, data 0xff01
rslt = 0x01FF <---------- correct value
Press anykey to continue
lcdDataread16(): Dummy 0xff01, data 0xff01
rslt = 0x01FF <---------- correct value
Press anykey to continue

Here are some speed tests using the 2D BTE (Block Transfer Engine) to write an image
to the display memory "lcd.writeRect(0,0,480,320,flexio_teensy_mm)":

Code:
 Teensy 4.1 and RA8876 parallel 8080 mode testing (8/16 bits)

Bus speed: 12 MHz
Bus Width: 8-bits
Wrote 153600 bytes in 26ms

Bus speed: 12 MHz
Bus Width: 16-bits                                                                                             
Wrote 153600 bytes in 13ms                                                                                     
                                                                                                              
Bus speed: 20 MHz                                                                                             
Bus Width: 8-bits                                                                                             
Wrote 153600 bytes in 20ms

Bus speed: 20 MHz
Bus Width: 16-bits
Wrote 153600 bytes in 10ms

Bus speed: 24 MHz
Bus Width: 8-bits
Wrote 153600 bytes in 20ms

Bus speed: 24 MHz
Bus Width: 16-bits
Wrote 153600 bytes in 10ms

20MHz seems to be the max speed of the RA8876 2D engine and as expected 16-bits is twice as fast as 8-bits.
I can now use the working driver information as a control to compare with the SDRAM board.

Here is the T4.1 working initialization code:

Code:
#define BUS_WIDTH 8  /*Available options are 8 or 16 */
#define SHIFTER_DMA_REQUEST 3 // only 0, 1, 2, 3 expected to work
#define SHIFTNUM 8 // number of shifters used (up to 8)
#define BYTES_PER_BEAT (sizeof(uint8_t))
#define BEATS_PER_SHIFTER (sizeof(uint32_t)/BYTES_PER_BEAT)
#define BYTES_PER_BURST (sizeof(uint32_t)*SHIFTNUM)
#define SHIFTER_IRQ (SHIFTNUM-1)
#define TIMER_IRQ 0
#define FLEXIO_ISR_PRIORITY 64 // interrupt is timing sensitive, so use relatively high priority (supersedes USB)

FASTRUN void RA8876_t3::FlexIO_Init()
{
#if defined(USE_MM) // Or SDRAM board.
  /* 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();

 
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_00 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_01 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_04 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_05 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_06 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_07 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_08 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_09 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_10 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_11 = 4;

  digitalWriteFast(10,HIGH);
  digitalWriteFast(12,HIGH);

    /* High speed and drive strength configuration */
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_00 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_01 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_04 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_05 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_06 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_07 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_08 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_09 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_10 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_11 = 0xFF;

if(BUS_WIDTH == 16) {
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_12 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_13 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_14 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_15 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_02 = 4;
  IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_03 = 4;

  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_12 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_13 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_14 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_15 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_00 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_01 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_02 = 0xFF;
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_03 = 0xFF;
}
    /* Set clock */
    pFlex->setClockSettings(3, 1, 0); // (480 MHz source, 1+1, 1+0) >> 480/2/1 >> 240Mhz

    /* 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;

#else // T4.1 setup

  /* Get a FlexIO channel */
    pFlex = FlexIOHandler::flexIOHandler_list[2]; // use FlexIO3
    /* 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(19, OUTPUT); // FlexIO3:0 D0
    pinMode(18, OUTPUT); // FlexIO3:1 |
    pinMode(14, OUTPUT); // FlexIO3:2 |
    pinMode(15, OUTPUT); // FlexIO3:3 |
    pinMode(40, OUTPUT); // FlexIO3:4 |
    pinMode(41, OUTPUT); // FlexIO3:5 |
    pinMode(17, OUTPUT); // FlexIO3:6 |
    pinMode(16, OUTPUT); // FlexIO3:7 D7

#if (BUS_WIDTH == 16)
    pinMode(22, OUTPUT); // FlexIO3:8 D8
    pinMode(23, OUTPUT); // FlexIO3:9  |
    pinMode(20, OUTPUT); // FlexIO3:10 |
    pinMode(21, OUTPUT); // FlexIO3:11 |
    pinMode(38, OUTPUT); // FlexIO3:12 |
    pinMode(39, OUTPUT); // FlexIO3:13 |
    pinMode(26, OUTPUT); // FlexIO3:14 |
    pinMode(27, OUTPUT); // FlexIO3:15 D15
#endif

    pinMode(36, OUTPUT);
    digitalWriteFast(36, HIGH);
    pinMode(37, OUTPUT);
    digitalWriteFast(37, HIGH);

    /* High speed and drive strength configuration */
    *(portControlRegister(36)) = 0xFF;
    *(portControlRegister(37)) = 0xFF;

    *(portControlRegister(19)) = 0xFF;
    *(portControlRegister(18)) = 0xFF;
    *(portControlRegister(14)) = 0xFF;
    *(portControlRegister(15)) = 0xFF;
    *(portControlRegister(40)) = 0xFF;
    *(portControlRegister(41)) = 0xFF;
    *(portControlRegister(17)) = 0xFF;
    *(portControlRegister(16)) = 0xFF;

#if (BUS_WIDTH == 16)
    *(portControlRegister(22)) = 0xFF;
    *(portControlRegister(23)) = 0xFF;
    *(portControlRegister(20)) = 0xFF;
    *(portControlRegister(21)) = 0xFF;
    *(portControlRegister(38)) = 0xFF;
    *(portControlRegister(39)) = 0xFF;
    *(portControlRegister(26)) = 0xFF;
    *(portControlRegister(27)) = 0xFF;
#endif

    /* Set clock */
    pFlex->setClockSettings(3, 1, 0); // (480 MHz source, 1+1, 1+0) >> 480/2/1 >> 240Mhz

    /* Set up pin mux */
    pFlex->setIOPinToFlexMode(36);
    pFlex->setIOPinToFlexMode(37);

    pFlex->setIOPinToFlexMode(19);
    pFlex->setIOPinToFlexMode(18);
    pFlex->setIOPinToFlexMode(14);
    pFlex->setIOPinToFlexMode(15);
    pFlex->setIOPinToFlexMode(40);
    pFlex->setIOPinToFlexMode(41);
    pFlex->setIOPinToFlexMode(17);
    pFlex->setIOPinToFlexMode(16);

#if (BUS_WIDTH == 16)
    pFlex->setIOPinToFlexMode(22);
    pFlex->setIOPinToFlexMode(23);
    pFlex->setIOPinToFlexMode(20);
    pFlex->setIOPinToFlexMode(21);
    pFlex->setIOPinToFlexMode(38);
    pFlex->setIOPinToFlexMode(39);
    pFlex->setIOPinToFlexMode(26);
    pFlex->setIOPinToFlexMode(27);
#endif

    hw->clock_gate_register |= hw->clock_gate_mask  ;
    /* Enable the FlexIO with fast access */
    p->CTRL = FLEXIO_CTRL_FLEXEN;
#endif   
}

The single beat read init:
Code:
FASTRUN void RA8876_t3::FlexIO_Config_SnglBeat_Read() {
#if defined(USE_MM) // Or SDRAM board

    p->CTRL &= ~FLEXIO_CTRL_FLEXEN;
    p->CTRL |= FLEXIO_CTRL_SWRST;
    p->CTRL &= ~FLEXIO_CTRL_SWRST;

    pFlex->setIOPinToFlexMode(12);

    /* Configure the shifters */
    p->SHIFTCFG[3] =
        //FLEXIO_SHIFTCFG_INSRC                                                /* Shifter input */
        FLEXIO_SHIFTCFG_SSTOP(0)                                               /* Shifter stop bit disabled */
       | FLEXIO_SHIFTCFG_SSTART(0)                                             /* Shifter start bit disabled and loading data on enabled */
       | FLEXIO_SHIFTCFG_PWIDTH(BUS_WIDTH - 1);                                /* Bus width */
    
    p->SHIFTCTL[3] =
        FLEXIO_SHIFTCTL_TIMSEL(0)                                              /* Shifter's assigned timer index */
      | FLEXIO_SHIFTCTL_TIMPOL*(1)                                             /* Shift on posedge of shift clock */
      | FLEXIO_SHIFTCTL_PINCFG(0)                                              /* Shifter's pin configured as input */
      | FLEXIO_SHIFTCTL_PINSEL(4)  //4                                            /* Shifter's pin start index */
      | FLEXIO_SHIFTCTL_PINPOL*(0) //0                                            /* Shifter's pin active high */
      | FLEXIO_SHIFTCTL_SMOD(1);                                               /* Shifter mode as recieve */

    /* Configure the timer for shift clock */
    p->TIMCMP[0] =
        (((1 * 2) - 1) << 8)                                                   /* TIMCMP[15:8] = number of beats x 2 – 1 */
      | (((_baud_div)/2) - 1);       //30             /* TIMCMP[7:0] = baud rate divider / 2 – 1 ::: 30 = 8Mhz with current controller speed */
    
    p->TIMCFG[0] =
        FLEXIO_TIMCFG_TIMOUT(0)                                                /* Timer output logic one when enabled and not affected by reset */
      | FLEXIO_TIMCFG_TIMDEC(0)                                                /* Timer decrement on FlexIO clock, shift clock equals timer output */
      | FLEXIO_TIMCFG_TIMRST(0)                                                /* Timer never reset */
      | FLEXIO_TIMCFG_TIMDIS(2)                                                /* Timer disabled on timer compare */
      | FLEXIO_TIMCFG_TIMENA(2)                                                /* Timer enabled on trigger high */
      | FLEXIO_TIMCFG_TSTOP(1)                                                 /* Timer stop bit disabled */
      | FLEXIO_TIMCFG_TSTART*(0);                                              /* Timer start bit disabled */
    
    p->TIMCTL[0] =
        FLEXIO_TIMCTL_TRGSEL((((3) << 2) | 1))                                 /* Timer trigger selected as shifter's status flag */
      | FLEXIO_TIMCTL_TRGPOL*(1)                                               /* Timer trigger polarity as active low */
      | FLEXIO_TIMCTL_TRGSRC*(1)                                               /* Timer trigger source as internal */
      | FLEXIO_TIMCTL_PINCFG(3)                                                /* Timer' pin configured as output */
      | FLEXIO_TIMCTL_PINSEL(1)                                                /* Timer' pin index: RD pin */
      | FLEXIO_TIMCTL_PINPOL*(1)                                               /* Timer' pin active low */
      | FLEXIO_TIMCTL_TIMOD(1);                                                /* Timer mode as dual 8-bit counters baud/bit */

 
    /* Enable FlexIO */
   p->CTRL |= FLEXIO_CTRL_FLEXEN;     

#else

    p->CTRL &= ~FLEXIO_CTRL_FLEXEN;
    p->CTRL |=  FLEXIO_CTRL_SWRST;
    p->CTRL &= ~FLEXIO_CTRL_SWRST;

    /* Configure the shifters */
    p->SHIFTCFG[3] =
         FLEXIO_SHIFTCFG_SSTOP(0)                                              /* Shifter stop bit disabled */
       | FLEXIO_SHIFTCFG_SSTART(0)                                             /* Shifter start bit disabled and loading data on enabled */
       | FLEXIO_SHIFTCFG_PWIDTH(BUS_WIDTH-1);                                  /* Bus width */
    
    p->SHIFTCTL[3] =
        FLEXIO_SHIFTCTL_TIMSEL(0)                                              /* Shifter's assigned timer index */
      | FLEXIO_SHIFTCTL_TIMPOL*(1)                                             /* Shift on negative edge of shift clock */
      | FLEXIO_SHIFTCTL_PINCFG(1)                                              /* Shifter's pin configured as output */
      | FLEXIO_SHIFTCTL_PINSEL(0)                                              /* Shifter's pin start index */
      | FLEXIO_SHIFTCTL_PINPOL*(0)                                             /* Shifter's pin active high */
      | FLEXIO_SHIFTCTL_SMOD(1);                                               /* Shifter mode as receive */

    /* Configure the timer for shift clock */
    p->TIMCMP[0] =
        (((1 * 2) - 1) << 8)                                                   /* TIMCMP[15:8] = number of beats x 2 – 1 */
      | ((60/2) - 1);                                                          /* TIMCMP[7:0] = baud rate divider / 2 – 1 */
    
    p->TIMCFG[0] =
        FLEXIO_TIMCFG_TIMOUT(0)                                                /* Timer output logic one when enabled and not affected by reset */
      | FLEXIO_TIMCFG_TIMDEC(0)                                                /* Timer decrement on FlexIO clock, shift clock equals timer output */
      | FLEXIO_TIMCFG_TIMRST(0)                                                /* Timer never reset */
      | FLEXIO_TIMCFG_TIMDIS(2)                                                /* Timer disabled on timer compare */
      | FLEXIO_TIMCFG_TIMENA(2)                                                /* Timer enabled on trigger high */
      | FLEXIO_TIMCFG_TSTOP(1)                                                 /* Timer stop bit enabled */
      | FLEXIO_TIMCFG_TSTART*(0);                                              /* Timer start bit disabled */
    
    p->TIMCTL[0] =
        FLEXIO_TIMCTL_TRGSEL((((3) << 2) | 1))                                 /* Timer trigger selected as shifter's status flag */
      | FLEXIO_TIMCTL_TRGPOL*(1)                                               /* Timer trigger polarity as active low */
      | FLEXIO_TIMCTL_TRGSRC*(1)                                               /* Timer trigger source as internal */
      | FLEXIO_TIMCTL_PINCFG(3)                                                /* Timer' pin configured as output */
      | FLEXIO_TIMCTL_PINSEL(19)                                               /* Timer' pin index: RD pin */
      | FLEXIO_TIMCTL_PINPOL*(1)                                               /* Timer' pin active low */
      | FLEXIO_TIMCTL_TIMOD(1);                                                /* Timer mode as dual 8-bit counters baud/bit */

  pFlex->setIOPinToFlexMode(37);
 
    /* Enable FlexIO */
   p->CTRL |= FLEXIO_CTRL_FLEXEN;     
#endif
}

These are the main low level access functions:
Code:
//**************************************************************//
// Read RA8876 status register 8bit data R/W only. 8/16 bit bus.
// Special case for status register access:
// /CS = 0, /DC = 0, /RD = 0, /WR = 1.
//**************************************************************//
ru8 RA8876_t3::lcdStatusRead(bool finalize)
{
  while(WR_DMATransferDone == false) {} //Wait for any DMA transfers to complete
  FlexIO_Config_SnglBeat_Read();

  CSLow();
  DCLow();

  uint16_t data = 0;
  while (0 == (p->SHIFTSTAT & (1 << 3))) {}
  data = p->SHIFTBUFBYS[3];

  DCHigh();
  CSHigh();
//Serial.printf("Dummy 0x%4.4x, data 0x%4.4x\n", dummy, data);

  //Set FlexIO back to Write mode
  FlexIO_Config_SnglBeat();
  
  if(BUS_WIDTH == 8)
    return data;
  else
    return (data >> 8) & 0xff;
}

//**************************************************************//
// Read RA8876 parallel Data (8-bit read) 8/16 bit bus mode.
//**************************************************************//
ru8 RA8876_t3::lcdDataRead(bool finalize) {
  uint16_t dummy = 0;
  uint16_t data = 0;

  while(WR_DMATransferDone == false) {} //Wait for any DMA transfers to complete

  CSLow();  // Must to go low after config and delay above.
  DCHigh(); // Should already be HIGH

  FlexIO_Config_SnglBeat_Read();

  while (0 == (p->SHIFTSTAT & (1 << 3))) {}
  dummy = p->SHIFTBUFBYS[3];
  while (0 == (p->SHIFTSTAT & (1 << 3))) {}
  data = p->SHIFTBUFBYS[3];
//  while(digitalReadFast(33) == 0);  // If monitoring XnWAIT signal from RA8876.
  CSHigh();

//  Serial.printf("lcdDataread(): Dummy 0x%2.2x, data 0x%2.2x\n", dummy, data);

  //Set FlexIO back to Write mode
  FlexIO_Config_SnglBeat(); // Not sure if this is needed.

  if(BUS_WIDTH == 8)
    return data;
  else
    return (data >> 8) & 0xff;
}

//**************************************************************//
// 16 bit read RA8876 Data. 8/16 bit bus mode.
//**************************************************************//
uint16_t RA8876_t3::lcdDataRead16(bool finalize)
{
  uint16_t dummy = 0;
  uint16_t data = 0;

  while(WR_DMATransferDone == false) {} //Wait for any DMA transfers to complete

  CSLow();  // Must to go low after config and delay above.
  DCHigh(); // Should already be HIGH

  FlexIO_Config_SnglBeat_Read();

  while (0 == (p->SHIFTSTAT & (1 << 3))) {}
  dummy = p->SHIFTBUFBYS[3];

  while (0 == (p->SHIFTSTAT & (1 << 3))) {}
  data = p->SHIFTBUFBYS[3];
  CSHigh();

//  Serial.printf("lcdDataread16(): Dummy 0x%4.4x, data 0x%4.4x\n", dummy, data);

  //Set FlexIO back to Write mode
  FlexIO_Config_SnglBeat(); // Not sure if this is needed.
  if(BUS_WIDTH == 8)
    return (dummy << 8) | (data & 0xff); // High byte to low byte and mask.
  else
    return (data >> 8) | (data << 8);
}

//****************************************************************
// Write to a RA8876 register (8 bit only) in 8/16 bbit buss mode.
//****************************************************************
void RA8876_t3::lcdRegWrite(ru8 reg, bool finalize)
{
  while(WR_IRQTransferDone == false) {} //Wait for any DMA transfers to complete
  FlexIO_Config_SnglBeat();
  CSLow();
  DCLow();
  /* Write command index */
  p->SHIFTBUF[0] = reg;
  /*Wait for transfer to be completed */
  while(0 == (p->SHIFTSTAT & (1 << 0))) {}
  while(0 == (p->TIMSTAT & (1 << 0))) {}
  /* De-assert RS pin */
  DCHigh();
  CSHigh();
}


//*****************************************************************
// Write RA8876 Data 8 bit data reg or memory in 8/16 bit bus mode.
//*****************************************************************
void RA8876_t3::lcdDataWrite(ru8 data, bool finalize) {
  while(WR_DMATransferDone == false) {}
  FlexIO_Config_SnglBeat();

  CSLow();
  DCHigh();

  p->SHIFTBUF[0] = data;
  /*Wait for transfer to be completed */
  while(0 == (p->SHIFTSTAT & (1 << 0))) {}
  while(0 == (p->TIMSTAT & (1 << 0))) {}
//  while(digitalReadFast(33) == 0);  // If monitoring XnWAIT signal from RA8876.
  CSHigh();
}

//*********************************************************
// Write RA8876 data to display memory, 8/16 bit buss mode.
//*********************************************************
void RA8876_t3::lcdDataWrite16(uint16_t data, bool finalize)
{
  while(WR_DMATransferDone == false) {} //Wait for any DMA transfers to complete
  FlexIO_Config_SnglBeat();

  CSLow();
  DCHigh();

  if(BUS_WIDTH == 16) {
    p->SHIFTBUF[0] = data;
    while(0 == (p->SHIFTSTAT & (1 << 0))) {}
    while(0 == (p->TIMSTAT & (1 << 0))) {}
  } else {
    p->SHIFTBUF[0] = data >> 8;
    while(0 == (p->SHIFTSTAT & (1 << 0))) {}
    p->SHIFTBUF[0] = data & 0xff;
    while(0 == (p->SHIFTSTAT & (1 << 0))) {}
    while(0 == (p->TIMSTAT & (1 << 0))) {}
  }
//while(digitalReadFast(33) == 0);  // If monitoring XnWAIT signal from RA8876.
  /* De-assert /CS pin */
  CSHigh();
}

Combinations of these functions are also used in other functions.

Now that I have a fairly stable library working on the T4.1 I will switch to the SDRAM board
and continue testing. 16-bit DMA is not working correctly yet, but that's next after getting
the basic communications working on the SDRAM board. The only other concern is if the trace
length of the SDRAM board with the three inch connecting wires are having an effect on the
SDRAM board. The traces are much shorter on the T4.1.

I really appreciate your help and advice. Sorry about the long post :D
I will let you know the results after I setup the SDRAM board again...
 
Back
Top