[posted] VGA out for Teensy 4.0/4.1

It's the reason i investigated how it works :)
I have take a look on google about the Belgian KB , everything is the same , only some symbols take other place ...
But take care , i just have made some mods in the FR section from the keylayouts.h ...
 
I have read that you use PCM5102 module for audio , i have some of them , is there a schematic for connect it to the T4.1 so i will use them too :)

Cheers.
 
Hmmm , then it have to do with DMA , they normally never collide and work in back of the MCU (at least on stm32) .... i hope T4.1 work the same way ...
So bad i don't know this MCU a little more ... he he
For the VGA have you try my timing and only one FlexIO ?
 
Teensy4AudioDAC.jpg
I have read that you use PCM5102 module for audio , i have some of them , is there a schematic for connect it to the T4.1 so i will use them too :)

Cheers.
You need to adapt it for i2s out i.e. just replace usb with i2s

This is for usbaudio from a pc

This is what I use with Teensy 4
// PCM5102-DAC Teensy 4
// VCC 5V
// GND GND
// LRCK 20 LRCLK1
// DATA 7 OUT1A
// BCK 21 BCLK1

You do not need the encoder or oled - just usbaudio-in via amp-LR to i2s-out
if pc used Amp allows you to use windows/mac/Linux volume control
if i2s-in used volume control from Teensy

See this post for other type of pcm5102 board https://forum.pjrc.com/threads/53069-Teensy-with-PCM5102a-Module-via-I2S
PCM5102A / Teensy 3.6
VCC = Vin
3.3v = NC
GND = GND
FLT = GND
SCL = GND (also works connected to 11 /MCL)
BCK = BCK (9)
DIN = TX (22)
LCK = LCRLK (23)
FMT = GND
XMT = 3.3V (HIGH)

I have to stop editing now I am going down a rabbit hole trying to remember difference teensy 3 and 4 to pcm5102...
 
Last edited:
That is the thread I used to setup the PCM5102 on the T4.1 last week.

There is no need to connect MCLK1 indeed.
With the module I have, I also had nothing else to connect than vcc,gnd,bck,lck and din. Connecting XMT was not needed and I did not connect other pins to ground. In fact I did first and it did not work at all so I disconnected them.

The sound is ok, it is just the I2S that seems to mess up the QTimer3 so VGA image is not stable.

I measured the timing of the H-SYNC yesterday and I it is ok. 31.4KHz. V-Sync is 60Hz. I have played with a margin but does not make much difference.
I will check the DMA clock output this PM after having painted the sleeping room ;-)
 
The margin have to be in the buffer you created for the picture.
For 640 x 480 resolution you have the 640x480 pixels in buffer.
So , for 512x480 you still have 640x480 pixels in buffer :)
It's just that you made 64 pixels black at left and 64 pixels black at right from you picture ...
64 + 512 + 64 = 680 pixels.
now for example with the 320 x 240 resolution , it's not supported from new screen , for use it you have to use the 640 x 480 resolution.
You have 2 choices :
1 : you use a 160 pixels margin at left and rigth from your buffer , and a margin from 120 up and down of you buffer , but you will get a small picture with allot of dark around.
2 : you use 2x bigger pixels :) and you have a full screen 320 x 240 resolution (320 x 2 = 640 , 240 x 2 = 480) , it was the method i use and the picture was ok.
Look that if it's not clear :
https://drive.google.com/file/d/1MrFSAgFrJuU54pQ43FG7hPFwQ6H8R1EB/view?usp=sharing

And take care with the vapor from painting ;) or it's possible you do a ZX81 emulator out the the Amiga one ... he he

Cheers.
 
I just discover something interesting in this i.MX RT1060 document.
https://drive.google.com/file/d/1q7aImWlO3-phsiTVXsSfwYTk7w1V9krD/view?usp=sharing

Page 11 : 8/16-bit CSI interface and 8/16/24-bit LCD interface , then it's a dedicated interface (parallel LCD interface = VGA interface)

So , then it's like stm32 :) the MCU manage the interface for you.

Page 60 : 8080 display interface , is what you actually do ... 8bit parallel ...

Page 97 to 103: LCD Interface , here is what is interesting ... i can't find more information on how to use it , but somewhere it have to exist , probably on NXP pages ...
 
I was aware of these chapters in the documentation but how do you get that out of the Teensy 4.1
I am not sure the pins are exposed to the outside. I know that Paul had to do some sacrifices when deciding on the pinout.
I only know about the flexio register and their limitations wrt to pin mapping.
May be there is a way to use PLL5 for the pixel clock on the flexio?

That all look so complex for me ...
 
If you want to misuse LCDIF for VGA and use lowest 8 DATA lines it is already problematic.

GPIO_B0_00 => LCD_CLK
GPIO_B0_01 => LCD_ENABLE
GPIO_B0_02 => LCD_HSYNC
GPIO_B0_03 => LCD_VSYNC

GPIO_B0_04 => LCD_DATA00
...
GPIO_B0_11 => LCD_DATA07

Looking at core_pins.h only the first 4 are available at the boundary ;-(
Does not look the good approach on the T4.1 from what I understand.
You could use the HSYNC and VSYNC but that is it.
How do I get the RGB out unless via Flex shift register....
 
Hi :)
I have DL and test MCUXpresso Config Tools , i have a demo that use PXP (pixels stuff to LCD) and you right , the T4.1 don't output enough of pins , LCD_CLK and LCD_ENABLE is not used by VGA , Only HSYNC , VSYNC , D0 - Dnn.
So then only your FlexIO can normally work on T4.1 , and it will ... he he ....
Pin used in the examples i have for LCD :

Code:
D7	LCDIF	CLK	GPIO_B0_00	LCDIF_CLK	LCDIF_CLK	NVCC_GPIO (0V)	Input	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
C8	LCDIF	DATA, 00	GPIO_B0_04	LCDIF_D0/BT_CFG[0]	LCDIF_D0	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
B8	LCDIF	DATA, 01	GPIO_B0_05	LCDIF_D1/BT_CFG[1]	LCDIF_D1	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
A8	LCDIF	DATA, 02	GPIO_B0_06	LCDIF_D2/BT_CFG[2]	LCDIF_D2	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
A9	LCDIF	DATA, 03	GPIO_B0_07	LCDIF_D3/BT_CFG[3]	LCDIF_D3	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
B9	LCDIF	DATA, 04	GPIO_B0_08	LCDIF_D4/BT_CFG[4]	LCDIF_D4	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
C9	LCDIF	DATA, 05	GPIO_B0_09	LCDIF_D5/BT_CFG[5]	LCDIF_D5	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
D9	LCDIF	DATA, 06	GPIO_B0_10	LCDIF_D6/BT_CFG[6]	LCDIF_D6	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
A10	LCDIF	DATA, 07	GPIO_B0_11	LCDIF_D7/BT_CFG[7]	LCDIF_D7	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
C10	LCDIF	DATA, 08	GPIO_B0_12	LCDIF_D8/BT_CFG[8]	LCDIF_D8	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
D10	LCDIF	DATA, 09	GPIO_B0_13	LCDIF_D9/BT_CFG[9]	LCDIF_D9	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
E10	LCDIF	DATA, 10	GPIO_B0_14	LCDIF_D10/BT_CFG[10]	LCDIF_D10	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
E11	LCDIF	DATA, 11	GPIO_B0_15	LCDIF_D11/BT_CFG[11]	LCDIF_D11	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
A11	LCDIF	DATA, 12	GPIO_B1_00	LCDIF_D12	LCDIF_D12	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
B11	LCDIF	DATA, 13	GPIO_B1_01	LCDIF_D13	LCDIF_D13	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
C11	LCDIF	DATA, 14	GPIO_B1_02	LCDIF_D14	LCDIF_D14	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
D11	LCDIF	DATA, 15	GPIO_B1_03	LCDIF_D15	LCDIF_D15	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
E7	LCDIF	ENABLE	GPIO_B0_01	LCDIF_ENABLE	LCDIF_ENABLE	NVCC_GPIO (0V)	Input/Output	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
E8	LCDIF	HSYNC	GPIO_B0_02	LCDIF_HSYNC	LCDIF_HSYNC	NVCC_GPIO (0V)	Input	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow
D8	LCDIF	VSYNC	GPIO_B0_03	LCDIF_VSYNC	LCDIF_VSYNC	NVCC_GPIO (0V)	Input	n/a	n/a	Disabled	Enable	100K Ohm Pull Up	Pull	Enabled	Disabled	medium(100MHz)	R0/6	Slow

To made it correctly we need a T4.2 with more IO from LCD interface ;)
In Teensy4 core on arduino , i don't see the pxp that is for the internal gfx engine , i presume it was not supposed to be in use with T4.1
And how is it with the 640 x 480 VGA , is it working ?
 
Unfortunately 640x480 does not work.

I created a 320x240 mode from the spec you shared.
I compute every parameter from the timing. You can look in the code, I pushed on the GIT together with your GFX primitives.
I also tried using PLL5 but it does not work at all. No pixel output by the DMA with PLL5 (you can also try yourself by uncommenting in the code)

For 320x240, I try to respect the back porch timing.
As the H-Sync interrupt occurs on rising edge, you have to add 96 pixels of the pulse + 48 for the back porch. Front porch I don't case as it is after the RGB pixels. According the spec it is 16 front porch and 48 back porch.
To have it centered 32 back porch is indeed better as you propose but why is the spec different?

If I apply the same timing for 640x240 (pixel clock is doubled) then I get rubbish on the screen. It is like the DMA cannot transfer at that frequency?

I propose you or somebody else have a look and review the code.

I will continue to port your keyboard changes and also the other emulators to the T4 VGA.
At least 320x240 and 352x240 is the most usable modes.
Tomorrow I will create a PCB because my wiring is too fragile. I will have to move USER1 and USER2 keys to other pins if I want to try 12 bits mode one day BTW...
 
The pixel clock is not so high , it's just 25.175Mhz for 640x480 60Hz.

And yes , is strange that the sync are after the pixels :) , i scrapped my head around and lost some hair when i do it in 2012/2013 ...
The timing i give you is for 640x480 ... not 320x240 , or it's 320x240 if you double the pixel size that give at end again 640x480.
I will look at your code and try to understand how the T4.1 is doing , and if i can i go to take a look at the scope for check all signals.
And i will like to see your other emulator run on VGA too ;)

I found another VGA explanation but at end it's same as mine :
http://lucidscience.com/pro-vga%20video%20generator-5.aspx

Cya :)

PS : i have made the change for the Quad on your VGA Lib , i clean it up and send you the source tomorrow.
 
I don't have wait tomorrow for put the signals under my scope :)
On your HSync , you don't have add the frontporch , i created a var and added the 16 pix.
After this i recompiled and the 640x480 stop dancing in the screen.
Now , your Vsync is inconsistent .... somewhere is something that make it change in the timing , take a look at this scope pics , it's the vsync signal.
https://drive.google.com/file/d/1-gnvh6cYgRVTIPHh9NnSGIruU5S0Hz9T/view?usp=sharing
On picture you see that the circle start to be more ... circular ...

I cleaned the source for the Quad added to the lib , it's here (with front porch on 640 x 480)
Now just take a look on the vsync signal and don't forget front and backporch ;)

code is here :
https://drive.google.com/file/d/17KqSjvzzOAo3Os2xBVhYzfu-cmwaFCr2/view?usp=sharing

Good night.
 
Last edited:
It is still strange to me.
Is the front porch not the timing before the H-pulse goes low?
I expect the line interrupt to occur on the falling edge so why to add the front porch before the RGB data are generated?

I agree that it did something. I also changed the DMA timing a bit and I have some kind of stable image for 640x480.
The only problem is that the image is now shifted to the right a lot.

Can you check the signal again?
I pushed your code + my latest change to the GIT.
 
Wow , allot better now :)
On the scope the vsync is good now.

why to add the front porch before the RGB data are generated?

Before ? , Hsync have to be after the pixels.

With hsync to 1
put the 640 pixels out then wait front porch (16 pixels) , put hsync to 0 , wait sync time of 96 pixels , put hsync to 1 , wait back porch (48 pixels).

Vsync have to be after the 480 line
With hsync to 1
put the 480 line on screen
wait v_frontporch (10 lines) , put vsync to 0 , wait vsync time of 2 lines , put vsync to 1 , wait v_backporch (33 lines) ... <- wait time for 1 line = time it need for 800 pixels = 31.777µS

What i don't remember is if we need hsync when the frame is finish and we do the v_frontporch , vsync , v_backporch
As i see on scope you actually output hsync like normal when you do vsync ... and i don't remember if this is correct :D
I will check on my CMM2 board that output VGA Too for see , but , after work :)
 
last change...
I changed the H-SYNC interrupt to the rising edge (iso facing edge) by adapting the QTIMER code.
It makes the parameters more meanful for me (back porch is then indeed after the pulse) and it spares some pixels in the buffer per line.
Last version on GIT...
I also put your vgatestalign in the example running at 640x480.

You better use that one to measure.
I hope we can have the video PLL being setup for better timings one day...
depending on wha is in the buffer, the image flickers a bit....
 
I cannot get the DMA copy at the proper frequency for 640xY.
It is flashing because of a too slow pixel clock for the DMA copy.
Using the proper frequency results in corruption of the data so I had to slow down the clock.
It copies some data during the front porch and the pulse which is not "in spec".
I have introduce pixel cropping so at the end I have a buffer of 640x480 but only (640-92)x480 is rendered, to stay in spec.
=> 548x480 max res... I kept it 640x480 to test the Amiga emulator at 640x480 but I better rename that more to 548x480.
So we can forget a real 640xY mode for the moment. I posted a message on the forum for the video PLL usage...
 
Hi ,

Is fb_stride supposed be the length of a whole line ? i mean , 640 pixels + frontporch + vsync + backporch ?
If yes , then the vsync lenght itself was not there , i added it but the result stay same.
I have try to find a 'real' docs about the register and how they work for irq , timing etc , but i just get a datasheet from the MCU that tell you what's in but not how to use it like a application notes.
They are some application notes around but not for what we need :(
If you know a place where all this info are available , it will help allot , now i just 'imagine' what the register used here are doing without be sure that's correct.
Now i measure on scope again , the hsynch seems to be ok.
The vsynch have now a consistent signal , BUT , the period is 33.45mS and it have to be 16.68mS ;)

scope image here :
hsync : https://drive.google.com/file/d/1tImmOf268In71CMHbNDx7VZ-3PVZKXjU/view?usp=sharing
vsync : https://drive.google.com/file/d/1fTiJbteEnFAyuku0y06kfRhJCmdWD_5W/view?usp=sharing

VGA_t4.cpp with the hsync_wide added to the fb_stride line.
https://drive.google.com/file/d/1d8fj15COub2EsipbZho1uHeiWJdn4dsr/view?usp=sharing

Cheers.
 
the hsync_wide should not be added to the fb_stride.
The stride is just the distance between 2 lines of the frame buffer.
One full line of the frame buffer (fb_stride) is what must be copied by the DMA copy per line.

Now that the DMA copy start on the rising edge of the HSYNC (I changed that) it means:
- pixels of the back porch (48)
- pixels of data (640)
- pixels of the front porch (16)
The RGB value during the H-PULSE remains 0 (last value of the pixel of the front porch)

Next h-sync will go low... and later high again (=> next interrupt)

Of course as the DMA copy is too slow probably the RGB is not zero during the HPULSE...this is why I said I should create a 548x480 mode.

Strange for the V-pulse. you mean it is not 60Hz?
 
On my scope it measure 29.9Hz for the vsync (see the picture).
And is bad that the DMA is too slow , will be good to see the max speed reach from the DMA at outputting FlexIO bytes.
The 548x480 mode must normally have the same sync speed than the 640x480 because for have the correct pixel size you need the same timing as 640 x 480 , you just ignore 46pix at start and end of the active area :)
I will try to find more info about this MCU , i just see allot for T3.6 but it does not work the same way , and they can output VGA without problem but those code are not applicable for the T4.1 ....

Cheers.
 
Hi :)

I have now 640x480 full screen , apparently the left black border was from reading empty memory (i think) , i shifted the start address from FlexIO memory start and the black band vanished

Here is the code : https://drive.google.com/file/d/1nm2fT7q4a3kqKzKul-EI4ld2ER7x5KPf/view?usp=sharing

Added is :
Code:
#define MEM_SHIFT     10

Modified is :
Code:
unsigned long * p=(uint32_t *)&gfxbuffer[fb_stride*y] + MEM_SHIFT;
and the other that follow ....

It's still not perfect but it become better ;)

Frog-Never-Give-Up-Frog.jpg

Cheers.
 
I will have a look in the evening as my VGA setup wires did break again ;-(

I have to edge my PCB but of course the toner was empty and now I have to go with my family.
I hope I have something usable this evening.

Then I have something more stable for my experiments...

For the 30Hz iso 60 Hz I now wonder if the interrupt does not occur on both rising and falling edges. That means the line would count twice faster and all timing for the V sync would be reduced by 2. But that would reduce period so increase frequency to 120Hz??
 
Nice setups!
I am not really a HW guy as you probably noticed but I was always impressed at 9 years old when my father was creating PCBs.
I am not a fan of PCBway. I still do PCBs myself, single sided, using laser printing on glossy paper later transferred to the copper plate with my cheap laminator.
It is also 99% recycled as the FeCl3 is reusable!

It is far from perfect but quality of edging is great with this process.
The edging was done 1 hour ago, I drilled all holes, soldered the header connectors.
It is a bit dark so I will continue tomorrow morning.
I hope there is no mistake!

I love your Maximite2 board. Were you involved in the project itself. I am a fan of the C64 so I liked the idea of running basic on a modern CPU.
It is a great project!
Is it also using PSRAM as external memory?
 
Back
Top