/** **************************************************************************************** * @brief Initialize ADC * @param[in] in_mod ADC input mode * @param[in] work_clk ADC work_clk = (ADC_SOURCE_CLK / (2<<ADC_DIV)), ADC_DIV = 0 ~ 15, * ADC_SOURCE_CLK is 32k or system clock(4 types, decided by CLK_MUX), * the max work_clk = 1MHz. * @param[in] ref_vol ADC reference voltage * @param[in] resolution ADC resolution * @description * This function is used to set ADC input mode, work clock, reference voltage, resolution, * and interrupt. * ***************************************************************************************** */ void adc_init(enum ADC_IN_MOD in_mod, enum ADC_WORK_CLK work_clk, enum ADC_REF ref_vol, enum ADC_RESOLUTION resolution) { adc_init_configuration adc_cfg; #if CONFIG_ADC_DEFAULT_IRQHANDLER==TRUE adc_env.mode = SINGLE_MOD; adc_env.samples = 0; adc_env.bufptr = NULL; #if ADC_CALLBACK_EN==TRUE adc_env.callback = NULL; #endif #endif // enable ADC module clock adc_clock_on(); // power on ADC module adc_power_on(); // delay for power on delay(30); // reset adc register adc_reset(); adc_cfg.work_clk = work_clk; adc_cfg.ref_vol = ref_vol; adc_cfg.resolution = resolution; switch (in_mod) { case ADC_DIFF_WITH_BUF_DRV: adc_cfg.buf_in_p = ADC_BUFIN_CHANNEL; adc_cfg.buf_in_n = ADC_BUFIN_CHANNEL; adc_cfg.gain = ADC_BUF_GAIN_BYPASS; break; case ADC_DIFF_WITHOUT_BUF_DRV: adc_cfg.buf_in_p = ADC_BUFIN_CHANNEL; adc_cfg.buf_in_n = ADC_BUFIN_CHANNEL; adc_cfg.gain = ADC_BUF_BYPASS; break; case ADC_SINGLE_WITH_BUF_DRV: adc_cfg.buf_in_p = ADC_BUFIN_CHANNEL; adc_cfg.buf_in_n = ADC_BUFIN_VCM; adc_cfg.gain = ADC_BUF_GAIN_BYPASS; break; case ADC_SINGLE_WITHOUT_BUF_DRV: adc_cfg.buf_in_p = ADC_BUFIN_CHANNEL; adc_cfg.buf_in_n = ADC_BUFIN_GND; adc_cfg.gain = ADC_BUF_BYPASS; break; default: break; } __adc_cofig(&adc_cfg); __adc_calibrate(&adc_cfg); }
/**************************************************************************** * Name: adc_setup * * Description: * Configure the ADC. This method is called the first time that the ADC * device is opened. This will occur when the port is first opened. * This setup includes configuring and attaching ADC interrupts. * Interrupts are all disabled upon return. * * Input Parameters: * * Returned Value: ****************************************************************************/ static int adc_setup(FAR struct adc_dev_s *dev) { int ret; FAR struct s5j_dev_s *priv = (FAR struct s5j_dev_s *)dev->ad_priv; /* Attach the ADC interrupt */ ret = irq_attach(IRQ_ADC, adc_interrupt, priv); if (ret < 0) { lldbg("irq_attach failed: %d\n", ret); return ret; } /* Make sure that the ADC device is in the powered up, reset state */ adc_reset(dev); /* * Enable the ADC interrupt, but it will not be generated until we * request to start the conversion. */ llwdbg("Enable the ADC interrupt: irq=%d\n", IRQ_ADC); up_enable_irq(IRQ_ADC); return OK; }
/** Initalises the ADC registers for polling operation. */ adc_t adc_init (const adc_cfg_t *cfg) { adc_sample_t dummy; adc_dev_t *adc; const adc_cfg_t adc_default_cfg = { .bits = 10, .channel = 0, .clock_speed_kHz = 1000 }; if (adc_devices_num >= ADC_DEVICES_NUM) return 0; if (adc_devices_num == 0) { /* The clock only needs to be enabled when sampling. The clock is automatically started for the SAM7. */ mcu_pmc_enable (ID_ADC); adc_reset (); } adc = adc_devices + adc_devices_num; adc_devices_num++; adc->MR = 0; /* The transfer field must have a value of 2. */ BITS_INSERT (adc->MR, 2, 28, 29); if (!cfg) cfg = &adc_default_cfg; adc_config_set (adc, cfg); /* Note, the ADC is not configured until adc_config is called. */ adc_config (adc); #if 0 /* I'm not sure why a dummy read is required; it is probably a quirk of the SAM7. This will require a software trigger... */ adc_read (adc, &dummy, sizeof (dummy)); #endif return adc; } /** Returns true if a conversion has finished. */ bool adc_ready_p (adc_t adc) { return (ADC->ADC_ISR & ADC_ISR_DRDY) != 0; } /** Blocking read. This will hang if a trigger is not supplied (except for software triggering mode). */ int8_t adc_read (adc_t adc, void *buffer, uint16_t size) { uint16_t i; uint16_t samples; adc_sample_t *data; adc_config (adc); samples = size / sizeof (adc_sample_t); data = buffer; for (i = 0; i < samples; i++) { /* When the ADC peripheral gets a trigger, it converts all the enabled channels consecutively in numerical order. */ if (adc->trigger == ADC_TRIGGER_SW) adc_conversion_start (adc); /* Should have timeout, especially for external trigger. */ while (!adc_ready_p (adc)) continue; data[i] = ADC->ADC_LCDR; } /* Disable channel. */ ADC->ADC_CHDR = ~0; return samples * sizeof (adc_sample_t); }
bool sec_hal_fg_reset(struct i2c_client *client) { adc_reset(client); return true; }
/** * Application main entry point * * Initialize device drivers, start applications and handle * cooperative scheduling. If no task is requiring CPU time, the * controller enters low power mode. */ int main(void) { msp430_cpu_init(); watchdog_stop(); /* Platform-specific initialization. */ msb_ports_init(); adc_reset(); clock_init(); rtimer_init(); // use XT2 as main clock, set clock divder for SMCLK to 1 // MLCK: 8 MHz // SMCLK: 8 MHz // ACLK: 32.768 kHz BCSCTL1 = RSEL2 | RSEL1 | RSEL0; BCSCTL2 = SELM1 | SELS; leds_init(); leds_on(LEDS_ALL); bluetooth_disable(); mma7361_init(); process_init(); /* System timers */ process_start(&etimer_process, NULL); ctimer_init(); leds_off(LEDS_ALL); ds2411_init(); /* Overwrite unique id, this was taken from the original Shimmer software */ /* University of California Berkeley's OUI */ ds2411_id[0] = 0x00; ds2411_id[1] = 0x12; ds2411_id[2] = 0x6d; /* Following two octets must be 'LO' -- "local" in order to use UCB's OUI */ ds2411_id[3] = 'L'; ds2411_id[4] = 'O'; autostart_start(autostart_processes); /* * This is the scheduler loop. */ ENERGEST_ON(ENERGEST_TYPE_CPU); while (1) { int r; #if PROFILE_CONF_ON profile_episode_start(); #endif /* PROFILE_CONF_ON */ do { /* Reset watchdog. */ watchdog_periodic(); r = process_run(); } while(r > 0); #if PROFILE_CONF_ON profile_episode_end(); #endif /* PROFILE_CONF_ON */ /* * Idle processing. */ int s = splhigh(); /* Disable interrupts. */ if (process_nevents() != 0) { splx(s); /* Re-enable interrupts. */ } else { static unsigned long irq_energest = 0; /* Re-enable interrupts and go to sleep atomically. */ ENERGEST_OFF(ENERGEST_TYPE_CPU); ENERGEST_ON(ENERGEST_TYPE_LPM); /* * We only want to measure the processing done in IRQs when we * are asleep, so we discard the processing time done when we * were awake. */ energest_type_set(ENERGEST_TYPE_IRQ, irq_energest); watchdog_stop(); /* * If a Bluetooth transmission is running, go only to LPM0. * LPM1 and higher interrupt running UART communications. */ if (bluetooth_active()) { _BIS_SR(GIE | LPM0_bits); } else { _BIS_SR(GIE | LPM1_bits); } watchdog_start(); /* * We get the current processing time for interrupts that was * done during the LPM and store it for next time around. */ dint(); irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); eint(); ENERGEST_OFF(ENERGEST_TYPE_LPM); ENERGEST_ON(ENERGEST_TYPE_CPU); #if PROFILE_CONF_ON profile_clear_timestamps(); #endif /* PROFILE_CONF_ON */ } } return 0; }