예제 #1
0
/**
 * @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;
}
예제 #3
0
파일: lcd.cpp 프로젝트: Kreyl/nute
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);
}