Forum: Mikrocontroller und Digitale Elektronik ESP8266 über USB-CDC mit STM32F4 flashen


von Mampf F. (mampf) Benutzerseite


Lesenswert?

Guten Abend,

ich bin langsam am verzweifeln ...

Hab einen STM32F4, an dem am UART6 ein ESP8266 hängt.

Der STM32F4 hängt per USB an einem PC und spricht CDC.

Geplant war es so, den ESP8266 über CDC zu flashen. D.h. CDC stellt ein 
Device /dev/ttyACM0 zur Verfügung und esptool --port /dev/ttyACM0 soll 
es verwenden und so indirekt über den STM32F4 den ESP8266 flashen.

Leider funktioniert das nicht ...

Ein esptool.py --port ... chip_id bringt meistens einen 
Kommunikations-Fehler. Manchmal erkennt er den ESP8266 und versucht 
einen "stub" hochzuladen ... Dann tritt der Timeout auf und der ESP8266 
macht nichts mehr.

Ich hatte das einerseits mit einer (eigenen) Implementierung 
ausprobiert, die HAL verwendet und auf andererseits mit einem fertigen 
Projekt (verwendet nur CMSIS), das eine USB-CDC nach Uart Bridge quasi 
implementiert.

Mit der AT-Kommando-Firmware (also nicht im UART-Flash-Modus) scheint 
alles zu klappen ... Keine Zeichen werden verschluckt, alles wird brav 
ausgeführt usw ... Scheint also zu gehen, eigentlich.

Zumindest funktioniert USB-CDC ohne HAL, was mich so schon mal weiter 
bringt ;-)

Hat jemand zufällig eine Idee, weshalb der ESP8266 sich nicht auf diese 
Art und Weise flashen lässt?

Hat jemand so eine USB-CDC nach UART Bridge schonmal gebaut oder 
gesehen, die mit dem ESP8266 klar kommt?

Vielen Dank,
Mampf

von DraconiX (Gast)


Lesenswert?

Hier ich, aber mit einem STM32F103.... Ich bin grad bis morgen 
unterwegs, ich schieben dir morgen mal meine Source zu, ist zwar 
StdPeriph und kein HAL aber lässt sich ja alles ableiten. Deinen ESP 
bringst du aber schon in den Bootloader Mode?!

von Mampf F. (mampf) Benutzerseite


Lesenswert?

DraconiX schrieb:
> Hier ich, aber mit einem STM32F103.... Ich bin grad bis morgen
> unterwegs, ich schieben dir morgen mal meine Source zu, ist zwar
> StdPeriph und kein HAL aber lässt sich ja alles ableiten.

Oh das wär Prima! Ist vmtl nur eine Kleinigkeit, die nicht passt, aber 
selbst draufkommen ist wohl ziemlich schwierig.

DraconiX schrieb:
> Deinen ESP
> bringst du aber schon in den Bootloader Mode?!

Jap, das sollte klappen ... Ich zieh den GPIO0 per Taster auf GND, 
während ich einen Reset ausführe.

von DraconiX (Gast)


Lesenswert?

Ja ich mach das per Software, der Pin am STM32 war für den GPIO0 noch 
frei :-D Das schöne daran ist nämlich, das man über die UART sieht das 
der ESP in den Bootloader Mode geht.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Jetzt bin ich ein bisserl weiter gekommen, aber zufriedenstellend klappt 
es immer noch nicht ...

Meine USB nach UART Bridge versucht die SLIP-Frames nun an einem Stück 
zu senden (Requests an die UART, Reponses über USB) anstatt 
zeichenweise.

Zumindest konnte ich jetzt ein Minimal-HTTP-Serverchen aus der 
Arduino-GUI erfolgreich flashen.

Aber ohne mindestens 3-5 Versuche klappt es bei mir doch nicht.

@DraconiX: Wenn du mir doch noch deinen Code zur Verfügung stellen 
könntest, wäre ich dir zu ewiger Dankbarkeit verpflichtet :*

Was mich interessieren würde ... Ist die Kommunikation im Upload-Modus 
nur Halb-Duplex, d.h. der ESP antwortet nur auf Requests?

: Bearbeitet durch User
von Mampf F. (mampf) Benutzerseite


Lesenswert?

So ich hab es jetzt endlich hinbekommen ... Blöder Dreck xD

Die Geschichte mit der Slip-Frame Erkennung konnte ich mir sparen.

Es funktioniert reproduzierbar gut, wenn man versucht, die Daten zu 
64Byte Chunks zusammenzufassen und dann zu versenden. Jedes Zeichen 
einzeln zu versenden kostet zuviel Zeit.

Hier der Code, falls jemand mal die gleichen Probleme hat:
1
#define RX_BUF_SIZE      4096
2
#define CDC_BUF_SIZE    4096
3
4
uint8_t   rx[RX_BUF_SIZE];
5
uint32_t   rxwrptr = 0;
6
uint32_t   rxrdptr = 0;
7
uint8_t   cdc[CDC_BUF_SIZE];
8
uint32_t   cdcwrptr = 0;
9
uint32_t   cdcrdptr = 0;
10
11
uint8_t data;
12
13
14
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
15
  if (huart->Instance == USART6) {
16
    rx[rxwrptr % RX_BUF_SIZE] = data;
17
    rxwrptr++;
18
    HAL_UART_Receive_IT(huart, &data, 1);
19
  }
20
}
21
22
extern "C" uint8_t USB_Receive(uint8_t* Buf, uint32_t *Len) {
23
  for (uint32_t i = 0; i < *Len; i++) {
24
    cdc[cdcwrptr % CDC_BUF_SIZE] = Buf[i];
25
    cdcwrptr++;
26
  }
27
  return 1;
28
}
29
30
uint8_t linbuf[256];
31
uint8_t uartitbuf[256];  // buffer is used by interrupt
32
33
int main(void) {
34
  HAL_Init();
35
36
  SystemClock_Config();
37
38
  /* Initialize all configured peripherals */
39
  MX_GPIO_Init();
40
  MX_USART1_UART_Init();
41
  MX_USART6_UART_Init();
42
43
  MX_USB_DEVICE_Init(); 
44
45
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
46
  HAL_Delay(500);
47
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
48
  HAL_Delay(500);
49
50
  HAL_UART_Receive_IT(&huart6, &data, 1);
51
52
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
53
54
  while (1) {
55
    if (hcdc->TxState == 0) {
56
      int i=0;
57
      for (;rxrdptr<rxwrptr;rxrdptr++) {
58
        linbuf[i++]=rx[rxrdptr % RX_BUF_SIZE];
59
        if (i==64) 
60
          break;
61
      }
62
      if (i)
63
        CDC_Transmit_FS(linbuf, i);
64
    }
65
66
    if (huart6.gState == HAL_UART_STATE_READY) {
67
      int i=0;
68
      for (;cdcrdptr<cdcwrptr;cdcrdptr++) {
69
        uartitbuf[i++]=cdc[cdcrdptr % RX_BUF_SIZE];
70
        if (i==64) 
71
          break;
72
      }
73
      if (i)
74
        HAL_UART_Transmit_IT(&huart6, uartitbuf, i);
75
    }
76
  }
77
}

: Bearbeitet durch User
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.