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:
- 10:8ffcefda667a
- Parent:
- 9:654866da5da4
- Child:
- 11:1b3dc5581b1b
diff -r 654866da5da4 -r 8ffcefda667a video.c --- 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; }