Call to arms | Teensy + SDRAM = true

@wwatson, note that the traces between the NXP and the SDRAM were directly copied from the EVAL board to minimize problems. The SDRAM has worked nicely for everyone else. But there has been some playing around with the capacitor and speeds. Perhaps that’s where the issues lie?
 
@wwatson, note that the traces between the NXP and the SDRAM were directly copied from the EVAL board to minimize problems. The SDRAM has worked nicely for everyone else. But there has been some playing around with the capacitor and speeds. Perhaps that’s where the issues lie?
I remember reading that. At this point I am not using the SDRAM at all with the display. It is strictly the traces between the 1062 MCU and the out side connectors of the board. Once that and DMA communications are solved then I can start testing with the SDRAM. I had similar problems with the MicroMod as well. Hopefully @Rezo can shed some light the issue :)
 
I had similar problems with the MicroMod as well.
Except for the SDRAM added connects as noted in p#926 - the majority of the pins present as a micromod since it is seen as T_MM because of the use of the 16MB Flash. Wonder if anything in the #IFDEF T_MM code might make the difference? Otherwise DevBoard V4.0 of has only some half of the pins present as the T_MM.
 
Except for the SDRAM added connects as noted in p#926 - the majority of the pins present as a micromod since it is seen as T_MM because of the use of the 16MB Flash. Wonder if anything in the #IFDEF T_MM code might make the difference? Otherwise DevBoard V4.0 of has only some half of the pins present as the T_MM.
That's why I hope Rezo can go over the low level drivers I posted to make sure I am not missing something. I have a general idea of how FlexIO works but I might be missing some little details. Meanwhile I am wiring up the DevBoard again to test the changes I made to the drivers...
 
@wwatson the code looks good from a brief overview.
What length wires are you using between the MCU and the display boards? WIth 10cm wires I could not get past 20Mhz when testing
With an LCD and Micromod mounted to the same pcb with 2cm traces we got 24/30Mhz working.

When I was developing the Micromode 8 bit driver with some of the other forum geniuses helping me, we ran into a problem where the data loaded into the buffer was being pushed out in the opposite order of loading it in. If we had loaded in 0x1234 it would send out 0x3412 or something alike.
So we had to configure DMA to load the shifters in the opposite order.

Getting 16 bit DMA to work might be a bit of a challenge, but the setup will be a bit less complex IMO.
My DMA config knowledge is very limited, and I had @easone help me out on almost all the DMA code. Perhaps with a short refresh he can assist on getting 16 bit DMA transfers running.

EDIT:
I did test SDRAM with an 8 bit display and it worked fine using the DMA code.
I would suggest trying 8 bit DMA on the dev board to make sure the base works fine there as well.
 
@wwatson the code looks good from a brief overview.
What length wires are you using between the MCU and the display boards? WIth 10cm wires I could not get past 20Mhz when testing
With an LCD and Micromod mounted to the same pcb with 2cm traces we got 24/30Mhz working.

When I was developing the Micromode 8 bit driver with some of the other forum geniuses helping me, we ran into a problem where the data loaded into the buffer was being pushed out in the opposite order of loading it in. If we had loaded in 0x1234 it would send out 0x3412 or something alike.
So we had to configure DMA to load the shifters in the opposite order.

Getting 16 bit DMA to work might be a bit of a challenge, but the setup will be a bit less complex IMO.
My DMA config knowledge is very limited, and I had @easone help me out on almost all the DMA code. Perhaps with a short refresh he can assist on getting 16 bit DMA transfers running.

EDIT:
I did test SDRAM with an 8 bit display and it worked fine using the DMA code.
I would suggest trying 8 bit DMA on the dev board to make sure the base works fine there as well.
Thanks for the response. I wired up the dev board again and started testing with the baseline driver code I posted. It shows something is wrong in the dev board/MicroMod side of my code. No matter what I set the bus speed to loading the same image as loaded on the T4.1 takes 39ms in 8-bit mode and 19ms in 16-bit mode. I'll have to track that down first. Other than that everything else is working the same on the dev Board as on the T4.1. As far as DMA goes here is what I am getting with 8-bit DMA on the dev board.
This is what I see most of the time:
noway.jpg


If I repeat loading the image by pressing a key in the loop(), I get this:
sorta.jpg


As far as 16 bit mode goes the picture comes out looking like zebra stripes. To get the pictures I showed I had to change from SHIFTBUF to SHIFTBUFBYS to swap bytes.
I'm getting there one step at a time...
 
It's hard to troubleshoot these things online, but can yo do a simple test with a logic analyzer? similar to what I did here?
We need to verify that the data is being sent out in the correct order.
The DMA is set up specifically to accept a 16 bit pixel and push it out over an 8 bit bus.
To support DMA with 16bpp on a 16 bit bus would require some changes, and vice versa, for 8bpp on a 16 bit or 8 bit bus
 
Code:
What length wires are you using between the MCU and the display boards? WIth 10cm wires I could not get past 20Mhz when testing
With an LCD and Micromod mounted to the same pcb with 2cm traces we got 24/30Mhz working.

I am using the same length wires with the same results. So if you add in the length of the traces on the dev board ~2.5"-3.0" equals up to 7". So the you would probably need a buffer circuit to get higher speeds or a dedicated connector mounted close to the MCU. I'll wire up the the MM again and check it out. In any case the ER-TFTM101-1 is faster in 8080 mode than in SPI mode.
I want to get started with elcdif. That's next after cleaning up the Ra8876LiteTeensy library...
 
Testing the different cameras on the SDRAM board became problematic - not sure if wiring/connector issue but alot of problems we were seeing was with the wiring as @KurtE mentioned on the camera thread about wiring. So we decided to make a adapter board for the displays and camera. Should have it next week to make sure I didn't mess it up.


1713455432712.png
 
Was hoping you'd included the voltage regulators for the OV2640's additional requirements... you don't want to see the mess I've got with LM317s.
 
Was hoping you'd included the voltage regulators for the OV2640's additional requirements... you don't want to see the mess I've got with LM317s.
Just wondering, are you saying that on the current Devboard 4, that the 3.3v Voltage regulator is maybe to anemic to run some of the different devices that you have connected to it? And that maybe we should add another one to connect the devices, such as displays and cameras to?

Hopefully the Devboard 5 will have a stronger one. On some of my own more recent boards, I ended up using one that is similar (different package) than Sparkfun used on their ATP micromod board, which puts out 1Amp.
 
Just wondering, are you saying that on the current Devboard 4, that the 3.3v Voltage regulator is maybe to anemic to run some of the different devices that you have connected to it? And that maybe we should add another one to connect the devices, such as displays and cameras to?
No. The OV2460 runs off three different voltages: 2.8V for the analog sensors, 1.2V for the core and 3.3V for the I/O portion. The ArduCam boards have two regulators on the back to generate the lower voltages from 3.3V but I just have the camera module directly connected to a breakout board.
 
I found an Arduino 8080 parallel IF used for the RA8875 (same 8080 interface as RA8876) that uses 74LV245's as buffers for the Due and possibly the Mega 2560 found here. I am going to order up some of these chips if I don't have any left and see what the results are with the dev board. I am kinda convince that this is the issue based on the fact that the T41 handles the highest reliable speeds in both 8-bit and 16-bit mode and has the shortest trace distance between the edge connectors and the MCU. The MicroMod and dev board are pretty much the same in usable speed settings. Just to satisfy my curiosity :D
 
One question did you bring out the csi pins?
I did not bring out any special ports. All that was done was SDCARD and USB-PD. But ofc we can keep going and make a gen5 that has more stuff. But it needs coordinating, Rezo and KurtE together could make a full pin mapping, that would be ideal. Then I just follow that. It will minimize mistakes.

Regarding power supply on the board, anything can be added. What voltages and amps are needed? I have several tested circuits that are reliable!

For the 4.5 (facelift) there’s USB-PD that can do max 3A. Will this suffice?

I got 10pcs of the 4.5 made.
 
Last edited:
Pushed the "DCD" intialization example to github: https://github.com/A-Dunstan/SDRAM_EXTMEM/tree/master/examples/DCD_Init

The magic is in dcd.cpp: DeviceConfigurationData is basically a uint32_t array of registers and values to be put in them, with a few "check data" commands near the end in order to issue the IP commands required to initialize the SDRAM chip. It looks pretty ugly because all the integers need to be big-endian (NXP whyyyy) and there's headers for each section that include the size, so I used template rubbish to take care of it at compile-time.
It's hardcoded to run the SDRAM at 198MHz because PLL2 PFD2 is the only "safe" clock source (the other possible SEMC clock sources come from the ARM PLL or PLL3, both of which get initialized later) and the core startup routine will set it to 396MHz - so the choices are either 396/3 (132Mhz) or 396/2 (198MHz), and 198 works well for me so I went with that.
The refresh timings are a little bit tighter than the old initialization code, they are still within spec and give a little bit of speed increase.

This hack relies on the linker placing "NewImageVectorTable" in the .ivt output section before the default "ImageVectorTable" included in bootdata.c from the Teensy core files. This works because that output section isn't sorted and the linker just plops data out in the same order that it consumes it, unless LTO is turned on - then it doesn't work because things get re-ordered. Either ImageVectorTable in the core would need to be marked weak so it could be replaced with user code, or it could reference a weak dcd pointer.

Additionally this example replaces _sbrk to use the SDRAM for heap memory instead of DMAMEM, so any code that wants to use large/aligned allocations with ordinary malloc or new can do so.
 
The SDRAM_EXTMEM github repository is the same (alternative to mjs513's) repository that I've been working all along, because I prefer the different initialization method (using startup_middle_hook without needing to be explicitly called) and the same extmem_* functions that PSRAM uses on a regular Teensy.
The DCD method is slightly different, it doesn't use any of the C/C++ initialisation code. It's all handled by the ROM so there's no header file to be included or functions to be called, only dcd.cpp needs to be included in the build to ensure the static data gets linked in.
 
id not bring out any special ports. All that was done was SDCARD and USB-PD. But ofc we can keep going and make a gen5 that has more stuff. But it needs coordinating, Rezo and KurtE together could make a full pin mapping, that would be ideal. Then I just follow that. It will minimize mistakes.
A couple of questions and things I am playing with...

With the 4.5 and SD adapter: guessing you used SDIO pins? (Same ones as defined for Micromod?) of if SPI which IO pins?

CSI pins - I am in the process of integrating in some CSI support into the library that @mjs513 and myself have been playing with.
So far there are no Teensy libraries. That have a bunch of CSI support. There is one for OV7670 from 4 years ago.

While adding this support, I am playing with a different way to map IO pins to pin functionality, that if it works OK, I may play with updating
some of my other libraries, like Flexio and maybe displays... I sort of don't like all of the places we have to define different tables for each of the different T4.x boards..

So my initial start for this I have a table like:
(Defines)
C++:
enum {
  CSI_D02=2, CSI_D03, CSI_D04, CSI_D05, CSI_D06, CSI_D07, CSI_D08, CSI_D09,
  CSI_VS=100, CSI_HS, CSI_PCLK, CSI_MCLK
};

typedef struct csi_pin_mapping_setup { // not really bitband, old name from Teensy3
  uint8_t csi_usage;
  volatile uint32_t *mux;
  uint32_t mux_val;
  volatile uint32_t *pin_select_input;
  uint32_t select_input_val;
  volatile uint32_t *pad;
  uint32_t pad_val;
} csi_pain_mapping_t;
Table:
C++:
const PROGMEM csi_pain_mapping_t csi_pin_mapping_table[] =
{
  // VSYNC
  {CSI_VS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06, 0x4U,   &IOMUXC_CSI_VSYNC_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_06, 0x00010000U},
  {CSI_VS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_13,    0x2U,     &IOMUXC_CSI_VSYNC_SELECT_INPUT, 0x2U,     &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_13, 0x0U},
  {CSI_VS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_14, 0x4U,   &IOMUXC_CSI_VSYNC_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_14, 0x00010000U},
  // HSYNC
  {CSI_HS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07, 0x4U,   &IOMUXC_CSI_HSYNC_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07, 0x00010000U},
  {CSI_HS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_14,    0x2U,   &IOMUXC_CSI_HSYNC_SELECT_INPUT, 0x2U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_14, 0x00010000U},
  {CSI_HS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_15, 0x4U,   &IOMUXC_CSI_HSYNC_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_15, 0x00010000U},
  // DCLK or Pixel Clk
  {CSI_PCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_04, 0x4U,   &IOMUXC_CSI_PIXCLK_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_04, 0x00010000U},
  {CSI_PCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_12,    0x2U,   &IOMUXC_CSI_PIXCLK_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_12, 0x00010000U},
  // MCLK
  {CSI_MCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_05, 0x4U,   0, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_05, 0x18},
  {CSI_MCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_15,    0x2U,   0, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_15, 0x18},

  // D7-D0
  {CSI_D02, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_15, 0x4U,   &IOMUXC_CSI_DATA02_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_15, 0x0U},
  {CSI_D02, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_11, 0x4U,   &IOMUXC_CSI_DATA02_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_11, 0x0U},

  {CSI_D03, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_14, 0x4U,   &IOMUXC_CSI_DATA03_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_14, 0x0U},
  {CSI_D03, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_10, 0x4U,   &IOMUXC_CSI_DATA03_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_10, 0x0U},

  {CSI_D04, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_13, 0x4U,   &IOMUXC_CSI_DATA04_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_13, 0x0U},
  {CSI_D04, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_09, 0x4U,   &IOMUXC_CSI_DATA04_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_09, 0x0U},

  {CSI_D05, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_12, 0x4U,   &IOMUXC_CSI_DATA05_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_12, 0x0U},
  {CSI_D05, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_08, 0x4U,   &IOMUXC_CSI_DATA05_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08, 0x0U},

  {CSI_D06, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_11, 0x4U,   &IOMUXC_CSI_DATA06_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11, 0x0U},
  {CSI_D06, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_07, 0x4U,   &IOMUXC_CSI_DATA06_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07, 0x0U},

  {CSI_D07, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_10, 0x4U,   &IOMUXC_CSI_DATA07_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_10, 0x0U},
  {CSI_D07, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_06, 0x4U,   &IOMUXC_CSI_DATA07_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_06, 0x0U},

  {CSI_D08, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09, 0x4U,   &IOMUXC_CSI_DATA08_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09, 0x0U},
  {CSI_D08, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_05, 0x4U,   &IOMUXC_CSI_DATA08_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_05, 0x0U},

  {CSI_D09, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08, 0x4U,   &IOMUXC_CSI_DATA09_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08, 0x0U},
  {CSI_D09, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_04, 0x4U,   &IOMUXC_CSI_DATA09_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_04, 0x0U},
};
Again WIP so the table will likely be adjusted.

And I have simple code that takes an Arduino pin number and maps it to one of these entries like:
C++:
const csi_pain_mapping_t *mapPinToCSIPinInfo(uint8_t pin) {
  if (pin > CORE_NUM_DIGITAL) return nullptr; // pin is out of range.
  volatile uint32_t *pin_mux = portConfigRegister(pin);


  for (uint8_t i = 0; i < (sizeof(csi_pin_mapping_table)/sizeof(csi_pin_mapping_table[0])); i++) {
    if (csi_pin_mapping_table[i].mux == pin_mux) return &csi_pin_mapping_table[i];
  }
  return nullptr;
}
The above table has for each of the CSI logical pins we use, has all of the possible pins for that function defined.
The first one in each section is the ones we use on T4.1...

So if PJRC or anyone else comes out with a new T4.xish board, we don't have to edit the library to make of use of it.
I may also extend this slightly to allow you to pass in the pin name like the mux name: IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06
Or if there is a shorter define elsewhere like: GPIO_AD_B1_06

Now back to fleshing this out...
 
So if PJRC or anyone else comes out with a new T4.xish board, we don't have to edit the library to make of use of it.
I can see how this is useful for supporting the existing different boards (4.x vs. micromod) that redefine arduino pin numbers to different IMXRT pins but I don't see how it would help with custom boards due to this:
C++:
  if (pin > CORE_NUM_DIGITAL) return nullptr; // pin is out of range.
For example it can't return values for any of the extra pins that the SDRAM devboard exposes that a regular micromod doesn't, because they're not included in core_pins.h.

(Also I think the check there should use >= instead of >)
 
I can see how this is useful for supporting the existing different boards (4.x vs. micromod) that redefine arduino pin numbers to different IMXRT pins but I don't see how it would help with custom boards due to this:
Works for me, with the Devboard, as I created a variant that had all of the extra pins defined. Otherwise you would not have pin numbers to work with...

(Also I think the check there should use >= instead of >)
True, typo...
 
A couple of questions and things I am playing with...

With the 4.5 and SD adapter: guessing you used SDIO pins? (Same ones as defined for Micromod?) of if SPI which IO pins?

CSI pins - I am in the process of integrating in some CSI support into the library that @mjs513 and myself have been playing with.
So far there are no Teensy libraries. That have a bunch of CSI support. There is one for OV7670 from 4 years ago.

While adding this support, I am playing with a different way to map IO pins to pin functionality, that if it works OK, I may play with updating
some of my other libraries, like Flexio and maybe displays... I sort of don't like all of the places we have to define different tables for each of the different T4.x boards..

So my initial start for this I have a table like:
(Defines)
C++:
enum {
  CSI_D02=2, CSI_D03, CSI_D04, CSI_D05, CSI_D06, CSI_D07, CSI_D08, CSI_D09,
  CSI_VS=100, CSI_HS, CSI_PCLK, CSI_MCLK
};

typedef struct csi_pin_mapping_setup { // not really bitband, old name from Teensy3
  uint8_t csi_usage;
  volatile uint32_t *mux;
  uint32_t mux_val;
  volatile uint32_t *pin_select_input;
  uint32_t select_input_val;
  volatile uint32_t *pad;
  uint32_t pad_val;
} csi_pain_mapping_t;
Table:
C++:
const PROGMEM csi_pain_mapping_t csi_pin_mapping_table[] =
{
  // VSYNC
  {CSI_VS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06, 0x4U,   &IOMUXC_CSI_VSYNC_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_06, 0x00010000U},
  {CSI_VS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_13,    0x2U,     &IOMUXC_CSI_VSYNC_SELECT_INPUT, 0x2U,     &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_13, 0x0U},
  {CSI_VS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_14, 0x4U,   &IOMUXC_CSI_VSYNC_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_14, 0x00010000U},
  // HSYNC
  {CSI_HS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07, 0x4U,   &IOMUXC_CSI_HSYNC_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07, 0x00010000U},
  {CSI_HS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_14,    0x2U,   &IOMUXC_CSI_HSYNC_SELECT_INPUT, 0x2U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_14, 0x00010000U},
  {CSI_HS, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_15, 0x4U,   &IOMUXC_CSI_HSYNC_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_15, 0x00010000U},
  // DCLK or Pixel Clk
  {CSI_PCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_04, 0x4U,   &IOMUXC_CSI_PIXCLK_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_04, 0x00010000U},
  {CSI_PCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_12,    0x2U,   &IOMUXC_CSI_PIXCLK_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_12, 0x00010000U},
  // MCLK
  {CSI_MCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_05, 0x4U,   0, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_05, 0x18},
  {CSI_MCLK, &IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_15,    0x2U,   0, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_15, 0x18},

  // D7-D0
  {CSI_D02, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_15, 0x4U,   &IOMUXC_CSI_DATA02_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_15, 0x0U},
  {CSI_D02, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_11, 0x4U,   &IOMUXC_CSI_DATA02_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_11, 0x0U},

  {CSI_D03, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_14, 0x4U,   &IOMUXC_CSI_DATA03_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_14, 0x0U},
  {CSI_D03, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_10, 0x4U,   &IOMUXC_CSI_DATA03_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_10, 0x0U},

  {CSI_D04, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_13, 0x4U,   &IOMUXC_CSI_DATA04_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_13, 0x0U},
  {CSI_D04, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_09, 0x4U,   &IOMUXC_CSI_DATA04_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_09, 0x0U},

  {CSI_D05, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_12, 0x4U,   &IOMUXC_CSI_DATA05_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_12, 0x0U},
  {CSI_D05, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_08, 0x4U,   &IOMUXC_CSI_DATA05_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08, 0x0U},

  {CSI_D06, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_11, 0x4U,   &IOMUXC_CSI_DATA06_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11, 0x0U},
  {CSI_D06, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_07, 0x4U,   &IOMUXC_CSI_DATA06_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07, 0x0U},

  {CSI_D07, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_10, 0x4U,   &IOMUXC_CSI_DATA07_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_10, 0x0U},
  {CSI_D07, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_06, 0x4U,   &IOMUXC_CSI_DATA07_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_06, 0x0U},

  {CSI_D08, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09, 0x4U,   &IOMUXC_CSI_DATA08_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09, 0x0U},
  {CSI_D08, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_05, 0x4U,   &IOMUXC_CSI_DATA08_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_05, 0x0U},

  {CSI_D09, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08, 0x4U,   &IOMUXC_CSI_DATA09_SELECT_INPUT, 0x0U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08, 0x0U},
  {CSI_D09, &IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_04, 0x4U,   &IOMUXC_CSI_DATA09_SELECT_INPUT, 0x1U,   &IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_04, 0x0U},
};
Again WIP so the table will likely be adjusted.

And I have simple code that takes an Arduino pin number and maps it to one of these entries like:
C++:
const csi_pain_mapping_t *mapPinToCSIPinInfo(uint8_t pin) {
  if (pin > CORE_NUM_DIGITAL) return nullptr; // pin is out of range.
  volatile uint32_t *pin_mux = portConfigRegister(pin);


  for (uint8_t i = 0; i < (sizeof(csi_pin_mapping_table)/sizeof(csi_pin_mapping_table[0])); i++) {
    if (csi_pin_mapping_table[i].mux == pin_mux) return &csi_pin_mapping_table[i];
  }
  return nullptr;
}
The above table has for each of the CSI logical pins we use, has all of the possible pins for that function defined.
The first one in each section is the ones we use on T4.1...

So if PJRC or anyone else comes out with a new T4.xish board, we don't have to edit the library to make of use of it.
I may also extend this slightly to allow you to pass in the pin name like the mux name: IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06
Or if there is a shorter define elsewhere like: GPIO_AD_B1_06

Now back to fleshing this out...
I’ll make a gen5 of this board, all I need from you is a complete list of pins. I know you’re very good with the pin stuff since you made those PDF’s on Git.

The SD-Card uses the SDIO pins yes.
 
Back
Top