/** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. * The function also enables the IRQ vector associated to the stream * and initializes its priority. * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. * @post The stream ISR vector is enabled and its priority configured. * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] priority IRQ priority mask for the DMA stream * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function * @return The operation status. * @retval false no error, stream taken. * @retval true error, stream already taken. * * @special */ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp, uint32_t priority, stm32_dmaisr_t func, void *param) { osalDbgCheck(dmastp != NULL); /* Checks if the stream is already taken.*/ if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) return true; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; dma_isr_redir[dmastp->selfindex].dma_param = param; dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) rccEnableDMA1(false); #if STM32_HAS_DMA2 if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) rccEnableDMA2(false); #endif /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) nvicEnableVector(dmastp->vector, priority); return false; }
/** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. * The function also enables the IRQ vector associated to the stream * and initializes its priority. * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. * @post The stream ISR vector is enabled and its priority configured. * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] priority IRQ priority mask for the DMA stream * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function * @return The operation status. * @retval FALSE no error, stream taken. * @retval TRUE error, stream already taken. * * @special */ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, uint32_t priority, stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); /* Checks if the stream is already taken.*/ if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) return TRUE; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; dma_isr_redir[dmastp->selfindex].dma_param = param; dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) rccEnableDMA1(FALSE); #if STM32_HAS_DMA2 if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) rccEnableDMA2(FALSE); #endif /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); return FALSE; }
void Lcd_t::Init() { // ==== Backlight: Timer15 Ch2 ==== // Setup pin PinSetupAlterFuncOutput(LCD_GPIO, LCD_BCKLT, omPushPull, ps50MHz); // Remap Timer15 to PB14 & PB15 AFIO->MAPR2 |= 0x00000001; // Setup timer15 rccEnableAPB2(RCC_APB2ENR_TIM15EN, false); TIM15->CR1 = 0x01; // Enable timer TIM15->CR2 = 0; TIM15->PSC = 0; // Do not divide input freq TIM15->ARR = 100; // Autoreload register: full brightness=100 TIM15->BDTR = 0xC000; // Main output Enable TIM15->CCMR1 = 0x6000; // PWM mode1 on Ch2 enabled TIM15->CCER = 0x0010; // Output2 enabled, polarity not inverted BackligthValue = 0; // ==== GPIOs ==== // Configure LCD_XRES, LCD_XCS, LCD_SCLK & LCD_SDA as Push-Pull output InitGpios(); // ========================= Init LCD ====================================== SCLK_Lo(); XCS_Hi(); // Reset display XRES_Lo(); chThdSleepMilliseconds(9); XRES_Hi(); WriteCmd(0xAF); // display ON // Reset display again XRES_Lo(); chThdSleepMilliseconds(7); XRES_Hi(); chThdSleepMilliseconds(7); // Initial commands WriteCmd(0xAF); // display ON WriteCmd(0xA4); // Set normal display mode WriteCmd(0x2F); // Charge pump on WriteCmd(0x40); // Set start row address = 0 // WriteCmd(0xC8); // mirror Y axis // WriteCmd(0xA1); // Mirror X axis // Set x=0, y=0 WriteCmd(0xB3); // Y axis initialization WriteCmd(0x10); // X axis initialisation1 WriteCmd(0x08); // X axis initialisation2 Cls(); // clear LCD buffer draw_mode = OVERWRITE; // ====================== Switch to USART + DMA ============================ #ifdef ENABLE_DMAUSART_MODE PinSetupAlterFuncOutput(LCD_GPIO, LCD_SCLK, omPushPull, ps50MHz); PinSetupAlterFuncOutput(LCD_GPIO, LCD_SDA, omPushPull, ps50MHz); // Workaround hardware bug with disabled CK3 when SPI2 is enabled SPI2->CR2 |= SPI_CR2_SSOE; // ==== USART init ==== rccEnableUSART3(false); // Usart clock: enabled, idle low, first edge, enable last bit pulse // Usart itself LCD_USART->BRR = Clk.APB1FreqHz / 100000; LCD_USART->CR1 = USART_CR1_TE | /* Transmitter enabled */ \ USART_CR1_M; /* 9 bit */ LCD_USART->CR2 = USART_CR2_CLKEN | \ USART_CR2_LBCL; LCD_USART->CR3 = USART_CR3_DMAT; // Enable DMA at transmitter LCD_USART->CR1 |= USART_CR1_UE; // Enable USART // ==== DMA ==== rccEnableDMA1(); dmaStreamAllocate(LCD_DMA, IRQ_PRIO_MEDIUM, LcdDmaCompIrq, NULL); dmaStreamSetPeripheral(LCD_DMA, &USART3->DR); dmaStreamSetMemory0(LCD_DMA, (uint32_t)&IBuf[0]); dmaStreamSetMode (LCD_DMA, LCD_DMA_MODE); // Start transmission XCS_Lo(); // DMA_Cmd(DMA1_Channel2, ENABLE); // Enable USARTy DMA TX Channel #else for(int i=0; i < 864; i++) WriteData(0x00); // Clear all screen #endif Backlight(0); chThdCreateStatic(waLcdThread, sizeof(waLcdThread), NORMALPRIO, (tfunc_t)LcdThread, NULL); }