sammytranGeo opened a new pull request, #19013:
URL: https://github.com/apache/nuttx/pull/19013

   ## Summary
   
   When an ADC conversion sequence is triggered via the ANIOC_TRIGGER ioctl, 
the priv->current channel counter was not being reset before starting the 
conversion. This meant that if a previous conversion sequence had ended mid-way 
through the channel list (e.g., due to an error or partial read), subsequent 
triggers would resume dispatching au_receive callbacks from the wrong channel 
index, corrupting the channel-to-data mapping reported to the upper half.
   
   This fix resets priv->current to 0 immediately before calling 
adc_startconv() in the ANIOC_TRIGGER handler, ensuring the interrupt handler 
always starts dispatching results from the first channel in the sequence. The 
same fix is applied consistently to both the STM32H5 and STM32H7 ADC drivers, 
which share the same architecture and bug.
   
   ## Impact
   
   Users relying on the ANIOC_TRIGGER ioctl to initiate ADC conversion 
sequences on STM32H5 or STM32H7 targets could receive channel data attributed 
to the wrong channel number if the internal current counter was in a non-zero 
state when the trigger fired. This is a silent data corruption — no error is 
returned. After this fix, every triggered conversion sequence correctly begins 
at channel index 0.
   
   ## Testing
   
   Tested on an STM32H5-based board with the following defconfig and 12 ADC 
channels
   ```
   CONFIG_ADC=y
   CONFIG_ADC_FIFOSIZE=16
   CONFIG_ANALOG=y
   ```
   
   With an application that does the following:
   ```
   struct adc_msg_s msg;
   int nchannels;
   uint8_t first_ch;
   
   int fd = open("/dev/adc0", O_RDONLY);
   
   nchannels = ioctl(fd, ANIOC_GET_NCHANNELS, 0);
   printf("nchannels = %d\n", nchannels);
   
   ioctl(fd, ANIOC_TRIGGER, 0);
   read(fd, &msg, sizeof(msg));
   
   first_ch = msg.am_channel;
   
   ioctl(fd, ANIOC_RESET_FIFO, 0);
   ioctl(fd, ANIOC_TRIGGER, 0);
   
   read(fd, &msg, sizeof(msg));
   if (msg.am_channel == first_ch)
   {
     printf("PASS: priv->current was reset on retrigger\n");
   }
   else
   {
     printf("FAIL: priv->current was NOT reset -- expected ch %u, got ch %u\n",
            first_ch, msg.am_channel);
   }
   ```
   
   Pre-fix (notice sample channel is higher than nchannels):
   ```
   nchannels = 12
   FAIL: priv->current was NOT reset -- expected ch 0, got ch 15
   ```
   
   Post fix
   ```
   nchannels = 12
   PASS: priv->current was reset on retrigger
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to