Demo of low res colour vga video for stm32f3 discovery board
Dependencies: STM32F3-Discovery-minimal
Fork of Space_Invaders_Demo by
Diff: video.c
- 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; }