Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2S ADC read values inverted (IDFGH-2444) #4557

Closed
skyscater opened this issue Dec 29, 2019 · 2 comments
Closed

I2S ADC read values inverted (IDFGH-2444) #4557

skyscater opened this issue Dec 29, 2019 · 2 comments
Assignees

Comments

@skyscater
Copy link

Environment

  • Development Kit: ESP32-DevKitC
  • Module or chip used: ESP32-WROOM-32
  • IDF version: v3.3.1
  • Build System: Make
  • Compiler version: 1.22.0-80-g6c4433a5
  • Operating System: Windows
  • Power Supply: USB

Problem Description

Read values by ADC1 with I2S are inverted. 0V leads to 4095, 3V3 leads to 0. adc_set_data_inv(ADC_UNIT_1, true|false) seems to have no effect (tried to change in rtc_module.c -> adc_i2s_mode_init as well).

Code to reproduce this issue

Code based on examples\peripherals\i2s_adc_dac.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "driver/i2s.h"
#include "soc/sens_struct.h"

#define ADC1_PIN ADC1_CHANNEL_0 /*!< ADC1 channel 0 is GPIO36 */

#define ADC_I2S_NUM I2S_NUM_0
#define ADC_I2S_READ_BUF_LEN 1024

// ADC test with the I2S-controller (DMA). ADC1 will be used.
// Data will be sampled with a fixed (high) frequency and saved directly to a buffer in memory (DMA).
static void adcI2sTask(void *arg) {

	// init I2S ADC
	i2s_config_t i2s_config = {
		.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN,
		.sample_rate =  10000,
		.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
		.communication_format = I2S_COMM_FORMAT_I2S  | I2S_COMM_FORMAT_I2S_MSB,
		.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
		.intr_alloc_flags = 0,
		.dma_buf_count = 2,
		.dma_buf_len = 1024,
		.use_apll = 0,
	 };
	// install and start I2S driver
	i2s_driver_install(ADC_I2S_NUM, &i2s_config, 0, NULL);
	// init ADC pad
	i2s_set_adc_mode(ADC_UNIT_1, ADC1_PIN);
	// enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init
	i2s_adc_enable(ADC_I2S_NUM);

	//adc_set_data_inv(ADC_UNIT_1, false);
	//adc_set_data_inv(ADC_UNIT_1, true);
	printf("ADC data inverted: ADC1=%d, ADC2=%d\n", SENS.sar_read_ctrl.sar1_data_inv, SENS.sar_read_ctrl2.sar2_data_inv);

	// init read buffer
	uint16_t* i2sReadBuffer = (uint16_t*)calloc(ADC_I2S_READ_BUF_LEN, sizeof(uint16_t));
	size_t bytesRead;

	while (1) {
		// read data from adc, will block until buffer is full
		i2s_read(ADC_I2S_NUM, (void*)i2sReadBuffer, ADC_I2S_READ_BUF_LEN * sizeof(uint16_t), &bytesRead, portMAX_DELAY);

		// calc average
		int64_t adcSumValue = 0;
		for (size_t i = 0; i < ADC_I2S_READ_BUF_LEN; i++) {
			// adcSumValue += (~i2sReadBuffer[i]) & 0xFFF; // invert data manually (12bit)
			adcSumValue += i2sReadBuffer[i];
		}
		int adcAvgValue = adcSumValue / ADC_I2S_READ_BUF_LEN;

		printf("ADC1 SPI: bufferLength=%d, bytesRead=%d, sumValue=%lld, avgValue=%d\n", ADC_I2S_READ_BUF_LEN * sizeof(uint16_t), bytesRead, adcSumValue, adcAvgValue);

		vTaskDelay(pdMS_TO_TICKS(1000));
	}

}

void app_main(void) {
	// wait for both cores to be started
	vTaskDelay(pdMS_TO_TICKS(200));

	xTaskCreate(adcI2sTask, "adc_i2s_task", 4096, NULL, 2, NULL);
}
@github-actions github-actions bot changed the title I2S ADC read values inverted I2S ADC read values inverted (IDFGH-2444) Dec 29, 2019
@xiongyumail
Copy link
Contributor

@skyscater

Thank you for your discovery, please modify the following functions in rtc_module.c, we will merge the changes into the corresponding branches later:

esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en)
{
    portENTER_CRITICAL(&rtc_spinlock);
    if (adc_unit & ADC_UNIT_1) {
        // Enable ADC data invert
        SENS.sar_read_ctrl.sar1_data_inv = inv_en;
        SYSCON.saradc_ctrl2.sar1_inv = inv_en;
    }
    if (adc_unit & ADC_UNIT_2) {
        // Enable ADC data invert
        SENS.sar_read_ctrl2.sar2_data_inv = inv_en;
        SYSCON.saradc_ctrl2.sar2_inv = inv_en;
    }
    portEXIT_CRITICAL(&rtc_spinlock);
    return ESP_OK;
}

espressif-bot pushed a commit that referenced this issue Jan 7, 2020
* fix i2s and timergroup dev array used by isr crash issue

* Closes IDFGH-2432

* Closes #4545

* fix i2s adc data inv issue

* Closes IDFGH-2444

* Closes #4557
espressif-bot pushed a commit that referenced this issue Feb 19, 2020
* fix i2s and timergroup dev array used by isr crash issue

* Closes IDFGH-2432

* Closes #4545

* fix i2s adc data inv issue

* Closes IDFGH-2444

* Closes #4557
espressif-bot pushed a commit that referenced this issue Feb 22, 2020
* fix i2s and timergroup dev array used by isr crash issue

* Closes IDFGH-2432

* Closes #4545

* fix i2s adc data inv issue

* Closes IDFGH-2444

* Closes #4557
espressif-bot pushed a commit that referenced this issue Feb 23, 2020
* fix i2s and timergroup dev array used by isr crash issue

* Closes IDFGH-2432

* Closes #4545

* fix i2s adc data inv issue

* Closes IDFGH-2444

* Closes #4557
@Alvin1Zhang
Copy link
Collaborator

@skyscater Thanks for reporting. Sorry for the slow turnaround. The issue has been fixed and fix available on GitHub. Please help try if the issue still happens, feel free to reopen if the issue persists. Thanks.

jack0c pushed a commit that referenced this issue Jul 29, 2020
* fix i2s and timergroup dev array used by isr crash issue

* Closes IDFGH-2432

* Closes #4545

* fix i2s adc data inv issue

* Closes IDFGH-2444

* Closes #4557
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants