Demo of low res colour vga video for stm32f3 discovery board

Dependencies:   STM32F3-Discovery-minimal

Fork of Space_Invaders_Demo by Martin Johnson

Revision:
3:93e488fbb8a2
Parent:
1:1b37c4b989b4
Child:
4:de45d218ed3c
--- a/video.c	Tue May 17 23:53:10 2016 +0000
+++ b/video.c	Wed May 16 02:39:14 2018 +0000
@@ -34,42 +34,57 @@
 // 
 #include "stm32f30x.h"
 #include "video.h"
-//#include "stm32f3xx_hal_conf.h"
-#define HTOTAL	(VID_HSIZE+2)					/* Total bytes to send through SPI */
+#define HTOTAL	(VID_HSIZE+3)					/* Total bytes to send */
 
-__attribute__ ((aligned (4))) u8 volatile fba[VID_VSIZE*HTOTAL*2];	/* Frame buffer */
+__attribute__ ((aligned (4))) u8 volatile fba[VID_VSIZE*HTOTAL];	/* Frame buffer */
 
-u8 volatile *fb[VID_VSIZE*2];
+__attribute__ ((section ("ccmram"))) u8 volatile *fb[VID_VSIZE];
 
 int fboffset=0;
 
 static volatile u16 vline = 0;				/* The current line being drawn */
-static volatile u32 vflag = 0;				/* When 1, the SPI DMA request can draw on the screen */
+static volatile u32 vflag = 0;				/* When 1, the DMA request can draw on the screen */
 static volatile u32 vdraw = 0;				/* Used to increment vline every 3 drawn lines */
 
-void TIMER_Configuration(void)
-{
-	GPIO_InitTypeDef GPIO_InitStructure;
-	NVIC_InitTypeDef nvic;
-	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-	TIM_OCInitTypeDef TIM_OCInitStructure;
+#define GPIO_MODE_INPUT 0
+#define GPIO_MODE_OUTPUT 1
+#define GPIO_MODE_AF 2
+
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_UP 1
+#define GPIO_PULL_DOWN 2
+
+#define GPIO_OUTPUT_PUSH_PULL 0
+
+
+#define GPIO_SPEED_MEDIUM 1
+#define GPIO_SPEED_LOW 0
+#define GPIO_SPEED_HIGH 3
+
+
+void gpio_set_mode(GPIO_TypeDef *g,int n,int mode) {
+	n=n<<1;
+	g->MODER = (g->MODER & ~(3<<n)) | (mode<<n);
+}
+
+void gpio_set_af(GPIO_TypeDef *g,int n,int af, int otype, int pupd, int speed) {
+	int reg=n>>3;
+	int pos=(n&7)*4;
+	g->AFR[reg] = (g->AFR[reg] & ~(0xf<<pos)) | (af<<pos); // alt func
+	pos=(n<<1);
+	g->OSPEEDR = (g->OSPEEDR & ~(3<<pos)) | (speed<<pos);
+	g->OTYPER = (g->OTYPER & ~(1<<n)) | (otype<<n);
+	gpio_set_mode(g,n,GPIO_MODE_AF);
+	g->PUPDR = (g->PUPDR & ~(3<<pos)) | (pupd<<pos);	
+}
+
+void TIMER_Configuration(void) {
 	u32 TimerPeriod = 0;
 	u16 Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;
 	
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_8;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
-	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
-	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	gpio_set_af(GPIOA,1,1,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_LOW);
+	gpio_set_af(GPIOA,8,6,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_LOW);
 
-	GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_6); // TIM1_CH1
-	GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_1); // TIM2_CH2
- 
-	
-
-	
-
-	
 	/*
 		SVGA 800x600 @ 56 Hz
 		Vertical refresh	35.15625 kHz
@@ -112,34 +127,37 @@
 	Channel1Pulse = 144;		/* HSYNC */
 	Channel2Pulse = 364; 		/* HSYNC + BACK PORCH */
 	
-	TIM_TimeBaseStructure.TIM_Prescaler = 0;
-	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-	TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
-	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
-	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
-	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
-
-	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
-	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
-	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
-	TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
-	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
-	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
-	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
-	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
-
-	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
+	TIM1->CR1 &= ~TIM_CR1_CEN;
+	TIM1->PSC=0;
+	TIM1->ARR=TimerPeriod;
+	TIM1->CNT=0;
 	
-	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
-	TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
-	TIM_OC2Init(TIM1, &TIM_OCInitStructure);
-
-	/* TIM1 counter enable and output enable */
-	TIM_CtrlPWMOutputs(TIM1, ENABLE);
-
-	/* Select TIM1 as Master */
-	TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
-	TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
+	// disable Capture and Compare 1 and 2
+	TIM1->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC2E);
+	// 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->CCR1=Channel1Pulse;
+	TIM1->CCR2=Channel2Pulse;
+	TIM1->CCR2 |= TIM_CR2_OIS1; // output idle state set
+	// enable Capture and Compare 1
+	TIM1->CCER |=  TIM_CCER_CC1E |  TIM_CCER_CC2E | TIM_CCER_CC1P | TIM_CCER_CC2P; // output polarity low
+	// main output enable
+    TIM1->BDTR |= TIM_BDTR_MOE; 
+	
+	TIM1->SMCR |= TIM_SMCR_MSM; // master slave mode
+	
+	TIM1->CR2 = (TIM1->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1;// TIM_TRGOSource_Update mode
+	
+	TIM8->CR1 &= ~TIM_CR1_CEN;
+	TIM8->PSC=2;
+	TIM8->ARR=2;
+	TIM8->CNT=0;
+	//TIM16->CR1 |= TIM_CR1_OPM; 
+	
+	TIM8->DIER |= TIM_DIER_UDE;
+	TIM8->SMCR=TIM8->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 4 ;
+	//TIM16->SMCR |= TIM_SMCR_MSM;
+	//TIM16->CR2 = (TIM16->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1;// TIM_TRGOSource_Update mode
 	
 	/*
 		Vertical timing
@@ -159,135 +177,85 @@
 
 	/* VSYNC (TIM2_CH2) and VSYNC_BACKPORCH (TIM2_CH3) */
 	/* Channel 2 and 3 Configuration in PWM mode */
-	TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated);
-	TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);
+	TIM2->SMCR=TIM2->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 5 ;// gated slave mode trigger source 0
+	
 	
 	TimerPeriod = 625;		/* Vertical lines */
 	Channel2Pulse = 2;		/* Sync pulse */
 	Channel3Pulse = 24;		/* Sync pulse + Back porch */
-	TIM_TimeBaseStructure.TIM_Prescaler = 0;
-	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-	TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
-	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
-	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
 
-	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
-
-	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
-	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
-	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
-	TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
-	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
-	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
-	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
-	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
-	TIM_OC2Init(TIM2, &TIM_OCInitStructure);
-	
-	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
-	TIM_OCInitStructure.TIM_Pulse = Channel3Pulse;
-	TIM_OC3Init(TIM2, &TIM_OCInitStructure);
+	TIM2->CR1 &= ~TIM_CR1_CEN;
+	TIM2->PSC=0;
+	TIM2->ARR=TimerPeriod;
+	TIM2->CNT=0;
 
-	/*	TIM2 counter enable and output enable */
-	TIM_CtrlPWMOutputs(TIM2, ENABLE);
-
-	/* Interrupt TIM2 */
-	nvic.NVIC_IRQChannel = TIM2_IRQn;
-    	nvic.NVIC_IRQChannelPreemptionPriority = 1;
-    	nvic.NVIC_IRQChannelSubPriority = 0;
-    	nvic.NVIC_IRQChannelCmd = ENABLE;
-
-	NVIC_Init(&nvic);
-	TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);
+	// disable Capture and Compare 2 and 3
+	TIM2->CCER &= ~(TIM_CCER_CC2E | TIM_CCER_CC3E);
+	// set output compare 1 to PWM mode with preload
+	TIM2->CCMR1 = (TIM2->CCMR1 & ~(TIM_CCMR1_OC2M | TIM_CCMR1_CC2S)) | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1;
+	TIM2->CCR2=Channel2Pulse;
+	TIM2->CCR3=Channel3Pulse;
+	
+//	TIM2->CCR2 |= 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
+	
+	// main output enable
+    TIM2->BDTR |= TIM_BDTR_MOE; 
 
-	/* Interrupt TIM1 */
-	nvic.NVIC_IRQChannel = TIM1_CC_IRQn;
-    	nvic.NVIC_IRQChannelPreemptionPriority = 1;
-    	nvic.NVIC_IRQChannelSubPriority = 0;
-    	nvic.NVIC_IRQChannelCmd = ENABLE;
+	NVIC->IP[TIM2_IRQn]=10; // Interrupt Priority, lower is higher priority
+	NVIC->ISER[TIM2_IRQn >> 0x05] = 1 << (TIM2_IRQn & 0x1F); // Interrupt enable
+	
+	TIM2->DIER |= TIM_DIER_CC3IE;
+	
+	NVIC->IP[TIM1_CC_IRQn]=1; // Interrupt Priority, lower is higher priority
+	NVIC->ISER[TIM1_CC_IRQn >> 0x05] = 1 << (TIM1_CC_IRQn & 0x1F); // Interrupt enable
 
-	NVIC_Init(&nvic);
-	TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
-	
-//	GPIOE->ODR=0;
-	TIM_Cmd(TIM2, ENABLE);
-	TIM_Cmd(TIM1, ENABLE);
+	TIM1->DIER |= TIM_DIER_CC2IE;
+
+	TIM2->CR1 |= TIM_CR1_CEN;
+	TIM1->CR1 |= TIM_CR1_CEN;
 }
 
-void SPI_Configuration(void)
-{
-	NVIC_InitTypeDef nvic;
-	SPI_InitTypeDef SPI_InitStructure;
-	DMA_InitTypeDef	DMA_InitStructure;
-	GPIO_InitTypeDef GPIO_InitStructure;
+void DMA_Configuration(void) {
+	//gpio_set_af(GPIOA,7,5,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_HIGH);
+	
+	GPIOD->PUPDR = (GPIOD->PUPDR & ~0xffff) | 0;//xaaaa; // pull down (1010)
+	GPIOD->OSPEEDR = (GPIOD->OSPEEDR & ~(0xffff)) | 0xffff;
+	
 	
-	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
-	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
-	GPIO_Init(GPIOA, &GPIO_InitStructure);
-
-	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_5); // SPI1_MOSI
-
-	SPI_Cmd(SPI1, DISABLE);
-	DMA_DeInit(DMA1_Channel3);
-
-	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
-	DMA_InitStructure.DMA_MemoryBaseAddr = (u32) fba+fboffset;
-	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
-	DMA_InitStructure.DMA_BufferSize = HTOTAL;
-	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
-	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
-	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
-	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
-	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
-	DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
-	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
-	DMA_Init(DMA1_Channel3, &DMA_InitStructure);
-
-	SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
-	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
-	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
-	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
-	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
-	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
-	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
-	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
-	SPI_InitStructure.SPI_CRCPolynomial = 7;
-	SPI_Init(SPI1, &SPI_InitStructure);
+	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*2;
+    // 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
 	
-	SPI_CalculateCRC(SPI1, DISABLE);
-	SPI_Cmd(SPI1, ENABLE);
-	
-	SPI1->CR2 |= SPI_I2S_DMAReq_Tx;
-	
-	nvic.NVIC_IRQChannel = DMA1_Channel3_IRQn;
-	nvic.NVIC_IRQChannelPreemptionPriority = 0;
-	nvic.NVIC_IRQChannelSubPriority = 0;
-	nvic.NVIC_IRQChannelCmd = ENABLE;
-	NVIC_Init(&nvic);
-	
-	DMA1_Channel3->CCR &= ~1;
-	DMA1_Channel3->CNDTR = HTOTAL;
-	DMA1_Channel3->CMAR = (u32) fba+fboffset;
-	
-	DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
 }
 
 //*****************************************************************************
 //	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 SPI device.
+//	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)
-{
-	if (vflag)
-	{
-		DMA1_Channel3->CCR = 0x3093;
+__attribute__ ((section ("ccmram"))) void TIM1_CC_IRQHandler(void) {
+	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;
 	}
 	TIM1->SR = 0xFFFB; //~TIM_IT_CC2;
-//	GPIOE->ODR ^= 0x2000;
 }
 
 //*****************************************************************************
@@ -295,12 +263,13 @@
 //	Sets the 'vflag' variable to 1 (valid vertical frame).
 //*****************************************************************************
 //__attribute__((interrupt)) 
-__attribute__ ((section ("ccmram"))) void TIM2_IRQHandler(void)
-{
-//	GPIOE->ODR = 0x100;
+__attribute__ ((section ("ccmram"))) void TIM2_IRQHandler(void) {
 	vflag = 1;
 	TIM2->SR = 0xFFF7; //~TIM_IT_CC3;
-//	GPIOE->ODR ^= 0x04000;
+//		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->CR1 |= TIM_CR1_CEN;
+
 }
 
 //*****************************************************************************
@@ -309,53 +278,56 @@
 //	in the DMA register.
 //*****************************************************************************
 //__attribute__((interrupt)) 
-__attribute__ ((section ("ccmram"))) void DMA1_Channel3_IRQHandler(void)
-{	
-//	GPIOE->ODR = 0x200;
-	DMA1->IFCR = DMA1_IT_TC3;
-	DMA1_Channel3->CCR = 0x92;// | (1<<10) | (1<<8);
-	DMA1_Channel3->CNDTR = HTOTAL;
+__attribute__ ((section ("ccmram"))) void DMA2_Channel1_IRQHandler(void) {	
+	DMA2->IFCR = DMA_ISR_TCIF1;
+	DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC  | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE;// 0x3093; 0x92;// | (1<<10) | (1<<8);
+	DMA2_Channel1->CNDTR = HTOTAL;
+	TIM8->CR1 &= ~TIM_CR1_CEN;
 	
 	vdraw++;
-	
-	if (vdraw == 2)
-	{
+	if (vdraw == 4) {
 		vdraw = 0;
-
 		vline++;
-		
-		if (vline == VID_VSIZE)
-		{
+		if (vline == VID_VSIZE) {
 			vdraw = vline = vflag = 0;
-			DMA1_Channel3->CMAR = (u32) fba+fboffset;
+			DMA2_Channel1->CMAR = (u32) fba+fboffset;
 		} else {
-			DMA1_Channel3->CMAR += HTOTAL;
+			DMA2_Channel1->CMAR += HTOTAL;
 		}
 	}
-//	GPIOE->ODR ^= 0x8000;
+}
+__attribute__ ((section ("ccmram"))) void vidNextBuffer(void) {
+	    char *fp=(unsigned *)fb[0];
+	    for(int i=0;i<VID_VSIZE*HTOTAL;i++)
+	    	*fp++=(*fp>>4);//&0xf0f0f0f;
 }
 
-void vidClearScreen(void)
-{
+__attribute__ ((section ("ccmram"))) void waitForRefresh(void) {
+	while(vflag) __wfi();
+}
+void vidClearScreen(void) {
 	u16 x, y;
 
-	for (y = 0; y < VID_VSIZE*2; y++)
-	{
-//		GPIOE->ODR=(y<<8);
-//		for(x=0;x<1000;x++);
-		for (x = 0; x < HTOTAL; x++)
-		{
+	for (y = 0; y < VID_VSIZE; y++) 	{
+		for (x = 0; x < HTOTAL; x++) {
 			fba[y*HTOTAL+x] = 0;
 		}
 	}
 }
 
-void vidInit(void)
-{
+void vidDot(int x, int y, int col) {
+	fb[y][x]=col;
+}
+
+void vidLine(int x, int y, int col) {
+	fb[y][x]=col;
+}
+
+void vidInit(void) {
 	int i;
-	SPI_Configuration();
+	DMA_Configuration();
 	TIMER_Configuration();
-	for(i=0;i<VID_VSIZE*2;i++)
+	for(i=0;i<VID_VSIZE;i++)
 		fb[i]=fba+i*HTOTAL;
 	vidClearScreen();
 }