Advertisement
broyildiz

stm32_ub_vga_screen.c

Feb 21st, 2020
917
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.09 KB | None | 0 0
  1. //--------------------------------------------------------------
  2. // File     : stm32_ub_vga_320x240.c
  3. // CPU      : STM32F4
  4. // IDE      : CooCox CoIDE 1.7.0
  5. // Module   : GPIO, TIM, MISC, DMA
  6. // Function : VGA out by GPIO (320x240 Pixel, 8bit color)
  7. // Autor    : UB
  8. // mods by  : J.F. van der Bent
  9. //
  10. // signals  : PB11      = HSync-Signal
  11. //            PB12      = VSync-Signal
  12. //            PE8+PE9   = color Blue
  13. //            PE10-PE12 = color Green
  14. //            PE13-PE15 = color red
  15. //
  16. // uses     : TIM1, TIM2
  17. //            DMA2, Channel6, Stream5
  18. //--------------------------------------------------------------
  19.  
  20.  
  21. //--------------------------------------------------------------
  22. // Includes
  23. //--------------------------------------------------------------
  24. #include "stm32_ub_vga_screen.h"
  25.  
  26.  
  27.  
  28. //--------------------------------------------------------------
  29. // internal Functions
  30. //--------------------------------------------------------------
  31. void P_VGA_InitIO(void);
  32. void P_VGA_InitTIM(void);
  33. void P_VGA_InitINT(void);
  34. void P_VGA_InitDMA(void);
  35.  
  36.  
  37. //--------------------------------------------------------------
  38. // Init VGA-Module
  39. //--------------------------------------------------------------
  40. void UB_VGA_Screen_Init(void)
  41. {
  42.   uint16_t xp,yp;
  43.  
  44.   VGA.hsync_cnt=0;
  45.   VGA.start_adr=0;
  46.   VGA.dma2_cr_reg=0;
  47.  
  48.   // RAM init total black
  49.   for(yp=0;yp<VGA_DISPLAY_Y;yp++) {
  50.     for(xp=0;xp<(VGA_DISPLAY_X+1);xp++) {
  51.       VGA_RAM1[(yp*(VGA_DISPLAY_X+1))+xp]=0;
  52.     }
  53.   }
  54.  
  55.   // init IO-Pins
  56.   P_VGA_InitIO();
  57.   // init Timer
  58.   P_VGA_InitTIM();
  59.   // init DMA
  60.   P_VGA_InitDMA();
  61.   // init Interrupts
  62.   P_VGA_InitINT();
  63.  
  64.   //-----------------------
  65.   // Register swap and safe
  66.   //-----------------------
  67.   // content of CR-Register read and save
  68.   VGA.dma2_cr_reg=DMA2_Stream5->CR;
  69. }
  70.  
  71.  
  72. //--------------------------------------------------------------
  73. // fill the DMA RAM buffer with one color
  74. //--------------------------------------------------------------
  75. void UB_VGA_FillScreen(uint8_t color)
  76. {
  77.   uint16_t xp,yp;
  78.  
  79.   for(yp=0;yp<VGA_DISPLAY_Y;yp++) {
  80.     for(xp=0;xp<VGA_DISPLAY_X;xp++) {
  81.       UB_VGA_SetPixel(xp,yp,color);
  82.     }
  83.   }
  84. }
  85.  
  86.  
  87. //--------------------------------------------------------------
  88. // put one Pixel on the screen with one color
  89. // Important : the last Pixel+1 from every line must be black (don't know why??)
  90. //--------------------------------------------------------------
  91. void UB_VGA_SetPixel(uint16_t xp, uint16_t yp, uint8_t color)
  92. {
  93.   if(xp>=VGA_DISPLAY_X) xp=0;
  94.   if(yp>=VGA_DISPLAY_Y) yp=0;
  95.  
  96.   // Write pixel to ram
  97.   VGA_RAM1[(yp*(VGA_DISPLAY_X+1))+xp]=color;
  98. }
  99.  
  100.  
  101. //--------------------------------------------------------------
  102. // interne Funktionen
  103. // init aller IO-Pins
  104. //--------------------------------------------------------------
  105. void P_VGA_InitIO(void)
  106. {
  107.   GPIO_InitTypeDef  GPIO_InitStructure;
  108.  
  109.  
  110.   //---------------------------------------------
  111.   // init RGB-Pins (PE8 - PE15)
  112.   // as normal GPIOs
  113.   //---------------------------------------------
  114.  
  115.   // Clock Enable
  116.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  117.  
  118.   // Config as Digital output
  119.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
  120.         GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  121.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  122.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  123.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  124.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  125.   GPIO_Init(GPIOE, &GPIO_InitStructure);
  126.  
  127.   GPIOE->BSRRH = VGA_GPIO_HINIBBLE;
  128.  
  129.  
  130.   //---------------------------------------------
  131.   // init of the H-Sync Pin (PB11)
  132.   // using Timer2 and CH4
  133.   //---------------------------------------------
  134.  
  135.   // Clock Enable
  136.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  137.  
  138.   // Config Pins as Digital-out
  139.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  140.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  141.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  142.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  143.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  144.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  145.  
  146.   // alternative function connect with IO
  147.   GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2);
  148.  
  149.  
  150.   //---------------------------------------------
  151.   // init of V-Sync Pin (PB12)
  152.   // using GPIO
  153.   //---------------------------------------------
  154.  
  155.   // Clock Enable
  156.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  157.  
  158.   // Config of the Pins as Digital out
  159.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  160.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  161.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  162.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  163.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  164.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  165.  
  166.   GPIOB->BSRRL = GPIO_Pin_12;
  167. }
  168.  
  169.  
  170. //--------------------------------------------------------------
  171. // internal Function
  172. // init Timer
  173. //--------------------------------------------------------------
  174. void P_VGA_InitTIM(void)
  175. {
  176.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  177.   TIM_OCInitTypeDef  TIM_OCInitStructure;
  178.  
  179.  
  180.   //---------------------------------------------
  181.   // init of Timer1 for
  182.   // Pixeldata via DMA
  183.   //---------------------------------------------
  184.  
  185.   // Clock enable
  186.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  187.  
  188.   // Timer1 init
  189.   TIM_TimeBaseStructure.TIM_Period =  VGA_TIM1_PERIODE;
  190.   TIM_TimeBaseStructure.TIM_Prescaler = VGA_TIM1_PRESCALE;
  191.   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  192.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  193.   TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  194.  
  195.  
  196.   //---------------------------------------------
  197.   // init Timer2
  198.   // CH4 for HSYNC-Signal
  199.   // CH3 for DMA Trigger start
  200.   //---------------------------------------------
  201.  
  202.   // Clock enable
  203.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  204.  
  205.   // Timer2 init
  206.   TIM_TimeBaseStructure.TIM_Period = VGA_TIM2_HSYNC_PERIODE;
  207.   TIM_TimeBaseStructure.TIM_Prescaler = VGA_TIM2_HSYNC_PRESCALE;
  208.   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  209.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  210.   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  211.  
  212.   // Timer2 Channel 3 ( for DMA Trigger start)
  213.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  214.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  215.   TIM_OCInitStructure.TIM_Pulse = VGA_TIM2_HTRIGGER_START-VGA_TIM2_DMA_DELAY;
  216.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  217.   TIM_OC3Init(TIM2, &TIM_OCInitStructure);
  218.   TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
  219.  
  220.   // Timer2 Channel 4 (for HSYNC)
  221.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  222.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  223.   TIM_OCInitStructure.TIM_Pulse = VGA_TIM2_HSYNC_IMP;
  224.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  225.   TIM_OC4Init(TIM2, &TIM_OCInitStructure);
  226.   TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
  227.  
  228.  
  229.   //---------------------------------------------
  230.   // enable all Timers
  231.   //---------------------------------------------
  232.  
  233.   // Timer1 enable
  234.   TIM_ARRPreloadConfig(TIM1, ENABLE);
  235.  
  236.   // Timer2 enable
  237.   TIM_ARRPreloadConfig(TIM2, ENABLE);
  238.   TIM_Cmd(TIM2, ENABLE);
  239.  
  240. }
  241.  
  242. //--------------------------------------------------------------
  243. // internal Function
  244. // init Interrupts
  245. //--------------------------------------------------------------
  246. void P_VGA_InitINT(void)
  247. {
  248.   NVIC_InitTypeDef NVIC_InitStructure;
  249.  
  250.   //---------------------------------------------
  251.   // init from DMA Interrupt
  252.   // for TransferComplete Interrupt
  253.   // DMA2, Stream5, Channel6
  254.   //---------------------------------------------
  255.  
  256.   DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, ENABLE);
  257.  
  258.   // NVIC config
  259.   NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream5_IRQn;
  260.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  261.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  262.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  263.   NVIC_Init(&NVIC_InitStructure);
  264.  
  265.  
  266.   //---------------------------------------------
  267.   // init of Timer2 Interrupt
  268.   // for HSync-Counter using Update
  269.   // for DMA Trigger START using CH3
  270.   //---------------------------------------------
  271.  
  272.   TIM_ITConfig(TIM2,TIM_IT_CC3,ENABLE);
  273.  
  274.   // NVIC config
  275.   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  276.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  277.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  278.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  279.   NVIC_Init(&NVIC_InitStructure);
  280. }
  281.  
  282.  
  283. //--------------------------------------------------------------
  284. // internal Function
  285. // init DMA
  286. //--------------------------------------------------------------
  287. void P_VGA_InitDMA(void)
  288. {
  289.   DMA_InitTypeDef DMA_InitStructure;
  290.  
  291.   //---------------------------------------------
  292.   // DMA of Timer1 Update
  293.   // (look at page 217 of the Ref Manual)
  294.   // DMA=2, Channel=6, Stream=5
  295.   //---------------------------------------------
  296.  
  297.   // Clock Enable (DMA)
  298.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  299.  
  300.   // DMA init (DMA2, Channel6, Stream5)
  301.   DMA_Cmd(DMA2_Stream5, DISABLE);
  302.   DMA_DeInit(DMA2_Stream5);
  303.   DMA_InitStructure.DMA_Channel = DMA_Channel_6;
  304.   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)VGA_GPIOE_ODR_ADDRESS;
  305.   DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&VGA_RAM1;
  306.   DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  307.   DMA_InitStructure.DMA_BufferSize = VGA_DISPLAY_X+1;
  308.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  309.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  310.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  311.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  312.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  313.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  314.   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  315.   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  316.   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  317.   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  318.   DMA_Init(DMA2_Stream5, &DMA_InitStructure);
  319.  
  320.   // DMA-Timer1 enable
  321.   TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);
  322. }
  323.  
  324.  
  325.  
  326. //--------------------------------------------------------------
  327. // Interrupt of Timer2
  328. //
  329. //   CC3-Interrupt    -> starts from DMA
  330. // Watch it.. higher troughput when interrupt flag is left alone
  331. //--------------------------------------------------------------
  332. void TIM2_IRQHandler(void)
  333. {
  334.  
  335.   // Interrupt of Timer2 CH3 occurred (for Trigger start)
  336.   TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
  337.  
  338.   VGA.hsync_cnt++;
  339.   if(VGA.hsync_cnt>=VGA_VSYNC_PERIODE) {
  340.     // -----------
  341.     VGA.hsync_cnt=0;
  342.     // Adresspointer first dot
  343.     VGA.start_adr=(uint32_t)(&VGA_RAM1[0]);
  344.   }
  345.  
  346.   // HSync-Pixel
  347.   if(VGA.hsync_cnt<VGA_VSYNC_IMP) {
  348.     // HSync low
  349.     GPIOB->BSRRH = GPIO_Pin_12;
  350.   }
  351.   else {
  352.     // HSync High
  353.     GPIOB->BSRRL = GPIO_Pin_12;
  354.   }
  355.  
  356.   // Test for DMA start
  357.   if((VGA.hsync_cnt>=VGA_VSYNC_BILD_START) && (VGA.hsync_cnt<=VGA_VSYNC_BILD_STOP)) {
  358.     // after FP start => DMA Transfer
  359.  
  360.     // DMA2 init
  361.     DMA2_Stream5->CR=VGA.dma2_cr_reg;
  362.     // set adress
  363.     DMA2_Stream5->M0AR=VGA.start_adr;
  364.     // Timer1 start
  365.     TIM1->CR1|=TIM_CR1_CEN;
  366.     // DMA2 enable
  367.     DMA2_Stream5->CR|=DMA_SxCR_EN;
  368.  
  369.     // Test Adrespointer for high
  370.     if((VGA.hsync_cnt & 0x01)!=0) {
  371.       // inc after Hsync
  372.       VGA.start_adr+=(VGA_DISPLAY_X+1);
  373.     }
  374.   }
  375. }
  376.  
  377.  
  378. //--------------------------------------------------------------
  379. // DMA Interrupt ISR
  380. //   after TransferCompleteInterrupt -> stop DMA
  381. //
  382. // still a bit buggy
  383. //--------------------------------------------------------------
  384. void DMA2_Stream5_IRQHandler(void)
  385. {
  386.   if(DMA_GetITStatus(DMA2_Stream5, DMA_IT_TCIF5))
  387.   {
  388.     // TransferInterruptComplete Interrupt from DMA2
  389.     DMA_ClearITPendingBit(DMA2_Stream5, DMA_IT_TCIF5);
  390.     // stop after all pixels => DMA Transfer stop
  391.  
  392.     // Timer1 stop
  393.     TIM1->CR1&=~TIM_CR1_CEN;
  394.     // DMA2 disable
  395.     DMA2_Stream5->CR=0;
  396.     // switch on black
  397.     GPIOE->BSRRH = VGA_GPIO_HINIBBLE;
  398.   }
  399. }
  400.  
  401. *
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement