Author Topic: CH32V003 ADC scan mode - DMA required?  (Read 1841 times)

0 Members and 1 Guest are viewing this topic.

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
CH32V003 ADC scan mode - DMA required?
« on: March 09, 2023, 03:56:20 pm »
Can anyone confirm whether or not the scan mode of the CH32V003's ADC can be used without DMA?

I have been trying to use scan mode to read two channels in sequence, but couldn't get it to work. I had the sequence length set up in RSQR1 (noting that it's a zero-based count, i.e. length of 2 = 1), and the relevant channels selected as 1st and 2nd in sequence in RSQR3, SCAN flag set in CTLR1, ADON in CTLR2. Then I assumed you could just do the following to perform a single scan conversion:

1. Set ADON bit in CTLR2 to initiate the scan.
2. Wait for EOC to be set in STATR.
3. Read first channel's value from RDATAR.
4. Repeat steps 2 & 3 for second channel.

But EOC never gets set, so the code just gets stuck in the polling loop.

The peripherals of the CH32V003 seem to be 99% identical to the STM32F10x, and looking at the reference manual for that (RM0008), it says that "When using scan mode, DMA bit must be set and the direct memory access controller is used to transfer the converted data of regular group channels to SRAM after each update of the ADC_DR register". But I can find nothing in the CH32V003 manual that says that DMA must be used with scan mode.
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6378
  • Country: ca
  • Non-expert
Re: CH32V003 ADC scan mode - DMA required?
« Reply #1 on: March 10, 2023, 12:17:18 am »
I would assume its not possible for the same reason its not possible on the STM32: where is the ADC going to store the second conversion value if you don't grab it in time?
Maybe try first getting a single conversion with interrupt working (EOCIE), then enable scan, see what happens.

If you do not want DMA, you may end up having to either:
- manually start each conversion and poll for the result
- or trigger the second conversion in the 1st ADC EOC interrupt
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
Re: CH32V003 ADC scan mode - DMA required?
« Reply #2 on: March 10, 2023, 05:31:59 pm »
I would assume its not possible for the same reason its not possible on the STM32: where is the ADC going to store the second conversion value if you don't grab it in time?

Yes, I suppose that's true. Although, I was imagining that perhaps it would not start the next conversion in the sequence until the EOC flag had been cleared from the prior.

Maybe try first getting a single conversion with interrupt working (EOCIE), then enable scan, see what happens.

I do have single conversion working already, so that's no issue.

Will probably look into trying to use DMA, although I've not yet put any effort into understanding the DMA system on the CH32V003. Presumably I just set up a buffer of N elements, then configure DMA to copy from ADC RDATAR register to memory when triggered, incrementing the memory address each time, a total of N times. Suppose in order to wait for completion I wait for DMA transfer completion flag, rather than any kind of ADC flag (there appears to be nothing else apart from EOC). And I'm not exactly sure what it would be that actually triggers the DMA transfers - the docs don't mention how that happens. Perhaps it's EOC - but then if that is raised after every conversion in sequence, why did I never see the flag being set in the status register in my earlier attempt?
 

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6378
  • Country: ca
  • Non-expert
Re: CH32V003 ADC scan mode - DMA required?
« Reply #3 on: March 10, 2023, 11:54:58 pm »
You have single conversion working, but was it interrupt? Adding to the end of the interrupt routine to select channel 2 and start a new scan, would be basically what you are trying to do right (maybe with a flag if you want it to keep going CH1 -> Ch2 -> CH1 etc).

Will probably look into trying to use DMA, although I've not yet put any effort into understanding the DMA system on the CH32V003. Presumably I just set up a buffer of N elements, then configure DMA to copy from ADC RDATAR register to memory when triggered, incrementing the memory address each time, a total of N times. Suppose in order to wait for completion I wait for DMA transfer completion flag, rather than any kind of ADC flag (there appears to be nothing else apart from EOC). And I'm not exactly sure what it would be that actually triggers the DMA transfers - the docs don't mention how that happens. Perhaps it's EOC - but then if that is raised after every conversion in sequence, why did I never see the flag being set in the status register in my earlier attempt?

Yeah there is your buffer array in memory, your DMA source (ADC) and destination address (array), and you either do regular DMA or circular mode.
Making sure to set the array variable to match the DMA setting (16-bit, 32-bit, whatever). DMA_CFGRx->MSIZE and PSIZE

It might be possible to setup the DMA and poll until its complete for initial testing:
Quote
When the number of DMA transfers decreases to 0, the DMA transfer completion flag will be generated, and if TCIE is set in the DMA_CCRx register, an interrupt will be generated.

I'm thinking how you have it setup either the EOC flag is never "seen", as its taken by DMA engine, or, the ADC conversion is just not starting if ADC_CTLR2->DMA is off and settings are for continuous? Not sure.
If you have a good debugger that can view the registers live its nice, unsure if thats available for CH32v003 though.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
Re: CH32V003 ADC scan mode - DMA required?
« Reply #4 on: March 11, 2023, 04:24:58 pm »
I got scan mode working with DMA. I decided to just use continuous mode and have the DMA cyclically transfer the scan sequence of channel readings into a struct with an appropriate number of fields.

It was actually pretty easy and clear what to do from looking at some of the SPL/HAL code and example code on WCH's GitHub. Although I am curious as to why on their ADC DMA example they choose to use a transfer size of 16 bits, when the ADC data register is 32 bit. I suppose it doesn't really matter, as the ADC has only 10 bit resolution, so values will never be larger than 16 bits. Maybe transfers with 16 bit size occupies the peripheral bus for less time? Anyway, it all works fine for me with 32-bit transfer size.

I'm still none the wiser exactly what mechanism is used to trigger the DMA transfer by the ADC. At the moment my best guess is "magic!". :-DD I wish their documentation was a bit better.

By the way, because the docs state that 32-bit transfer sizes must have a 4-byte-aligned source and destination address, I did this for the memory destination:

Code: [Select]
static struct {
uint32_t ch_a2 __attribute__((warn_if_not_aligned(4)));
uint32_t ch_a3 __attribute__((warn_if_not_aligned(4)));
} adc_values __attribute__((aligned(4)));

Overkill? ;D

I'm thinking how you have it setup either the EOC flag is never "seen", as its taken by DMA engine, or, the ADC conversion is just not starting if ADC_CTLR2->DMA is off and settings are for continuous?

Hmm, maybe you're right. Perhaps the EOC is 'stolen' by the DMA in scan mode, or scanning doesn't start without DMA mode set too.

If you have a good debugger that can view the registers live its nice, unsure if thats available for CH32v003 though.

Yes, you're able to debug with GDB, although I can't right now because for some reason OpenOCD is not cooperating lately, even though I had it working before and haven't changed anything. Oh well... :-//
 
The following users thanked this post: thm_w

Offline Sacodepatatas

  • Regular Contributor
  • *
  • Posts: 80
  • Country: es
Re: CH32V003 ADC scan mode - DMA required?
« Reply #5 on: March 12, 2023, 01:38:49 am »
Have you tested if the ADC has really 10bit resolution? Just for the sake of curiosity, because according to the datasheet, the ADC value is 12 bit aligned and the blocks diagram shows a 12bit Converter (maybe it is a typo), but all of this make me think that WCH just used the same ADC peripheral block from their higher MCU models. Maybe the 10bit limit comes from the number of conversion cycles in the SAR, or maybe the 2 LSB are shadowed by noise generated by a poor quantizer, in such a case the two missing bits could be retrieved just by using an averaging filter.

Edit: I bet for the second case, because 14 cycles are needed for the EOC.
« Last Edit: March 12, 2023, 01:55:40 am by Sacodepatatas »
 

Offline HwAoRrDkTopic starter

  • Super Contributor
  • ***
  • Posts: 1477
  • Country: gb
Re: CH32V003 ADC scan mode - DMA required?
« Reply #6 on: March 12, 2023, 03:46:20 pm »
Just for the sake of curiosity, because according to the datasheet, the ADC value is 12 bit aligned and the blocks diagram shows a 12bit Converter (maybe it is a typo), but all of this make me think that WCH just used the same ADC peripheral block from their higher MCU models.

I think that is just a mistake in the reference manual in the section talking about data alignment (right- or left-aligned) - probably a copy-paste mistake. Their other chips (e.g. CH32V103, CH32V30x) have 12-bit ADCs, so probably copied over. Everywhere else refers to the ADC in the CH32V003 as 10-bit.
 
The following users thanked this post: thm_w

Offline Sajeev

  • Contributor
  • Posts: 13
  • Country: in
Re: CH32V003 ADC scan mode - DMA required?
« Reply #7 on: January 23, 2024, 07:46:21 pm »
Dear Sir,
Please find the attached code which scans 2 channels in continues mode and prints result in polling mode to UART. Scan converts PD4 and PD3 and result is printed by polling EOC. works without DMA
« Last Edit: January 23, 2024, 07:52:15 pm by Sajeev »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf