Demo of low res colour vga video for stm32f3 discovery board

Dependencies:   STM32F3-Discovery-minimal

Fork of Space_Invaders_Demo by Martin Johnson

Revision:
10:8ffcefda667a
Parent:
9:654866da5da4
Child:
11:1b3dc5581b1b
--- a/video.c	Tue May 29 23:52:40 2018 +0000
+++ b/video.c	Wed May 30 03:23:47 2018 +0000
@@ -2,7 +2,8 @@
  * STM32 VGA demo
  * Copyright (C) 2012 Artekit Italy
  * http://www.artekit.eu
- * Written by Ruben H. Meleca
+ * Originally Written by Ruben H. Meleca
+ * updated for STM32F3 discovery with colour VGA output
  
 ### video.c
  
@@ -28,13 +29,12 @@
 //  \ o  o  o  o Xo   /		H=HSync=PA8	R=Red=PD0
 //   \ o  o Ho Vo  o /		V=Vsync=PA1 G=Green=PD1
 //    --------------		            B=Blue=PD2
-//
+// 8x2 connector
 // R G B o   o X X 
 // o o o o o H V o
 // 
 #include "stm32f30x.h"
 #include "video.h"
-//#define HTOTAL	(VID_HSIZE+3)					/* Total bytes to send */
 
 __attribute__ ((aligned (4))) u8 volatile fba[VID_VSIZE*HTOTAL];	/* Frame buffer */
 
@@ -133,9 +133,7 @@
 	// main output enable
     TIM1->BDTR |= TIM_BDTR_MOE; 
 	
-	//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
+	TIM1->CR2 = (TIM1->CR2 & ~TIM_CR2_MMS) | (2<<4); // TIM_TRGOSource_Update mode
 	
 	TIM8->CR1 &= ~TIM_CR1_CEN;
 	TIM8->CR1 |= TIM_CR1_ARPE | TIM_CR1_URS;
@@ -160,7 +158,7 @@
 		Vertical timing
 		---------------
 		
-		Polarity of vertical sync pulse is positive.
+		Polarity of vertical sync pulse is negative.
 
 						Lines
 		------------------------------
@@ -174,7 +172,7 @@
 
 	/* 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;//5 ;// gated slave mode trigger source 0
+	TIM2->SMCR=TIM2->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 5 ;// gated slave mode trigger source 0
 	
 	
 	TimerPeriod = 525;		/* Vertical lines */
@@ -193,8 +191,6 @@
 	TIM2->CCR2=Channel2Pulse;
 	TIM2->CCR3=Channel3Pulse;
 	
-	//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
 	
@@ -205,35 +201,29 @@
 	NVIC->ISER[TIM2_IRQn >> 0x05] = 1 << (TIM2_IRQn & 0x1F); // Interrupt enable
 	
 	TIM2->DIER |= TIM_DIER_CC3IE;
-	
-	NVIC->IP[TIM1_CC_IRQn]=0; // Interrupt Priority, lower is higher priority
-	NVIC->ISER[TIM1_CC_IRQn >> 0x05] = 1 << (TIM1_CC_IRQn & 0x1F); // Interrupt enable
-
-	//TIM1->DIER |= TIM_DIER_CC2IE;
 
 	TIM2->CR1 |= TIM_CR1_CEN;
 	TIM1->CR1 |= TIM_CR1_CEN;
 }
 
-void DMA_Configuration(void) {
-	//gpio_set_af(GPIOA,7,5,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_HIGH);
-	
+void DMA_Configuration(void) {	
+	RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;
+	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM8EN ;
+	RCC->AHBENR |= RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN | RCC_AHBENR_GPIODEN;
+
+	GPIOD->MODER = (GPIOD->MODER&0xffff0000) | 0x5555; // output mode for PD0-7
 	GPIOD->PUPDR = (GPIOD->PUPDR & ~0xffff);//0xaaaa; // pull down (1010)
 	GPIOD->OSPEEDR = (GPIOD->OSPEEDR & ~0xffff) | 0xffff;
 	
-	
 	RCC->AHBENR |= RCC_AHBENR_DMA2EN;
     // direction = peripheral dest, memory inc, peripheral size=halfword, memory size=byte, priority level=high, transmission complete interrupt enabled
     DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE;
-//    DMA1_Channel3->CCR =  DMA_CCR_PINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_MEM2MEM;
     // bytes to transfer
     DMA2_Channel1->CNDTR = HTOTAL;
     // peripheral address
     DMA2_Channel1->CPAR =(uint32_t) &GPIOD->ODR;
     // memory address
     DMA2_Channel1->CMAR =(u32) fba+fboffset;
-    // enable CC DMA for TIM16
-   // TIM16->DIER |= TIM_DIER_CC1DE;
 	// configure NVIC
     NVIC->IP[DMA2_Channel1_IRQn]=16; // Interrupt Priority, lower is higher priority
 	NVIC->ISER[DMA2_Channel1_IRQn >> 0x05] = 1 << (DMA2_Channel1_IRQn & 0x1F); // Interrupt enable
@@ -241,53 +231,20 @@
 }
 
 //*****************************************************************************
-//	This irq is generated at the end of the horizontal back porch.
-//	Test if inside a valid vertical start frame (vflag variable), 
-//	and start the DMA to output a single frame buffer line through the GPIO device.
-//*****************************************************************************
-//__attribute__((interrupt)) 
-/*
-__attribute__ ((section ("ccmram"))) void TIM1_CC_IRQHandler(void) {
-	//GPIOD->MODER=0x5555;
-	GPIOD->MODER = (GPIOD->MODER&0xffff0000) | 0x5555; // output mode for PD0-7
-	
-	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;// 0x3093;
-//		TIM8->CNT=0;//TIM8->ARR;
-		
-		TIM8->CR1 |= TIM_CR1_CEN;
-		//TIM8->CNT=7;//4-(TIM1->CNT&7);
-	}
-	TIM1->SR = 0xFFFB; //~TIM_IT_CC2;
-	
-	TIM1->SR = 0xFFFB;
-}
-*/
-
-//*****************************************************************************
 //	This irq is generated at the end of the vertical back porch.
 //	Sets the 'vflag' variable to 1 (valid vertical frame).
 //*****************************************************************************
-//__attribute__((interrupt)) 
 
-int nlines=0;
+uint32_t dummy=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;
-	// 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;
+	TIM8->CNT=0;
+	DMA2_Channel1->CPAR=(uint32_t)&dummy;//(uint32_t) &GPIOD->ODR+1;
+	GPIOD->ODR=0x00;
 	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;
 }
 
@@ -296,17 +253,14 @@
 //	It will increment the line number and set the corresponding line pointer
 //	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_CIRC;// | 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;
 	DMA2_Channel1->CNDTR = HTOTAL;
 	DMA2_Channel1->CPAR=(uint32_t) &GPIOD->ODR;;
-	nlines++;
 	vdraw++;
 	if (vdraw == 3) {
 		vdraw = 0;
@@ -314,15 +268,14 @@
 		if (vline == VID_VSIZE) {
 			vdraw = vline = vflag = 0;
 			DMA2_Channel1->CMAR = (u32)fba;
-			DMA2_Channel1->CPAR=&nlines;
+			DMA2_Channel1->CPAR=(uint32_t)&dummy;
 			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;// | DMA_CCR_CIRC;
+		DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN;
 	
 	
 }