int adc_read_channel(enum adc_channel ch) { /* voltage 0 ~ 3v = adc data register raw data 0 ~ 3FFh (10-bit ) */ uint16_t adc_raw_data; int num; int adc_ch; adc_ch = adc_channels[ch].channel; adc_enable_channel(adc_ch); /* Maximum time for waiting ADC conversion is ~1.525ms */ for (num = 0x00; num < 100; num++) { /* delay ~15.25us */ IT83XX_GCTRL_WNCKR = 0; /* data valid of adc channel[x] */ if (IT83XX_ADC_ADCDVSTS & (1 << adc_ch)) { /* read adc raw data msb and lsb */ adc_raw_data = (*adc_ctrl_regs[adc_ch].adc_datm << 8) + *adc_ctrl_regs[adc_ch].adc_datl; /* W/C data valid flag */ IT83XX_ADC_ADCDVSTS = (1 << adc_ch); adc_disable_channel(adc_ch); return adc_raw_data * adc_channels[ch].factor_mul / adc_channels[ch].factor_div + adc_channels[ch].shift; } } adc_disable_channel(adc_ch); return ADC_READ_ERROR; }
/* * Checking that an ADC channel is disabled. * Requires "test_adc_channel_enabled" * to pass it's test */ void test_adc_channel_disabled(void) { uint8_t channel = ADC_CHANNEL_0; adc_enable_channel(channel); // Check if that channel is enabled TEST_ASSERT_TRUE(ADC->ADC_CHSR & (0x1u << channel)); adc_disable_channel(channel); // Check if that channel is disabled TEST_ASSERT_FALSE(ADC->ADC_CHSR & (0x1u << channel)); }
/* * Test getting the state of a channel (enabled or not). * Requires "test_adc_channel_enabled" and * "test_adc_channel_disabled" to pass it's tests */ void test_adc_channel_status(void) { uint32_t channel = ADC_CHANNEL_0; adc_enable_channel(channel); // Check if registry value and function has the same value TEST_ASSERT_TRUE(ADC->ADC_CHSR & (0x1u << channel)); TEST_ASSERT_TRUE(adc_channel_enabled(channel)); adc_disable_channel(channel); // Check if registry value and function has the same value TEST_ASSERT_FALSE(ADC->ADC_CHSR & (0x1u << channel)); TEST_ASSERT_FALSE(adc_channel_enabled(channel)); }
// Enable or disable a channel. Use AnalogCheckReady to make sure the ADC is ready before calling this. void AnalogInEnableChannel(AnalogChannelNumber channel, bool enable) { if ((unsigned int)channel < numChannels) { if (enable) { activeChannels |= (1u << channel); #if SAM3XA || SAM4S adc_enable_channel(ADC, GetAdcChannel(channel)); #if SAM4S adc_set_calibmode(ADC); // auto calibrate at start of next sequence #endif if (GetAdcChannel(channel) == ADC_TEMPERATURE_SENSOR) { adc_enable_ts(ADC); } #elif SAM4E || SAME70 afec_ch_config cfg; afec_ch_get_config_defaults(&cfg); afec_ch_set_config(GetAfec(channel), GetAfecChannel(channel), &cfg); afec_channel_set_analog_offset(GetAfec(channel), GetAfecChannel(channel), 2048); // need this to get the full ADC range afec_channel_enable(GetAfec(channel), GetAfecChannel(channel)); #if SAM4E afec_start_calibration(GetAfec(channel)); // do automatic calibration #endif #endif } else { activeChannels &= ~(1u << channel); #if SAM3XA || SAM4S adc_disable_channel(ADC, GetAdcChannel(channel)); if (GetAdcChannel(channel) == ADC_TEMPERATURE_SENSOR) { adc_disable_ts(ADC); } #elif SAM4E || SAME70 afec_channel_disable(GetAfec(channel), GetAfecChannel(channel)); #endif } } }
uint16_t hal_analog_read(uint8_t adc_channel) { uint32_t ulValue = 0; // Enable the corresponding channel adc_enable_channel( ADC, adc_channel ); // Start the ADC adc_start( ADC ); // Wait for end of conversion while ((adc_get_status(ADC) & ADC_ISR_DRDY) != ADC_ISR_DRDY) ; // Read the value ulValue = adc_get_latest_value(ADC); //!! ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution); // Disable the corresponding channel adc_disable_channel(ADC, adc_channel); return ulValue; }
extern void pinMode( uint32_t ulPin, uint32_t ulMode ) { if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN ) { return ; } if ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_ANALOG) { adc_disable_channel( ADC, g_APinDescription[ulPin].ulADCChannelNumber); } if ((g_pinStatus[ulPin] & 0xF) < PIN_STATUS_DIGITAL_OUTPUT && g_pinStatus[ulPin] != 0) { // return if already configured in the right way if (((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT && ulMode == INPUT) || ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_INPUT_PULLUP && ulMode == INPUT_PULLUP) || ((g_pinStatus[ulPin] & 0xF) == PIN_STATUS_DIGITAL_OUTPUT && ulMode == OUTPUT)) return; } switch ( ulMode ) { case INPUT: /* Enable peripheral for clocking input */ pmc_enable_periph_clk( g_APinDescription[ulPin].ulPeripheralId ) ; PIO_Configure( g_APinDescription[ulPin].pPort, PIO_INPUT, g_APinDescription[ulPin].ulPin, 0 ) ; g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT; break ; case INPUT_PULLUP: /* Enable peripheral for clocking input */ pmc_enable_periph_clk( g_APinDescription[ulPin].ulPeripheralId ) ; PIO_Configure( g_APinDescription[ulPin].pPort, PIO_INPUT, g_APinDescription[ulPin].ulPin, PIO_PULLUP ) ; g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_INPUT_PULLUP; break ; case OUTPUT: PIO_Configure( g_APinDescription[ulPin].pPort, (g_pinStatus[ulPin] & 0xF0) >> 4 ? PIO_OUTPUT_1 : PIO_OUTPUT_0, g_APinDescription[ulPin].ulPin, g_APinDescription[ulPin].ulPinConfiguration ) ; g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; /* if all pins are output, disable PIO Controller clocking, reduce power consumption */ if ( g_APinDescription[ulPin].pPort->PIO_OSR == 0xffffffff ) { pmc_disable_periph_clk( g_APinDescription[ulPin].ulPeripheralId ) ; } break ; default: break ; } }