Forum: Mikrocontroller und Digitale Elektronik STM32 DMA umstellung vom Circular Buffer zu Einfachen Buffer


von Markus H. (haniham) Benutzerseite


Lesenswert?

Hallo meine Lieben,

Ich schreibe bei meinem STM32 dauernd in einen Ringbuffer - das 
Funktioniert bereits wunderbar.

Ich möchte wenn der Analog Watchdog einen Grenzwert überschritten hat 
von dem circulat buffer auf einen anderen Buffer in einem anderen 
Speicherbereich umstellen.
Leider tut der DMA das nicht:
1
/*
2
 * When the Analog Watchdog is tripped this callback function gets executed
3
 */
4
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
5
{
6
  DMA_Stream_TypeDef * dmaStreamTypeDefInstance = hadc->DMA_Handle->Instance;
7
8
  // (1) Stop ongoing DMA transfer with setting EN to Zero
9
  dmaStreamTypeDefInstance->CR &= ~DMA_SxCR_EN;
10
  //DMA Channel is stopped when EN is 0
11
  uint8_t i = 0;
12
  while(hadc->DMA_Handle->Instance->CR & DMA_SxCR_EN )
13
  {
14
    //DMA not Stopping )-;
15
    if(i>100)
16
      _Error_Handler(__FILE__, __LINE__);
17
    i++;
18
  }
19
  //DMA now is stopped and can be reconfigured
20
21
  //Read the position of the last circular write operation - needed for later move operations and is away when restarting
22
  uint32_t ndtr = dmaStreamTypeDefInstance->NDTR;
23
24
  // (2) Set Peripherial Register
25
  // Nothing TODO
26
27
  // (3) Set Memory Address
28
  dmaStreamTypeDefInstance->M0AR = (uint32_t)memoryPostRecordPtr;
29
30
  // (4) Configure Item Numbers
31
  dmaStreamTypeDefInstance->NDTR = memoryPostRecord;
32
33
  // (5) Set DMA channel
34
  // (6) Set Flow CNTRL
35
  // (7) Configure Stream Priority
36
  // (8) FIFO Mode
37
  // (9) Configure Direction, increment, data widths, circular and interrupts
38
  // Disable Circular mode Enable DMA
39
  dmaStreamTypeDefInstance->CR &= (~DMA_SxCR_CIRC);
40
41
  // (10) (Re)Enable DMA
42
  dmaStreamTypeDefInstance->CR |= DMA_SxCR_EN ;
43
44
  if(hadc1.Instance->SR & ADC_SR_OVR)
45
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
46
  if(!(dmaStreamTypeDefInstance->CR&DMA_SxCR_EN))
47
    HAL_GPIO_WritePin(white_Led_GPIO_Port, white_Led_Pin, GPIO_PIN_SET);
48
49
50
51
  //Disable Analog Watchdog before exiting
52
  hadc->Instance->CR1 &= (~ADC_CR1_AWDEN);
53
54
  //Calculate the position  of the last circular write operation
55
  uint32_t elementPos = memoryCyclicSize - 1 - ndtr;
56
  uint16_t* ndtrPtr = &memoryCyclicPtr[elementPos];
57
58
  //Set LD2 LED
59
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
60
61
  systemState = LinearRecordingAndDataRearrangement;
62
}


Leider geht die weiße LED an, d.h. das das Enable vom DMA gleich wieder 
zurück genommen wird.
Es tritt jedoch kein OVR beim ADC auf.

Danach hab ich dem DMA einen Wartepunkt gesetzt.
Der Teil unter //Disable Analog Watchdog before exiting wird also nichgt 
aufgerufen.

Hat jemand einen Plan?

Gruß und Danke, Markus

von Sebastian K. (sek)


Lesenswert?

Ich habe vor einiger Zeit auch sehr lange intensiv mit Stop/Go Betrieb 
des ADC + DMA experimentiert. Erschwerend auch noch im Dual bzw. Triple 
Mode.

Zu deiner Vorgehensweise den DMA bei laufendem ADC abzuschalten, zu 
rekonfigurieren und wieder einzuschalten kann ich sagen, ist kritisch. 
Der ADC wird höchstwahrscheinlich nach Deaktivierung des DMA ebenfalls 
den Dienst quittieren. Je nachdem welchen STM32 du verwendest steht dir 
zwar das DDS Bit im CR2 Register zur Verfügung, um ein Stoppen des ADC 
Wandlungen am Ende des DMA Transfers zu Verhindern. Das ist laut 
Reference Manual aber nur für Double Buffer Betrieb vorgesehen.

Mein Vorgehen ist nach Deaktivierung des DMA auch den ADC zu 
deaktivieren und eine Neukonfiguration und Neustart beider.
Du könntest in deiner Anwendung alternativ versuchen, den DMA im Double 
Buffer Mode zu konfigurieren und im Analog Watchdog Interrupt On-The-Fly 
die DMA Memory Zieladresse umzusetzen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.