Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Deze hexfile is toch duidelijk anders en werkt in MPsim.
Met installeren van MPLab heb ik nog nooit problemen gehad, en dat heb ik toch al heel vaak gedaan... (8.92 is inderdaad de laatste versie; MPLabX: nooit aan beginnen)
Op vrijdag 19 januari 2024 14:06:19 schreef SparkyGSX:
[...]Wellicht, maar dan kan hij niets anders meer doen.
Dat hoeft ook niet voor een simpele balkengenerator... 
Balken in grijstinten is trouwens ook geen probleem...
Op vrijdag 19 januari 2024 15:49:21 schreef Arco:
Deze hexfile is toch duidelijk anders en werkt in MPsim.Met installeren van MPLab heb ik nog nooit problemen gehad, en dat heb ik toch al heel vaak gedaan... (8.92 is inderdaad de laatste versie; MPLabX: nooit aan beginnen)
[...]
Dat hoeft ook niet voor een simpele balkengenerator...
Balken in grijstinten is trouwens ook geen probleem...
Ik had inderdaad MPLabX geïnstalleerd. Wat een drama. Gauw deinstalleren en MPLAB gebruiken. Maar wat moet ik nu met die 'language tool exception'?
Als het goed is zit er toch een ASM compiler in?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Ik gebruik altijd deze download uit de Microchip archives: https://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_IDE_8_92.zip
Complete project heb ik bijgevoegd in zipfile...
Op vrijdag 19 januari 2024 16:06:12 schreef Arco:
Ik gebruik altijd deze download uit de Microchip archives: https://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_IDE_8_92.zip
Complete project heb ik bijgevoegd in zipfile...[bijlage]
Die zipfile had ik vanmiddag ook genomen; dat werkt nu zonder language tool gedoe.
Het project openen strandt op:
Hij verwacht ergens iets dat niet kan worden gevonden.
Als ik met de ProjectWizzard een nieuw project aanmaak dan resulteert dat in:
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bij Project -> Build Options -> Project -> MPAssembler vinkje 'disable case sensitivity' aanzetten...
Nogmaals poging:
[Bericht gewijzigd door Arco op (15%)]
Ok, dat is nu gelukt. Met de Project Wizzard heb ik een nieuw project gemaakt en de ASM ingevoegd. Compileren gaat nu goed met uitschakeling van Case Sensitivity (wie gebruikt dit dat nu?
)
Een uitstapje, maar ik kan nu ASM files compileren.
Dit komt er nu uit:
Poort B.2 geeft een puls van 27uS hoog en ca 38uS laag (zal samen wel die 64 zijn).
Maar hij komt dus niet om de 20 milli Seconde (50Hz Vsync)
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Het lijkt toch of je de oude hexfile gebruikt... (in MPsim werkt het hier wel)
Aangepaste project file (je kunt de binaire status van de outputs zien in het special function registers window.)
Voor debugger/simulator:
F5 = Halt
F6 = Reset
F7 = Single step
F9 = Run
F11 = Animate
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Met de laatste zip zou je ook de binaire status moeten zien in het SFR window. Nogmaals zip...
Op vrijdag 19 januari 2024 18:27:39 schreef Arco:
Met de laatste zip zou je ook de binaire status moeten zien in het SFR window. Nogmaals zip...
Ik heb de PIC eerst 'erased', daarna deze .hex opnieuw geflasht.
Dit komt er dan uit:
Puls van 24 uS hoog, 40 uS laag.
(valt me op dat die hex van 15:56 hr is, project is van 17:01 Hr)
Ik heb de debugger geprobeerd. F5, F7. F9 werkt. Bij F11 (animate) zie ik niks gebeuren (maar kijk vermoedelijk naar iets verkeerds)
Ik heb het resultaat bij wijze van proef even op de modulator aangesloten. Je ziet dat er totaal geen synchronisatie plaatsvindt. Ik had verwacht dat hij horizontaal wel zou syncen (omdat de 64uS horizontale syncpuls er wel is ) en verticaal zou rollen vanwege het ontbreken van de verticale sync.
Maar het is nu random...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Ik zal eens kijken of ik mijn oude tv kan uitgraven op zolder dan kan ik het proberen...
Het laatste scoopbeeld klopt totaal niet met wat ik in de simulator zie...
[Bericht gewijzigd door Arco op (30%)]
Op vrijdag 19 januari 2024 22:47:38 schreef Arco:
Ik zal eens kijken of ik mijn oude tv kan uitgraven op zolder dan kan ik het proberen...
Het laatste scoopbeeld klopt totaal niet met wat ik in de simulator zie...
Maar hoe kan ik die simulator activeren? Dan zou ik het ook kunnen zien.
Op vrijdag 19 januari 2024 22:01:09 schreef Bavelt:
Ik heb het resultaat bij wijze van proef even op de modulator aangesloten. Je ziet dat er totaal geen synchronisatie plaatsvindt. Ik had verwacht dat hij horizontaal wel zou syncen (omdat de 64uS horizontale syncpuls er wel is ) en verticaal zou rollen vanwege het ontbreken van de verticale sync.
Maar het is nu random...
Ik heb het vermoeden dat het doorlopen van de witte balk, ook in het blankinggebied, de H- oscillator steeds uit zijn vanggebied slaat, en zo de H-PLL er niet in slaagt om te locken. testen van dit vermoeden is eenvoudig, verwijder de witte balk uit het programma, en check of locken dan wel plaatstvind.
Een PAL synchronisatie signaal heeft een timing resolutie van 0,01us nodig voor het genereren van een correcte timing van de Equalizing/Serration pulses gedurende de vertikale blanking/sync. Een timing resolutie van maar 1us is daarvoor niet bruikbaar. Video (of aanverwante) apparatuur kan mogelijk bij het geheel ontbreken van Equalizing/Serration pulses (of een incorrecte timing daarvan) niet synchroniseren.
Op zaterdag 20 januari 2024 00:14:59 schreef Bobosje:
Een PAL synchronisatie signaal heeft een timing resolutie van 0,01us nodig voor het genereren van een correcte timing van de Equalizing/Serration pulses gedurende de vertikale blanking/sync. Een timing resolutie van maar 1us is daarvoor niet bruikbaar. Video (of aanverwante) apparatuur kan mogelijk bij het geheel ontbreken van Equalizing/Serration pulses (of een incorrecte timing daarvan) niet synchroniseren.
Je zoekt het wat te ver. dit is geen PAl ontvanger, (maar ook een pal ontvanger kan vrolijk syncen zonder egalisatiepulsen) maar een Z/W CCIR uit lang vervlogen tijden. of de sync nu 4,7 of 5 µsec duurt, het zal de ontvanger lak wezen.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Op vrijdag 19 januari 2024 23:54:29 schreef Bavelt:
En hoe ziet het scopebeeld er bij jou dan uit?
Scoopbeeld is wat lastig met alleen een simulatie... 
Soms kan iets je bezighouden. Tot héél laat.
Midden in de nacht werd ik wakker en bleef ik me maar afvragen waarom het niet werkte.
Want Arco maakt - in tegenstelling tot mij - niet gauw fouten.
En ineens realiseerde ik me: de extra puls komt op Poort B.2. Heb ik de scope daar wel op hangen?
Rond 5.00 uur opgestaan, naar de werkkamer.
Nee dus, de scope hangt 'gewoon' aan poort B.0 en B.1 (pin 6 en 7)
Maar Poort B.2 is pin 8 van de PIC16F1847...
Wat erg, zijn anderen voor mij bezig en ik maak zo'n fout.
Nederigheid is hetgeen mij nu past.. En excuses

Ik heb het net geprobeerd. Pin B.2 is laag, zonder puls...
Maar dat ga ik eerst vandaag maar eens zelf uitzoeken.
KGE
Golden Member
In 2013 heb ik zitten spelen met de LPC800 in 8 pin DIP uitvoering.
Dit is/was een NXP ARM processor met ik meen 1 kByte RAM
De uitdaging was om er een TV beeld mee te genereren en dat leidde to een PONG variant.
De TV output wordt met een 'state machine' constructie gemaakt en er is alleen een enkele lijnbuffer beschikbaar die door de SPI output met DMA naar buiten gestuurd wordt.
Het werkte verassend goed, had alleen een hardware bug ontdekt in de eerste generatie van de chips: de analoge comparator was 'dead'. Ik heb het gemeld aan NXP en kreeg een handvol verbeterde versies toegestuurd maar heb daarna er niets meer mee gedaan
Ik had als alternatief voor de potmeters twee joysticks aangesloten (alleen up/down, serveren ging met up+down) maar je kon ook tegen de computer spelen.
Voor een ieder die geintereerd is in de (C) code:
/**************************************************************************/
/**************************************************************************/
//
// PONG by KGE (c)2013
// unfortunately the comparator function of my LPC810 seems to be broken
// so the analog controller is replaced by two simple buttons (up and down)
//
// Video output is serialized by the SPI function of the LPC
// line timing is done by the use of timer interrupts every 64 usec
// #define SINGLEPLAYER
#include <stdio.h>
#include "LPC8xx.h"
#include "gpio.h"
#include "mrt.h"
#include "uart.h"
#include "spi.h"
#include "string.h"
#if defined(__CODE_RED)
#include <cr_section_macros.h>
#include <NXP/crp.h>
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
#endif
// let's try that for my sync pin..
#define SYNC_OUTPUT (2)
// define IO pins for controller
#define RIGHT_PADDLE_UP (4)
#define RIGHT_PADDLE_DOWN (1)
#define LEFT_PADDLE_UP (0)
#define LEFT_PADDLE_DOWN (5)
// used in winner testing
#define LEFT 1
#define RIGHT 2
#define PORT0 0
// as it says: the line counter
volatile int line_counter;
// define PAL signals
#define VTOTAL 312 // total number of lines
#define VSYNC_START (VTOTAL-8) // start of vertical sync
#define VSYNC_END (VTOTAL-4) // end of vertical sync
#define VISIBLE_START 35 // start of visible area
#define VISIBLE_END 275 // end of visible area
#define HSYNCWIDTH (12-1) // width of horizontal synchronisation (SPI word size)
// #define HSYNCWIDTH 16-1
// note MAX_X is width in pixels
// MAX_Y is height in lines
#define MAX_X 208
#define MAX_Y (VISIBLE_END-8)
// define BAT positions and size (in pixels/lines)
#define BAT_LEFT_XPOS 24 // left bat horizontal position
#define BAT_RIGHT_XPOS (MAX_X-BAT_LEFT_XPOS-8) // right bat mirrored position
#define BAT_SIZE 31 // the vertical size of the bat
#define BALL_HEIGHT 8 // the vertical size of the ball
#define BALL_WIDTH 8 // the horizontal size of the ball
#define ANGLE_STEPS 7 // number of bounce steps on the bat
#define ANGLE_FACTOR (BAT_SIZE/ANGLE_STEPS) // the calculated factor for vertical movement
#define SCORE_LEFT_XPOS ((MAX_X/2)-24) // horizontal position of the left player score
#define SCORE_RIGHT_XPOS ((MAX_X/2)+24) // horizontal position of the right player score
#define SCORE_YPOS (VISIBLE_START+10) // vertical position of both scores
// standard speed setting
#define BALL_SPEED_X 2
#define BALL_SPEED_Y 1
// hardware init
void SwitchMatrix_Init()
{
/* Enable SWM clock */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
// Enable IOCON clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<18);
/* Pin Assign 8 bit Configuration */
/* SPI0_MOSI */
LPC_SWM->PINASSIGN4 = 0xffffff03UL;
/* Pin Assign 1 bit Configuration */
/* RESET */
#ifdef SINGLEPLAYER
LPC_SWM->PINENABLE0 = 0xffffffbfUL;
#else
LPC_SWM->PINENABLE0 = 0xffffffffUL;
#endif
/* Set the SYNC output pin to output (1 = output, 0 = input) */
LPC_GPIO_PORT->DIR0 |= (1 << SYNC_OUTPUT);
// switch PIO pins to input
LPC_GPIO_PORT->DIR0 &= ~(1<< RIGHT_PADDLE_DOWN);
LPC_GPIO_PORT->DIR0 &= ~(1<< RIGHT_PADDLE_UP);
// init SPI to run at 30/6 = 5 MHz, no delay (0)
spiInit(LPC_SPI0,(6-1),0);
// disable IOCON clock
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<18);
/* SWM clock no longer needed now it's configured */
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<7);
}
// the 'font'
static unsigned char bitmap[][8]={
{255,129,129,129,129,129,129,255}, // 0
{1,1,1,1,1,1,1,1}, // 1
{255,1,1,255,128,128,128,255}, // 2
{255,1,1,15,1,1,1,255}, // 3
{129,129,129,255,1,1,1,1}, // 4
{255,128,128,255,1,1,1,255}, // 5
{255,128,128,255,129,129,129,255}, // 6
{255,1,1,1,1,1,1,1}, // 7
{255,129,129,255,129,129,129,255}, // 8
{255,129,129,255,1,1,1,255}, // 9
{24,60,126,126,126,126,60,24}, // ball
};
// storage space
volatile unsigned char linebuffer[(MAX_X/8)+1]; // single line display buffer
volatile unsigned short ball_x,ball_y; // storage for ball position
volatile unsigned short bat_left_ypos,bat_right_ypos; // storage for bat positions
volatile unsigned short score_l,score_r; // storage for score (left and right player)
volatile unsigned char vbl_flag; // flag for signaling the vertical sync
// simple delay routine, n is the number of vertical syncs to wait
void wait(int n)
{
while (n--)
{
vbl_flag=0;
while (!vbl_flag);
}
}
// the main event
int main(void)
{
signed char dx,dy;
unsigned char game_end=0;
unsigned char winner=LEFT;
unsigned char distx;
unsigned char disty;
int paused;
unsigned char single_player=0;
SystemCoreClockUpdate(); // retrieve the clock
/* Initialise the GPIO block */
gpioInit();
/* Configure the switch matrix (setup pins) */
SwitchMatrix_Init();
/* Configure the multi-rate timer for 64us ticks and start interrupts */
mrtInit(__SYSTEM_CLOCK/15525);
// initial bat positions
bat_left_ypos=100;
bat_right_ypos=100;
// reset score
score_l=0;
score_r=0;
// reset ball
ball_x=BAT_LEFT_XPOS+BALL_WIDTH;
ball_y=bat_left_ypos+(BAT_SIZE/2)-(BALL_HEIGHT/2);
if (!gpioGetPinValue(PORT0,RIGHT_PADDLE_UP)) single_player=1; else single_player=0;
// startup delay (give monitor some time to sync and display)
paused=150; // startup delay
game_end=1; // force new game
// endless loop
while(1)
{
vbl_flag=0;
while (!vbl_flag); // wait for vsync to happen
// are we is PAUSE mode ?
if (paused)
{
// count down pause timer
paused--;
// test for new game
if ((paused==0) && (game_end==1))
{
// reset score
score_l=0;
score_r=0;
// reset ball
if (winner==LEFT)
{
ball_x=BAT_LEFT_XPOS+BALL_WIDTH;
ball_y=bat_left_ypos+(BAT_SIZE/2)-(BALL_HEIGHT/2);
// set vector
dx=BALL_SPEED_X;
dy=BALL_SPEED_Y;
}
else
{
ball_x=BAT_RIGHT_XPOS-BALL_WIDTH;
ball_y=bat_right_ypos+(BAT_SIZE/2)-(BALL_HEIGHT/2);
dx=-BALL_SPEED_X;
dy=BALL_SPEED_Y;
}
game_end=0;
}
}
else
{
// move ball in X direction
ball_x+=dx;
// test for X limits
if (ball_x > (MAX_X-8))
{
if (dx>0)
{
if (score_l<9) score_l++;
// serve position halfway bat
ball_y=bat_left_ypos+(BAT_SIZE/2)-(BALL_HEIGHT/2);
ball_x=BAT_LEFT_XPOS+BALL_WIDTH;
dx=BALL_SPEED_X;
dy=BALL_SPEED_Y;
paused=50;
// wait(50);
}
else
{
if (score_r<9) score_r++;
// serve position halfway bat
ball_y=bat_right_ypos+(BAT_SIZE/2)-(BALL_HEIGHT/2);
ball_x=BAT_RIGHT_XPOS-BALL_WIDTH;
dx=-BALL_SPEED_X;
dy=BALL_SPEED_Y;
paused=50;
// wait(50);
}
}
if (score_r==9)
{
game_end=1;
paused=200;
winner=RIGHT;
}
if (score_l==9)
{
game_end=1;
paused=200;
winner=LEFT;
}
// move ball in Y direction
ball_y+=dy;
// bounce ball on Y limits
if ((ball_y>(MAX_Y-1)) || (ball_y<VISIBLE_START))
{
dy=-dy;
}
// test for collision with right bat
if (dx>0) // only if ball is moving right
{
// calculate X distance
distx=BAT_RIGHT_XPOS - ball_x;
if (distx < BALL_WIDTH)
{
// calculate Y distance
disty=(ball_y + (BALL_HEIGHT/2)) - bat_right_ypos;
// we have a hit
if (disty < BAT_SIZE)
{
dx=-dx;
// calculate Y angle depending on position of impact on bat
dy=((disty-(BAT_SIZE/2))/ANGLE_FACTOR);
}
}
}
// test for collision with left bat
if (dx<0) // only if ball is moving left
{
// calculate X distance
distx=ball_x - BAT_LEFT_XPOS;
if (distx < BALL_WIDTH)
{
// calculate Y distance
disty=(ball_y + (BALL_HEIGHT/2)) - bat_left_ypos;
// we have a hit
if (disty < BAT_SIZE)
{
dx=-dx;
// calculate Y angle depending on position of impact on bat
dy=((disty-(BAT_SIZE/2))/ANGLE_FACTOR);
}
}
}
}
// test for single player mode
if (single_player)
{
// play computer opponent on left bat
// try and keep up with the Y position of the ball
if ((ball_y>(bat_left_ypos+(BAT_SIZE-8))) && (bat_left_ypos<(VISIBLE_END-BAT_SIZE-1))) bat_left_ypos+=2;
if ((ball_y<bat_left_ypos) && (bat_left_ypos>VISIBLE_START)) bat_left_ypos-=2;
}
else
{
// handle left paddle
if (!gpioGetPinValue(PORT0,LEFT_PADDLE_DOWN) && (bat_left_ypos<(VISIBLE_END-BAT_SIZE-1)))
{
bat_left_ypos+=2;
}
if (!gpioGetPinValue(PORT0,LEFT_PADDLE_UP) && (bat_left_ypos>(VISIBLE_START)))
{
bat_left_ypos-=2;
}
}
// handle right paddle
if (!gpioGetPinValue(PORT0,RIGHT_PADDLE_DOWN) && (bat_right_ypos<(VISIBLE_END-BAT_SIZE-1)))
{
bat_right_ypos+=2;
}
if (!gpioGetPinValue(PORT0,RIGHT_PADDLE_UP) && (bat_right_ypos>(VISIBLE_START)))
{
bat_right_ypos-=2;
}
}
}
// This is the pseudo state machine for the video output generator
// dummy state
static void state_before_vsync(void);
// this is needed for every line in a frame of video
static void hsync()
{
// set sync pin low
LPC_GPIO_PORT->CLR0 = 1 << SYNC_OUTPUT;
// send three more nulls (sync width)
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(HSYNCWIDTH)| SPI_TXDATACTL_RXIGNORE ;
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(HSYNCWIDTH)| SPI_TXDATACTL_RXIGNORE ;
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(HSYNCWIDTH)| SPI_TXDATACTL_RXIGNORE ;
// set sync pin high
LPC_GPIO_PORT->SET0 = 1 << SYNC_OUTPUT;
}
// setup initial state
static void (*state)(void) = state_before_vsync;
// emit a line from the visible area (framebuffer)
static void state_visible_area(void) {
register unsigned short ofs_y;
register unsigned short ofs_x;
register unsigned short temp16;
extern volatile unsigned char linebuffer[];
int n;
// always start by emitting a horizontal sync pulse
hsync();
// if not yet in the active part of the screen we're done here so just return
if (line_counter < VISIBLE_START) return;
// but if within visible part...
if( line_counter<(VISIBLE_END+1))
{
// emit back porch (black level)
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 ); // wait for SPI register to be flushed
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(16-1) | SPI_TXDATACTL_RXIGNORE;
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 ); // wait for SPI register to be flushed
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(8-1) | SPI_TXDATACTL_RXIGNORE;
// active line part
// now send MAX_X dots
// send contents of linebuffer
for(n=0; n<(MAX_X/8); n++){
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 ); // wait for SPI register to be flushed
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(8-1) | linebuffer[n] | SPI_TXDATACTL_RXIGNORE;
linebuffer[n]=0; // clear linebuffer along the way
}
// now send 1 byte blanking to set black level
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 ); // wait for SPI register to be flushed
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(8-1)| SPI_TXDATACTL_RXIGNORE ;
// create dotted vertical center line
linebuffer[MAX_X/16]=(line_counter & 0x08);
// place appropriate line of left and right bats and score
ofs_y=line_counter-bat_left_ypos;
if (ofs_y<BAT_SIZE) linebuffer[BAT_LEFT_XPOS/8]|=0x0f;
ofs_y=line_counter-bat_right_ypos;
if (ofs_y<BAT_SIZE) linebuffer[BAT_RIGHT_XPOS/8]|=0xf0;
// stretch 8 line font for score to double size (16) by dividing ofs_y by two
ofs_y=line_counter-SCORE_YPOS;
if (ofs_y<16)
{
linebuffer[SCORE_LEFT_XPOS/8]|=bitmap[score_l][ofs_y>>1];
linebuffer[SCORE_RIGHT_XPOS/8]|=bitmap[score_r][ofs_y>>1];
}
// place the ball
ofs_y=line_counter-ball_y;
if (ofs_y<8)
{
// divide by 8
ofs_x=ball_x>>3;
// pre shift object data
temp16=bitmap[10][ofs_y]<<(8-(ball_x % 8));
// place object data in linebuffer
linebuffer[ofs_x]|=(temp16>>8);
linebuffer[ofs_x+1]|=(temp16 & 0xff);
}
}
else // we're beyond the active screen part so just emit blank lines until vsync
{
state = state_before_vsync;
}
}
// VSYNC is over, now wait for end of frame
static void state_after_vsync(void)
{
// always emit horizontal sync
hsync();
if (line_counter != VTOTAL) return;
line_counter = 0; // reset line counter
vbl_flag=1;
state = state_visible_area; // we're in visible mode
}
// VSYNC is active
static void state_during_vsync(void)
{
// keep sending horizontal sync pulses (but inverted)
LPC_GPIO_PORT->SET0 = 1 << SYNC_OUTPUT;
// send three more nulls (sync width)
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(HSYNCWIDTH)| SPI_TXDATACTL_RXIGNORE ;
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(HSYNCWIDTH)| SPI_TXDATACTL_RXIGNORE ;
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_TXDATCTL_FSIZE(HSYNCWIDTH)| SPI_TXDATACTL_RXIGNORE ;
// set sync pin low
LPC_GPIO_PORT->CLR0 = 1 << SYNC_OUTPUT;
if (line_counter != VSYNC_END) return;
LPC_GPIO_PORT->SET0 = 1 << SYNC_OUTPUT;
state = state_after_vsync; // VSYNC is done
}
static void state_before_vsync(void)
{
// always emit horizontal sync
hsync();
// wait for VSYNC start
if (line_counter != VSYNC_START) return;
state = state_during_vsync; // VSYNC has started
}
void MRT_IRQHandler(void)
{
// test IRQ register if it was caused by the timer
if ( LPC_MRT->Channel[0].STAT & MRT_STAT_IRQ_FLAG )
{
state(); // here the active state is executed
line_counter++; // advance line counter
LPC_MRT->Channel[0].STAT = MRT_STAT_IRQ_FLAG; /* clear interrupt flag */
}
return;
}
Op zaterdag 20 januari 2024 00:36:47 schreef Arco:
[...]
Scoopbeeld is wat lastig met alleen een simulatie...
Er komt inderdaad een positieve puls op B.2. Keurig om de 20 mS,
hij is 17uS lang.
Op mijn scope is een combinatie 17uS per 20ms moeilijk waar te nemen.
De logic Analyzer echter geeft het keurig weer. (wat een fijn tool is dat toch..
)
In het uiteindelijke videosignaal zou deze dan 'inverse' moeten zijn, d.w.z 17uS laag.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Op het moment van de positieve puls op B.2 moet er op B.0 een negatieve puls van 20uS zijn...
B.2 is er alleen voor triggeren van de scoop. Kun je die LA ook laten triggeren op het B.2 signaal?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Kan iedereen wel eens gebeuren.. 
De spanningsnivo's zijn ook goed? (ik heb geen idee hoeveel afwijking daarin is toegestaan)