After booting, DMA fed ADC sometimes shows 4095 always!

rfleming
Posts: 62
Joined: Tue Oct 09, 2018 12:30 am

After booting, DMA fed ADC sometimes shows 4095 always!

Postby rfleming » Fri Jan 11, 2019 4:19 am

I am currently working with the adc on a WROVER module on some custom hardware. I can confirm that the signal being fed into the adc has a steady state value of 200mV. This with a 3.3V reference results in ~200 as a raw adc sample.

After rebooting my unit, specifically power cycling rather than using the reset pin (no hardware option for it at this stage) my dma fed adc will only show 4095 values instead of the usual ~200. This happens very randomly. For instance 10 power ups in a row will show 4095, then the next 10 will work correctly. Perhaps I am doing something wrong with my initialisation?

Do I need some sort of delay between initialisation and tasks? Or would this potentially be more of hardware issue? Not that I can see anything currently wrong with my hardware :(

In my adc class I have the following:

Code: Select all

Hal_ADC::Hal_ADC(adc1_channel_t adc1_io, QueueHandle_t outQueue) {
	i2s_config_t i2s_config;
	i2s_config.mode =  i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN);
	i2s_config.sample_rate = ADC_SAMPLE_RATE;	//minimum 2442. else error "I2S: clkmdiv is too large"
	i2s_config.dma_buf_len = DMA_BUF_LEN;	//max size is 1024
	i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT;
	i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
	i2s_config.use_apll = false;
	i2s_config.communication_format = I2S_COMM_FORMAT_I2S;
	i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
	i2s_config.dma_buf_count = 2;
	esp_err_t err_adc_install = i2s_driver_install(I2S_NUM_0, &i2s_config, 1, &i2s_event_queue);
	ESP_ERROR_CHECK(err_adc_install);

	esp_err_t err_adc_mode = i2s_set_adc_mode(ADC_UNIT_1, adc1_io);
	ESP_ERROR_CHECK(err_adc_mode);

	esp_err_t err_adc_enable = i2s_adc_enable(I2S_NUM_0);
	ESP_ERROR_CHECK(err_adc_enable);

	this->adc_io = adc1_io;
}

int16_t i2s_read_buff[2000];	//2000 samples
void Hal_ADC::Tasks(void) {
	//ADC1_5 results specifically structured like this!!!
	//20480 0b0101 0000 0000 0000 = max 3.3v (6.35V)
	//24575 0b0101 1111 1111 1111 = min 0v
	//0b0101 = 5 for adc5. maybe these are linked somehow? Still unsure why the data is negative though?
	//register: APB_SARADC_SAR1_INV must be set

	system_event_t evt;
	if (xQueueReceive(i2s_event_queue, &evt, portMAX_DELAY) == pdPASS) {
		if (evt.event_id == 2) {
			memset(i2s_read_buff, 0, sizeof(i2s_read_buff));

			size_t bytes_read;
			esp_err_t err_i2s_read = i2s_read(I2S_NUM_0, (char*)i2s_read_buff, ARRAY_SIZE(i2s_read_buff), &bytes_read, portMAX_DELAY);	//*2 since its int16_t data
			ESP_ERROR_CHECK(err_i2s_read);

			//sometimes unit will boot and constantly read 4095. Not sure why but after a few reboots it goes away!
			if (((i2s_read_buff[0] & 0xFFF) - 4095)*-1 == 4095) {
				printf("ADC read error: %d\n", ((i2s_read_buff[0] & 0xFFF) - 4095)*-1);
				return;
			}
			
			//Handle data...
		}
	}
}
In my general task in my app.cpp I have the following:

Code: Select all

static void ADC_Tasks(void *pvParameter) {
	static Hal_ADC _adc(ADC1_CHANNEL_5, appQueue);	//set io33 as input
	adc = &_adc;	//makes using adc class for extern much easier to handle.

	while (1) {
		_adc.Tasks();
		//vTaskDelay(pdMS_TO_TICKS(1000));
	}

	//safety
	vTaskDelete(NULL);
}

Who is online

Users browsing this forum: Majestic-12 [Bot] and 118 guests