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:
Mon May 09 22:35:58 2016 +0000
Revision:
1:1b37c4b989b4
Parent:
0:404dae88af71
Child:
3:93e488fbb8a2
use library

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 0:404dae88af71 37 //#include "stm32f3xx_hal_conf.h"
MartinJohnson 0:404dae88af71 38 #define HTOTAL (VID_HSIZE+2) /* Total bytes to send through SPI */
MartinJohnson 0:404dae88af71 39
MartinJohnson 0:404dae88af71 40 __attribute__ ((aligned (4))) u8 volatile fba[VID_VSIZE*HTOTAL*2]; /* Frame buffer */
MartinJohnson 0:404dae88af71 41
MartinJohnson 0:404dae88af71 42 u8 volatile *fb[VID_VSIZE*2];
MartinJohnson 0:404dae88af71 43
MartinJohnson 0:404dae88af71 44 int fboffset=0;
MartinJohnson 0:404dae88af71 45
MartinJohnson 0:404dae88af71 46 static volatile u16 vline = 0; /* The current line being drawn */
MartinJohnson 0:404dae88af71 47 static volatile u32 vflag = 0; /* When 1, the SPI DMA request can draw on the screen */
MartinJohnson 0:404dae88af71 48 static volatile u32 vdraw = 0; /* Used to increment vline every 3 drawn lines */
MartinJohnson 0:404dae88af71 49
MartinJohnson 0:404dae88af71 50 void TIMER_Configuration(void)
MartinJohnson 0:404dae88af71 51 {
MartinJohnson 0:404dae88af71 52 GPIO_InitTypeDef GPIO_InitStructure;
MartinJohnson 0:404dae88af71 53 NVIC_InitTypeDef nvic;
MartinJohnson 0:404dae88af71 54 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
MartinJohnson 0:404dae88af71 55 TIM_OCInitTypeDef TIM_OCInitStructure;
MartinJohnson 0:404dae88af71 56 u32 TimerPeriod = 0;
MartinJohnson 0:404dae88af71 57 u16 Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;
MartinJohnson 0:404dae88af71 58
MartinJohnson 0:404dae88af71 59 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_8;
MartinJohnson 0:404dae88af71 60 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
MartinJohnson 0:404dae88af71 61 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
MartinJohnson 0:404dae88af71 62 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
MartinJohnson 0:404dae88af71 63 GPIO_Init(GPIOA, &GPIO_InitStructure);
MartinJohnson 0:404dae88af71 64
MartinJohnson 0:404dae88af71 65 GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_6); // TIM1_CH1
MartinJohnson 0:404dae88af71 66 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_1); // TIM2_CH2
MartinJohnson 0:404dae88af71 67
MartinJohnson 0:404dae88af71 68
MartinJohnson 0:404dae88af71 69
MartinJohnson 0:404dae88af71 70
MartinJohnson 0:404dae88af71 71
MartinJohnson 0:404dae88af71 72
MartinJohnson 0:404dae88af71 73 /*
MartinJohnson 0:404dae88af71 74 SVGA 800x600 @ 56 Hz
MartinJohnson 0:404dae88af71 75 Vertical refresh 35.15625 kHz
MartinJohnson 0:404dae88af71 76 Pixel freq. 36.0 MHz
MartinJohnson 0:404dae88af71 77
MartinJohnson 0:404dae88af71 78 1 system tick @ 72Mhz = 0,0138 us
MartinJohnson 0:404dae88af71 79 */
MartinJohnson 0:404dae88af71 80
MartinJohnson 0:404dae88af71 81 /*
MartinJohnson 0:404dae88af71 82 Horizontal timing
MartinJohnson 0:404dae88af71 83 -----------------
MartinJohnson 0:404dae88af71 84
MartinJohnson 0:404dae88af71 85 Timer 1 period = 35156 Hz
MartinJohnson 0:404dae88af71 86
MartinJohnson 0:404dae88af71 87 Timer 1 channel 1 generates a pulse for HSYNC each 28.4 us.
MartinJohnson 0:404dae88af71 88 28.4 us = Visible area + Front porch + Sync pulse + Back porch.
MartinJohnson 0:404dae88af71 89 HSYNC is 2 us long, so the math to do is:
MartinJohnson 0:404dae88af71 90 2us / 0,0138us = 144 system ticks.
MartinJohnson 0:404dae88af71 91
MartinJohnson 0:404dae88af71 92 Timer 1 channel 2 generates a pulse equal to HSYNC + back porch.
MartinJohnson 0:404dae88af71 93 This interrupt will fire the DMA request to draw on the screen if vflag == 1.
MartinJohnson 0:404dae88af71 94 Since firing the DMA takes more or less 800ns, we'll add some extra time.
MartinJohnson 0:404dae88af71 95 The math for HSYNC + back porch is:
MartinJohnson 0:404dae88af71 96 (2us + 3,55us - dma) / 0,0138us = +-350 system ticks
MartinJohnson 0:404dae88af71 97
MartinJohnson 0:404dae88af71 98 Horizontal timing info
MartinJohnson 0:404dae88af71 99 ----------------------
MartinJohnson 0:404dae88af71 100
MartinJohnson 0:404dae88af71 101 Dots us
MartinJohnson 0:404dae88af71 102 --------------------------------------------
MartinJohnson 0:404dae88af71 103 Visible area 800 22.222222222222
MartinJohnson 0:404dae88af71 104 Front porch 24 0.66666666666667
MartinJohnson 0:404dae88af71 105 Sync pulse 72 2
MartinJohnson 0:404dae88af71 106 Back porch 128 3.5555555555556
MartinJohnson 0:404dae88af71 107 Whole line 1024 28.444444444444
MartinJohnson 0:404dae88af71 108
MartinJohnson 0:404dae88af71 109 */
MartinJohnson 0:404dae88af71 110
MartinJohnson 0:404dae88af71 111 TimerPeriod = 2048;
MartinJohnson 0:404dae88af71 112 Channel1Pulse = 144; /* HSYNC */
MartinJohnson 1:1b37c4b989b4 113 Channel2Pulse = 364; /* HSYNC + BACK PORCH */
MartinJohnson 0:404dae88af71 114
MartinJohnson 0:404dae88af71 115 TIM_TimeBaseStructure.TIM_Prescaler = 0;
MartinJohnson 0:404dae88af71 116 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
MartinJohnson 0:404dae88af71 117 TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
MartinJohnson 0:404dae88af71 118 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
MartinJohnson 0:404dae88af71 119 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
MartinJohnson 0:404dae88af71 120 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
MartinJohnson 0:404dae88af71 121
MartinJohnson 0:404dae88af71 122 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
MartinJohnson 0:404dae88af71 123 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
MartinJohnson 0:404dae88af71 124 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
MartinJohnson 0:404dae88af71 125 TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
MartinJohnson 0:404dae88af71 126 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
MartinJohnson 0:404dae88af71 127 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
MartinJohnson 0:404dae88af71 128 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
MartinJohnson 0:404dae88af71 129 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
MartinJohnson 0:404dae88af71 130
MartinJohnson 0:404dae88af71 131 TIM_OC1Init(TIM1, &TIM_OCInitStructure);
MartinJohnson 0:404dae88af71 132
MartinJohnson 0:404dae88af71 133 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
MartinJohnson 0:404dae88af71 134 TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
MartinJohnson 0:404dae88af71 135 TIM_OC2Init(TIM1, &TIM_OCInitStructure);
MartinJohnson 0:404dae88af71 136
MartinJohnson 0:404dae88af71 137 /* TIM1 counter enable and output enable */
MartinJohnson 0:404dae88af71 138 TIM_CtrlPWMOutputs(TIM1, ENABLE);
MartinJohnson 0:404dae88af71 139
MartinJohnson 0:404dae88af71 140 /* Select TIM1 as Master */
MartinJohnson 0:404dae88af71 141 TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
MartinJohnson 0:404dae88af71 142 TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
MartinJohnson 0:404dae88af71 143
MartinJohnson 0:404dae88af71 144 /*
MartinJohnson 0:404dae88af71 145 Vertical timing
MartinJohnson 0:404dae88af71 146 ---------------
MartinJohnson 0:404dae88af71 147
MartinJohnson 0:404dae88af71 148 Polarity of vertical sync pulse is positive.
MartinJohnson 0:404dae88af71 149
MartinJohnson 0:404dae88af71 150 Lines
MartinJohnson 0:404dae88af71 151 ------------------------------
MartinJohnson 0:404dae88af71 152 Visible area 600
MartinJohnson 0:404dae88af71 153 Front porch 1
MartinJohnson 0:404dae88af71 154 Sync pulse 2
MartinJohnson 0:404dae88af71 155 Back porch 22
MartinJohnson 0:404dae88af71 156 Whole frame 625
MartinJohnson 0:404dae88af71 157
MartinJohnson 0:404dae88af71 158 */
MartinJohnson 0:404dae88af71 159
MartinJohnson 0:404dae88af71 160 /* VSYNC (TIM2_CH2) and VSYNC_BACKPORCH (TIM2_CH3) */
MartinJohnson 0:404dae88af71 161 /* Channel 2 and 3 Configuration in PWM mode */
MartinJohnson 0:404dae88af71 162 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated);
MartinJohnson 0:404dae88af71 163 TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);
MartinJohnson 0:404dae88af71 164
MartinJohnson 0:404dae88af71 165 TimerPeriod = 625; /* Vertical lines */
MartinJohnson 0:404dae88af71 166 Channel2Pulse = 2; /* Sync pulse */
MartinJohnson 0:404dae88af71 167 Channel3Pulse = 24; /* Sync pulse + Back porch */
MartinJohnson 0:404dae88af71 168 TIM_TimeBaseStructure.TIM_Prescaler = 0;
MartinJohnson 0:404dae88af71 169 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
MartinJohnson 0:404dae88af71 170 TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
MartinJohnson 0:404dae88af71 171 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
MartinJohnson 0:404dae88af71 172 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
MartinJohnson 0:404dae88af71 173
MartinJohnson 0:404dae88af71 174 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
MartinJohnson 0:404dae88af71 175
MartinJohnson 0:404dae88af71 176 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
MartinJohnson 0:404dae88af71 177 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
MartinJohnson 0:404dae88af71 178 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
MartinJohnson 0:404dae88af71 179 TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
MartinJohnson 0:404dae88af71 180 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
MartinJohnson 0:404dae88af71 181 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
MartinJohnson 0:404dae88af71 182 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
MartinJohnson 0:404dae88af71 183 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
MartinJohnson 0:404dae88af71 184 TIM_OC2Init(TIM2, &TIM_OCInitStructure);
MartinJohnson 0:404dae88af71 185
MartinJohnson 0:404dae88af71 186 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
MartinJohnson 0:404dae88af71 187 TIM_OCInitStructure.TIM_Pulse = Channel3Pulse;
MartinJohnson 0:404dae88af71 188 TIM_OC3Init(TIM2, &TIM_OCInitStructure);
MartinJohnson 0:404dae88af71 189
MartinJohnson 0:404dae88af71 190 /* TIM2 counter enable and output enable */
MartinJohnson 0:404dae88af71 191 TIM_CtrlPWMOutputs(TIM2, ENABLE);
MartinJohnson 0:404dae88af71 192
MartinJohnson 0:404dae88af71 193 /* Interrupt TIM2 */
MartinJohnson 0:404dae88af71 194 nvic.NVIC_IRQChannel = TIM2_IRQn;
MartinJohnson 0:404dae88af71 195 nvic.NVIC_IRQChannelPreemptionPriority = 1;
MartinJohnson 0:404dae88af71 196 nvic.NVIC_IRQChannelSubPriority = 0;
MartinJohnson 0:404dae88af71 197 nvic.NVIC_IRQChannelCmd = ENABLE;
MartinJohnson 0:404dae88af71 198
MartinJohnson 0:404dae88af71 199 NVIC_Init(&nvic);
MartinJohnson 0:404dae88af71 200 TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);
MartinJohnson 0:404dae88af71 201
MartinJohnson 0:404dae88af71 202 /* Interrupt TIM1 */
MartinJohnson 0:404dae88af71 203 nvic.NVIC_IRQChannel = TIM1_CC_IRQn;
MartinJohnson 0:404dae88af71 204 nvic.NVIC_IRQChannelPreemptionPriority = 1;
MartinJohnson 0:404dae88af71 205 nvic.NVIC_IRQChannelSubPriority = 0;
MartinJohnson 0:404dae88af71 206 nvic.NVIC_IRQChannelCmd = ENABLE;
MartinJohnson 0:404dae88af71 207
MartinJohnson 0:404dae88af71 208 NVIC_Init(&nvic);
MartinJohnson 0:404dae88af71 209 TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
MartinJohnson 0:404dae88af71 210
MartinJohnson 0:404dae88af71 211 // GPIOE->ODR=0;
MartinJohnson 0:404dae88af71 212 TIM_Cmd(TIM2, ENABLE);
MartinJohnson 0:404dae88af71 213 TIM_Cmd(TIM1, ENABLE);
MartinJohnson 0:404dae88af71 214 }
MartinJohnson 0:404dae88af71 215
MartinJohnson 0:404dae88af71 216 void SPI_Configuration(void)
MartinJohnson 0:404dae88af71 217 {
MartinJohnson 0:404dae88af71 218 NVIC_InitTypeDef nvic;
MartinJohnson 0:404dae88af71 219 SPI_InitTypeDef SPI_InitStructure;
MartinJohnson 0:404dae88af71 220 DMA_InitTypeDef DMA_InitStructure;
MartinJohnson 0:404dae88af71 221 GPIO_InitTypeDef GPIO_InitStructure;
MartinJohnson 0:404dae88af71 222
MartinJohnson 0:404dae88af71 223 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
MartinJohnson 0:404dae88af71 224 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
MartinJohnson 0:404dae88af71 225 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
MartinJohnson 0:404dae88af71 226 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
MartinJohnson 0:404dae88af71 227 GPIO_Init(GPIOA, &GPIO_InitStructure);
MartinJohnson 0:404dae88af71 228
MartinJohnson 0:404dae88af71 229 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_5); // SPI1_MOSI
MartinJohnson 0:404dae88af71 230
MartinJohnson 0:404dae88af71 231 SPI_Cmd(SPI1, DISABLE);
MartinJohnson 0:404dae88af71 232 DMA_DeInit(DMA1_Channel3);
MartinJohnson 0:404dae88af71 233
MartinJohnson 0:404dae88af71 234 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
MartinJohnson 0:404dae88af71 235 DMA_InitStructure.DMA_MemoryBaseAddr = (u32) fba+fboffset;
MartinJohnson 0:404dae88af71 236 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
MartinJohnson 0:404dae88af71 237 DMA_InitStructure.DMA_BufferSize = HTOTAL;
MartinJohnson 0:404dae88af71 238 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
MartinJohnson 0:404dae88af71 239 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
MartinJohnson 0:404dae88af71 240 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
MartinJohnson 0:404dae88af71 241 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
MartinJohnson 0:404dae88af71 242 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
MartinJohnson 0:404dae88af71 243 DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
MartinJohnson 0:404dae88af71 244 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
MartinJohnson 0:404dae88af71 245 DMA_Init(DMA1_Channel3, &DMA_InitStructure);
MartinJohnson 0:404dae88af71 246
MartinJohnson 0:404dae88af71 247 SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
MartinJohnson 0:404dae88af71 248 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
MartinJohnson 0:404dae88af71 249 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
MartinJohnson 0:404dae88af71 250 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
MartinJohnson 0:404dae88af71 251 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
MartinJohnson 0:404dae88af71 252 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
MartinJohnson 0:404dae88af71 253 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
MartinJohnson 0:404dae88af71 254 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
MartinJohnson 0:404dae88af71 255 SPI_InitStructure.SPI_CRCPolynomial = 7;
MartinJohnson 0:404dae88af71 256 SPI_Init(SPI1, &SPI_InitStructure);
MartinJohnson 0:404dae88af71 257
MartinJohnson 0:404dae88af71 258 SPI_CalculateCRC(SPI1, DISABLE);
MartinJohnson 0:404dae88af71 259 SPI_Cmd(SPI1, ENABLE);
MartinJohnson 0:404dae88af71 260
MartinJohnson 0:404dae88af71 261 SPI1->CR2 |= SPI_I2S_DMAReq_Tx;
MartinJohnson 0:404dae88af71 262
MartinJohnson 0:404dae88af71 263 nvic.NVIC_IRQChannel = DMA1_Channel3_IRQn;
MartinJohnson 0:404dae88af71 264 nvic.NVIC_IRQChannelPreemptionPriority = 0;
MartinJohnson 0:404dae88af71 265 nvic.NVIC_IRQChannelSubPriority = 0;
MartinJohnson 0:404dae88af71 266 nvic.NVIC_IRQChannelCmd = ENABLE;
MartinJohnson 0:404dae88af71 267 NVIC_Init(&nvic);
MartinJohnson 0:404dae88af71 268
MartinJohnson 0:404dae88af71 269 DMA1_Channel3->CCR &= ~1;
MartinJohnson 0:404dae88af71 270 DMA1_Channel3->CNDTR = HTOTAL;
MartinJohnson 0:404dae88af71 271 DMA1_Channel3->CMAR = (u32) fba+fboffset;
MartinJohnson 0:404dae88af71 272
MartinJohnson 0:404dae88af71 273 DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
MartinJohnson 0:404dae88af71 274 }
MartinJohnson 0:404dae88af71 275
MartinJohnson 0:404dae88af71 276 //*****************************************************************************
MartinJohnson 0:404dae88af71 277 // This irq is generated at the end of the horizontal back porch.
MartinJohnson 0:404dae88af71 278 // Test if inside a valid vertical start frame (vflag variable),
MartinJohnson 0:404dae88af71 279 // and start the DMA to output a single frame buffer line through the SPI device.
MartinJohnson 0:404dae88af71 280 //*****************************************************************************
MartinJohnson 0:404dae88af71 281 //__attribute__((interrupt))
MartinJohnson 0:404dae88af71 282
MartinJohnson 0:404dae88af71 283 __attribute__ ((section ("ccmram"))) void TIM1_CC_IRQHandler(void)
MartinJohnson 0:404dae88af71 284 {
MartinJohnson 0:404dae88af71 285 if (vflag)
MartinJohnson 0:404dae88af71 286 {
MartinJohnson 0:404dae88af71 287 DMA1_Channel3->CCR = 0x3093;
MartinJohnson 0:404dae88af71 288 }
MartinJohnson 0:404dae88af71 289 TIM1->SR = 0xFFFB; //~TIM_IT_CC2;
MartinJohnson 0:404dae88af71 290 // GPIOE->ODR ^= 0x2000;
MartinJohnson 0:404dae88af71 291 }
MartinJohnson 0:404dae88af71 292
MartinJohnson 0:404dae88af71 293 //*****************************************************************************
MartinJohnson 0:404dae88af71 294 // This irq is generated at the end of the vertical back porch.
MartinJohnson 0:404dae88af71 295 // Sets the 'vflag' variable to 1 (valid vertical frame).
MartinJohnson 0:404dae88af71 296 //*****************************************************************************
MartinJohnson 0:404dae88af71 297 //__attribute__((interrupt))
MartinJohnson 0:404dae88af71 298 __attribute__ ((section ("ccmram"))) void TIM2_IRQHandler(void)
MartinJohnson 0:404dae88af71 299 {
MartinJohnson 0:404dae88af71 300 // GPIOE->ODR = 0x100;
MartinJohnson 0:404dae88af71 301 vflag = 1;
MartinJohnson 0:404dae88af71 302 TIM2->SR = 0xFFF7; //~TIM_IT_CC3;
MartinJohnson 0:404dae88af71 303 // GPIOE->ODR ^= 0x04000;
MartinJohnson 0:404dae88af71 304 }
MartinJohnson 0:404dae88af71 305
MartinJohnson 0:404dae88af71 306 //*****************************************************************************
MartinJohnson 0:404dae88af71 307 // This interrupt is generated at the end of every line.
MartinJohnson 0:404dae88af71 308 // It will increment the line number and set the corresponding line pointer
MartinJohnson 0:404dae88af71 309 // in the DMA register.
MartinJohnson 0:404dae88af71 310 //*****************************************************************************
MartinJohnson 0:404dae88af71 311 //__attribute__((interrupt))
MartinJohnson 0:404dae88af71 312 __attribute__ ((section ("ccmram"))) void DMA1_Channel3_IRQHandler(void)
MartinJohnson 0:404dae88af71 313 {
MartinJohnson 0:404dae88af71 314 // GPIOE->ODR = 0x200;
MartinJohnson 0:404dae88af71 315 DMA1->IFCR = DMA1_IT_TC3;
MartinJohnson 0:404dae88af71 316 DMA1_Channel3->CCR = 0x92;// | (1<<10) | (1<<8);
MartinJohnson 0:404dae88af71 317 DMA1_Channel3->CNDTR = HTOTAL;
MartinJohnson 0:404dae88af71 318
MartinJohnson 0:404dae88af71 319 vdraw++;
MartinJohnson 0:404dae88af71 320
MartinJohnson 0:404dae88af71 321 if (vdraw == 2)
MartinJohnson 0:404dae88af71 322 {
MartinJohnson 0:404dae88af71 323 vdraw = 0;
MartinJohnson 0:404dae88af71 324
MartinJohnson 0:404dae88af71 325 vline++;
MartinJohnson 0:404dae88af71 326
MartinJohnson 0:404dae88af71 327 if (vline == VID_VSIZE)
MartinJohnson 0:404dae88af71 328 {
MartinJohnson 0:404dae88af71 329 vdraw = vline = vflag = 0;
MartinJohnson 0:404dae88af71 330 DMA1_Channel3->CMAR = (u32) fba+fboffset;
MartinJohnson 0:404dae88af71 331 } else {
MartinJohnson 0:404dae88af71 332 DMA1_Channel3->CMAR += HTOTAL;
MartinJohnson 0:404dae88af71 333 }
MartinJohnson 0:404dae88af71 334 }
MartinJohnson 0:404dae88af71 335 // GPIOE->ODR ^= 0x8000;
MartinJohnson 0:404dae88af71 336 }
MartinJohnson 0:404dae88af71 337
MartinJohnson 0:404dae88af71 338 void vidClearScreen(void)
MartinJohnson 0:404dae88af71 339 {
MartinJohnson 0:404dae88af71 340 u16 x, y;
MartinJohnson 0:404dae88af71 341
MartinJohnson 0:404dae88af71 342 for (y = 0; y < VID_VSIZE*2; y++)
MartinJohnson 0:404dae88af71 343 {
MartinJohnson 0:404dae88af71 344 // GPIOE->ODR=(y<<8);
MartinJohnson 0:404dae88af71 345 // for(x=0;x<1000;x++);
MartinJohnson 0:404dae88af71 346 for (x = 0; x < HTOTAL; x++)
MartinJohnson 0:404dae88af71 347 {
MartinJohnson 0:404dae88af71 348 fba[y*HTOTAL+x] = 0;
MartinJohnson 0:404dae88af71 349 }
MartinJohnson 0:404dae88af71 350 }
MartinJohnson 0:404dae88af71 351 }
MartinJohnson 0:404dae88af71 352
MartinJohnson 0:404dae88af71 353 void vidInit(void)
MartinJohnson 0:404dae88af71 354 {
MartinJohnson 0:404dae88af71 355 int i;
MartinJohnson 0:404dae88af71 356 SPI_Configuration();
MartinJohnson 0:404dae88af71 357 TIMER_Configuration();
MartinJohnson 0:404dae88af71 358 for(i=0;i<VID_VSIZE*2;i++)
MartinJohnson 0:404dae88af71 359 fb[i]=fba+i*HTOTAL;
MartinJohnson 0:404dae88af71 360 vidClearScreen();
MartinJohnson 0:404dae88af71 361 }
MartinJohnson 0:404dae88af71 362