So I'm making a breadboard video card that I will eventually be using with a 6502 based computer that I'm making. The way I want to go about this is to have a hsync timing circuit like normal but have the vsync emulated through a microcontroller to save on components and physical space when I eventually get this printed on a PCB (and to add a bit of challenge for myself). My goal is to get it to produce a 640x480 resolution at around 60hz. I've done this in a very similar way to Ben Eater has with his video card except I've used more appropriate components like a 25.175mhz clock, etc.
I have already attempted this with an MSP430G2553 but not surprisingly it didn't work given that the max clock for that MCU is only 16mhz, or at least I assume that's what the issue is. I'll paste the code at the end of the post, keep in mind I attached P2.5 to the to vsync on the vga port, P2.6 was the vsync signal at 800 (I set it to count slightly past this number to avoid the case where the 25mhz clock would count faster than the MSP430 could detect) and P2.7 was attached to reset the counters.
So I'm wondering if I have to use a faster microcontroller like the Raspberry Pi Pico which I just picked up, or if it actually is possible to do with the MSP430. Or is this idea even possible in the first place? I know its possible to emulate the whole thing with the Pico but I'd much prefer to do it this way if its possible. I'm also not sure how lenient/flexible I can be with the timings, as most information I've found doesn't really give me a specific answer.
#include "msp430g2553.h"
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
static volatile int vsync = 0;
//------------------------------------------------------------------------------
// Function Prototypes
//------------------------------------------------------------------------------
void init_device(void);
//------------------------------------------------------------------------------
// Main Function
//------------------------------------------------------------------------------
int main(void){
init_device();
_EINT();
while(1){
if(vsync == 480) {
//do something
}
if(vsync == 490) {
P2OUT |= BIT5;
}
if(vsync == 492) {
P2OUT &= ~BIT5;
}
if(vsync == 525) {
vsync = 0;
}
P2IFG = 0;
}
return 0;
}
//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
void init_device(void){
WDTCTL = WDTPW + WDTHOLD; //Setup watch dog timer
P1DIR = 0xFF; //11111111b null
P2DIR = 0xBF; //10111111b null|vsync|null
P1SEL = 0x00; //Disable pin special functions
P2SEL = 0x00; //Disable pin special functions
P1REN = 0x00; //Internal pullups disabled
BCSCTL1 = CALBC1_16MHZ; //Use 16MHz Clock
DCOCTL = CALDCO_16MHZ; //Use 16MHz Clock
P2IES = BIT6;
P2IE = BIT6;
}
//------------------------------------------------------------------------------
// Interrupts
//------------------------------------------------------------------------------
#pragma vector = PORT2_VECTOR
__interrupt void VERTICAL_SYNC(void) {
if((P2IFG & BIT6) != 0) {
vsync++;
P2IFG = 0;
P2OUT &= ~BIT7;
P2OUT |= BIT7;
}
}