Example #1
0
/**
 * @brief   Configures and activates the DAC peripheral.
 *
 * @param[in] dacp      pointer to the @p DACDriver object
 *
 * @notapi
 */
void dac_lld_start(DACDriver *dacp) {

  /* If the driver is in DAC_STOP state then a full initialization is
     required.*/
  if (dacp->state == DAC_STOP) {
    /* Enabling the clock source.*/
#if STM32_DAC_USE_DAC1_CH1
    if (&DACD1 == dacp) {
      rccEnableDAC1(false);
    }
#endif

#if STM32_DAC_USE_DAC1_CH2
    if (&DACD2 == dacp) {
      rccEnableDAC1(false);
    }
#endif

#if STM32_DAC_USE_DAC2_CH1
    if (&DACD3 == dacp) {
      rccEnableDAC2(false);
    }
#endif

#if STM32_DAC_USE_DAC2_CH2
    if (&DACD3 == dacp) {
      rccEnableDAC2(false);
    }
#endif

    /* Enabling DAC in SW triggering mode initially, initializing data to
       zero.*/
#if STM32_DAC_DUAL_MODE == FALSE
    dacp->params->dac->CR &= dacp->params->regmask;
    dacp->params->dac->CR |= DAC_CR_EN1 << dacp->params->regshift;
    dac_lld_put_channel(dacp, 0U, dacp->config->init);
#else
    if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) ||
        (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) ||
        (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) {
      dacp->params->dac->CR = DAC_CR_EN2 | DAC_CR_EN1;
      dac_lld_put_channel(dacp, 1U, dacp->config->init);
    }
    else {
      dacp->params->dac->CR = DAC_CR_EN1;
    }
    dac_lld_put_channel(dacp, 0U, dacp->config->init);
#endif
  }
}
Example #2
0
/**
 * @brief   Configures and activates the DAC peripheral.
 *
 * @param[in] dacp      pointer to the @p DACDriver object
 *
 * @notapi
 */
void dac_lld_start(DACDriver *dacp) {
  uint32_t arr, regshift, trgo, dataoffset;
  bool b;
  /* If in stopped state then enables the DAC and DMA clocks.*/
  if (dacp->state == DAC_STOP) {
#if STM32_DAC_USE_CHN1
    if (&DACD1 == dacp) {
      rccEnableDAC1(FALSE);
      /* DAC1 CR data is at bits 0:15 */
      regshift = 0;
      dataoffset = 0;
      /* Timer setup */
      rccEnableTIM6(FALSE);
      rccResetTIM6();
      trgo = STM32_DAC_CR_TSEL_TIM6;
    }
#endif
#if STM32_DAC_USE_CHN2
    if (&DACD2 == dacp) {
      rccEnableDAC1(FALSE);
      /* DAC2 CR data is at bits 16:31 */
      regshift = 16;
      dataoffset = &dacp->dac->DHR12R2 - &dacp->dac->DHR12R1;
      /* Timer setup */
      rccEnableTIM7(FALSE);
      rccResetTIM7();
      trgo = STM32_DAC_CR_TSEL_TIM7;
    }
#endif
#if STM32_DAC_USE_CHN3
    if (&DACD3 == dacp) {
      rccEnableDAC2(FALSE);
      /* DAC3 CR data is at bits 0:15 */
      regshift = 0;
      dataoffset = 0;
      /* Timer setup */
      rccEnableTIM18(FALSE);
      rccResetTIM18();
      trgo = STM32_DAC_CR_TSEL_TIM18;
    }
#endif
#if STM32_DAC_USE_CHN1 || STM32_DAC_USE_CHN2 || STM32_DAC_USE_CHN3
    dacp->clock = STM32_TIMCLK1;
    arr = (dacp->clock / dacp->config->frequency);
    osalDbgAssert((arr <= 0xFFFF),
        "invalid frequency");

    /* Timer configuration.*/
    dacp->tim->CR1  = 0;                        /* Initially stopped.   */
    dacp->tim->PSC  = 0;                        /* Prescaler value.     */
    dacp->tim->DIER = 0;
    dacp->tim->ARR  = arr;
    dacp->tim->EGR  = TIM_EGR_UG;               /* Update event.        */
    dacp->tim->CR2  &= (uint16_t)~TIM_CR2_MMS;
    dacp->tim->CR2  |= (uint16_t)TIM_CR2_MMS_1; /* Enable TRGO updates. */
    dacp->tim->CNT  = 0;                        /* Reset counter.       */
    dacp->tim->SR   = 0;                        /* Clear pending IRQs.  */
    /* Update Event IRQ enabled. */
    /* Timer start.*/
    dacp->tim->CR1  = TIM_CR1_CEN;

    /* DAC configuration */
    dacp->dac->CR |= ( (dacp->dac->CR & ~STM32_DAC_CR_MASK) | \
      (STM32_DAC_CR_EN | STM32_DAC_CR_DMAEN | dacp->config->cr_flags) ) << regshift;
      
    /* DMA setup. */
    b = dmaStreamAllocate(dacp->dma,
          dacp->irqprio,
          (stm32_dmaisr_t)dac_lld_serve_tx_interrupt,
          (void *)dacp);
    osalDbgAssert(!b, "stream already allocated");
    switch (dacp->config->dhrm) {
      /* Sets the DAC data register */
      case DAC_DHRM_12BIT_RIGHT:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12R1 + dataoffset);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_12BIT_LEFT:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12L1 + dataoffset);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_8BIT_RIGHT:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8R1 + dataoffset);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
        break;
#if defined(STM32_HAS_DAC_CHN2) && STM32_HAS_DAC_CHN2
      case DAC_DHRM_12BIT_RIGHT_DUAL:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12RD);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_12BIT_LEFT_DUAL:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12LD);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_8BIT_RIGHT_DUAL:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8RD);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
             STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
        break;
#endif
  }
  
  dacp->dac->CR |= trgo << regshift; /* Enable timer trigger */
#endif
  }
}