Demo of low res colour vga video for stm32f3 discovery board

Dependencies:   STM32F3-Discovery-minimal

Fork of Space_Invaders_Demo by Martin Johnson

Revision:
8:34fb94209517
Parent:
7:513afc954d6e
Child:
9:654866da5da4
--- a/video.c	Mon May 28 10:38:27 2018 +0000
+++ b/video.c	Tue May 29 23:16:35 2018 +0000
@@ -34,7 +34,7 @@
 // 
 #include "stm32f30x.h"
 #include "video.h"
-#define HTOTAL	(VID_HSIZE+3)					/* Total bytes to send */
+//#define HTOTAL	(VID_HSIZE+3)					/* Total bytes to send */
 
 __attribute__ ((aligned (4))) u8 volatile fba[VID_VSIZE*HTOTAL];	/* Frame buffer */
 
@@ -86,8 +86,8 @@
 	gpio_set_af(GPIOA,8,6,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_LOW);
 
 	/*
-		SVGA 800x600 @ 56 Hz
-		Vertical refresh	35.15625 kHz
+		VGA 640x480 @ 60 Hz
+		Vertical refresh	31.46875 kHz
 		Pixel freq.			36.0 MHz
 		
 		1 system tick @ 72Mhz = 0,0138 us
@@ -97,91 +97,65 @@
 		Horizontal timing
 		-----------------
 		
-		Timer 1 period = 35156 Hz
+		Timer 1 period = 31468.53 Hz
 		
-		Timer 1 channel 1 generates a pulse for HSYNC each 28.4 us.
-		28.4 us	= Visible area + Front porch + Sync pulse + Back porch.
-		HSYNC is 2 us long, so the math to do is:
-		2us / 0,0138us = 144 system ticks.
+		Since firing the DMA takes more or less 400ns, we'll start it 28 ticks early.
 		
-		Timer 1 channel 2 generates a pulse equal to HSYNC + back porch.
-		This interrupt will fire the DMA request to draw on the screen if vflag == 1.
-		Since firing the DMA takes more or less 800ns, we'll add some extra time.
-		The math for HSYNC + back porch is:
-		(2us + 3,55us - dma) / 0,0138us = +-350 system ticks
 	
 		Horizontal timing info
 		----------------------
 
-						Dots	us
-		--------------------------------------------		
-		Visible area	800		22.222222222222
-		Front porch		24		0.66666666666667
-		Sync pulse		72		2
-		Back porch		128		3.5555555555556
-		Whole line		1024	28.444444444444
+						Dots	us					ticks
+		----------------------------------------------------		
+		Visible area	640		25.422045680238		1830
+		Front porch		16		0.6355511420059		46
+		Sync pulse		96		3.8133068520357		275
+		Back porch		48		1.9066534260179		137
+		Whole line		800		31.777557100298		2288
 	
 	*/
 
 	TimerPeriod = 2288;//2303;
-	Channel1Pulse = 274;//274;//274;//277;		/* HSYNC */
-	//Channel2Pulse = 850;//410;//348; 		/* HSYNC + BACK PORCH */
-	Channel3Pulse = 392;//412;//394;
+	Channel1Pulse = 275;//274;//274;//277;		/* HSYNC */
+	Channel3Pulse = 382;//412;//394;
 	
 	TIM1->CR1 &= ~TIM_CR1_CEN;
+	
 	TIM1->PSC=0;
 	TIM1->ARR=TimerPeriod;
 	TIM1->CNT=0;
 	
-	// disable Capture and Compare 1 and 2
-	TIM1->CCER &= ~(TIM_CCER_CC1E);// | TIM_CCER_CC2E);
+	// disable Capture and Compare
+	TIM1->CCER &= ~(TIM_CCER_CC1E);
 	// set output compare 1 to PWM mode with preload
 	TIM1->CCMR1 = (TIM1->CCMR1 & ~(TIM_CCMR1_OC1M | TIM_CCMR1_CC1S)) | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
-	//TIM1->CCMR1 = (TIM1->CCMR1 & ~(TIM_CCMR1_OC2M | TIM_CCMR1_CC2S)) | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2CE;
 	TIM1->CCR1=Channel1Pulse;
-//	TIM1->CCR2=Channel2Pulse;
-//	TIM1->CCR3=Channel2Pulse+100;
-	//TIM1->CCR2 |= TIM_CR2_OIS1; // output idle state set
-	//TIM1->CR2 |= TIM_CR2_OIS1; 
 	// enable Capture and Compare 1
-	TIM1->CCER |=  TIM_CCER_CC1E | TIM_CCER_CC1P ;// | TIM_CCER_CC2E  | TIM_CCER_CC1P | TIM_CCER_CC2P; // output polarity low
+	TIM1->CCER |=  TIM_CCER_CC1E | TIM_CCER_CC1P ; // output polarity low
 	// main output enable
     TIM1->BDTR |= TIM_BDTR_MOE; 
 	
-	TIM1->SMCR |= TIM_SMCR_MSM; // master slave mode
+	//TIM1->SMCR |= TIM_SMCR_MSM; // master slave mode
 	
 	TIM1->CR2 = (TIM1->CR2 & ~TIM_CR2_MMS) | (2<<4); ///*TIM_CR2_MMS_2 |*/ TIM_CR2_MMS_1 /*| TIM_CR2_MMS_0*/;// TIM_TRGOSource_Update mode
 	
 	TIM8->CR1 &= ~TIM_CR1_CEN;
-	TIM8->CR1 |= TIM_CR1_ARPE;
+	TIM8->CR1 |= TIM_CR1_ARPE | TIM_CR1_URS;
 	TIM8->PSC=0;
-	TIM8->ARR=11;
+	TIM8->ARR=8;
 	TIM8->CNT=0;
-	//TIM16->CR1 |= TIM_CR1_OPM; 
 	
 	TIM8->DIER |= TIM_DIER_UDE;
 	
 	TIM8->SMCR=TIM8->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 6 | (3<<4); // trigger mode from itr3 (tim3)
-	//TIM16->SMCR |= TIM_SMCR_MSM;
-	//TIM16->CR2 = (TIM16->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1;// TIM_TRGOSource_Update mode
 	
 	TIM3->CR1 &= ~TIM_CR1_CEN;
 	TIM3->PSC=0;
-	TIM3->ARR=Channel3Pulse;//TimerPeriod/2;
+	TIM3->ARR=Channel3Pulse;
 	TIM3->CNT=0;
-	
-	// disable Capture and Compare 1 and 2
-//	TIM3->CCER &= ~(TIM_CCER_CC1E);
-	// set output compare 1 to PWM mode with preload
-//	TIM3->CCMR1 = (TIM3->CCMR1 & ~(TIM_CCMR1_OC1M | TIM_CCMR1_CC1S)) | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
-//	TIM3->CCR1=Channel3Pulse;
-
+	TIM3->CR1 |= TIM_CR1_ARPE | TIM_CR1_URS;
 	TIM3->CR1 |= TIM_CR1_OPM; 
-//	TIM3->CCER |=  TIM_CCER_CC1E | TIM_CCER_CC1P; // output polarity low
-	
-	//TIM3->SMCR |= TIM_SMCR_MSM; // master slave mode
 	TIM3->SMCR=TIM3->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 6 ; // trigger mode from itr0 (tim1)
-	
 	TIM3->CR2 = (TIM3->CR2 & ~TIM_CR2_MMS) | (2<<4); ///*TIM_CR2_MMS_2 |*/ TIM_CR2_MMS_1 /*| TIM_CR2_MMS_0*/;// TIM_TRGOSource_Update mode
 
 	/*
@@ -192,17 +166,17 @@
 
 						Lines
 		------------------------------
-		Visible area	600
-		Front porch		1
+		Visible area	480
+		Front porch		10
 		Sync pulse		2
-		Back porch		22
-		Whole frame		625
+		Back porch		33
+		Whole frame		525
 		
 	*/
 
 	/* VSYNC (TIM2_CH2) and VSYNC_BACKPORCH (TIM2_CH3) */
 	/* Channel 2 and 3 Configuration in PWM mode */
-	TIM2->SMCR=TIM2->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 5 ;// gated slave mode trigger source 0
+	TIM2->SMCR=TIM2->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 5;//5 ;// gated slave mode trigger source 0
 	
 	
 	TimerPeriod = 525;		/* Vertical lines */
@@ -221,8 +195,8 @@
 	TIM2->CCR2=Channel2Pulse;
 	TIM2->CCR3=Channel3Pulse;
 	
-	
-	TIM2->CR2 &= ~TIM_CR2_OIS1; // output idle state set
+	//TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_URS;
+	//TIM2->CR2 &= ~TIM_CR2_OIS1; // output idle state set
 	// enable Capture and Compare 2 and 3
 	TIM2->CCER |=  TIM_CCER_CC2E |  TIM_CCER_CC3E | TIM_CCER_CC1P | TIM_CCER_CC2P; // output polarity low
 	
@@ -297,21 +271,26 @@
 //	Sets the 'vflag' variable to 1 (valid vertical frame).
 //*****************************************************************************
 //__attribute__((interrupt)) 
+
+int nlines=0;
 __attribute__ ((section ("ccmram"))) void TIM2_IRQHandler(void) {
 	vflag = 1;
 	TIM2->SR = 0xFFF7; //~TIM_IT_CC3;
 	TIM8->CR1 &= ~TIM_CR1_CEN;
-	//DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE ;
-	//DMA2_Channel1->CNDTR = HTOTAL;
-	DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN;// 0x3093;
+	DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE ;
+	DMA2_Channel1->CNDTR = HTOTAL;
+	// 0x3093;
 	//GPIOD->MODER=0;
 	//GPIOD->MODER = (GPIOD->MODER&0xffff0000); // input mode for PD0-7
 //	GPIOD->ODR=0x00;
 	//GPIOD->MODER=0xaaaa;
 		TIM8->CNT=0;
+		DMA2_Channel1->CPAR=&nlines;//(uint32_t) &GPIOD->ODR+1;
 		GPIOD->ODR=0x00;
 		
-
+	//printf("l:%d\n",nlines);
+	nlines=0;
+	DMA2_Channel1->CCR = DMA_CCR_DIR  | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN | DMA_CCR_CIRC;
 }
 
 //*****************************************************************************
@@ -320,29 +299,32 @@
 //	in the DMA register.
 //*****************************************************************************
 //__attribute__((interrupt)) 
+
 __attribute__ ((section ("ccmram"))) void DMA2_Channel1_IRQHandler(void) {	
 	DMA2->IFCR = DMA_ISR_TCIF1;
 	TIM8->CR1 &= ~TIM_CR1_CEN;
 	TIM8->CNT=0;
 	//while(DMA2_Channel1->CNDTR);
-	DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE;// | DMA_CCR_EN;// 0x3093; 0x92;// | (1<<10) | (1<<8);
+	DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE;// | DMA_CCR_CIRC;// | DMA_CCR_EN;// 0x3093; 0x92;// | (1<<10) | (1<<8);
 	DMA2_Channel1->CNDTR = HTOTAL;
-	
-	
+	DMA2_Channel1->CPAR=(uint32_t) &GPIOD->ODR;;
+	nlines++;
 	vdraw++;
-	if (vdraw == 2) {
+	if (vdraw == 3) {
 		vdraw = 0;
 		vline++;
 		if (vline == VID_VSIZE) {
 			vdraw = vline = vflag = 0;
 			DMA2_Channel1->CMAR = (u32) fba+fboffset;
+			DMA2_Channel1->CPAR=&nlines;
+			GPIOD->ODR=0x00;
 		} else {
 			DMA2_Channel1->CMAR += HTOTAL;
 		}
 	}
 	//GPIOD->ODR=0x00;
 	if(vflag)
-		DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN;
+		DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN | DMA_CCR_CIRC;
 	
 	
 }