static void adc_init(adc_t *adc) { uint32_t sadc_clk_div = adc->sadc_clk_div; // set adc clk to 6MHz RCC_APB2PeriphClockCmd(adc_apb2_periph(adc->base), ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_SDADCAnalogCmd(adc_pwr_periph(adc->base), ENABLE); if (sadc_clk_div) RCC_SDADCCLKConfig(sadc_clk_div); else // default to max speed if not specified RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div12); // int the dma if given if (adc->dma) dma_init(adc->dma); // setup the different adc configurations SDADC_VREFSelect(adc->ref); sys_spin(5); SDADC_Cmd(adc->base, ENABLE); SDADC_InitModeCmd(adc->base, ENABLE); while (SDADC_GetFlagStatus(adc->base, SDADC_FLAG_INITRDY) == RESET) {} SDADC_AINInit(adc->base, SDADC_Conf_0, &adc->SDADC_AINStructure[0]); SDADC_AINInit(adc->base, SDADC_Conf_1, &adc->SDADC_AINStructure[1]); SDADC_AINInit(adc->base, SDADC_Conf_2, &adc->SDADC_AINStructure[2]); // option to allow adc's to be sync'ed SDADC_InjectedSynchroSDADC1(adc->base, adc->trigger.sync_adc1); SDADC_InitModeCmd(adc->base, DISABLE); // calibrate SDADC_CalibrationSequenceConfig(adc->base, SDADC_CalibrationSequence_3); SDADC_StartCalibration(adc->base); while (SDADC_GetFlagStatus(adc->base, SDADC_FLAG_EOCAL) == RESET) {} SDADC_ClearFlag(adc->base, SDADC_FLAG_EOCAL); adc->initalised = true; }
/** * @brief This function handles SDADC1 interrupt request. * @param None * @retval : None */ void SDADC1_IRQHandler(void) { uint32_t ChannelIndex; if(SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_JEOC) != RESET) { /* Get the converted value */ SDADC1testread = SDADC_GetInjectedConversionValue(SDADC1, &ChannelIndex); } }
static void adc_dma_complete(dma_request_t *req, void *param) { adc_channel_t *ch = (adc_channel_t *)param; adc_t * adc = ch->adc; adc_trace_complete_t cb; int count; sys_enter_critical_section(); // if we are in circular mode just keep going if (!adc->dma->circ) { // stop the DMA, and turn off continuous mode, we are done SDADC_DMAConfig(ch->adc->base, SDADC_DMATransfer_Injected, DISABLE); // stop continous mode SDADC_InjectedContinuousModeCmd(ch->adc->base, DISABLE); // reset the trigger source SDADC_InitModeCmd(adc->base, ENABLE); while (SDADC_GetFlagStatus(adc->base, SDADC_FLAG_INITRDY) == RESET) {} SDADC_ExternalTrigInjectedConvEdgeConfig(adc->base, SDADC_ExternalTrigInjecConvEdge_None); SDADC_InitModeCmd(adc->base, DISABLE); } ///@todo handle any overruns (we should really handle this in a isr /// but for now we can just clear the flag and hope the dma still completes) SDADC_ClearITPendingBit(adc->base, SDADC_IT_JOVR); sys_leave_critical_section(); if (req->dma->isr_status & 2) count = ch->count; else if (ch->count & 0x01) // if count is odd isr rounds up count = (ch->count >> 1) + 1; else