ADC and DMA

aarizaq
Posts: 1
Joined: Tue Feb 27, 2018 6:26 pm

ADC and DMA

Postby aarizaq » Tue Feb 27, 2018 6:47 pm

I have just begun to use this platform and I am suffering trying to understand how the ADC DMA works, and for my embarrassment I cannot.
Using the i2s_adc_dac example I have set the i2s with this configuration

Code: Select all

void example_i2s_init()
{
	 int i2s_num = EXAMPLE_I2S_NUM;
	 i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
        .sample_rate =  EXAMPLE_I2S_SAMPLE_RATE,
        .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
	    .communication_format = I2S_COMM_FORMAT_PCM, // I2S_COMM_FORMAT_I2S_MSB,
	    .channel_format = EXAMPLE_I2S_FORMAT,
	    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
	.use_apll = false,
	    .dma_buf_count = 2,
        .dma_buf_len = SIN_LEN
	 };
	 
	 adc1_config_channel_atten(I2S_ADC_CHANNEL, ADC_ATTEN_11db);
	 adc1_config_width(ADC_WIDTH_12Bit);
	 //install and start i2s driver
      i2s_driver_install(i2s_num, &i2s_config, 2, &i2s_queue);
	 //init DAC pad
      i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
     //    i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
	 //init ADC pad
	 i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
}
And I try to read the data using the event sent by the irruption

Code: Select all

void example_i2s_adc_dac(void*arg)
{
 	i2s_event_t event;
	uint32_t* buff_write = (uint32_t*) calloc(SIN_LEN*2, sizeof(uint32_t));
	uint16_t* buff_read = (uint16_t*) calloc(SIN_LEN*2, sizeof(uint16_t));
	uint16_t countRead = 0;
	uint16_t countWrite = 0;
	
	esp_adc_cal_characteristics_t characteristics;
	esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_11db, ADC_WIDTH_12Bit, &characteristics);
	
	for(int i = 0; i < SIN_LEN; i++) {
  		double sin_float = sin(i * PI / 180.0);
		sin_float *= (pow(2, 16)/2 - 1);
		uint32_t  sample_val = 0;
		sample_val = sample_val << 16;
		sample_val += (short) sin_float;
		buff_write[i] = sample_val;
	 }

	// first
	ESP_ERROR_CHECK(i2s_adc_enable(EXAMPLE_I2S_NUM));
	i2s_write_bytes(EXAMPLE_I2S_NUM, (const char*) buff_write, SIN_LEN*4, portMAX_DELAY);
	while(1) {
		BaseType_t val = xQueueReceive(i2s_queue, &event, (2*EXAMPLE_I2S_SAMPLE_RATE)/  portTICK_PERIOD_MS);
		if (val == pdPASS) {
			if (event.type == I2S_EVENT_RX_DONE) {
				countRead++;
				int bytes = i2s_read_bytes(EXAMPLE_I2S_NUM, (char*) buff_read, SIN_LEN*4, 100);
				if (SIN_LEN*4 != bytes)
					printf("read buffer problem ...%i \n", bytes);
				if (countRead > 5) {
					printf("read cicle...\n");
					countRead = 0;
					int index = -1;						
					printf("read buffer 1 %i and 2 %i...%i\n",buff_read[0],buff_read[1],index);
				}
			}
			else if (event.type == I2S_EVENT_TX_DONE) {
				int bytes = i2s_write_bytes(EXAMPLE_I2S_NUM, (const char*) buff_write, SIN_LEN*4, 100);
				if (SIN_LEN*4 != bytes)
					printf("write buffer problem ... %i \n", bytes);
			}
			else if (event.type == I2S_EVENT_DMA_ERROR) {
				printf("Error DMA...\n");
			}
			else {
				printf("Error unknow ...\n");
			}
		}
		else if (val == errQUEUE_EMPTY)
			printf("Error ...\n");
    }
}
The code receives the event but there is a behavior that have completely perplexed. I set the pin 36 to GND and the data received are all 4095, but if I put the pin to 3.3 volt the value read are 0.

Please, what am I doing erroneously?

Gianluca.Loi
Posts: 19
Joined: Mon Jun 03, 2019 3:46 pm

Re: ADC and DMA

Postby Gianluca.Loi » Tue Aug 27, 2019 9:37 am

aarizaq wrote:
Tue Feb 27, 2018 6:47 pm
I have just begun to use this platform and I am suffering trying to understand how the ADC DMA works, and for my embarrassment I cannot.
Using the i2s_adc_dac example I have set the i2s with this configuration

Code: Select all

void example_i2s_init()
{
	 int i2s_num = EXAMPLE_I2S_NUM;
	 i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
        .sample_rate =  EXAMPLE_I2S_SAMPLE_RATE,
        .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
	    .communication_format = I2S_COMM_FORMAT_PCM, // I2S_COMM_FORMAT_I2S_MSB,
	    .channel_format = EXAMPLE_I2S_FORMAT,
	    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
	.use_apll = false,
	    .dma_buf_count = 2,
        .dma_buf_len = SIN_LEN
	 };
	 
	 adc1_config_channel_atten(I2S_ADC_CHANNEL, ADC_ATTEN_11db);
	 adc1_config_width(ADC_WIDTH_12Bit);
	 //install and start i2s driver
      i2s_driver_install(i2s_num, &i2s_config, 2, &i2s_queue);
	 //init DAC pad
      i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
     //    i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
	 //init ADC pad
	 i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL);
}
And I try to read the data using the event sent by the irruption

Code: Select all

void example_i2s_adc_dac(void*arg)
{
 	i2s_event_t event;
	uint32_t* buff_write = (uint32_t*) calloc(SIN_LEN*2, sizeof(uint32_t));
	uint16_t* buff_read = (uint16_t*) calloc(SIN_LEN*2, sizeof(uint16_t));
	uint16_t countRead = 0;
	uint16_t countWrite = 0;
	
	esp_adc_cal_characteristics_t characteristics;
	esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_11db, ADC_WIDTH_12Bit, &characteristics);
	
	for(int i = 0; i < SIN_LEN; i++) {
  		double sin_float = sin(i * PI / 180.0);
		sin_float *= (pow(2, 16)/2 - 1);
		uint32_t  sample_val = 0;
		sample_val = sample_val << 16;
		sample_val += (short) sin_float;
		buff_write[i] = sample_val;
	 }

	// first
	ESP_ERROR_CHECK(i2s_adc_enable(EXAMPLE_I2S_NUM));
	i2s_write_bytes(EXAMPLE_I2S_NUM, (const char*) buff_write, SIN_LEN*4, portMAX_DELAY);
	while(1) {
		BaseType_t val = xQueueReceive(i2s_queue, &event, (2*EXAMPLE_I2S_SAMPLE_RATE)/  portTICK_PERIOD_MS);
		if (val == pdPASS) {
			if (event.type == I2S_EVENT_RX_DONE) {
				countRead++;
				int bytes = i2s_read_bytes(EXAMPLE_I2S_NUM, (char*) buff_read, SIN_LEN*4, 100);
				if (SIN_LEN*4 != bytes)
					printf("read buffer problem ...%i \n", bytes);
				if (countRead > 5) {
					printf("read cicle...\n");
					countRead = 0;
					int index = -1;						
					printf("read buffer 1 %i and 2 %i...%i\n",buff_read[0],buff_read[1],index);
				}
			}
			else if (event.type == I2S_EVENT_TX_DONE) {
				int bytes = i2s_write_bytes(EXAMPLE_I2S_NUM, (const char*) buff_write, SIN_LEN*4, 100);
				if (SIN_LEN*4 != bytes)
					printf("write buffer problem ... %i \n", bytes);
			}
			else if (event.type == I2S_EVENT_DMA_ERROR) {
				printf("Error DMA...\n");
			}
			else {
				printf("Error unknow ...\n");
			}
		}
		else if (val == errQUEUE_EMPTY)
			printf("Error ...\n");
    }
}
The code receives the event but there is a behavior that have completely perplexed. I set the pin 36 to GND and the data received are all 4095, but if I put the pin to 3.3 volt the value read are 0.

Please, what am I doing erroneously?
Hello,

the data you are reading is inverted inside the function "i2s_set_adc_mode". Inside it there is a function "adc_i2s_mode_init" which calls inside "adc_set_data_inv(adc_unit, true);" which is, as you read, always true.

Regards.

Gianluca

Who is online

Users browsing this forum: Bhaydar, ok-home and 51 guests