PDA

View Full Version : VGA out for Teensy 4.0/4.1



Jean-Marc
08-09-2020, 03:03 PM
Trying to bring something like uVGA library to the Teensy4.
Now all MCUME emulators support VGA output!!!

https://www.youtube.com/watch?v=UE9MPr-iVOg

https://github.com/Jean-MarcHarvengt/VGA_t4

KE4EST
08-09-2020, 04:44 PM
Nice work!

flashburn
08-10-2020, 06:56 PM
Fantastic!
Go on for the 12 bit. It is so good to have an Amiga again. Thank you!

darthvader
08-15-2020, 08:51 PM
So nice :)
I just have to wait for some components and i try it , Amiga Forever ;)
Is the teensy 4.1 uae version updated for VGA on your github ? , i have look but i think it's the ili9341 version.

Cheers.

Jean-Marc
08-16-2020, 09:16 AM
Emulator's code adapted for VGA is not yet published. Still trying to fix higher resolution for the Amiga and Atari ST!

darthvader
08-16-2020, 11:02 AM
I just made a R2R VGA DAC that output perfect colors , but when i try to upload the schematic (png 1280 x 688) it don't work.

So the schematic is dropped to google drive : https://drive.google.com/file/d/12U0av5Nhf6820NMHgQIal0NNC7oYMvSH/view?usp=sharing

Cheers.

darthvader
08-16-2020, 11:32 AM
This VGA to HDMI converter work fine with your project :

https://www.amazon.fr/gp/product/B01N2LZDP8/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

It's french amazon , but it must be available on other country too ...

Cheers.

Jean-Marc
08-16-2020, 02:48 PM
I will upload the schematic to the GIT website. Thanks a lot!

darthvader
08-16-2020, 04:10 PM
After playing around i added some functionalities to the graphics lib :

void drawline(int16_t x1, int16_t y1, int16_t x2, int16_t y2, vga_pixel color);
void drawcircle(int16_t x, int16_t y, uint16_t radius, vga_pixel color);
void drawfilledcircle(int16_t x, int16_t y, int16_t radius, vga_pixel fillcolor, vga_pixel bordercolor);
void drawellipse(int16_t cx, int16_t cy, uint16_t radius1, uint16_t radius2, vga_pixel color);
void drawfilledellipse(int16_t cx, int16_t cy, uint16_t radius1, uint16_t radius2, vga_pixel fillcolor, vga_pixel bordercolor);
void drawtriangle(int16_t ax, int16_t ay, int16_t bx, int16_t by, int16_t cx, int16_t cy, vga_pixel color);
void drawfilledtriangle(int16_t ax, int16_t ay, int16_t bx, int16_t by, int16_t cx, int16_t cy, vga_pixel fillcolor, vga_pixel bordercolor);

you can see the result here :
https://drive.google.com/file/d/1qb_T9d1RTNZqkkz_75CRN3HInjJrsr14/view?usp=sharing

I just see one problem , the circle are ... ovale ;)

The horizontal and vertical lines are spaced from 10 pixels , here we see that the pixels have a size in x of 2 and 1 in Y.

Well ... i will go for manage my circle differently :)

Cheers.

PS : for the schematic , take this one , it's the original before reduction :
https://drive.google.com/file/d/15tzG6HwElvlZym2a9YxOU0MsCzWxibKU/view?usp=sharing

Jean-Marc
08-16-2020, 07:32 PM
Thanks. I will merge your code into the git tomorrow.

In meanwhile, I pushed the VGA support code to the teensyuae41.

https://github.com/Jean-MarcHarvengt/MCUME

I was trying the all day to introduce a 640x240 mode but I don't manage.
Still runs at 352x240 (320x240 in fact) wo sound but not too bad...even in RRRGGGBB mode.

Pay attention to iopins.h for the 3 keys needed an the joypad,... and you the need psram soldered of course!

darthvader
08-16-2020, 08:56 PM
Thanks. I will merge your code into the git tomorrow.

The code is here :

https://drive.google.com/file/d/1il82ZcmjEY7mm4wsr_fqGjO8SeuZedSP/view?usp=sharing

I don't have finished the "Quad" function , it need pre calculed sin/cos for efficiency , as i am new in teensy world , i have do allot with STM32F4 / F7 in the past , and need some time to understand how everything is working :)

And thanks for your code update , i will test it tomorrow ;)

darthvader
08-16-2020, 11:08 PM
Here is the source from my old STM32 library for the exact timing of some VGA resolution :

HSync_Level and VSync_Level change , it depend the resolution , you have to take care on this too ...
PLLSAI_VCO , PLLSAI_R , PLLSAIDivR are just for STM32Fxx timing .... most important is to stay in the 25.175Mhz range , a little drift is working so long it's not too much :D
I hope it can help you for the 640 x 240 resolution ...



// VGA Parameter common to all resolution made with
// the standard 640x480 at 60Hz base.
// 25.175Mhz base (here is 25.187 Mhz)
#if defined USE_240x320_60 || defined USE_320x240_60 || defined USE_320x240_60_DOUBLE || defined USE_640x480_60
#define GFX_H_Front_Porch ((uint16_t)8) //pixels
#define GFX_H_Sync ((uint16_t)96) //pixels
#define GFX_H_Back_Porch ((uint16_t)40) //pixels
#define GFX_V_Front_Porch ((uint16_t)2) //lines
#define GFX_V_Sync ((uint16_t)2) //lines
#define GFX_V_Back_Porch ((uint16_t)25) //lines
#define GFX_Total_line_length ((uint16_t)800) //pixels
#define GFX_Total_Height ((uint16_t)525) //lines
#define Freq_PLLSAI_VCO ((uint16_t)403) //Mhz
#define Freq_PLLSAI_R ((uint16_t)2) //Div 2 (403/2 = 201.5 Mhz)
#define Freq_PLLSAIDivR ((uint16_t)7) //Div 8 (201.5/8 = 25.187 Mhz) do -1 from divider
#define HSync_Level ((uint16_t)0) //Low
#define VSync_Level ((uint16_t)0) //Low
#endif

#ifdef USE_240x320_60
#define GFX_H_Left_Border ((uint16_t)208) //pixels
#define GFX_H_Video_Line ((uint16_t)240) //pixels
#define GFX_H_Right_Border ((uint16_t)208) //pixels
#define GFX_V_Top_Border ((uint16_t)88) //lines
#define GFX_V_Video_Height ((uint16_t)320) //lines
#define GFX_V_Bottom_Border ((uint16_t)88) //lines
#endif

#ifdef USE_320x240_60
#define GFX_H_Left_Border ((uint16_t)168) //pixels
#define GFX_H_Video_Line ((uint16_t)320) //pixels
#define GFX_H_Right_Border ((uint16_t)168) //pixels
#define GFX_V_Top_Border ((uint16_t)128) //lines
#define GFX_V_Video_Height ((uint16_t)240) //lines
#define GFX_V_Bottom_Border ((uint16_t)128) //lines
#endif

#ifdef USE_320x240_60_DOUBLE
#define GFX_H_Left_Border ((uint16_t)8) //pixels
#define GFX_H_Video_Line ((uint16_t)640) //pixels
#define GFX_H_Right_Border ((uint16_t)8) //pixels
#define GFX_V_Top_Border ((uint16_t)8) //lines
#define GFX_V_Video_Height ((uint16_t)480) //lines
#define GFX_V_Bottom_Border ((uint16_t)8) //lines
#endif

#ifdef USE_640x480_60
#define GFX_H_Left_Border ((uint16_t)8) //pixels
#define GFX_H_Video_Line ((uint16_t)640) //pixels
#define GFX_H_Right_Border ((uint16_t)8) //pixels
#define GFX_V_Top_Border ((uint16_t)8) //lines
#define GFX_V_Video_Height ((uint16_t)480) //lines
#define GFX_V_Bottom_Border ((uint16_t)8) //lines
#endif

#ifdef USE_640x350_70 //25.175 Mhz
#define GFX_H_Left_Border ((uint16_t)0) //pixels
#define GFX_H_Video_Line ((uint16_t)640) //pixels
#define GFX_H_Right_Border ((uint16_t)0) //pixels
#define GFX_V_Top_Border ((uint16_t)0) //lines
#define GFX_V_Video_Height ((uint16_t)350) //lines
#define GFX_V_Bottom_Border ((uint16_t)0) //lines
#define GFX_H_Front_Porch ((uint16_t)16) //pixels
#define GFX_H_Sync ((uint16_t)96) //pixels
#define GFX_H_Back_Porch ((uint16_t)48) //pixels
#define GFX_V_Front_Porch ((uint16_t)37) //lines
#define GFX_V_Sync ((uint16_t)2) //lines
#define GFX_V_Back_Porch ((uint16_t)60) //lines
#define GFX_Total_line_length ((uint16_t)800) //pixels
#define GFX_Total_Height ((uint16_t)449) //lines
#define Freq_PLLSAI_VCO ((uint16_t)403) //Mhz
#define Freq_PLLSAI_R ((uint16_t)2) //Div 2 (403/2 = 201.5 Mhz)
#define Freq_PLLSAIDivR ((uint16_t)7) //Div 8 (201.5/8 = 25.187 Mhz) do -1 from divider
#define HSync_Level ((uint16_t)1) //High
#define VSync_Level ((uint16_t)0) //Low
#endif

#ifdef USE_640x400_70 //25.175 Mhz
#define GFX_H_Left_Border ((uint16_t)0) //pixels
#define GFX_H_Video_Line ((uint16_t)640) //pixels
#define GFX_H_Right_Border ((uint16_t)0) //pixels
#define GFX_V_Top_Border ((uint16_t)0) //lines
#define GFX_V_Video_Height ((uint16_t)400) //lines
#define GFX_V_Bottom_Border ((uint16_t)0) //lines
#define GFX_H_Front_Porch ((uint16_t)16) //pixels
#define GFX_H_Sync ((uint16_t)96) //pixels
#define GFX_H_Back_Porch ((uint16_t)48) //pixels
#define GFX_V_Front_Porch ((uint16_t)12) //lines
#define GFX_V_Sync ((uint16_t)2) //lines
#define GFX_V_Back_Porch ((uint16_t)35) //lines
#define GFX_Total_line_length ((uint16_t)800) //pixels
#define GFX_Total_Height ((uint16_t)449) //lines
#define Freq_PLLSAI_VCO ((uint16_t)403) //Mhz
#define Freq_PLLSAI_R ((uint16_t)2) //Div 2 (403/2 = 201.5 Mhz)
#define Freq_PLLSAIDivR ((uint16_t)7) //Div 8 (201.5/8 = 25.187 Mhz) do -1 from divider
#define HSync_Level ((uint16_t)0) //Low
#define VSync_Level ((uint16_t)1) //High
#endif

MarkT
08-16-2020, 11:49 PM
[sorry to snoop on the "Quad" code, but I couldn't help noticing]

I'm sure you only need to call sine and cosine once each for the rectangle drawing, using transformation
matrix... Transform one coord of one corner (w/2, h/2), transform two vectors for the sides (w, 0), (0, h),
reconstruction of the other corners is then addition/subtraction of vectors.

Calculating four different angles doesn't seem an efficient method to me.

darthvader
08-17-2020, 05:04 PM
I just tested uae on T4.1 ;)
So great to see a full speed Amiga coming out of this little Teensy !!
I need now a keyboard , i take a look at your i2c keyboard , your schematic is 'Ugly' :)
Do you have something more explicit to build the KB ? , you use Atmega328 (same as arduino nano) , now your pinout and key distribution made some knot into my poor brain.
It will be better with a real schematic or is it possible to connect a usb kb directly ?
Some game need more than one disk , and i was not able to 'change' disk when requested , is it a way to do it ?

Cheers.

Jean-Marc
08-17-2020, 05:19 PM
The original idea was to create a portable amiga with the ILI display, so I had chosen to build a I2C interfaced keyboard matrix ;-)

I did not try to add usb keyboard support but should be doable.
I need to find a usb cable. I can have a look this week.

I received my PCM5102a sound module today.
I just connected it over I2S and it sounds great together with the VGA out.
It disturbs the line interrupt a bit but sound is ok!

Jean-Marc
08-17-2020, 05:27 PM
May I ask you to try something for me...
You probably have a better cable than me and you also use the R2R ladder you proposed.
Could try to activate sound in platform_config.h on the amiga emulator.
Just uncomment HAS_SOUND line...

Do you also have disturbance on the video lines?

defragster
08-17-2020, 05:45 PM
Impressive the 1062 allows upgrade from the 6502!

For USB Host keyboard ref perhaps:: On github.com/FrankBoesing/Teensy64 (https://github.com/FrankBoesing/Teensy64) 3 years back - Commodore C64 Emulation on a Teensy 3.6 Microcontroller used USB for keyboard - also did VGA and ILI9341. It also had PS/2 keyboard support.

darthvader
08-17-2020, 05:53 PM
Hi :)

I tested , i get disturbance in video line , when sound is activated.
I2C Keyboard is a good idea , but then we need a ... real ... schematic ;)

On this picture you can see the disturbance on the vertical lines (you have to zoom in):
https://drive.google.com/file/d/1cO7NwD4TxsylFM5K1WqV75-yYtKabANj/view?usp=sharing

Cheers.

darthvader
08-17-2020, 05:58 PM
Impressive the 1062 allows upgrade from the 6502!

For USB Host keyboard ref perhaps:: On github.com/FrankBoesing/Teensy64 (https://github.com/FrankBoesing/Teensy64) 3 years back - Commodore C64 Emulation on a Teensy 3.6 Microcontroller used USB for keyboard - also did VGA and ILI9341. It also had PS/2 keyboard support.

Hi , the teensy64 is included in the emulator pack from Jean-Marc :)

defragster
08-17-2020, 06:05 PM
Hi , the teensy64 is included in the emulator pack from Jean-Marc :)

Though so ... has been a while - just a reminder - so USB keyboard or PS/2 usage should be easy to port as Frank did it.

darthvader
08-18-2020, 05:55 PM
Hi :D

Today i connected a PS2 or (USB to PS2) keyboard to a arduino nano who read the KB and send the character out to I2C when requested.
Is it something to know to made it work like your I2C KB ? so it will be good for all of your emulators.

Cheers.

Jean-Marc
08-18-2020, 07:10 PM
It is a great idea indeed. The I2C protocol is quite simple. I just reads (one single read command) an array of bytes where each bit reflects the status of one key. I had 2 variants. 4 rows of 10 keys (4bits-4bits-4bits ...4bits grouped in bytes per 2 columns) => 5 bytes. I also had variant with 5 rows of 10 keys but the portable console T4 has only 4x10 keys.

About Teensy64, it is indeed the project of Frank! I forked the code when I added support for a on screen keyboard using the ILI touch screen when using the VGA output (uVGA) on the T3.6.

I tried activating USB and I think it will also work to add USB keyboard directly on UAE. I found a USB connector I will try to connect it to the T4 tomorrow.

I am off next week so I will measure the accuracy of the H-pulses with a scope. Still did not manage to get proper clock for 640x240.
I think it was a miracle to have 352x240 working!

Thanks for your interest to the project ;-)

darthvader
08-18-2020, 08:52 PM
Hi :)

Strange that you can't get the 640 x 240 resolution , it must be something with the timing.
I got problems with that some years ago with the STM32F407 MCU , when everything was ok the 640 x 480 native VGA was perfect.
Now with STM32H7 i'm sure we can have the 800x600 or 1024x768 , but it use the DMA2D + LTDC ...
Teensy 4.1 got 200+ Mhz than the STM32H7 then it will work too ... for sure ... ;)
Now for the keyboard , i found this in 'emuapi.h' :


#ifdef HAS_I2CKBD
const unsigned short i2ckeys[] = {
0X0080,0X0008,0X0180,0X0108,0X0280,0X0208,0X0380,0 X0308,0X0480,0X0408,
0X0040,0X0004,0X0140,0X0104,0X0240,0X0204,0X0340,0 X0304,0X0440,0X0404,
0X0020,0X0002,0X0120,0X0102,0X0220,0X0202,0X0320,0 X0302,0X0420,0X0402,
0X0010,0X0001,0X0110,0X0101,0X0210,0X0201,0X0310,0 X0301,0X0410,0X0401 };
//0X0580,0X0540,0X0520,0X0510,0X0508,0X0504,0X0502,0 X0501,0X0680,0X0640 };
#endif


I presume that is the keycode , you are using 40 keys , on your picture they are no characters written on the keys :eek:
Is there a corresponding table to know what key trigger what character ?
I will take it as example for finish my actual setup with the i2c (real keyboard).
Only KB with cable are working actually , i tested 2 wireless KB with no luck.


I tried activating USB and I think it will also work to add USB keyboard directly on UAE
I hope it will not take precious resources :)


Thanks for your interest to the project ;-)
Lol , thanks to you who made it work !

Cheers.

Jean-Marc
08-18-2020, 09:59 PM
indeed, each emulator in MCUME (computer with a keyboard) has a similar table.
The table you pasted above is somehow derived from the I2C data read (see emuapi.cpp for details). Kind of row+col code.

Next to that you have a keymap table of same size with the code injected to the emulator itself.

In case of the amiga, there are 2 keymaps table. One where Function keys are sent in first row, one where digits are sent.
You toggle via a user button between the 2 keymaps

Not all keys are mapped in current layout but it can be extended.

const unsigned short key_map1[]={

1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };

const unsigned short key_map2[]={

41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };

In case of the amiga each entry in the keymap is an index to the amiga key but does not matter.

darthvader
08-18-2020, 10:33 PM
Ok :)

So i will look that my I2C code correspond to yours.
Is just that i put only one char on I2C bus each time , i see in 'emuapi.c' that you get 7 bytes each time ....
So i have to made some mods :D
Or add a new #define for 102 key KB ... will see ....
Thanks for your infos :)

Cheers.

defragster
08-18-2020, 11:32 PM
IIRC there was some timing noise/jitter introduced with USB on the original VGA - with T_3.6 - that went into the Teensy64. But it still allowed ALL of C64 to run there. Initially Frank did a private USBHost it seems to disable/alter something - but scan at that old github looked like he went to PJRC release?

Timing and USB different of course with 1062 and faster USB - for better or worse.

I enjoyed working along with FrankB - good to have somebody else on board. And as cool as the T_3.6 was back then ... T_4.1 with PSRAM and more other is a step up.

Jean-Marc
08-19-2020, 06:19 AM
Frank is definitively a great guy. Very knowledgeable and who contributed to many things on this forum, next to his own projects.

May be someone has a clue why i2s audio is also causing jitter on my qtimer3 line interrupt. Teensy3.6 has its own DAC and was not interfering with uVGA. May be I should try another qtimer or another timer than timer 3 in qtimer 3? I tried raising the priority of qtimer3 ISR but not much change. Not sure how to decrease I2S ISR to see if any effect.

defragster
08-19-2020, 01:51 PM
Indeed - FrankB has done some awesome things - hopefully he'll be back from his break and all moved into his new place and ready for more Teensy fun in good time.

@luni or others might have good feedback on timers. They are a bit different and not all for the better than T_3.6 it seems. Interrupts are a bit less efficient on timers and pin interrupts are all cascaded across a single interrupt with the default 1062 switched to fast GPIO.

KurtE made yield() less intrusive and faster to check the serialEvent_X_() things. But doing a "void yield() {}" in sketch can still make even that 'weak' thing go away, as long as none of the Event code [ Arduino serialEvent(), or PJRC's eventResponder's ] are in use. That yield() is called on every exit of loop() - and on delay() as well.

Jean-Marc
08-20-2020, 07:31 AM
USB keyboard is working fine. I wired the connector and it all went fine with my wireless keyboard. I added a table for handling main keys in the emulator. It works but I have to handle the release differently as that version of UAE does no handle keyup properly. I hope to share the code. I used the keyboard class part of the host library. Hard to say if there is disturbancel effect at this point...!

darthvader
08-20-2020, 01:28 PM
Hi :)

Great news if we can use directly a USB KB , i was trying to understand how to use my version ( 1 char sent per I2C at a time ) , but how it's done in UAE it's like to try to find out your way in a maze ;)
In your VGA Lib i see this :



#ifdef BITS12
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(16); // 16-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(0); // Select pins FXIO_D0 through FXIO_D12
#else
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(4); // 8-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(0); // Select pins FXIO_D0 through FXIO_D3
#endif


Is this correct ? , 1st for 12 bits / pixels you use FLEXIO_SHIFTCFG_PWIDTH(16); // 16-bit parallel shift width , but for 8 bits/pixel you use FLEXIO_SHIFTCFG_PWIDTH(4); // 8-bit parallel shift width , why is there a 4 in the parameter ?

some lines after thoose you use :



#ifdef BITS12
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(5); // 5-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(4); // Select pins FXIO_D4 through FXIO_D8
#else
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(4); // 8-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(4); // Select pins FXIO_D4 through FXIO_D7
#endif


Again for 5 bit shift you use 5 but for 8 bit shift you use 4 :D ....

I don't know if it's correct , but if not then you can presume that some graphics tearing can come from here.

When i made it on STM32Fxx i have use this info and take the 640 x 480 60Hz resolution as base of all other res i made.
https://drive.google.com/file/d/1W3YmJdLxMdyg50v7ym3aeKtSyewpI1Kt/view?usp=sharing

For example :

320 x 240 res was just 640 x 480 but with 2x bigger pixels

now for your 512 x 480 i will add 64 black pixels border on left and right , the advantage is that the pixel ratio is still OK , and when you trace a circle it appear as circle and not as oval :)

And it's working on the 640 x 480 base resolution.

I just hope i explain correctly :D VGA is not a easy stuff ... he he


Cheers.

Jean-Marc
08-20-2020, 02:21 PM
The 12bits mode is not tested an probably incorrect too ;-(

For 8bits mode is this also incorrect?

the first FLEXIO (the IO I need starts at D0)
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(4); // 8-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(0); // Select pins FXIO_D0 through FXIO_D3

the second uses (the IO I need starts at D4)
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(4); // 8-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(4); // Select pins FXIO_D4 through FXIO_D7

I guess you will have to change the clock divider to add 64 pixels left and right.
I am very curious now...
Again, I must have been very lucky with the 352x480 mode...
I think it is time to use a scope to verify all those signals....
May be they are just all wrong...

I also found that changing CPU clock was making everything wrong.
I was expecting the PLL used for the shift register to be independent...

darthvader
08-20-2020, 02:56 PM
You have to set the PLL that output the pixels , vsynch , hsync at closest you can from 25.175Mhz to get the perfect timing.



1 : Do this 480 times : Output the 640 pixels , then , after waiting the time it need for 16 pixels (H front porch) , you put hsync signal to 0 , now after waiting the time for 96 pixels (H sync pulse) , you put hsync back to 1 and wait again the time it need for 48 pixels (H back porch).

2 : After this wait the time it need to write 10 lines (V front porch) , you put Vsync to 0 , wait the time it need to write 2 line (V sync pulse) , put Vsync back to 1 , wait the time it need for write 48 lines (V back porch).

3 : return to 1 ;)

If you apply this timing , you no more need ... luck ... ;)

Cheers.

easone
08-20-2020, 05:47 PM
About the FlexIO shift width register...

FlexIO only has 1,2,4,8,16, and 32 bit shift modes.

FLEXIO_SHIFTCFG_PWIDTH(x) configures for x+1 parallel output bits, and the shifter mode is the smallest power of two that greater than or equal to x+1. So PWIDTH(5) is 8 bit mode, but PWIDTH(8) is 16 bit mode and PWIDTH(16) is 32 bit mode.

The difference between PWIDTH(4) and PWIDTH(5) is that either 5 or 6 consecutive bits are enabled inside the FlexIO peripheral, but the shifter still shifts by 8 bits each trigger. The extra bits are discarded.

Hope that helps!

Jean-Marc
08-20-2020, 07:48 PM
Hi,

Thanks for you clarifications!
So at least 8bits colors mode FLEXIO is correct then. 12bits will have to be adapted and tested.

I pushed the code of the emulator with USB keyboard support (QWERTY, at least relevant basic keys)

I will try to focus on the VGA aspect the coming days ;-)

darthvader
08-20-2020, 08:53 PM
Great news for the USB KB :)

If you tell me where you do the decoding for USA QWERTY KB to Amiga KB , i will add the AZERTY French one (so i can use mine;) )

I have try to understand how the timing , FlexIO and DMA work on teensy , but a little too hard for me who just know this MCU for at least 10 days ..

But in looking on how the other do i will learn faster :)

Cheers.

Jean-Marc
08-20-2020, 09:58 PM
Actually my keyboard is also AZERTY but somehow the USB library decodes it as QWERTY (a sends q...) ;-) Not sure what occurs with a real qwerty keyboard, I guess that table works.
May be there is a method to configure keyboard1 in emu_api.cpp as qwerty/azerty in the init?

USB keyboard callback ends up in emu_KeyboardOnUp() and emu_KeyboardOnDown() in UAE.cpp
The code commented out there is printing the key from the USB lib.

keyboardAsciiConv table convert codes <= 0x7f to amiga codes (in keyboard.h)
keyboardSpecialConv table converts codes between 0xc0 and 0xdf.
You could add a #define param in platform_config.h for AZERTY/ QUERTY and make another table for AZERTY then?
You can also add all amiga keys of the keyboard.h if you want.

Jean-Marc
08-21-2020, 08:28 AM
I forgot to mentioned that I get the keys as in the usbhost36 Mouse example library.
I use the main callbacks as I am not interested in the special keys as Volume control...
The keys I get looks like ascii codes (and special codes for F1-F10) if you look at the keyboard USB lib and not really keycodes.
I am not familiar with USB HID keyboard.
Maybe there is a way to know if the keyboard is AZERTY or QWERTY using USB lib?

https://github.com/PaulStoffregen/USBHost_t36

darthvader
08-21-2020, 10:29 AM
Press A,Q,W on azerty KB if you get Q,A,Z ... then you need FR conversion , not hard to do , i'm on it ..
I have do FR , DE , IT , ES keyboard for the Maximite in 2012/2013 and i do the same on Maximite 2 actually :D
But , i just see that my USB OTG don't have 5v on the T4.1 ... do you know why ?

PS : i tested on 2 different T4.1 board ... no 5v on the OTG

Jean-Marc
08-21-2020, 12:01 PM
Teensy4.1 has just standard USB, not OTG.
You just solder the connector (header pins) on top of the Teensy (close to the mini USB). 5 wires (2 gnd)
. 5 volt is there too!

https://www.pjrc.com/teensy-4-1-released/

darthvader
08-21-2020, 12:33 PM
My bad , i say OTG but it's USB HOST :)
The 5v is not active on the pin , on the schematic i see i'ts something to do with USB_VBUS pin from the MCU
Now on KB i followed the files to see where it go , all country are still done in this file :

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4\ke ylayouts.h
It's an #include to this file in :

C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\USBHos t_t36\keyboard.cpp
The only thing to do is uncoment your language #define in start of keylayouts.h
I go to try to activate the FR KB , it can be that USB_VBUS is set only if something is active in the USB lib ...

Jean-Marc
08-21-2020, 12:36 PM
I think I read that you have to init the USB_HOST lib to have the 5v active.
Do you have a sketch with USB running?

darthvader
08-21-2020, 01:02 PM
No USB before for me on T4.1
The 1st sketch is your emulator :D
I go check for some usb demo stuff and try to made them work to see what happens


So , i found a sketch that work :D

KeyboardBT from USB_Host_t36 , it activate the 5v pin

darthvader
08-21-2020, 01:48 PM
I find out what it was :)

Reset your board , check for 5v on USB Host , it's nothing ...
Start a Game from SD Card ...
5v appear on USB Host !
From the start i think it's active at start from the board ;)
Now i go to look if KB is ok with azerty mode

Jean-Marc
08-21-2020, 02:11 PM
I find out what it was :)

Reset your board , check for 5v on USB Host , it's nothing ...
Start a Game from SD Card ...
5v appear on USB Host !
From the start i think it's active at start from the board ;)
Now i go to look if KB is ok with azerty mode

Sorry, I forgot...
The keyboard so USB lib is only initialized in the emulator when you launch the game/image.
Else the callbacks were injecting keys in the emulator before the init....

darthvader
08-21-2020, 02:18 PM
AZERTY is ok , they just don't care on the 'ALT GR' key ... so the special chars are not present
~#{|`\^@]}
"<>" was not here too ... i go investigate where they are :)

darthvader
08-21-2020, 08:18 PM
Hi ,
I was the full evening in trying to get right code out :D
In debugging the KB , the code are correct , but is the conversion to amiga code that didn't work great.
Shift key , AltGr key are not really integrated to the Amiga Stuff.
The USB KB Lib use the HID Code that is easy to understand , but somewhere they made bit mask and from there , it's hard to follow :confused:
I stop for this evening ... tomorrow with fresh idea , it will go better ...

darthvader
08-22-2020, 11:19 AM
Hi ,
I have use one from the USB HID KB example to understand how the lib work :)
So i modified the example code to follow what we need , actually i made change for the FR KB that use the special 'Alt Gr' key.
Now for the other key that we don't get correct code '^*' i see that the HID give a OEM code that we can use too if combined with other key modifier.
For now you can test this if you got some time :
https://drive.google.com/file/d/1sWxrBxc2etCNb7KUEf3CV-W3r_61rJPV/view?usp=sharing

Open the serial monitor to see the key code.
Some chars don't appear in serial monitor , i think it use system basic chars , but so long the correct ascii code comes out is good :)

Cheers.

Jean-Marc
08-22-2020, 05:40 PM
Sorry, I was absent for the day with my family...
Just tried your sketch after selecting the proper layout in keylayouts.h.
I tried French and French Belgian.

I still have some problem with the Alt Gr.
If I want to type @ I do Alt GR + 2 normally but I get character 126 which is "tilt" instead of 64.

Have you adapted ALT GR for French or for French Belgian?
What is Alt GR + 2 on your keyboard?
For the rest it is good enough Alt GR + 3 is # so ok

darthvader
08-22-2020, 06:01 PM
Hi :)

I was not here too .. he he , i have do some debug on Colour Maximite 2 on the FR KB and corrected one error on the DE KB.
After that i have investigate the T4.1 KB system , and i corrected some keys for FR KB in keylayouts.h.
Actually i send key to serial for see what it's coming out and it's not bad at all.
On the FR KB '@' is ALTGR + 0
You can get my file here :
https://drive.google.com/file/d/1e6iV6bHFBAPcOxcPyMipRmmWerIlUhAR/view?usp=sharing

Some of the keys don't show up in the serial terminal , due to the key-code , but the ASCII code is OK.
And i don't have touch at the Belgian KB , just to understand the FR one was a dantesk task ... he he

Now , for the Amiga emulator , if the keys inside the emulator are not ok , then i think that we don't give the correct conversion ... but here ... i let you take a look , it's a little to much a maze for me ;)

Cheers.

Jean-Marc
08-22-2020, 06:16 PM
I found..
This code will make us both happy ;-)
if(keymodifier == 0x40){
// ALTGR Key modifier FR Keyboard
switch (key) {
#ifdef LAYOUT_FRENCH
case 233 : key = '~' ; break;
case 34 : key = '#' ; break;
case 39 : key = '{' ; break;
case 40 : key = '[' ; break;
case 45 : key = '|' ; break;
case 232 : key = '`' ; break;
case 95 : key = 92 ; break;
case 231 : key = '^' ; break;
case 224 : key = '@' ; break;
case 41 : key = ']' ; break;
case 61 : key = '}' ; break;
#endif
#ifdef LAYOUT_FRENCH_BELGIAN
case 38 : key = '|' ; break; //1
case 233 : key = '@' ; break; //2
case 34 : key = '#' ; break; //3
case 167 : key = '^' ; break; //6
case 231 : key = '{' ; break; //9
case 224 : key = '}' ; break; //0
case 36 : key = ']' ; break; //$
case 61 : key = '~' ; break; //=
#endif
}
}

darthvader
08-22-2020, 06:27 PM
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 ...

darthvader
08-22-2020, 08:47 PM
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.

Jean-Marc
08-22-2020, 09:42 PM
You will be disappointed. Sound really messes up the all VGA output and vice versa... ;-(

darthvader
08-22-2020, 09:50 PM
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 ?

Saibot
08-23-2020, 06:14 AM
21445
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...

Jean-Marc
08-23-2020, 09:43 AM
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 ;-)

darthvader
08-23-2020, 10:39 AM
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.

darthvader
08-23-2020, 12:57 PM
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 ...

Jean-Marc
08-23-2020, 01:47 PM
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 ...

Jean-Marc
08-23-2020, 02:11 PM
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....

darthvader
08-23-2020, 03:11 PM
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 :


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 ?

Jean-Marc
08-23-2020, 07:10 PM
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...

darthvader
08-23-2020, 08:44 PM
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.

darthvader
08-23-2020, 10:48 PM
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.

Jean-Marc
08-24-2020, 07:57 AM
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.

darthvader
08-24-2020, 09:26 AM
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.777S

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 :)

Jean-Marc
08-24-2020, 01:23 PM
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....

Jean-Marc
08-24-2020, 02:33 PM
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...

darthvader
08-24-2020, 03:08 PM
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.

Jean-Marc
08-24-2020, 04:07 PM
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?

darthvader
08-24-2020, 04:40 PM
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.

darthvader
08-25-2020, 10:24 AM
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 :
#define MEM_SHIFT 10

Modified is :
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 ;)

21470

Cheers.

Jean-Marc
08-25-2020, 10:55 AM
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??

darthvader
08-25-2020, 11:16 AM
The VGA Standard say to output vsync every 16.6832mS that is 1000/16.6832 = 59.94Hz
I don't have made any PCB here :o , i just take my 8 year old R2R VGA DAC PCB and fitted the some resistances that was needed and pull everything together :)
After everything was soldered on a test board i was ready ... he he ... just take a look at my setup ...
https://drive.google.com/file/d/1SHik8_LnQbqh65aWD2Vz6s_7CL-UhWwq/view?usp=sharing

Jean-Marc
08-25-2020, 07:52 PM
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?

darthvader
08-25-2020, 08:22 PM
Hi :)

I was involved in the 1st Maximite and Colour Maximite , and was so to say my job to made and fix keyboard for some country.
After that my work evolved and i was no more able to stay active in the project.
With a German guy's i made the 1st STM32 Maximite , but then he was not able to stay as on my side i have not allot of time the project was retaken from Peter Matter , Geoff Graham who invented the Basic interpreter continu now with Peter to make evolve the project on the new Colour MAximite 2.
I just have made the FR KB Layout and fixed a bug in the German KB , here stop my involvement in this project , with more time it will be easier to take active part but ... hmmm ... it's not the case :rolleyes:
Soon i go to Hinkley Point close from Bristol to install 7 Robots i programmed here in France , it's for the new EPR Power plant and i will be a little over booked :)
But so long i'm at home (this week and next but not sure) i try to play with the T4.1 and as i said , i know this MCU for little more than one week now.
For the maximite 2 use the STM32H7xx MCU and for memory it use 8Mb SDRAM , it's this card : https://www.waveshare.com/product/mcu-tools/core-boards-compact-boards/stm32-core/coreh743i.htm
The VGA is done directly from the integrated 2D engine (LTDC + DMA2D) , it's why i know VGA so good , i have do VGA 1st time in 2013 with this project : https://www.youtube.com/watch?v=axJRn_WZFY0

I am a fan of the C64 so I liked the idea of running basic on a modern CPU
Well , for me it was the ... Amiga ... ;)

Cheers

Jean-Marc
08-26-2020, 07:38 PM
I finished the small PCB this morning.
I added a joystick connector for a second joystick and I had to remap the analog joypad + button to other pins for convenience.

I have been playing with the video PLL a bit this PM.
Best I can get is 544x480.
Higher frequency also results in rubbish on screen.
I don't fully understand the setup of the video PLL. I need to read the chapter better. From what I understand:

F = (24MHz * (DIV_SELECT + NUM/DENOM) ) * POST_DIV_SELECT
Reading the spec DIV_SELECT is between 27 and 54.
POST_DIV_SELECT is 1,1/2 or 1/4.

I tried your version but you still don't get 640x480. If you print an digits pattern you will see that you also don't see 80 characters (8x80=640 pixels)

darthvader
08-26-2020, 08:25 PM
Hi ,
I don't have try char actually , just have try to have better image , it's like the FlexIO1 and FlexIO2 are shifted on 2 pixels , but i don't understand how all it's done ...
If you have some docs that explain how it's working it will be good for me to learn it :)
And when your PCB and final pinout is set , don't forget to made a schematic for explain how everything is connected ,i will do the same.

Cheers.

Jean-Marc
08-27-2020, 07:48 AM
The 2 DMAs cannot be started exactly at the same time as the DMA has a kind of queue of control.
This is why the RRRG and GGBB per pixel are not in phase.

You have to compensate by shifting the pixels.
I could compensate by modifying the source address (+2) for one of the copy but that only works for the lowest resolution somehow.
Another solution is to change the frame buffer itself (interleave the nibbles of the pixels)

R0R0R0G0 R1R1R1G1 R2R2R2G2
G2G2B2B2 G3G3B3B3 G4G4B4B4

I verified the V-pulse on my setup and I have 16ms BTW.
I have to go now.
I will continue and push the code in the evening.

darthvader
08-27-2020, 07:29 PM
Some times ago , Bitluni made allot of test about VGA on ESP32 MCU.
https://github.com/bitluni/ESP32Lib

I compiled all timing and put them in a PDF that you can take here :
https://drive.google.com/file/d/1tJVGBW-cIN8eUkuPiJZDJjny3Q-9X1Kn/view?usp=sharing

It will probably help you for all other resolution you want use on VGA :)

And i finally found some information on T4.1 that can a little help me to understand this MCU , it was here :
https://www.pjrc.com/teensy/datasheets.html

For the FlexIO they don't explain why you can't use any pins you want , it will be easy to made a 8bit parallel port that we can use directly without splitting him in 2 distinct part that give pixel shift :rolleyes:

As you say you checked the vsync timing and it was good , i do it too and strangely , now it's good too .. 16.74mS ... :) ... don't ask why ... he he

Cheers.

Jean-Marc
08-28-2020, 07:32 AM
Thank again for you support.
I understand the video PLL now and could use it at the place of the SW PLL.
It does not really improve but I learned at least something new!

I found why I have so much miseries with the timing.
The problem is really the 2 DMA copy at the same time.
If I only use one and show 4 bits (RRRG or GGBB does not matter), the timing are all logical with proper values for front and back porch, image is also perfectly centered at 640x480

As soon as the 2 DMA are started (even 32bit aligned copy), timing all becoming bad.
Not sure why.

The reason why you don't have 8 bits available on one FlexIO is again bounding and function offered at pin level.

https://github.com/KurtE/FlexIO_t4

In fact there is:

There is one possibility to use 8 pins at flexio1 on T4.1.
2, 3, 4, 5, 33, 49, 50, 52, 54 => pins
4, 5, 6, 8, 7, 13, 14, 12, 15 => flexio

But I have then to use 16bits to store 8bits color in memory which I find waste. An the pins are not that easy to access.
I will investigate other possibilities with this track...I think it is the only way to get 640x480 on the T4.1 (not the T4.0). Unless 4bits color is enough...;-(

darthvader
08-28-2020, 09:18 AM
Pins 48 to 54 are in use for the PSRAM , so , it's not possible to use them :)
I have take a look at the LCDIF pins with the nxp pin tool , all what we need is on FLEXIO2 but some pins are not accessible , the T41 just don't have the right pins connected to the world.
Is just bad that the FLEXIO3 don't have DMA ....
Now for accessing 8bit from 16bit is not a waste if you manage to access 2 different 8bit in this 16bit. You shift on 8bit not on 16bit for accessing the pixel color :)
And if you want your 12bit colors , then you have to use 16bit too.

darthvader
08-28-2020, 10:58 AM
I just got a stupid idea ... but not sure that's so stupid :) and go in a total reverse way than VGA ...
As all this emulator emulate ooOOooOOooLD machines , and all this old (computer) have use PAL or NTSC signals to generate composite video , is it not a way to create such signal on MQS pin to create this signal ?
I know it was something like that on ESP32 and it will resolve allot of problem if it's possible to do it on T41 , only 1pin needed for video , and the frequency is low 14Mhz or something like that.

Jean-Marc
08-28-2020, 12:37 PM
There is no DAC on the Teensy 4.
I am not sure MQS can be used for video signal.

BTW Bitluni used a tricky feature of the DAC on the ESP32.
It was possible to use the I2S to output on the DAC output of the ESP32.
I also think its VGA feature was using some tricky feature of the I2S block (to use it as some shift register?)
I watched the video a some time ago I cannot remember.

May be using the DMA is scatter/gather mode is our solution?
Switch destination every 4 bytes?
I run out of idea to be honest...

easone
08-28-2020, 03:08 PM
You could always use 8 bits of FlexIO3... It would be more processor intensive because you would need to use an interrupt to load the shift buffer instead of DMA. One thing you can do to decrease the number of interrupts is to use all four 32-bit shift buffers, which could hold 16 pixels worth of data...

I wonder if it's possible to synchronize FlexIO1 and FlexIO2 by using a single external trigger signal? Not sure how to achieve that.

darthvader
08-28-2020, 03:26 PM
Well , i'm not good enough with this MCU to tell you if it's ok or not for triggering 2 FLEXIO with only one signal :)
But for the FLEXIO3 it's sure that it will slow down everything without DMA.
And like Jean Marc , with this pin arrangement from the T41 i don't have allot idea rest in stock ...

Jean-Marc
08-28-2020, 05:06 PM
Is it possible to combine 4 shift registers to store 16 pixels in one go instead of 4?

How do I do this?

Now it copies 4 bytes per major loop into a single 32bits shift reg and I use SHIFTS_PER_TRANSFER = 4
FLEXIO2_TIMCMP0 = ((SHIFTS_PER_TRANSFER*2-1)<<8) | ((flexio_clock_div/2-1)<<0);

flexio2DMA.TCD->NBYTES = 4;
flexio2DMA.TCD->SOFF = 4;
flexio2DMA.TCD->SLAST = 0;
flexio2DMA.TCD->BITER = maxpixperline / 4;
flexio2DMA.TCD->CITER = maxpixperline / 4;
flexio2DMA.TCD->DADDR = &FLEXIO2_SHIFTBUF0;
flexio2DMA.TCD->DOFF = 0;
flexio2DMA.TCD->DLASTSGA = 0;
flexio2DMA.TCD->ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2); // 32bits
flexio2DMA.TCD->CSR |= DMA_TCD_CSR_DREQ;

What should become above params?

darthvader
08-30-2020, 12:14 AM
Hi :)
I just tested your new VGA_T4 lib , now the 640x480 is perfect , it's just little blue but no more pixel shift ;)
Your code is so far away from what i understand on T41 !! , where do you get all information's ?
The reference manual is OK for general information but then you have to found examples to really understand what to do :)
As i see , i think the emulators will be perfect if your VGA code become stable with no shift in screen ....
I can't wait for your next news ... he he ...

easone
08-30-2020, 12:18 AM
Is it possible to combine 4 shift registers to store 16 pixels in one go instead of 4?

How do I do this?
I haven't been able to test the following for VGA, but it is nearly the same as the configuration I am using for the SmartMatrix driver. Please forgive any errors!

First, you need to configure all 4 shift buffers. Set SHIFTCFG[INSRC] = 1 for each shifter to use the next shifter's output as input. Only shifter 0 can drive parallel pins, so the pins need to be disabled for shifters 1-3.


uint32_t timerSelect, timerPolarity, pinConfig, pinSelect, pinPolarity, shifterMode, parallelWidth, inputSource, stopBit, startBit;
uint32_t triggerSelect, triggerPolarity, triggerSource, timerMode, timerOutput, timerDecrement, timerReset, timerDisable, timerEnable;

// Shifter 0 registers
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(7); // 8-bit parallel shift width
pinSelect = FLEXIO_SHIFTCTL_PINSEL(0); // Select pins FXIO_D0 through FXIO_D7
inputSource = FLEXIO_SHIFTCFG_INSRC*(1); // Input source from next shifter
stopBit = FLEXIO_SHIFTCFG_SSTOP(0); // Stop bit disabled
startBit = FLEXIO_SHIFTCFG_SSTART(0); // Start bit disabled, transmitter loads data on enable
timerSelect = FLEXIO_SHIFTCTL_TIMSEL(0); // Use timer 0
timerPolarity = FLEXIO_SHIFTCTL_TIMPOL*(1); // Shift on negedge of clock
pinConfig = FLEXIO_SHIFTCTL_PINCFG(3); // Shifter pin output
pinPolarity = FLEXIO_SHIFTCTL_PINPOL*(0); // Shifter pin active high polarity
shifterMode = FLEXIO_SHIFTCTL_SMOD(2); // Shifter transmit mode
FLEXIO2_SHIFTCFG0 = parallelWidth | inputSource | stopBit | startBit;
FLEXIO2_SHIFTCTL0 = timerSelect | timerPolarity | pinConfig | pinSelect | pinPolarity | shifterMode;

// Shifter 1-3 registers are identical except with pin output disabled
parallelWidth = FLEXIO_SHIFTCFG_PWIDTH(7); // 8-bit parallel shift width
inputSource = FLEXIO_SHIFTCFG_INSRC*(1); // Input source from next shifter
stopBit = FLEXIO_SHIFTCFG_SSTOP(0); // Stop bit disabled
startBit = FLEXIO_SHIFTCFG_SSTART(0); // Start bit disabled, transmitter loads data on enable
timerSelect = FLEXIO_SHIFTCTL_TIMSEL(0); // Use timer 0
timerPolarity = FLEXIO_SHIFTCTL_TIMPOL*(1); // Shift on negedge of clock
pinConfig = FLEXIO_SHIFTCTL_PINCFG(0); // Shifter pin output disabled
shifterMode = FLEXIO_SHIFTCTL_SMOD(2); // Shifter transmit mode
FLEXIO2_SHIFTCFG1 = parallelWidth | inputSource | stopBit | startBit;
FLEXIO2_SHIFTCTL1 = timerSelect | timerPolarity | pinConfig | shifterMode;
FLEXIO2_SHIFTCFG2 = parallelWidth | inputSource | stopBit | startBit;
FLEXIO2_SHIFTCTL2 = timerSelect | timerPolarity | pinConfig | shifterMode;
FLEXIO2_SHIFTCFG3 = parallelWidth | inputSource | stopBit | startBit;
FLEXIO2_SHIFTCTL3 = timerSelect | timerPolarity | pinConfig | shifterMode;


The FlexIO timer and the DMA request should be configured to trigger on Shifter 3 instead of Shifter 0 (because shift buffer 3 will be loaded last), and the SHIFTS_PER_TRANSFER is 16 instead of 4:


// Timer 0 registers
timerOutput = FLEXIO_TIMCFG_TIMOUT(1); // Timer output is logic zero when enabled and is not affected by the Timer reset
timerDecrement = FLEXIO_TIMCFG_TIMDEC(0); // Timer decrements on FlexIO clock, shift clock equals timer output
timerReset = FLEXIO_TIMCFG_TIMRST(0); // Timer never reset
timerDisable = FLEXIO_TIMCFG_TIMDIS(2); // Timer disabled on Timer compare
timerEnable = FLEXIO_TIMCFG_TIMENA(2); // Timer enabled on Trigger assert
stopBit = FLEXIO_TIMCFG_TSTOP(0); // Stop bit disabled
startBit = FLEXIO_TIMCFG_TSTART*(0); // Start bit disabled
triggerSelect = FLEXIO_TIMCTL_TRGSEL(1+4*(3)); // Trigger select Shifter 3 status flag
triggerPolarity = FLEXIO_TIMCTL_TRGPOL*(1); // Trigger active low
triggerSource = FLEXIO_TIMCTL_TRGSRC*(1); // Internal trigger selected
pinConfig = FLEXIO_TIMCTL_PINCFG(0); // Timer pin output disabled
timerMode = FLEXIO_TIMCTL_TIMOD(1); // Dual 8-bit counters baud mode
#define SHIFTS_PER_TRANSFER 16 // Shift out 8 bits 16 times with every transfer = four 32-bit words = contents of Shifters 0-3
FLEXIO2_TIMCFG0 = timerOutput | timerDecrement | timerReset | timerDisable | timerEnable | stopBit | startBit;
FLEXIO2_TIMCTL0 = triggerSelect | triggerPolarity | triggerSource | pinConfig | timerMode;
FLEXIO2_TIMCMP0 = ((SHIFTS_PER_TRANSFER*2-1)<<8) | ((flexio_clock_div/2-1)<<0);
FLEXIO2_SHIFTSDEN |= (1<<3);

To configure the DMA transfer to fill up all 4 buffers in a single burst each time it is triggered, you can use a minor loop offset to reset the destination address after each burst. Conveniently, the FlexIO buffer registers are adjacent in memory space. The number of pixels in each line needs to be a multiple of 16.



unsigned int minorLoopBytes, minorLoopIterations, majorLoopBytes, majorLoopIterations;
int destinationAddressOffset, destinationAddressLastOffset, sourceAddressOffset, sourceAddressLastOffset, minorLoopOffset;
volatile uint32_t *destinationAddress, *sourceAddress;

DMA_CR |= DMA_CR_EMLM; // Enable minor loop mapping so that we can have a minor loop offset
minorLoopIterations = 4; // transfer 4 words with each DMA trigger into 4 FlexIO buffers
minorLoopBytes = minorLoopIterations * sizeof(uint32_t);
#define BYTES_PER_PIXEL 1
majorLoopBytes = maxpixperline * BYTES_PER_PIXEL; // This must be evenly divisible by 16
majorLoopIterations = majorLoopBytes / minorLoopBytes;
sourceAddress = (uint32_t*) & gfxbuffer[0];
sourceAddressOffset = sizeof(uint32_t);
sourceAddressLastOffset = - majorLoopBytes; // at completion of major loop, reset source address
destinationAddress = &FLEXIO2_SHIFTBUF0;
destinationAddressOffset = sizeof(uint32_t);
minorLoopOffset = -minorLoopIterations * destinationAddressOffset; // reset destination address at end of each minor loop...
destinationAddressLastOffset = minorLoopOffset; // ...and at end of major loop
flexio2DMA.TCD->SADDR = sourceAddress;
flexio2DMA.TCD->SOFF = sourceAddressOffset;
flexio2DMA.TCD->SLAST = sourceAddressLastOffset;
flexio2DMA.TCD->ATTR_SRC = DMA_TCD_ATTR_SIZE_32BIT;
flexio2DMA.TCD->DADDR = destinationAddress;
flexio2DMA.TCD->DOFF = destinationAddressOffset;
flexio2DMA.TCD->ATTR_DST = DMA_TCD_ATTR_SIZE_32BIT;
flexio2DMA.TCD->DLASTSGA = destinationAddressLastOffset;
flexio2DMA.TCD->NBYTES_MLOFFYES = DMA_TCD_NBYTES_DMLOE | DMA_TCD_NBYTES_MLOFFYES_MLOFF(minorLoopOffset) | DMA_TCD_NBYTES_MLOFFYES_NBYTES(minorLoopBytes);
flexio2DMA.TCD->BITER = majorLoopIterations;
flexio2DMA.TCD->CITER = majorLoopIterations;
flexio2DMA.disableOnCompletion(); // disable on completion or else it will be triggered by FlexIO continuously


By the way, I would configure both FlexIO1 and FlexIO2 to use FLEXIO_SHIFTCFG_PWIDTH(7) and FLEXIO_SHIFTCTL_PINSEL(0). This will select signals FXIO_D0 through FXIO_D7 to be output on both FlexIOs, but since the Teensy 4.1 only has pins 0 through 3 on FlexIO2 and pins 4 through 7 on FlexIO1, the extra signals will be discarded. And this should enable you to use FLEXIO2_SHIFTBUF0 and FLEXIO1_SHIFTBUF0 as your destination registers - no need to use the nibble byte swapped register FLEXIO1_SHIFTBUFNBS0 or to use an unaligned copy.

Hope that helps...

Jean-Marc
08-30-2020, 08:39 AM
Thanks a lot!
I will try all that today if I have the time between the various family trips planned. It is the last opportunity as tomorrow I am back to work...

The code I had pushed 2 days ago was just the version using the video PLL and for the 640x480 mode, I was only copying the lowest nibble with a single DMA, that is why the image was green/blue (only GGBB was copied!)
(but UAE is looking so much nicer at 640x240, even in blue!)
I am interested to see how the 2 DMAs will interfere by using the 4 shifters combined. I had experimented yesterday but no luck...
I will verify will your input.

Jean-Marc
08-30-2020, 11:05 AM
The code you propose results in a black screen.
I was looking at your DMA copy code, trying to use it with a single shift register (at least I know what I expect on the screen for that one!)


if I use my original code:
minorLoopIterations=1;
flexio2DMA.TCD->NBYTES = 4*minorLoopIterations;
flexio2DMA.TCD->SOFF = 4*minorLoopIterations;
flexio2DMA.TCD->SLAST = 0;
flexio2DMA.TCD->BITER = maxpixperline / (4*minorLoopIterations);
flexio2DMA.TCD->CITER = maxpixperline / (4*minorLoopIterations);
flexio2DMA.TCD->DADDR = &FLEXIO2_SHIFTBUF0;
flexio2DMA.TCD->DOFF = 0;
flexio2DMA.TCD->DLASTSGA = 0;
flexio2DMA.TCD->ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2); // 32bits
flexio2DMA.TCD->CSR |= DMA_TCD_CSR_DREQ;
=> that results a correct full screen image (single DMA copy)

If I do minorLoopIterations=4 (=> it will copy 16bytes to FLEXIO2_SHIFTBUF0 to 3 I guess), then I get the 4 times the image on the half left image (I understand 4 times the image as only the pixel copied to FLEXIO2_SHIFTBUF0 is used but why on 1/2 LEFT screen?)

If I use your DMA code with minorLoopIterations=1 I get a correct full screen image.
With minorLoopIterations=4 I get a black image.

Jean-Marc
08-30-2020, 12:09 PM
I noticed that I needed the full DMA setup in the interrupt. Then your DMA config seems to work with minorLoopOperation=4(at least I get what I would expect with a single shiftbuf, with minorLoopOperation=2 I get an half screen image, with 4 a smaller image however not 1/4th) So better than with mine...

But still I have a black image as soon I use 4 shift buffers...
I will continue a bit in the evening, I have to go now.
Thanks for the support...

easone
08-30-2020, 03:33 PM
I don't know exactly what's wrong without seeing the full code, but if you have TCD->DOFF = 0 with minorLoopIterations = 4 then your DMA is copying into single destination SHIFTBUF0 four times in a row before the FlexIO has shifted out all the data, so some data is being lost.

With 4 shift buffers and TCD->DOFF = 4, the triggers for the FlexIO timer and the DMA request need to be set to use shifter 3 instead of shifter 0 (FLEXIO_TIMCTL_TRGSEL(1+4*(3)) and FLEXIO2_SHIFTSDEN |= (1<<3)) so that all the data is correctly copied to the buffers before the shifters are loaded and shifting starts, and all the buffers are empty before the next copy starts. Make sure to set SHIFTS_PER_TRANSFER to 16 or else you may not get correct behavior.

Jean-Marc
08-30-2020, 08:12 PM
No luck with the code...;-(
I really believe that the DMA copy in the interrupt does not fill the 4 shift registers...
So below code is not behaving as expected.
triggerSelect = FLEXIO_TIMCTL_TRGSEL(1+4*(3)); // Trigger select Shifter 3 status flag
...
FLEXIO2_SHIFTSDEN |= (1<<3);
How to prove is not easy...
I tried keeping the same DMA copy (filling the 4 shift registers) and used SHIFTER1 iso SHIFTER0 in the single shift register variant.
triggerSelect = FLEXIO_TIMCTL_TRGSEL(1+4*(1));
FLEXIO2_SHIFTSDEN |= (1<<1);
I get strange behavior too...


I pushed the code as it is now. May be you can have a look.
https://github.com/Jean-MarcHarvengt/VGA_t4

The variant using 4 shift registers is under below compiler switch (commented out in commit!)
//#define COMBINED_SHIFTREGISTERS 1

BTW using FLEXIO_SHIFTCFG_PWIDTH(7) and FLEXIO_SHIFTCTL_PINSEL(0) to use destinationAddress = &FLEXIO1_SHIFTBUF0 and avoid the nibble shift is also not working somehow but I tried (not in the commit).

darthvader
08-31-2020, 07:29 PM
Hi , i've found bug in VGA_T4 , i corrected it , that was the pixel who can go out the screen and it append some time a freeze from the T41. Now it's OK :)
I made 2 new easy function :

void draw_h_line(int16_t x1, int16_t y1, uint16_t lenght, vga_pixel color);
void draw_v_line(int16_t x1, int16_t y1, uint16_t lenght, vga_pixel color);

I modified :
void drawfilledcircle(int16_t x, int16_t y, int16_t radius, vga_pixel fillcolor, vga_pixel bordercolor);
void drawfilledellipse(int16_t cx, int16_t cy, uint16_t radius1, uint16_t radius2, vga_pixel fillcolor, vga_pixel bordercolor);

The function call are like before , it's just internal code that have change.

I have a bug in the Ellipse , it's round ... Filled Ellipse is ok , the strange is that i have exactly the same code that work on STM32 ... he he
I completed the vgatestalign demo , it's little more active now :o

Bye the way , my old Rigol DS5102M scope died last night :(
I will get a Siglent SDS1204X-E for Wednesday in the hope it will last longer , only 10 years for the Rigol ... , my previous 50mhz old Hameg that i give to a friend is close to 30 year old and is still alive !!

Mods are here :
https://drive.google.com/file/d/1-owzPkVA3YcsHXdJkxBimh056VJPY_Ue/view?usp=sharing

Cheers.

darthvader
08-31-2020, 09:05 PM
I just found my Ellipse bug :)

replace
rad2 = radius1;
with
rad2 = radius2;

that's it :rolleyes:

Jean-Marc
08-31-2020, 09:16 PM
I will merge the changes tomorrow ;-)

Still no solution for the DMA ;-(

darthvader
08-31-2020, 09:30 PM
With byte decomposed in 2 parts it will not be easy to resolve for the DMA.
And use a little SPI LCD for Amiga emulator it's not the ideal way :)
A SPI LCD with more resolution will become too slow at refresh rate .... i just hope that a solution exist on VGA ...

darthvader
09-01-2020, 11:33 AM
Hi ,

I optimized the drawcircle , the test if pixels x,y was > to 0 is now useless because it's tested in drawpixel.
The precalculed sin/cos and ABS declaration are now in VGA_t4.h , so they are accessible from everywhere if #include "VGA_t4.h" is used , and by the way , it make VGA_t4.c more ... aesthetic :)
Code is here :
https://drive.google.com/file/d/1IzUOP46VVHHVgXdzS6fhWUM4xiNgBRfJ/view?usp=sharing

Jean-Marc
09-01-2020, 02:47 PM
I will merge your changes this evening. May be we should introduce cropping at pixel level for every primitives...
Another idea would be to use the 2D HW block to provide Blit/ScaledBlit. Of course with the non standard RGB 8bit mode it will be tricky.
Not sure if CLUT mode was supported by the 2D block.
At least for scrolling and sprites it might be interesting to have a Blit support in HW.

May be the 2D block could also be used to expand each line from 8bits to 32bits before the DMA does the copy, and use 32bits shift registers...you never know ;-)

darthvader
09-01-2020, 02:50 PM
What you explain with the 2D HW Block is like it work on STM32F7xx / H7xx with the LTDC and DMA2D ;) ... but you need to have the corresponding pins available ...

darthvader
09-02-2020, 01:20 PM
Hi ,
i continued with functions in VGA_T4 , now you can use polygon too :)
draw_h_line , draw_v_line mod to accept negative length value.
I will try to do a drawfilledpolygon but i got some problem with the filling algorithm :)
New code is here :
https://drive.google.com/file/d/1coY2GZcvwCdorhwGak5xrHQr9f_EkNLy/view?usp=sharing

The demo program use all of the gfx routine i added.

Cheers.

darthvader
09-02-2020, 05:43 PM
I just get my new scope :)
I see that after the last pixel from the last line you just wait 6 lines for the V front porch ... it have to be 11 (for 640 x 480) , the vsync itself is OK with 2 lines.
A little pics here :
https://drive.google.com/file/d/13e83n7x7Ya6SviAlq42Fs1I3j4AO0Vn_/view?usp=sharing

yellow is vsync , red is hsync , blue is pixels

darthvader
09-03-2020, 07:27 PM
Hi ,
I finally made the drawfullpolygon , it seem to work now :)
Code is here :
https://drive.google.com/file/d/1cuT6xqE7OqCBtNcQd_AwLePSVZRvaxpo/view?usp=sharing

Cheers.

darthvader
09-06-2020, 07:57 PM
Hi Jean Marc :)
Any news on the project ? , i have work on some other project and hope you advance in your VGA problems ...

Jean-Marc
09-06-2020, 09:26 PM
Hi,
No, not really. I tried isolating the DMA code to ask more support on the forum but I finally decided to work on another project too.
And no much more luck on the new project too ;-(

darthvader
09-12-2020, 07:19 PM
Hi ,
to overcome the tiny 320x240 SPI LCD , have you consider to use something like this chip ? :
http://www.vlsi.fi/en/products/vs23s010.html
I don't know the max res we can get but it's for PAL/NTSC composite , like what was used in the time the computer you emulate was doing.
Here is just SPI needed , no more 8 bits parallel bus.
But it add another pcb ....
The other model "VS23S040" have 4x more internal SRAM , but here it's only in BGA ....

Cheers.

PS : or use the esp32 ability to made composite video out in place of this chip .... or ... this time VGA out from esp32 :) ... well i stop ... too much idea ...

Jean-Marc
09-13-2020, 10:24 AM
I did not know that chip but I have good news...

Since 5 mins ago, the 640x480 more is working.... yeah!!!
I used 2 shift registers combined with a 64bit destination DMA transfer.

I will publish the code this evening or tomorrow as I have some guest for a BBQ in the afternoon.
If you have changes in your drawing routines, please share them again, I will merge it at same time. Sorry I did not do it last time, I was so desperate and I had some other work to do...

There is still some disturbance with the amiga emulator but I think combining shift registers is the good approach. If I could combine 4 that would be even better.

darthvader
09-13-2020, 10:52 AM
Great to ear it finally work :)
I have code other project in that time (colour maximite 2 with 1024x600 LCD)
Last code was : https://drive.google.com/file/d/1cuT6xqE7OqCBtNcQd_AwLePSVZRvaxpo/view from post #104.
And we have to hope that the next Teensy model will have the right pinouts next time :)

Cheers.

Jean-Marc
09-13-2020, 06:54 PM
Last version of the code has been pushed to the git !

darthvader
09-13-2020, 08:27 PM
Hi Jean Marc :)
I just tested your new lib , it work well.
But i have to compile for 'smallest code' , in other mode they are more glitch in screen.
640x480 is one of the mode that work at best actually , but i don't have test everything ;)

Congratz !!

Jean-Marc
09-13-2020, 09:20 PM
I did not notice that with the vgatestpatern sample but if I run your drawing test, there is indeed at some point some small horizontal lines and I also noticed that the screen becomes black few secs when compiling for faster code but not with smallest code. Not sure what it is. At least some progress this w-e ;-)