Demo of low res colour vga video for stm32f3 discovery board

Dependencies:   STM32F3-Discovery-minimal

Fork of Space_Invaders_Demo by Martin Johnson

Committer:
MartinJohnson
Date:
Wed May 16 02:39:14 2018 +0000
Revision:
3:93e488fbb8a2
Parent:
1:1b37c4b989b4
Child:
4:de45d218ed3c
working colour video output

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MartinJohnson 0:404dae88af71 1 /***************************************************************************
MartinJohnson 0:404dae88af71 2 * STM32 VGA demo
MartinJohnson 0:404dae88af71 3 * Copyright (C) 2012 Artekit Italy
MartinJohnson 0:404dae88af71 4 * http://www.artekit.eu
MartinJohnson 0:404dae88af71 5 * Written by Ruben H. Meleca
MartinJohnson 0:404dae88af71 6
MartinJohnson 0:404dae88af71 7 ### video.c
MartinJohnson 0:404dae88af71 8
MartinJohnson 0:404dae88af71 9 # This program is free software; you can redistribute it and/or modify
MartinJohnson 0:404dae88af71 10 # it under the terms of the GNU General Public License as published by
MartinJohnson 0:404dae88af71 11 # the Free Software Foundation; either version 2 of the License, or
MartinJohnson 0:404dae88af71 12 # (at your option) any later version.
MartinJohnson 0:404dae88af71 13 #
MartinJohnson 0:404dae88af71 14 # This program is distributed in the hope that it will be useful,
MartinJohnson 0:404dae88af71 15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
MartinJohnson 0:404dae88af71 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MartinJohnson 0:404dae88af71 17 # GNU General Public License for more details.
MartinJohnson 0:404dae88af71 18 #
MartinJohnson 0:404dae88af71 19 # You should have received a copy of the GNU General Public License
MartinJohnson 0:404dae88af71 20 # along with this program; if not, write to the Free Software
MartinJohnson 0:404dae88af71 21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
MartinJohnson 0:404dae88af71 22
MartinJohnson 0:404dae88af71 23 ***************************************************************************/
MartinJohnson 0:404dae88af71 24
MartinJohnson 0:404dae88af71 25 // VGA connector
MartinJohnson 0:404dae88af71 26 // ---------------------
MartinJohnson 0:404dae88af71 27 // \ Ro Go Bo o Xo / X=Gnd
MartinJohnson 0:404dae88af71 28 // \ o o o o Xo / H=HSync=PA8
MartinJohnson 0:404dae88af71 29 // \ o o Ho Vo o / V=Vsync=PA1
MartinJohnson 0:404dae88af71 30 // -------------- G=Green=PA7
MartinJohnson 0:404dae88af71 31 //
MartinJohnson 1:1b37c4b989b4 32 // o G o o o X X
MartinJohnson 1:1b37c4b989b4 33 // o o o o o H V o
MartinJohnson 1:1b37c4b989b4 34 //
MartinJohnson 0:404dae88af71 35 #include "stm32f30x.h"
MartinJohnson 0:404dae88af71 36 #include "video.h"
MartinJohnson 3:93e488fbb8a2 37 #define HTOTAL (VID_HSIZE+3) /* Total bytes to send */
MartinJohnson 0:404dae88af71 38
MartinJohnson 3:93e488fbb8a2 39 __attribute__ ((aligned (4))) u8 volatile fba[VID_VSIZE*HTOTAL]; /* Frame buffer */
MartinJohnson 0:404dae88af71 40
MartinJohnson 3:93e488fbb8a2 41 __attribute__ ((section ("ccmram"))) u8 volatile *fb[VID_VSIZE];
MartinJohnson 0:404dae88af71 42
MartinJohnson 0:404dae88af71 43 int fboffset=0;
MartinJohnson 0:404dae88af71 44
MartinJohnson 0:404dae88af71 45 static volatile u16 vline = 0; /* The current line being drawn */
MartinJohnson 3:93e488fbb8a2 46 static volatile u32 vflag = 0; /* When 1, the DMA request can draw on the screen */
MartinJohnson 0:404dae88af71 47 static volatile u32 vdraw = 0; /* Used to increment vline every 3 drawn lines */
MartinJohnson 0:404dae88af71 48
MartinJohnson 3:93e488fbb8a2 49 #define GPIO_MODE_INPUT 0
MartinJohnson 3:93e488fbb8a2 50 #define GPIO_MODE_OUTPUT 1
MartinJohnson 3:93e488fbb8a2 51 #define GPIO_MODE_AF 2
MartinJohnson 3:93e488fbb8a2 52
MartinJohnson 3:93e488fbb8a2 53 #define GPIO_NO_PULL 0
MartinJohnson 3:93e488fbb8a2 54 #define GPIO_PULL_UP 1
MartinJohnson 3:93e488fbb8a2 55 #define GPIO_PULL_DOWN 2
MartinJohnson 3:93e488fbb8a2 56
MartinJohnson 3:93e488fbb8a2 57 #define GPIO_OUTPUT_PUSH_PULL 0
MartinJohnson 3:93e488fbb8a2 58
MartinJohnson 3:93e488fbb8a2 59
MartinJohnson 3:93e488fbb8a2 60 #define GPIO_SPEED_MEDIUM 1
MartinJohnson 3:93e488fbb8a2 61 #define GPIO_SPEED_LOW 0
MartinJohnson 3:93e488fbb8a2 62 #define GPIO_SPEED_HIGH 3
MartinJohnson 3:93e488fbb8a2 63
MartinJohnson 3:93e488fbb8a2 64
MartinJohnson 3:93e488fbb8a2 65 void gpio_set_mode(GPIO_TypeDef *g,int n,int mode) {
MartinJohnson 3:93e488fbb8a2 66 n=n<<1;
MartinJohnson 3:93e488fbb8a2 67 g->MODER = (g->MODER & ~(3<<n)) | (mode<<n);
MartinJohnson 3:93e488fbb8a2 68 }
MartinJohnson 3:93e488fbb8a2 69
MartinJohnson 3:93e488fbb8a2 70 void gpio_set_af(GPIO_TypeDef *g,int n,int af, int otype, int pupd, int speed) {
MartinJohnson 3:93e488fbb8a2 71 int reg=n>>3;
MartinJohnson 3:93e488fbb8a2 72 int pos=(n&7)*4;
MartinJohnson 3:93e488fbb8a2 73 g->AFR[reg] = (g->AFR[reg] & ~(0xf<<pos)) | (af<<pos); // alt func
MartinJohnson 3:93e488fbb8a2 74 pos=(n<<1);
MartinJohnson 3:93e488fbb8a2 75 g->OSPEEDR = (g->OSPEEDR & ~(3<<pos)) | (speed<<pos);
MartinJohnson 3:93e488fbb8a2 76 g->OTYPER = (g->OTYPER & ~(1<<n)) | (otype<<n);
MartinJohnson 3:93e488fbb8a2 77 gpio_set_mode(g,n,GPIO_MODE_AF);
MartinJohnson 3:93e488fbb8a2 78 g->PUPDR = (g->PUPDR & ~(3<<pos)) | (pupd<<pos);
MartinJohnson 3:93e488fbb8a2 79 }
MartinJohnson 3:93e488fbb8a2 80
MartinJohnson 3:93e488fbb8a2 81 void TIMER_Configuration(void) {
MartinJohnson 0:404dae88af71 82 u32 TimerPeriod = 0;
MartinJohnson 0:404dae88af71 83 u16 Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;
MartinJohnson 0:404dae88af71 84
MartinJohnson 3:93e488fbb8a2 85 gpio_set_af(GPIOA,1,1,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_LOW);
MartinJohnson 3:93e488fbb8a2 86 gpio_set_af(GPIOA,8,6,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_LOW);
MartinJohnson 0:404dae88af71 87
MartinJohnson 0:404dae88af71 88 /*
MartinJohnson 0:404dae88af71 89 SVGA 800x600 @ 56 Hz
MartinJohnson 0:404dae88af71 90 Vertical refresh 35.15625 kHz
MartinJohnson 0:404dae88af71 91 Pixel freq. 36.0 MHz
MartinJohnson 0:404dae88af71 92
MartinJohnson 0:404dae88af71 93 1 system tick @ 72Mhz = 0,0138 us
MartinJohnson 0:404dae88af71 94 */
MartinJohnson 0:404dae88af71 95
MartinJohnson 0:404dae88af71 96 /*
MartinJohnson 0:404dae88af71 97 Horizontal timing
MartinJohnson 0:404dae88af71 98 -----------------
MartinJohnson 0:404dae88af71 99
MartinJohnson 0:404dae88af71 100 Timer 1 period = 35156 Hz
MartinJohnson 0:404dae88af71 101
MartinJohnson 0:404dae88af71 102 Timer 1 channel 1 generates a pulse for HSYNC each 28.4 us.
MartinJohnson 0:404dae88af71 103 28.4 us = Visible area + Front porch + Sync pulse + Back porch.
MartinJohnson 0:404dae88af71 104 HSYNC is 2 us long, so the math to do is:
MartinJohnson 0:404dae88af71 105 2us / 0,0138us = 144 system ticks.
MartinJohnson 0:404dae88af71 106
MartinJohnson 0:404dae88af71 107 Timer 1 channel 2 generates a pulse equal to HSYNC + back porch.
MartinJohnson 0:404dae88af71 108 This interrupt will fire the DMA request to draw on the screen if vflag == 1.
MartinJohnson 0:404dae88af71 109 Since firing the DMA takes more or less 800ns, we'll add some extra time.
MartinJohnson 0:404dae88af71 110 The math for HSYNC + back porch is:
MartinJohnson 0:404dae88af71 111 (2us + 3,55us - dma) / 0,0138us = +-350 system ticks
MartinJohnson 0:404dae88af71 112
MartinJohnson 0:404dae88af71 113 Horizontal timing info
MartinJohnson 0:404dae88af71 114 ----------------------
MartinJohnson 0:404dae88af71 115
MartinJohnson 0:404dae88af71 116 Dots us
MartinJohnson 0:404dae88af71 117 --------------------------------------------
MartinJohnson 0:404dae88af71 118 Visible area 800 22.222222222222
MartinJohnson 0:404dae88af71 119 Front porch 24 0.66666666666667
MartinJohnson 0:404dae88af71 120 Sync pulse 72 2
MartinJohnson 0:404dae88af71 121 Back porch 128 3.5555555555556
MartinJohnson 0:404dae88af71 122 Whole line 1024 28.444444444444
MartinJohnson 0:404dae88af71 123
MartinJohnson 0:404dae88af71 124 */
MartinJohnson 0:404dae88af71 125
MartinJohnson 0:404dae88af71 126 TimerPeriod = 2048;
MartinJohnson 0:404dae88af71 127 Channel1Pulse = 144; /* HSYNC */
MartinJohnson 1:1b37c4b989b4 128 Channel2Pulse = 364; /* HSYNC + BACK PORCH */
MartinJohnson 0:404dae88af71 129
MartinJohnson 3:93e488fbb8a2 130 TIM1->CR1 &= ~TIM_CR1_CEN;
MartinJohnson 3:93e488fbb8a2 131 TIM1->PSC=0;
MartinJohnson 3:93e488fbb8a2 132 TIM1->ARR=TimerPeriod;
MartinJohnson 3:93e488fbb8a2 133 TIM1->CNT=0;
MartinJohnson 0:404dae88af71 134
MartinJohnson 3:93e488fbb8a2 135 // disable Capture and Compare 1 and 2
MartinJohnson 3:93e488fbb8a2 136 TIM1->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC2E);
MartinJohnson 3:93e488fbb8a2 137 // set output compare 1 to PWM mode with preload
MartinJohnson 3:93e488fbb8a2 138 TIM1->CCMR1 = (TIM1->CCMR1 & ~(TIM_CCMR1_OC1M | TIM_CCMR1_CC1S)) | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
MartinJohnson 3:93e488fbb8a2 139 TIM1->CCR1=Channel1Pulse;
MartinJohnson 3:93e488fbb8a2 140 TIM1->CCR2=Channel2Pulse;
MartinJohnson 3:93e488fbb8a2 141 TIM1->CCR2 |= TIM_CR2_OIS1; // output idle state set
MartinJohnson 3:93e488fbb8a2 142 // enable Capture and Compare 1
MartinJohnson 3:93e488fbb8a2 143 TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC1P | TIM_CCER_CC2P; // output polarity low
MartinJohnson 3:93e488fbb8a2 144 // main output enable
MartinJohnson 3:93e488fbb8a2 145 TIM1->BDTR |= TIM_BDTR_MOE;
MartinJohnson 3:93e488fbb8a2 146
MartinJohnson 3:93e488fbb8a2 147 TIM1->SMCR |= TIM_SMCR_MSM; // master slave mode
MartinJohnson 3:93e488fbb8a2 148
MartinJohnson 3:93e488fbb8a2 149 TIM1->CR2 = (TIM1->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1;// TIM_TRGOSource_Update mode
MartinJohnson 3:93e488fbb8a2 150
MartinJohnson 3:93e488fbb8a2 151 TIM8->CR1 &= ~TIM_CR1_CEN;
MartinJohnson 3:93e488fbb8a2 152 TIM8->PSC=2;
MartinJohnson 3:93e488fbb8a2 153 TIM8->ARR=2;
MartinJohnson 3:93e488fbb8a2 154 TIM8->CNT=0;
MartinJohnson 3:93e488fbb8a2 155 //TIM16->CR1 |= TIM_CR1_OPM;
MartinJohnson 3:93e488fbb8a2 156
MartinJohnson 3:93e488fbb8a2 157 TIM8->DIER |= TIM_DIER_UDE;
MartinJohnson 3:93e488fbb8a2 158 TIM8->SMCR=TIM8->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 4 ;
MartinJohnson 3:93e488fbb8a2 159 //TIM16->SMCR |= TIM_SMCR_MSM;
MartinJohnson 3:93e488fbb8a2 160 //TIM16->CR2 = (TIM16->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1;// TIM_TRGOSource_Update mode
MartinJohnson 0:404dae88af71 161
MartinJohnson 0:404dae88af71 162 /*
MartinJohnson 0:404dae88af71 163 Vertical timing
MartinJohnson 0:404dae88af71 164 ---------------
MartinJohnson 0:404dae88af71 165
MartinJohnson 0:404dae88af71 166 Polarity of vertical sync pulse is positive.
MartinJohnson 0:404dae88af71 167
MartinJohnson 0:404dae88af71 168 Lines
MartinJohnson 0:404dae88af71 169 ------------------------------
MartinJohnson 0:404dae88af71 170 Visible area 600
MartinJohnson 0:404dae88af71 171 Front porch 1
MartinJohnson 0:404dae88af71 172 Sync pulse 2
MartinJohnson 0:404dae88af71 173 Back porch 22
MartinJohnson 0:404dae88af71 174 Whole frame 625
MartinJohnson 0:404dae88af71 175
MartinJohnson 0:404dae88af71 176 */
MartinJohnson 0:404dae88af71 177
MartinJohnson 0:404dae88af71 178 /* VSYNC (TIM2_CH2) and VSYNC_BACKPORCH (TIM2_CH3) */
MartinJohnson 0:404dae88af71 179 /* Channel 2 and 3 Configuration in PWM mode */
MartinJohnson 3:93e488fbb8a2 180 TIM2->SMCR=TIM2->SMCR & ~(TIM_SMCR_SMS | TIM_SMCR_TS) | 5 ;// gated slave mode trigger source 0
MartinJohnson 3:93e488fbb8a2 181
MartinJohnson 0:404dae88af71 182
MartinJohnson 0:404dae88af71 183 TimerPeriod = 625; /* Vertical lines */
MartinJohnson 0:404dae88af71 184 Channel2Pulse = 2; /* Sync pulse */
MartinJohnson 0:404dae88af71 185 Channel3Pulse = 24; /* Sync pulse + Back porch */
MartinJohnson 0:404dae88af71 186
MartinJohnson 3:93e488fbb8a2 187 TIM2->CR1 &= ~TIM_CR1_CEN;
MartinJohnson 3:93e488fbb8a2 188 TIM2->PSC=0;
MartinJohnson 3:93e488fbb8a2 189 TIM2->ARR=TimerPeriod;
MartinJohnson 3:93e488fbb8a2 190 TIM2->CNT=0;
MartinJohnson 0:404dae88af71 191
MartinJohnson 3:93e488fbb8a2 192 // disable Capture and Compare 2 and 3
MartinJohnson 3:93e488fbb8a2 193 TIM2->CCER &= ~(TIM_CCER_CC2E | TIM_CCER_CC3E);
MartinJohnson 3:93e488fbb8a2 194 // set output compare 1 to PWM mode with preload
MartinJohnson 3:93e488fbb8a2 195 TIM2->CCMR1 = (TIM2->CCMR1 & ~(TIM_CCMR1_OC2M | TIM_CCMR1_CC2S)) | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1;
MartinJohnson 3:93e488fbb8a2 196 TIM2->CCR2=Channel2Pulse;
MartinJohnson 3:93e488fbb8a2 197 TIM2->CCR3=Channel3Pulse;
MartinJohnson 3:93e488fbb8a2 198
MartinJohnson 3:93e488fbb8a2 199 // TIM2->CCR2 |= TIM_CR2_OIS1; // output idle state set
MartinJohnson 3:93e488fbb8a2 200 // enable Capture and Compare 2 and 3
MartinJohnson 3:93e488fbb8a2 201 TIM2->CCER |= TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC1P | TIM_CCER_CC2P; // output polarity low
MartinJohnson 3:93e488fbb8a2 202
MartinJohnson 3:93e488fbb8a2 203 // main output enable
MartinJohnson 3:93e488fbb8a2 204 TIM2->BDTR |= TIM_BDTR_MOE;
MartinJohnson 0:404dae88af71 205
MartinJohnson 3:93e488fbb8a2 206 NVIC->IP[TIM2_IRQn]=10; // Interrupt Priority, lower is higher priority
MartinJohnson 3:93e488fbb8a2 207 NVIC->ISER[TIM2_IRQn >> 0x05] = 1 << (TIM2_IRQn & 0x1F); // Interrupt enable
MartinJohnson 3:93e488fbb8a2 208
MartinJohnson 3:93e488fbb8a2 209 TIM2->DIER |= TIM_DIER_CC3IE;
MartinJohnson 3:93e488fbb8a2 210
MartinJohnson 3:93e488fbb8a2 211 NVIC->IP[TIM1_CC_IRQn]=1; // Interrupt Priority, lower is higher priority
MartinJohnson 3:93e488fbb8a2 212 NVIC->ISER[TIM1_CC_IRQn >> 0x05] = 1 << (TIM1_CC_IRQn & 0x1F); // Interrupt enable
MartinJohnson 0:404dae88af71 213
MartinJohnson 3:93e488fbb8a2 214 TIM1->DIER |= TIM_DIER_CC2IE;
MartinJohnson 3:93e488fbb8a2 215
MartinJohnson 3:93e488fbb8a2 216 TIM2->CR1 |= TIM_CR1_CEN;
MartinJohnson 3:93e488fbb8a2 217 TIM1->CR1 |= TIM_CR1_CEN;
MartinJohnson 0:404dae88af71 218 }
MartinJohnson 0:404dae88af71 219
MartinJohnson 3:93e488fbb8a2 220 void DMA_Configuration(void) {
MartinJohnson 3:93e488fbb8a2 221 //gpio_set_af(GPIOA,7,5,GPIO_OUTPUT_PUSH_PULL, GPIO_NO_PULL, GPIO_SPEED_HIGH);
MartinJohnson 3:93e488fbb8a2 222
MartinJohnson 3:93e488fbb8a2 223 GPIOD->PUPDR = (GPIOD->PUPDR & ~0xffff) | 0;//xaaaa; // pull down (1010)
MartinJohnson 3:93e488fbb8a2 224 GPIOD->OSPEEDR = (GPIOD->OSPEEDR & ~(0xffff)) | 0xffff;
MartinJohnson 3:93e488fbb8a2 225
MartinJohnson 0:404dae88af71 226
MartinJohnson 3:93e488fbb8a2 227 RCC->AHBENR |= RCC_AHBENR_DMA2EN;
MartinJohnson 3:93e488fbb8a2 228 // direction = peripheral dest, memory inc, peripheral size=halfword, memory size=byte, priority level=high, transmission complete interrupt enabled
MartinJohnson 3:93e488fbb8a2 229 DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE;
MartinJohnson 3:93e488fbb8a2 230 // DMA1_Channel3->CCR = DMA_CCR_PINC | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_MEM2MEM;
MartinJohnson 3:93e488fbb8a2 231 // bytes to transfer
MartinJohnson 3:93e488fbb8a2 232 DMA2_Channel1->CNDTR = HTOTAL*2;
MartinJohnson 3:93e488fbb8a2 233 // peripheral address
MartinJohnson 3:93e488fbb8a2 234 DMA2_Channel1->CPAR =(uint32_t) &GPIOD->ODR;
MartinJohnson 3:93e488fbb8a2 235 // memory address
MartinJohnson 3:93e488fbb8a2 236 DMA2_Channel1->CMAR =(u32) fba+fboffset;
MartinJohnson 3:93e488fbb8a2 237 // enable CC DMA for TIM16
MartinJohnson 3:93e488fbb8a2 238 // TIM16->DIER |= TIM_DIER_CC1DE;
MartinJohnson 3:93e488fbb8a2 239 // configure NVIC
MartinJohnson 3:93e488fbb8a2 240 NVIC->IP[DMA2_Channel1_IRQn]=16; // Interrupt Priority, lower is higher priority
MartinJohnson 3:93e488fbb8a2 241 NVIC->ISER[DMA2_Channel1_IRQn >> 0x05] = 1 << (DMA2_Channel1_IRQn & 0x1F); // Interrupt enable
MartinJohnson 0:404dae88af71 242
MartinJohnson 0:404dae88af71 243 }
MartinJohnson 0:404dae88af71 244
MartinJohnson 0:404dae88af71 245 //*****************************************************************************
MartinJohnson 0:404dae88af71 246 // This irq is generated at the end of the horizontal back porch.
MartinJohnson 0:404dae88af71 247 // Test if inside a valid vertical start frame (vflag variable),
MartinJohnson 3:93e488fbb8a2 248 // and start the DMA to output a single frame buffer line through the GPIO device.
MartinJohnson 0:404dae88af71 249 //*****************************************************************************
MartinJohnson 0:404dae88af71 250 //__attribute__((interrupt))
MartinJohnson 0:404dae88af71 251
MartinJohnson 3:93e488fbb8a2 252 __attribute__ ((section ("ccmram"))) void TIM1_CC_IRQHandler(void) {
MartinJohnson 3:93e488fbb8a2 253 if (vflag) {
MartinJohnson 3:93e488fbb8a2 254 DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN;;// 0x3093;
MartinJohnson 3:93e488fbb8a2 255 // TIM8->CNT=0;//TIM8->ARR;
MartinJohnson 3:93e488fbb8a2 256 TIM8->CR1 |= TIM_CR1_CEN;
MartinJohnson 0:404dae88af71 257 }
MartinJohnson 0:404dae88af71 258 TIM1->SR = 0xFFFB; //~TIM_IT_CC2;
MartinJohnson 0:404dae88af71 259 }
MartinJohnson 0:404dae88af71 260
MartinJohnson 0:404dae88af71 261 //*****************************************************************************
MartinJohnson 0:404dae88af71 262 // This irq is generated at the end of the vertical back porch.
MartinJohnson 0:404dae88af71 263 // Sets the 'vflag' variable to 1 (valid vertical frame).
MartinJohnson 0:404dae88af71 264 //*****************************************************************************
MartinJohnson 0:404dae88af71 265 //__attribute__((interrupt))
MartinJohnson 3:93e488fbb8a2 266 __attribute__ ((section ("ccmram"))) void TIM2_IRQHandler(void) {
MartinJohnson 0:404dae88af71 267 vflag = 1;
MartinJohnson 0:404dae88af71 268 TIM2->SR = 0xFFF7; //~TIM_IT_CC3;
MartinJohnson 3:93e488fbb8a2 269 // DMA2_Channel1->CCR = DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PL_1 | DMA_CCR_PL_0 | DMA_CCR_TCIE | DMA_CCR_EN;;// 0x3093;
MartinJohnson 3:93e488fbb8a2 270 // TIM8->CNT=0;
MartinJohnson 3:93e488fbb8a2 271 TIM8->CR1 |= TIM_CR1_CEN;
MartinJohnson 3:93e488fbb8a2 272
MartinJohnson 0:404dae88af71 273 }
MartinJohnson 0:404dae88af71 274
MartinJohnson 0:404dae88af71 275 //*****************************************************************************
MartinJohnson 0:404dae88af71 276 // This interrupt is generated at the end of every line.
MartinJohnson 0:404dae88af71 277 // It will increment the line number and set the corresponding line pointer
MartinJohnson 0:404dae88af71 278 // in the DMA register.
MartinJohnson 0:404dae88af71 279 //*****************************************************************************
MartinJohnson 0:404dae88af71 280 //__attribute__((interrupt))
MartinJohnson 3:93e488fbb8a2 281 __attribute__ ((section ("ccmram"))) void DMA2_Channel1_IRQHandler(void) {
MartinJohnson 3:93e488fbb8a2 282 DMA2->IFCR = DMA_ISR_TCIF1;
MartinJohnson 3:93e488fbb8a2 283 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);
MartinJohnson 3:93e488fbb8a2 284 DMA2_Channel1->CNDTR = HTOTAL;
MartinJohnson 3:93e488fbb8a2 285 TIM8->CR1 &= ~TIM_CR1_CEN;
MartinJohnson 0:404dae88af71 286
MartinJohnson 0:404dae88af71 287 vdraw++;
MartinJohnson 3:93e488fbb8a2 288 if (vdraw == 4) {
MartinJohnson 0:404dae88af71 289 vdraw = 0;
MartinJohnson 0:404dae88af71 290 vline++;
MartinJohnson 3:93e488fbb8a2 291 if (vline == VID_VSIZE) {
MartinJohnson 0:404dae88af71 292 vdraw = vline = vflag = 0;
MartinJohnson 3:93e488fbb8a2 293 DMA2_Channel1->CMAR = (u32) fba+fboffset;
MartinJohnson 0:404dae88af71 294 } else {
MartinJohnson 3:93e488fbb8a2 295 DMA2_Channel1->CMAR += HTOTAL;
MartinJohnson 0:404dae88af71 296 }
MartinJohnson 0:404dae88af71 297 }
MartinJohnson 3:93e488fbb8a2 298 }
MartinJohnson 3:93e488fbb8a2 299 __attribute__ ((section ("ccmram"))) void vidNextBuffer(void) {
MartinJohnson 3:93e488fbb8a2 300 char *fp=(unsigned *)fb[0];
MartinJohnson 3:93e488fbb8a2 301 for(int i=0;i<VID_VSIZE*HTOTAL;i++)
MartinJohnson 3:93e488fbb8a2 302 *fp++=(*fp>>4);//&0xf0f0f0f;
MartinJohnson 0:404dae88af71 303 }
MartinJohnson 0:404dae88af71 304
MartinJohnson 3:93e488fbb8a2 305 __attribute__ ((section ("ccmram"))) void waitForRefresh(void) {
MartinJohnson 3:93e488fbb8a2 306 while(vflag) __wfi();
MartinJohnson 3:93e488fbb8a2 307 }
MartinJohnson 3:93e488fbb8a2 308 void vidClearScreen(void) {
MartinJohnson 0:404dae88af71 309 u16 x, y;
MartinJohnson 0:404dae88af71 310
MartinJohnson 3:93e488fbb8a2 311 for (y = 0; y < VID_VSIZE; y++) {
MartinJohnson 3:93e488fbb8a2 312 for (x = 0; x < HTOTAL; x++) {
MartinJohnson 0:404dae88af71 313 fba[y*HTOTAL+x] = 0;
MartinJohnson 0:404dae88af71 314 }
MartinJohnson 0:404dae88af71 315 }
MartinJohnson 0:404dae88af71 316 }
MartinJohnson 0:404dae88af71 317
MartinJohnson 3:93e488fbb8a2 318 void vidDot(int x, int y, int col) {
MartinJohnson 3:93e488fbb8a2 319 fb[y][x]=col;
MartinJohnson 3:93e488fbb8a2 320 }
MartinJohnson 3:93e488fbb8a2 321
MartinJohnson 3:93e488fbb8a2 322 void vidLine(int x, int y, int col) {
MartinJohnson 3:93e488fbb8a2 323 fb[y][x]=col;
MartinJohnson 3:93e488fbb8a2 324 }
MartinJohnson 3:93e488fbb8a2 325
MartinJohnson 3:93e488fbb8a2 326 void vidInit(void) {
MartinJohnson 0:404dae88af71 327 int i;
MartinJohnson 3:93e488fbb8a2 328 DMA_Configuration();
MartinJohnson 0:404dae88af71 329 TIMER_Configuration();
MartinJohnson 3:93e488fbb8a2 330 for(i=0;i<VID_VSIZE;i++)
MartinJohnson 0:404dae88af71 331 fb[i]=fba+i*HTOTAL;
MartinJohnson 0:404dae88af71 332 vidClearScreen();
MartinJohnson 0:404dae88af71 333 }
MartinJohnson 0:404dae88af71 334