/**
  * @brief  Initialize wave recording
  * @param  AudioFreq Audio frequency acquisition.
  *         Note: On STM32L1 evaluation board, the microphone acquisition is 
  *               done through an analong amplifier with a band-pass filter 
  *               centered at 32kHz.
  *               Therefore, this parameter value should be set at maximum 
  *               to 32kHz (value "32000").
  * @param  BitRes Audio frequency to be configured for the I2S peripheral.
  *         Note: On STM32L1 evaluation board, this parameter is not used, but
  *               kept as parameter for compatibility with other STM32 BSP 
  *               drivers.
  * @param ChnlNbr Audio frequency to be configured for the I2S peripheral.
  *         Note: On STM32L1 evaluation board, this parameter is not used, but
  *               kept as parameter for compatibility with other STM32 BSP 
  *               drivers.
  * @retval AUDIO_OK if correct communication, else wrong communication
  */
uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
{
  
  /*## Configure the OPAMP ###################################################*/
  
  /* Set OPAMP instance */
  hAudioInOpamp.Instance = OPAMP1;
  
  /* Configure the OPAMP if not already configured (on the first occurrence   */
  /* of this function ().                                                     */
  if(HAL_OPAMP_GetState(&hAudioInOpamp) == HAL_OPAMP_STATE_RESET)
  {
    /* Configuration of OPAMP */
    hAudioInOpamp.Init.Mode               = OPAMP_STANDALONE_MODE;
    hAudioInOpamp.Init.NonInvertingInput  = OPAMP_NONINVERTINGINPUT_IO0;
    hAudioInOpamp.Init.InvertingInput     = OPAMP_INVERTINGINPUT_IO0;
    hAudioInOpamp.Init.PowerMode          = OPAMP_POWERMODE_NORMAL;
    hAudioInOpamp.Init.PowerSupplyRange   = OPAMP_POWERSUPPLY_HIGH;
    hAudioInOpamp.Init.UserTrimming       = OPAMP_TRIMMING_FACTORY;

    /* Init MSP of OPAMPx */
    OPAMPx_MspInit(&hAudioInOpamp);
    
    /* Init OPAMPx */
    if (HAL_OPAMP_Init(&hAudioInOpamp) != HAL_OK)
    {
      return AUDIO_ERROR;
    }
  }
    
  /* Enable OPAMPx */
  if (HAL_OPAMP_Start(&hAudioInOpamp) != HAL_OK)
  {
    return AUDIO_ERROR;
  }  
  
  /*## Configure the ADC #####################################################*/
  
  /* Set ADC instance */
  hAudioInAdc.Instance = ADC1;
  
  /* Deinitialize the ADC peripheral registers to its default reset values */
  HAL_ADC_DeInit(&hAudioInAdc);
  
  /* Configure the ADC */
  /* Configuration of ADCx init structure: ADC parameters and regular group */
  hAudioInAdc.Init.ClockPrescaler        = ADC_CLOCK_ASYNC_DIV1;         /* ADC clock equal to HSI frequency: 16MHz */
  hAudioInAdc.Init.Resolution            = ADC_RESOLUTION_12B;
  hAudioInAdc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  hAudioInAdc.Init.ScanConvMode          = DISABLE;                      /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  hAudioInAdc.Init.EOCSelection          = ADC_EOC_SEQ_CONV;
  hAudioInAdc.Init.LowPowerAutoWait      = ADC_AUTOWAIT_DISABLE;
  hAudioInAdc.Init.LowPowerAutoPowerOff  = ADC_AUTOPOWEROFF_DISABLE;
  hAudioInAdc.Init.ChannelsBank          = ADC_CHANNELS_BANK_A;
  hAudioInAdc.Init.ContinuousConvMode    = DISABLE;                      /* Continuous mode disabled to have only 1 conversion at each ADC external event trig */
  hAudioInAdc.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T3_TRGO; /* Trig of conversion start done by external event */
  hAudioInAdc.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hAudioInAdc.Init.DMAContinuousRequests = ENABLE;
  
  /* Init MSP of ADCx */
  ADCx_MspInit(&hAudioInAdc);

  /* Init ADCx */
  if (HAL_ADC_Init(&hAudioInAdc) != HAL_OK)
  {
    return AUDIO_ERROR;
  }

  /* Configuration of channel on ADCx regular group on rank 1 */
  hAudioInConfigAdc.Channel       = AUDIO_IN_ADC_CHANNEL;
  hAudioInConfigAdc.SamplingTime  = ADC_SAMPLETIME_384CYCLES;  /* With ADC frequency of 16MHz, conversion time will be 24.75us. This is compliant with sampling time of 32kHz (31.25us) or below */
  hAudioInConfigAdc.Rank          = ADC_REGULAR_RANK_1;
  HAL_ADC_ConfigChannel(&hAudioInAdc, &hAudioInConfigAdc);

  
  /*## Configure the Timer ###################################################*/
  
  /* Set TIM3 period to AudioFreq using system clock 32Mhz */
  hAudioInTim3.Instance           = TIM3;
  hAudioInTim3.Init.Period        = (HAL_RCC_GetPCLK1Freq() / (AudioFreq)) -1;
  hAudioInTim3.Init.Prescaler     = 0;
  hAudioInTim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  hAudioInTim3.Init.CounterMode   = TIM_COUNTERMODE_UP;
  
  /* Init MSP of TIMx */
  TIMx_Base_MspInit(&hAudioInTim3);
  
  /* Init TIMx time base */
  HAL_TIM_Base_Init(&hAudioInTim3);
  
  /* Return 0 if all operations are OK */
  return AUDIO_OK;
}
Esempio n. 2
0
/// \function info([dump_alloc_table])
/// Print out lots of information about the board.
STATIC mp_obj_t pyb_info(uint n_args, const mp_obj_t *args) {
    // get and print unique id; 96 bits
    {
        byte *id = (byte*)0x1fff7a10;
        printf("ID=%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x\n", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11]);
    }

    // get and print clock speeds
    // SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
    {
        printf("S=%lu\nH=%lu\nP1=%lu\nP2=%lu\n",
               HAL_RCC_GetSysClockFreq(),
               HAL_RCC_GetHCLKFreq(),
               HAL_RCC_GetPCLK1Freq(),
               HAL_RCC_GetPCLK2Freq());
    }

    // to print info about memory
    {
        printf("_etext=%p\n", &_etext);
        printf("_sidata=%p\n", &_sidata);
        printf("_sdata=%p\n", &_sdata);
        printf("_edata=%p\n", &_edata);
        printf("_sbss=%p\n", &_sbss);
        printf("_ebss=%p\n", &_ebss);
        printf("_estack=%p\n", &_estack);
        printf("_ram_start=%p\n", &_ram_start);
        printf("_heap_start=%p\n", &_heap_start);
        printf("_heap_end=%p\n", &_heap_end);
        printf("_ram_end=%p\n", &_ram_end);
    }

    // qstr info
    {
        uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
        qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
        printf("qstr:\n  n_pool=%u\n  n_qstr=%u\n  n_str_data_bytes=%u\n  n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
    }

    // GC info
    {
        gc_info_t info;
        gc_info(&info);
        printf("GC:\n");
        printf("  " UINT_FMT " total\n", info.total);
        printf("  " UINT_FMT " : " UINT_FMT "\n", info.used, info.free);
        printf("  1=" UINT_FMT " 2=" UINT_FMT " m=" UINT_FMT "\n", info.num_1block, info.num_2block, info.max_block);
    }

    // free space on flash
    {
        DWORD nclst;
        FATFS *fatfs;
        f_getfree("/flash", &nclst, &fatfs);
        printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
    }

    if (n_args == 1) {
        // arg given means dump gc allocation table
        gc_dump_alloc_table();
    }

    return mp_const_none;
}
/**
  * @brief  This function configures the TIM3 as a time base source. 
  *         The time source is configured  to have 1ms time base with a dedicated 
  *         Tick interrupt priority. 
  * @note   This function is called  automatically at the beginning of program after
  *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). 
  * @param  TickPriority: Tick interrupt priority.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority)
{
  RCC_ClkInitTypeDef    clkconfig;
  uint32_t              uwTimclock, uwAPB1Prescaler = 0;
  uint32_t              uwPrescalerValue = 0;
  uint32_t              pFLatency;
  
    /*Configure the TIM3 IRQ priority */
  HAL_NVIC_SetPriority(TIM3_IRQn, TickPriority ,0);
  
  /* Enable the TIM3 global Interrupt */
  HAL_NVIC_EnableIRQ(TIM3_IRQn);
  
  /* Enable TIM3 clock */
  __HAL_RCC_TIM3_CLK_ENABLE();
  
  /* Get clock configuration */
  HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
  
  /* Get APB1 prescaler */
  uwAPB1Prescaler = clkconfig.APB1CLKDivider;
  
  /* Compute TIM3 clock */
  if (uwAPB1Prescaler == RCC_HCLK_DIV1) 
  {
    uwTimclock = HAL_RCC_GetPCLK1Freq();
  }
  else
  {
    uwTimclock = 2*HAL_RCC_GetPCLK1Freq();
  }

  /* Compute the prescaler value to have TIM3 counter clock equal to 1MHz */
  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1);
  
  /* Initialize TIM3 */
  TimHandle.Instance = TIM3;
    
  /* Initialize TIMx peripheral as follow:
       + Period = [(TIM3CLK/1000) - 1]. to have a (1/1000) s time base.
       + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
       + ClockDivision = 0
       + Counter direction = Up
  */
  TimHandle.Init.Period = (1000000 / 1000) - 1;
  TimHandle.Init.Prescaler = uwPrescalerValue;
  TimHandle.Init.ClockDivision = 0;
  TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
  if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
  
  /* Start the TIM time Base generation in interrupt mode */
  if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
  {
    /* Starting Error */
    Error_Handler();
  }
 

   /* Return function status */
  return HAL_OK;
}
Esempio n. 4
0
File: main.c Progetto: z80/stm32f429
/**
  * @brief  Configures TIM5 to measure the LSI oscillator frequency.
  * @param  None
  * @retval LSI Frequency
  */
static uint32_t GetLSIFrequency(void)
{
  uint32_t pclk1 = 0, latency = 0;
  TIM_IC_InitTypeDef timinputconfig = {0};
  RCC_OscInitTypeDef oscinit = {0};
  RCC_ClkInitTypeDef  clkinit =  {0};
  
  /* Enable LSI Oscillator */
  oscinit.OscillatorType = RCC_OSCILLATORTYPE_LSI;
  oscinit.LSIState = RCC_LSI_ON;
  oscinit.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&oscinit)!= HAL_OK)
  {
    Error_Handler(); 
  }

  /* Configure the TIM peripheral */
  /* Set TIMx instance */
  TimInputCaptureHandle.Instance = TIMx;

  /* TIMx configuration: Input Capture mode ---------------------
  The LSI clock is connected to TIM5 CH4.
  The Rising edge is used as active edge.
  The TIM5 CCR4 is used to compute the frequency value.
  ------------------------------------------------------------ */
  TimInputCaptureHandle.Init.Prescaler         = 0;
  TimInputCaptureHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  TimInputCaptureHandle.Init.Period            = 0xFFFF;
  TimInputCaptureHandle.Init.ClockDivision     = 0;
  TimInputCaptureHandle.Init.RepetitionCounter = 0;
  
  if (HAL_TIM_IC_Init(&TimInputCaptureHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
  /* Connect internally the  TIM5 CH4 Input Capture to the LSI clock output */
  HAL_TIMEx_RemapConfig(&TimInputCaptureHandle, TIMx_REMAP);

  /* Configure the Input Capture of channel 4 */
  timinputconfig.ICPolarity  = TIM_ICPOLARITY_RISING;
  timinputconfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
  timinputconfig.ICPrescaler = TIM_ICPSC_DIV8;
  timinputconfig.ICFilter    = 0;

  if (HAL_TIM_IC_ConfigChannel(&TimInputCaptureHandle, &timinputconfig, TIM_CHANNEL_4) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /* Reset the flags */
  TimInputCaptureHandle.Instance->SR = 0;

  /* Start the TIM Input Capture measurement in interrupt mode */
  if (HAL_TIM_IC_Start_IT(&TimInputCaptureHandle, TIM_CHANNEL_4) != HAL_OK)
  {
    /* Starting Error */
    Error_Handler();
  }

  /* Wait until the TIM5 get 2 LSI edges (refer to TIM5_IRQHandler() in
  stm32f4xx_it.c file) */
  while (uwMeasurementDone == 0)
  {
  }
  uwCaptureNumber = 0;

  /* Deinitialize the TIM5 peripheral registers to their default reset values */
  HAL_TIM_IC_DeInit(&TimInputCaptureHandle);

  /* Compute the LSI frequency, depending on TIM5 input clock frequency (PCLK1)*/
  /* Get PCLK1 frequency */
  pclk1 = HAL_RCC_GetPCLK1Freq();
  HAL_RCC_GetClockConfig(&clkinit, &latency);

  /* Get PCLK1 prescaler */
  if ((clkinit.APB1CLKDivider) == RCC_HCLK_DIV1)
  {
    /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */
    return ((pclk1 / uwPeriodValue) * 8);
  }
  else
  {
    /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */
    return (((2 * pclk1) / uwPeriodValue) * 8) ;
  }
}
Esempio n. 5
0
static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configuration *cfg)
{
    RT_ASSERT(spi_drv != RT_NULL);
    RT_ASSERT(cfg != RT_NULL);

    SPI_HandleTypeDef *spi_handle = &spi_drv->handle;

    if (cfg->mode & RT_SPI_SLAVE)
    {
        spi_handle->Init.Mode = SPI_MODE_SLAVE;
    }
    else
    {
        spi_handle->Init.Mode = SPI_MODE_MASTER;
    }

    if (cfg->mode & RT_SPI_3WIRE)
    {
        spi_handle->Init.Direction = SPI_DIRECTION_1LINE;
    }
    else
    {
        spi_handle->Init.Direction = SPI_DIRECTION_2LINES;
    }

    if (cfg->data_width == 8)
    {
        spi_handle->Init.DataSize = SPI_DATASIZE_8BIT;
        spi_handle->TxXferSize = 8;
        spi_handle->RxXferSize = 8;
    }
    else if (cfg->data_width == 16)
    {
        spi_handle->Init.DataSize = SPI_DATASIZE_16BIT;
    }
    else
    {
        return RT_EIO;
    }

    if (cfg->mode & RT_SPI_CPHA)
    {
        spi_handle->Init.CLKPhase = SPI_PHASE_2EDGE;
    }
    else
    {
        spi_handle->Init.CLKPhase = SPI_PHASE_1EDGE;
    }

    if (cfg->mode & RT_SPI_CPOL)
    {
        spi_handle->Init.CLKPolarity = SPI_POLARITY_HIGH;
    }
    else
    {
        spi_handle->Init.CLKPolarity = SPI_POLARITY_LOW;
    }

    if (cfg->mode & RT_SPI_NO_CS)
    {
        spi_handle->Init.NSS = SPI_NSS_SOFT;
    }
    else
    {
        spi_handle->Init.NSS = SPI_NSS_SOFT;
    }

    uint32_t SPI_APB_CLOCK;

#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
    SPI_APB_CLOCK = HAL_RCC_GetPCLK1Freq();
#else
    SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq();
#endif

    if (cfg->max_hz >= SPI_APB_CLOCK / 2)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
    }
    else if (cfg->max_hz >= SPI_APB_CLOCK / 4)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
    }
    else if (cfg->max_hz >= SPI_APB_CLOCK / 8)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
    }
    else if (cfg->max_hz >= SPI_APB_CLOCK / 16)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
    }
    else if (cfg->max_hz >= SPI_APB_CLOCK / 32)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
    }
    else if (cfg->max_hz >= SPI_APB_CLOCK / 64)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
    }
    else if (cfg->max_hz >= SPI_APB_CLOCK / 128)
    {
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
    }
    else
    {
        /*  min prescaler 256 */
        spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
    }

    LOG_D("sys freq: %d, pclk2 freq: %d, SPI limiting freq: %d, BaudRatePrescaler: %d",
          HAL_RCC_GetSysClockFreq(),
          SPI_APB_CLOCK,
          cfg->max_hz,
          spi_handle->Init.BaudRatePrescaler);

    if (cfg->mode & RT_SPI_MSB)
    {
        spi_handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
    }
    else
    {
        spi_handle->Init.FirstBit = SPI_FIRSTBIT_LSB;
    }

    spi_handle->Init.TIMode = SPI_TIMODE_DISABLE;
    spi_handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    spi_handle->State = HAL_SPI_STATE_RESET;
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0)
    spi_handle->Init.NSSPMode          = SPI_NSS_PULSE_DISABLE;
#endif

    if (HAL_SPI_Init(spi_handle) != HAL_OK)
    {
        return RT_EIO;
    }

#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) \
        || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32G0)
    SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF);
#endif

    /* DMA configuration */
    if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
    {
        HAL_DMA_Init(&spi_drv->dma.handle_rx);

        __HAL_LINKDMA(&spi_drv->handle, hdmarx, spi_drv->dma.handle_rx);

        /* NVIC configuration for DMA transfer complete interrupt */
        HAL_NVIC_SetPriority(spi_drv->config->dma_rx->dma_irq, 0, 0);
        HAL_NVIC_EnableIRQ(spi_drv->config->dma_rx->dma_irq);
    }

    if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
    {
        HAL_DMA_Init(&spi_drv->dma.handle_tx);

        __HAL_LINKDMA(&spi_drv->handle, hdmatx, spi_drv->dma.handle_tx);

        /* NVIC configuration for DMA transfer complete interrupt */
        HAL_NVIC_SetPriority(spi_drv->config->dma_tx->dma_irq, 0, 1);
        HAL_NVIC_EnableIRQ(spi_drv->config->dma_tx->dma_irq);
    }

    __HAL_SPI_ENABLE(spi_handle);

    LOG_D("%s init done", spi_drv->config->bus_name);
    return RT_EOK;
}
Esempio n. 6
0
/// \function freq([sys_freq])
///
/// If given no arguments, returns a tuple of clock frequencies:
/// (SYSCLK, HCLK, PCLK1, PCLK2).
///
/// If given an argument, sets the system frequency to that value in Hz.
/// Eg freq(120000000) gives 120MHz.  Note that not all values are
/// supported and the largest supported frequency not greater than
/// the given sys_freq will be selected.
STATIC mp_obj_t pyb_freq(mp_uint_t n_args, const mp_obj_t *args) {
    if (n_args == 0) {
        // get
        mp_obj_t tuple[4] = {
           mp_obj_new_int(HAL_RCC_GetSysClockFreq()),
           mp_obj_new_int(HAL_RCC_GetHCLKFreq()),
           mp_obj_new_int(HAL_RCC_GetPCLK1Freq()),
           mp_obj_new_int(HAL_RCC_GetPCLK2Freq()),
        };
        return mp_obj_new_tuple(4, tuple);
    } else {
        // set
        mp_int_t wanted_sysclk = mp_obj_get_int(args[0]) / 1000000;
        // search for a valid PLL configuration that keeps USB at 48MHz
        for (; wanted_sysclk > 0; wanted_sysclk--) {
            for (mp_uint_t p = 2; p <= 8; p += 2) {
                if (wanted_sysclk * p % 48 != 0) {
                    continue;
                }
                mp_uint_t q = wanted_sysclk * p / 48;
                if (q < 2 || q > 15) {
                    continue;
                }
                if (wanted_sysclk * p % (HSE_VALUE / 1000000) != 0) {
                    continue;
                }
                mp_uint_t n_by_m = wanted_sysclk * p / (HSE_VALUE / 1000000);
                mp_uint_t m = 192 / n_by_m;
                while (m < (HSE_VALUE / 2000000) || n_by_m * m < 192) {
                    m += 1;
                }
                if (m > (HSE_VALUE / 1000000)) {
                    continue;
                }
                mp_uint_t n = n_by_m * m;
                if (n < 192 || n > 432) {
                    continue;
                }

                // found values!

                // let the USB CDC have a chance to process before we change the clock
                HAL_Delay(USBD_CDC_POLLING_INTERVAL + 2);

                // set HSE as system clock source to allow modification of the PLL configuration
                RCC_ClkInitTypeDef RCC_ClkInitStruct;
                RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
                RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
                if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
                    goto fail;
                }

                // re-configure PLL
                RCC_OscInitTypeDef RCC_OscInitStruct;
                RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
                RCC_OscInitStruct.HSEState = RCC_HSE_ON;
                RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
                RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
                RCC_OscInitStruct.PLL.PLLM = m;
                RCC_OscInitStruct.PLL.PLLN = n;
                RCC_OscInitStruct.PLL.PLLP = p;
                RCC_OscInitStruct.PLL.PLLQ = q;
                if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
                    goto fail;
                }

                // set PLL as system clock source
                RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
                RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
                RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
                RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
                RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
                if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
                    goto fail;
                }

                // re-init TIM3 for USB CDC rate
                timer_tim3_init();

                return mp_const_none;

                void __fatal_error(const char *msg);
                fail:
                __fatal_error("can't change freq");
            }
        }
        nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't make valid freq"));
    }
}
Esempio n. 7
0
/// \function freq([sys_freq])
///
/// If given no arguments, returns a tuple of clock frequencies:
/// (SYSCLK, HCLK, PCLK1, PCLK2).
///
/// If given an argument, sets the system frequency to that value in Hz.
/// Eg freq(120000000) gives 120MHz.  Note that not all values are
/// supported and the largest supported frequency not greater than
/// the given sys_freq will be selected.
STATIC mp_obj_t pyb_freq(mp_uint_t n_args, const mp_obj_t *args) {
    if (n_args == 0) {
        // get
        mp_obj_t tuple[4] = {
           mp_obj_new_int(HAL_RCC_GetSysClockFreq()),
           mp_obj_new_int(HAL_RCC_GetHCLKFreq()),
           mp_obj_new_int(HAL_RCC_GetPCLK1Freq()),
           mp_obj_new_int(HAL_RCC_GetPCLK2Freq()),
        };
        return mp_obj_new_tuple(4, tuple);
    } else {
        // set
        mp_int_t wanted_sysclk = mp_obj_get_int(args[0]) / 1000000;

        // default PLL parameters that give 48MHz on PLL48CK
        uint32_t m = HSE_VALUE / 1000000, n = 336, p = 2, q = 7;
        uint32_t sysclk_source;

        // the following logic assumes HSE < HSI
        if (HSE_VALUE / 1000000 <= wanted_sysclk && wanted_sysclk < HSI_VALUE / 1000000) {
            // use HSE as SYSCLK
            sysclk_source = RCC_SYSCLKSOURCE_HSE;
        } else if (HSI_VALUE / 1000000 <= wanted_sysclk && wanted_sysclk < 24) {
            // use HSI as SYSCLK
            sysclk_source = RCC_SYSCLKSOURCE_HSI;
        } else {
            // search for a valid PLL configuration that keeps USB at 48MHz
            for (; wanted_sysclk > 0; wanted_sysclk--) {
                for (p = 2; p <= 8; p += 2) {
                    // compute VCO_OUT
                    mp_uint_t vco_out = wanted_sysclk * p;
                    // make sure VCO_OUT is between 192MHz and 432MHz
                    if (vco_out < 192 || vco_out > 432) {
                        continue;
                    }
                    // make sure Q is an integer
                    if (vco_out % 48 != 0) {
                        continue;
                    }
                    // solve for Q to get PLL48CK at 48MHz
                    q = vco_out / 48;
                    // make sure Q is in range
                    if (q < 2 || q > 15) {
                        continue;
                    }
                    // make sure N/M is an integer
                    if (vco_out % (HSE_VALUE / 1000000) != 0) {
                        continue;
                    }
                    // solve for N/M
                    mp_uint_t n_by_m = vco_out / (HSE_VALUE / 1000000);
                    // solve for M, making sure VCO_IN (=HSE/M) is between 1MHz and 2MHz
                    m = 192 / n_by_m;
                    while (m < (HSE_VALUE / 2000000) || n_by_m * m < 192) {
                        m += 1;
                    }
                    if (m > (HSE_VALUE / 1000000)) {
                        continue;
                    }
                    // solve for N
                    n = n_by_m * m;
                    // make sure N is in range
                    if (n < 192 || n > 432) {
                        continue;
                    }

                    // found values!
                    sysclk_source = RCC_SYSCLKSOURCE_PLLCLK;
                    goto set_clk;
                }
            }
            nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't make valid freq"));
        }

    set_clk:
        //printf("%lu %lu %lu %lu %lu\n", sysclk_source, m, n, p, q);

        // let the USB CDC have a chance to process before we change the clock
        HAL_Delay(USBD_CDC_POLLING_INTERVAL + 2);

        // desired system clock source is in sysclk_source
        RCC_ClkInitTypeDef RCC_ClkInitStruct;
        RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
        if (sysclk_source == RCC_SYSCLKSOURCE_PLLCLK) {
            // set HSE as system clock source to allow modification of the PLL configuration
            // we then change to PLL after re-configuring PLL
            RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
        } else {
            // directly set the system clock source as desired
            RCC_ClkInitStruct.SYSCLKSource = sysclk_source;
        }
        RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
        RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
        RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
        if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
            goto fail;
        }

        // re-configure PLL
        // even if we don't use the PLL for the system clock, we still need it for USB, RNG and SDIO
        RCC_OscInitTypeDef RCC_OscInitStruct;
        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
        RCC_OscInitStruct.HSEState = RCC_HSE_ON;
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
        RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
        RCC_OscInitStruct.PLL.PLLM = m;
        RCC_OscInitStruct.PLL.PLLN = n;
        RCC_OscInitStruct.PLL.PLLP = p;
        RCC_OscInitStruct.PLL.PLLQ = q;
        if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
            goto fail;
        }

        // set PLL as system clock source if wanted
        if (sysclk_source == RCC_SYSCLKSOURCE_PLLCLK) {
            RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
            RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
            if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
                goto fail;
            }
        }

        // re-init TIM3 for USB CDC rate
        timer_tim3_init();

        return mp_const_none;

    fail:;
        void NORETURN __fatal_error(const char *msg);
        __fatal_error("can't change freq");
    }
}
Esempio n. 8
0
void pwmout_period_us(pwmout_t* obj, int us)
{
    TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    uint32_t PclkFreq;
    uint32_t APBxCLKDivider;
    float dc = pwmout_read(obj);

    __HAL_TIM_DISABLE(&TimHandle);

    // Get clock configuration
    // Note: PclkFreq contains here the Latency (not used after)
    HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &PclkFreq);

    // Get the PCLK and APBCLK divider related to the timer
    switch (obj->pwm) {

            // APB1 clock
#if defined(TIM2_BASE)
        case PWM_2:
#endif
#if defined(TIM3_BASE)
        case PWM_3:
#endif
#if defined(TIM4_BASE)
        case PWM_4:
#endif
#if defined(TIM5_BASE)
        case PWM_5:
#endif
#if defined(TIM12_BASE)
        case PWM_12:
#endif
#if defined(TIM13_BASE)
        case PWM_13:
#endif
#if defined(TIM14_BASE)
        case PWM_14:
#endif
            PclkFreq = HAL_RCC_GetPCLK1Freq();
            APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
            break;

            // APB2 clock
#if defined(TIM1_BASE)
        case PWM_1:
#endif
#if defined(TIM8_BASE)
        case PWM_8:
#endif
#if defined(TIM9_BASE)
        case PWM_9:
#endif
#if defined(TIM10_BASE)
        case PWM_10:
#endif
#if defined(TIM11_BASE)
        case PWM_11:
#endif
            PclkFreq = HAL_RCC_GetPCLK2Freq();
            APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
            break;
        default:
            return;
    }

    TimHandle.Init.Period        = us - 1;
    // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
    if (APBxCLKDivider == RCC_HCLK_DIV1)
        TimHandle.Init.Prescaler   = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 us tick
    else
        TimHandle.Init.Prescaler   = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 us tick
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;

    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
        error("Cannot initialize PWM\n");
    }

    // Set duty cycle again
    pwmout_write(obj, dc);

    // Save for future use
    obj->period = us;

    __HAL_TIM_ENABLE(&TimHandle);
}
/**
  * @brief Configure the SMARTCARD associated USART peripheral 
  * @param hsc: SMARTCARD handle
  * @retval None
  */
static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
{
  uint32_t tmpreg      = 0x00000000U;
  uint32_t clocksource = 0x00000000U;
  
  /* Check the parameters */ 
  assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
  assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); 
  assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));  
  assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));   
  assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
  assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
  assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
  assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
  assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));    
  assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsc->Init.OneBitSampling));
  assert_param(IS_SMARTCARD_NACK(hsc->Init.NACKState));
  assert_param(IS_SMARTCARD_TIMEOUT(hsc->Init.TimeOutEnable));
  assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsc->Init.AutoRetryCount)); 

  /*-------------------------- USART CR1 Configuration -----------------------*/
  /* In SmartCard mode, M and PCE are forced to 1 (8 bits + parity).
   * Oversampling is forced to 16 (OVER8 = 0).
   * Configure the Parity and Mode: 
   *  set PS bit according to hsc->Init.Parity value
   *  set TE and RE bits according to hsc->Init.Mode value */
  tmpreg = (uint32_t) hsc->Init.Parity | hsc->Init.Mode;
  /* in case of TX-only mode, if NACK is enabled, the USART must be able to monitor 
     the bidirectional line to detect a NACK signal in case of parity error. 
     Therefore, the receiver block must be enabled as well (RE bit must be set). */
  if((hsc->Init.Mode == SMARTCARD_MODE_TX) && (hsc->Init.NACKState == SMARTCARD_NACK_ENABLE))
  {
    tmpreg |= USART_CR1_RE;   
  }
  tmpreg |= (uint32_t) hsc->Init.WordLength;
  MODIFY_REG(hsc->Instance->CR1, USART_CR1_FIELDS, tmpreg);

  /*-------------------------- USART CR2 Configuration -----------------------*/
  /* Stop bits are forced to 1.5 (STOP = 11) */
  tmpreg = hsc->Init.StopBits;
  /* Synchronous mode is activated by default */
  tmpreg |= (uint32_t) USART_CR2_CLKEN | hsc->Init.CLKPolarity; 
  tmpreg |= (uint32_t) hsc->Init.CLKPhase | hsc->Init.CLKLastBit;
  tmpreg |= (uint32_t) hsc->Init.TimeOutEnable;
  MODIFY_REG(hsc->Instance->CR2, USART_CR2_FIELDS, tmpreg); 
    
  /*-------------------------- USART CR3 Configuration -----------------------*/
  /* Configure 
   * - one-bit sampling method versus three samples' majority rule 
   *   according to hsc->Init.OneBitSampling 
   * - NACK transmission in case of parity error according 
   *   to hsc->Init.NACKEnable   
   * - autoretry counter according to hsc->Init.AutoRetryCount     */
  tmpreg =  (uint32_t) hsc->Init.OneBitSampling | hsc->Init.NACKState;
  tmpreg |= (uint32_t) (hsc->Init.AutoRetryCount << SMARTCARD_CR3_SCARCNT_LSB_POS);
  MODIFY_REG(hsc->Instance-> CR3,USART_CR3_FIELDS, tmpreg);
  
  /*-------------------------- USART GTPR Configuration ----------------------*/
  tmpreg = (uint32_t) (hsc->Init.Prescaler | (hsc->Init.GuardTime << SMARTCARD_GTPR_GT_LSB_POS));
  MODIFY_REG(hsc->Instance->GTPR, (uint32_t)(USART_GTPR_GT|USART_GTPR_PSC), tmpreg); 
  
  /*-------------------------- USART RTOR Configuration ----------------------*/ 
  tmpreg =   (uint32_t) (hsc->Init.BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS);
  if(hsc->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE)
  {
    assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsc->Init.TimeOutValue));
    tmpreg |=  (uint32_t) hsc->Init.TimeOutValue;
  }
  MODIFY_REG(hsc->Instance->RTOR, (USART_RTOR_RTO|USART_RTOR_BLEN), tmpreg);
  
  /*-------------------------- USART BRR Configuration -----------------------*/
  SMARTCARD_GETCLOCKSOURCE(hsc, clocksource);
  switch (clocksource)
  {
  case SMARTCARD_CLOCKSOURCE_PCLK1: 
    hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
    break;
  case SMARTCARD_CLOCKSOURCE_PCLK2: 
    hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
    break;
  case SMARTCARD_CLOCKSOURCE_HSI: 
    hsc->Instance->BRR = (uint16_t)((HSI_VALUE + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate); 
    break; 
  case SMARTCARD_CLOCKSOURCE_SYSCLK:  
    hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
    break;  
  case SMARTCARD_CLOCKSOURCE_LSE:                
    hsc->Instance->BRR = (uint16_t)((LSE_VALUE + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate); 
    break;
  default:
    break;
  } 
}
Esempio n. 10
0
/**
  * @brief  Configures TIM5 to measure the LSI oscillator frequency.
  * @param  None
  * @retval LSI Frequency
  */
static uint32_t GetLSIFrequency(void)
{
  uint32_t pclk1 = 0;
  TIM_IC_InitTypeDef timinputconfig;


  /* Configure the TIM peripheral */
  /* Set TIM5 instance */
  TimInputCaptureHandle.Instance = TIM5;

  /* TIM5 configuration: Input Capture mode ---------------------
  The LSI oscillator is connected to TIM5 CH4.
  The Rising edge is used as active edge.
  The TIM5 CCR4 is used to compute the frequency value.
  ------------------------------------------------------------ */
  TimInputCaptureHandle.Init.Prescaler         = 0;
  TimInputCaptureHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  TimInputCaptureHandle.Init.Period            = 0xFFFF;
  TimInputCaptureHandle.Init.ClockDivision     = 0;
  TimInputCaptureHandle.Init.RepetitionCounter = 0;

  if(HAL_TIM_IC_Init(&TimInputCaptureHandle) != HAL_OK)
  {}
  /* Connect internally the TIM5_CH4 Input Capture to the LSI clock output */
  HAL_TIMEx_RemapConfig(&TimInputCaptureHandle, TIM_TIM5_LSI);

  /* Configure the Input Capture of channel 4 */
  timinputconfig.ICPolarity  = TIM_ICPOLARITY_RISING;
  timinputconfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
  timinputconfig.ICPrescaler = TIM_ICPSC_DIV8;
  timinputconfig.ICFilter    = 0;

  if(HAL_TIM_IC_ConfigChannel(&TimInputCaptureHandle, &timinputconfig, TIM_CHANNEL_4) != HAL_OK)
  {}
  /* Reset the flags */
  TimInputCaptureHandle.Instance->SR = 0;

  /* Start the TIM Input Capture measurement in interrupt mode */
  if(HAL_TIM_IC_Start_IT(&TimInputCaptureHandle, TIM_CHANNEL_4) != HAL_OK)
  {
  }



  /* Wait until the TIM5 get 2 LSI edges (refer to TIM5_IRQHandler() in
  stm32f4xx_it.c file) */
  while(uwMeasurementDone == 0)
  {
  }
  uwCaptureNumber = 0;

  /* Deinitialize the TIM5 peripheral registers to their default reset values */
  HAL_TIM_IC_DeInit(&TimInputCaptureHandle);

  /* Compute the LSI frequency, depending on TIM5 input clock frequency (PCLK1)*/
  /* Get PCLK1 frequency */
  pclk1 = HAL_RCC_GetPCLK1Freq();

  /* Get PCLK1 prescaler */
  if((RCC->CFGR & RCC_CFGR_PPRE1) == 0)
  {
    /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */
    return ((pclk1 / uwPeriodValue) * 8);
  }
  else
  {
    /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */
    return (((2 * pclk1) / uwPeriodValue) * 8);
  }
}
Esempio n. 11
0
// Reconfigure the HAL tick using a standard timer instead of systick.
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    uint32_t PclkFreq;

    // Get clock configuration
    // Note: PclkFreq contains here the Latency (not used after)
    HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &PclkFreq);

    // Get timer clock value
#if TIM_MST_PCLK == 1
    PclkFreq = HAL_RCC_GetPCLK1Freq();
#else
    PclkFreq = HAL_RCC_GetPCLK2Freq();
#endif

    // Enable timer clock
    TIM_MST_RCC;

    // Reset timer
    TIM_MST_RESET_ON;
    TIM_MST_RESET_OFF;

    // Configure time base
    TimMasterHandle.Instance = TIM_MST;
    TimMasterHandle.Init.Period          = 0xFFFFFFFF;

    // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
#if TIM_MST_PCLK == 1
    if (RCC_ClkInitStruct.APB1CLKDivider == RCC_HCLK_DIV1) {
#else
    if (RCC_ClkInitStruct.APB2CLKDivider == RCC_HCLK_DIV1) {
#endif
        TimMasterHandle.Init.Prescaler   = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 us tick
    } else {
        TimMasterHandle.Init.Prescaler   = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 us tick
    }

    TimMasterHandle.Init.ClockDivision     = 0;
    TimMasterHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
#if !TARGET_STM32L1
    TimMasterHandle.Init.RepetitionCounter = 0;
#endif
#if TARGET_STM32F0||TARGET_STM32F7
    TimMasterHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
#endif
    HAL_TIM_OC_Init(&TimMasterHandle);

    NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
    NVIC_EnableIRQ(TIM_MST_IRQ);

    // Channel 1 for mbed timeout
    HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);

    // Channel 2 for HAL tick
    HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2);
    PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle);
    __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY);
    __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2);

#if DEBUG_TICK > 0
    __GPIOB_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
#endif

    return HAL_OK;
}

void HAL_SuspendTick(void)
{
    TimMasterHandle.Instance = TIM_MST;
    __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC2);
}
Esempio n. 12
0
_Bool CAN_init(void *data) {
	CAN_HandleTypeDef *handle = data;

	HAL_StatusTypeDef result = HAL_ERROR;
	const uint32_t baudRate = 125000;

	CAN_InitTypeDef ifaceParams = {
			HAL_RCC_GetPCLK1Freq()/(baudRate*(1+4+3)), //(CAN_SJW + CAN_BS1 + CAN_BS2)
			CAN_MODE_NORMAL,
			CAN_SJW_1TQ,
			CAN_BS1_4TQ,
			CAN_BS2_3TQ,
			.TTCM = DISABLE,
			.ABOM = DISABLE,
			.AWUM = DISABLE,
			.NART = DISABLE,
			.RFLM = DISABLE,
			.TXFP = DISABLE,
	};
	CAN_FilterConfTypeDef filter = {
			0, 0, 0, 0,
			CAN_FIFO0,
			0,
			CAN_FILTERMODE_IDMASK,
			CAN_FILTERSCALE_32BIT,
			ENABLE,
			0
	};

	if (handle) {
		free(handle->pRxMsg);
		free(handle->pTxMsg);
		handle->pRxMsg = NULL;
		handle->pTxMsg = NULL;
		memset(handle, 0, sizeof(*handle));
		handle->Instance = CAN1;
		handle->Init = ifaceParams;

		result = HAL_CAN_Init(handle);
		if (result == HAL_OK) {
			HAL_CAN_ConfigFilter(handle, &filter);
			HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
			HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
			HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
//			HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
			handle->pRxMsg = malloc(sizeof(*handle->pRxMsg));
			result &= HAL_CAN_Receive_IT(handle, CAN_FIFO0);
		}
		s_can1Handle = handle;
	}
	return result == HAL_OK;
}

_Bool CAN_write(const CanMsg_t *data) {
	HAL_StatusTypeDef result = HAL_ERROR;
	static const size_t msgSize = sizeof(CanTxMsgTypeDef);
	if (!data)
		return false;
	CanTxMsgTypeDef txMsg = {
		data->id,
		data->id,
		data->isExtended ? CAN_ID_EXT : CAN_ID_STD,
		data->isRemoteFrame ? CAN_RTR_REMOTE : CAN_RTR_DATA,
		data->isRemoteFrame ? 0 :
				data->size > 8 ? 8 : data->size,
	};

	do {
		if (!s_can1Handle)
			break;
		memcpy(txMsg.Data, data->buff, txMsg.DLC);
		free(s_can1Handle->pTxMsg);
		s_can1Handle->pTxMsg = malloc(msgSize);
		if (!s_can1Handle->pTxMsg)
			break;
		memcpy(s_can1Handle->pTxMsg, &txMsg, msgSize);
		result = HAL_CAN_Transmit_IT(s_can1Handle);
	} while (0);
	return result == HAL_OK;
}
Esempio n. 13
0
int
hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
  enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl)
{
    struct hal_uart *u;
    const struct stm32f4_uart_cfg *cfg;
    uint32_t cr1, cr2, cr3;

    if (port >= UART_CNT) {
        return -1;
    }

    u = &uarts[port];
    if (u->u_open) {
        return -1;
    }
    cfg = bsp_uart_config(port);
    assert(cfg);

    /*
     * RCC
     * pin config
     * UART config
     * nvic config
     * enable uart
     */
    cr1 = cfg->suc_uart->CR1;
    cr2 = cfg->suc_uart->CR2;
    cr3 = cfg->suc_uart->CR3;

    cr1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_RE |
      USART_CR1_OVER8);
    cr2 &= ~(USART_CR2_STOP);
    cr3 &= ~(USART_CR3_RTSE | USART_CR3_CTSE);

    switch (databits) {
    case 8:
        cr1 |= UART_WORDLENGTH_8B;
        break;
    case 9:
        cr1 |= UART_WORDLENGTH_9B;
        break;
    default:
        assert(0);
        return -1;
    }

    switch (stopbits) {
    case 1:
        cr2 |= UART_STOPBITS_1;
        break;
    case 2:
        cr2 |= UART_STOPBITS_2;
        break;
    default:
        return -1;
    }

    switch (parity) {
    case HAL_UART_PARITY_NONE:
        cr1 |= UART_PARITY_NONE;
        break;
    case HAL_UART_PARITY_ODD:
        cr1 |= UART_PARITY_ODD;
        break;
    case HAL_UART_PARITY_EVEN:
        cr1 |= UART_PARITY_EVEN;
        break;
    }

    switch (flow_ctl) {
    case HAL_UART_FLOW_CTL_NONE:
        cr3 |= UART_HWCONTROL_NONE;
        break;
    case HAL_UART_FLOW_CTL_RTS_CTS:
        cr3 |= UART_HWCONTROL_RTS_CTS;
        if (cfg->suc_pin_rts < 0 || cfg->suc_pin_cts < 0) {
            /*
             * Can't turn on HW flow control if pins to do that are not
             * defined.
             */
            assert(0);
            return -1;
        }
        break;
    }

    cr1 |= (UART_MODE_RX | UART_MODE_TX | UART_OVERSAMPLING_16);

    *cfg->suc_rcc_reg |= cfg->suc_rcc_dev;

    hal_gpio_init_af(cfg->suc_pin_tx, cfg->suc_pin_af, 0);
    hal_gpio_init_af(cfg->suc_pin_rx, cfg->suc_pin_af, 0);
    if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
        hal_gpio_init_af(cfg->suc_pin_rts, cfg->suc_pin_af, 0);
        hal_gpio_init_af(cfg->suc_pin_cts, cfg->suc_pin_af, 0);
    }

    u->u_regs = cfg->suc_uart;
    u->u_regs->CR3 = cr3;
    u->u_regs->CR2 = cr2;
    u->u_regs->CR1 = cr1;
    if (cfg->suc_uart == USART1 || cfg->suc_uart == USART6) {
        u->u_regs->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), baudrate);
    } else {
        u->u_regs->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), baudrate);
    }

    (void)u->u_regs->DR;
    (void)u->u_regs->SR;
    hal_uart_set_nvic(cfg->suc_irqn, u);

    u->u_regs->CR1 |= (USART_CR1_RXNEIE | USART_CR1_UE);
    u->u_open = 1;

    return 0;
}
Esempio n. 14
0
/** @brief: set registers acc to info in huart
 *  @details: used in HAL_UART3Debug_Init, private
 ****************************************************************/
static void MyUARTSetConfig(UART_HandleTypeDef *huart) {
	uint32_t tmpreg = 0x00;

	/* Check the parameters */
	assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
	assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
	assert_param(IS_UART_PARITY(huart->Init.Parity));
	assert_param(IS_UART_MODE(huart->Init.Mode));

	/*-------------------------- USART CR2 Configuration -----------------------*/
	tmpreg = huart->Instance->CR2;

	/* Clear STOP[13:12] bits */
	tmpreg &= (uint32_t) ~((uint32_t) USART_CR2_STOP);

	/* Configure the UART Stop Bits: Set STOP[13:12] bits according to huart->Init.StopBits value */
	tmpreg |= (uint32_t) huart->Init.StopBits;

	/* Write to USART CR2 */
	huart->Instance->CR2 = (uint32_t) tmpreg;

	/*-------------------------- USART CR1 Configuration -----------------------*/
	tmpreg = huart->Instance->CR1;

	/* Clear M, PCE, PS, TE and RE bits */
	tmpreg &= (uint32_t) ~((uint32_t) (USART_CR1_M | USART_CR1_PCE
			| USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8));

	/* Configure the UART Word Length, Parity and mode:
	 Set the M bits according to huart->Init.WordLength value
	 Set PCE and PS bits according to huart->Init.Parity value
	 Set TE and RE bits according to huart->Init.Mode value
	 Set OVER8 bit according to huart->Init.OverSampling value */
	tmpreg |= (uint32_t) huart->Init.WordLength | huart->Init.Parity
			| huart->Init.Mode | huart->Init.OverSampling;

	/* Write to USART CR1 */
	huart->Instance->CR1 = (uint32_t) tmpreg;

	/*-------------------------- USART CR3 Configuration -----------------------*/
	tmpreg = huart->Instance->CR3;

	/* Clear CTSE and RTSE bits */
	tmpreg &= (uint32_t) ~((uint32_t) (USART_CR3_RTSE | USART_CR3_CTSE));

	/* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
	tmpreg |= huart->Init.HwFlowCtl;

	/* Write to USART CR3 */
	huart->Instance->CR3 = (uint32_t) tmpreg;

	/* Check the Over Sampling */
	if (huart->Init.OverSampling == UART_OVERSAMPLING_8) {
		/*-------------------------- USART BRR Configuration ---------------------*/
		if ((huart->Instance == USART1) || (huart->Instance == USART6)) {
			huart->Instance->BRR = UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(),
					huart->Init.BaudRate);
		} else {
			huart->Instance->BRR = UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(),
					huart->Init.BaudRate);
		}
	} else {
		/*-------------------------- USART BRR Configuration ---------------------*/
		if ((huart->Instance == USART1) || (huart->Instance == USART6)) {
			huart->Instance->BRR = UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(),
					huart->Init.BaudRate);
		} else {
			huart->Instance->BRR = UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(),
					huart->Init.BaudRate);
		}
	}
}
Esempio n. 15
0
/**
  * @brief Configure the SMARTCARD peripheral 
  * @param  hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for SMARTCARD module.
  * @retval None
  */
static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
{
  uint32_t tmpreg = 0x00;
  
  /* Check the parameters */
  assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
  assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
  assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
  assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
  assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));  
  assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
  assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
  assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
  assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
  assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));

  /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
     receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
  hsc->Instance->CR1 &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
  
  /*---------------------------- USART CR2 Configuration ---------------------*/
  tmpreg = hsc->Instance->CR2;
  /* Clear CLKEN, CPOL, CPHA and LBCL bits */
  tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL));
  /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/
  /* Set CPOL bit according to hsc->Init.CLKPolarity value */
  /* Set CPHA bit according to hsc->Init.CLKPhase value */
  /* Set LBCL bit according to hsc->Init.CLKLastBit value */
  /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
  tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | 
                      hsc->Init.CLKPhase| hsc->Init.CLKLastBit | hsc->Init.StopBits);
  /* Write to USART CR2 */
  hsc->Instance->CR2 = (uint32_t)tmpreg;
  
  tmpreg = hsc->Instance->CR2;

  /* Clear STOP[13:12] bits */
  tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);

  /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
  tmpreg |= (uint32_t)(hsc->Init.StopBits);
  
  /* Write to USART CR2 */
  hsc->Instance->CR2 = (uint32_t)tmpreg;

  /*-------------------------- USART CR1 Configuration -----------------------*/
  tmpreg = hsc->Instance->CR1;

  /* Clear M, PCE, PS, TE and RE bits */
  tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
                                   USART_CR1_RE));

  /* Configure the SMARTCARD Word Length, Parity and mode: 
     Set the M bits according to hsc->Init.WordLength value 
     Set PCE and PS bits according to hsc->Init.Parity value
     Set TE and RE bits according to hsc->Init.Mode value */
  tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode;

  /* Write to USART CR1 */
  hsc->Instance->CR1 = (uint32_t)tmpreg;

  /*-------------------------- USART CR3 Configuration -----------------------*/  
  /* Clear CTSE and RTSE bits */
  hsc->Instance->CR3 &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE));

  /*-------------------------- USART BRR Configuration -----------------------*/
  if((hsc->Instance == USART1) || (hsc->Instance == USART6))
  {
    hsc->Instance->BRR = __SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate);
  }
  else
  {
    hsc->Instance->BRR = __SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate);
  }
}
Esempio n. 16
0
/**
  * @brief  Configures TIM4 Peripheral for LEDs lighting.
  * @param  None
  * @retval None
  */
static void TIM_LED_Config(void)
{
  uint16_t prescalervalue = 0;
  uint32_t tmpvalue = 0;

  /* TIM4 clock enable */
  __HAL_RCC_TIM4_CLK_ENABLE();
  
  /* Enable the TIM4 global Interrupt */
  HAL_NVIC_SetPriority(TIM4_IRQn, 7, 0);  
  HAL_NVIC_EnableIRQ(TIM4_IRQn);
  
  /* -----------------------------------------------------------------------
  TIM4 Configuration: Output Compare Timing Mode:  
    To get TIM4 counter clock at 550 KHz, the prescaler is computed as follows:
    Prescaler = (TIM4CLK / TIM4 counter clock) - 1
    Prescaler = ((f(APB1) * 2) /550 KHz) - 1
  
    CC update rate = TIM4 counter clock / CCR_Val = 32.687 Hz
    ==> Toggling frequency = 16.343 Hz  
  ----------------------------------------------------------------------- */
  
  /* Compute the prescaler value */
  tmpvalue = HAL_RCC_GetPCLK1Freq();
  prescalervalue = (uint16_t) ((tmpvalue * 2) / 480000) - 1; //Configurado a 48 KHz
  
  /* Time base configuration */
  hTimLed.Instance = TIM4;
  hTimLed.Init.Period = 65535;
  hTimLed.Init.Prescaler = prescalervalue;
  hTimLed.Init.ClockDivision = 0;
  hTimLed.Init.CounterMode = TIM_COUNTERMODE_UP;
  if(HAL_TIM_OC_Init(&hTimLed) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
  
  /* Output Compare Timing Mode configuration: Channel1 */
  sConfigLed.OCMode = TIM_OCMODE_TIMING;
  sConfigLed.OCIdleState = TIM_OCIDLESTATE_SET;
  sConfigLed.Pulse = CCR1Val;
  sConfigLed.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigLed.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigLed.OCFastMode = TIM_OCFAST_ENABLE;
  sConfigLed.OCNIdleState = TIM_OCNIDLESTATE_SET;
  
  /* Initialize the TIM4 Channel1 with the structure above */
  if(HAL_TIM_OC_ConfigChannel(&hTimLed, &sConfigLed, TIM_CHANNEL_1) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /* Start the Output Compare */
  if(HAL_TIM_OC_Start_IT(&hTimLed, TIM_CHANNEL_1) != HAL_OK)
  {
    /* Start Error */
    Error_Handler();
  }
}
Esempio n. 17
0
/**
  * @brief  TIM configuration
  * @param  None
  * @retval None
  */
static void TIM_Config(void)
{
  TIM_MasterConfigTypeDef master_timer_config;
  RCC_ClkInitTypeDef clk_init_struct = {0};       /* Temporary variable to retrieve RCC clock configuration */
  uint32_t latency;                               /* Temporary variable to retrieve Flash Latency */
  
  uint32_t timer_clock_frequency = 0;             /* Timer clock frequency */
  uint32_t timer_prescaler = 0;                   /* Time base prescaler to have timebase aligned on minimum frequency possible */
  
  /* Configuration of timer as time base:                                     */ 
  /* Caution: Computation of frequency is done for a timer instance on APB1   */
  /*          (clocked by PCLK1)                                              */
  /* Timer frequency is configured from the following constants:              */
  /* - TIMER_FREQUENCY: timer frequency (unit: Hz).                           */
  /* - TIMER_FREQUENCY_RANGE_MIN: timer minimum frequency possible            */
  /*   (unit: Hz).                                                            */
  /* Note: Refer to comments at these literals definition for more details.   */
  
  /* Retrieve timer clock source frequency */
  HAL_RCC_GetClockConfig(&clk_init_struct, &latency);
  /* If APB1 prescaler is different of 1, timers have a factor x2 on their    */
  /* clock source.                                                            */
  if (clk_init_struct.APB1CLKDivider == RCC_HCLK_DIV1)
  {
    timer_clock_frequency = HAL_RCC_GetPCLK1Freq();
  }
  else
  {
    timer_clock_frequency = HAL_RCC_GetPCLK1Freq() *2;
  }
  
  /* Timer prescaler calculation */
  /* (computation for timer 16 bits, additional + 1 to round the prescaler up) */
  timer_prescaler = (timer_clock_frequency / (TIMER_PRESCALER_MAX_VALUE * TIMER_FREQUENCY_RANGE_MIN)) +1;
  
  /* Set timer instance */
  TimHandle.Instance = TIMx;
  
  /* Configure timer parameters */
  TimHandle.Init.Period            = ((timer_clock_frequency / (timer_prescaler * TIMER_FREQUENCY)) - 1);
  TimHandle.Init.Prescaler         = (timer_prescaler - 1);
  TimHandle.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
  TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  TimHandle.Init.RepetitionCounter = 0x0;
  
  if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
  {
    /* Timer initialization Error */
    Error_Handler();
  }

  /* Timer TRGO selection */
  master_timer_config.MasterOutputTrigger = TIM_TRGO_UPDATE;
  master_timer_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&TimHandle, &master_timer_config) != HAL_OK)
  {
    /* Timer TRGO selection Error */
    Error_Handler();
  }
  
}
Esempio n. 18
0
/**
  * @brief  This function configures the TIM5 as a time base source. 
  *         The time source is configured  to have 1ms time base with a dedicated 
  *         Tick interrupt priority. 
  * @note   This function is called  automatically at the beginning of program after
  *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). 
  * @param  TickPriority: Tick interrupt priority.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority)
{
  RCC_ClkInitTypeDef sClokConfig;
  uint32_t uwTimclock, uwAPB1Prescaler = 0;
  uint32_t uwPrescalerValue = 0;
  uint32_t pFLatency;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable TIM5 clock */
  __HAL_RCC_TIM5_CLK_ENABLE();

  /*##-2- Configure the NVIC for TIMx ########################################*/
  /* Set the TIM5 priority */
  HAL_NVIC_SetPriority(TIM5_IRQn, TICK_INT_PRIORITY, 0);
  
  /* Enable the TIM5 global Interrupt */
  HAL_NVIC_EnableIRQ(TIM5_IRQn);

  /* Configure the TIM5 IRQ priority */
  HAL_NVIC_SetPriority(TIM5_IRQn, TickPriority ,0); 
  
  /* Get clock configuration */
  HAL_RCC_GetClockConfig(&sClokConfig, &pFLatency);
  
  /* Get APB1 prescaler */
  uwAPB1Prescaler = sClokConfig.APB1CLKDivider;
  
  /* Compute TIM5 clock */
  if (uwAPB1Prescaler == 0) 
  {
    uwTimclock = HAL_RCC_GetPCLK1Freq();
  }
  else
  {
    uwTimclock = 2*HAL_RCC_GetPCLK1Freq();
  }

  /* Compute the prescaler value to have TIM5 counter clock equal to 1MHz */
  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1);
  
  /* Initialize TIM5 */
  TimHandle.Instance = TIM5;
    
  /* Initialize TIMx peripheral as follow:
       + Period = [(TIM5CLK/1000) - 1]. to have a (1/1000) s time base.
       + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
       + ClockDivision = 0
       + Counter direction = Up
  */
  TimHandle.Init.Period = (1000000 / 1000) - 1;
  TimHandle.Init.Prescaler = uwPrescalerValue;
  TimHandle.Init.ClockDivision = 0;
  TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
  if(HAL_TIM_Base_Init(&TimHandle) == HAL_OK)
  {
    /* Start the TIM time Base generation in interrupt mode */
    return HAL_TIM_Base_Start_IT(&TimHandle);
  }

  /* Return function status */
  return HAL_OK;
}