Forum: Mikrocontroller und Digitale Elektronik XMEGA A4U USB


von Michael (Gast)


Lesenswert?

Hallo zusammen,

ich kämpfe gerade mit der Inbetriebnahme vom ASF Stack bzgl. USB CDC 
beim XMEGA A4U. Aus einem anderen Thread habe ich einen super Link 
gefunden:

http://asf.atmel.com/docs/latest/xmegaau/html/udi_cdc_quickstart.html

Der USB-Stack funktioniert prinzipiell auf meiner eigenen HW, weil im 
Geräte-Manager der Virtuelle COM Port angezeigt wird.

Eine Sache kapiere aber unter den oben genannten Link nicht:

main ()
{
  ...

while(1)
 {
  if (my_flag_autorize_cdc_transfert)
  {
        udi_cdc_putc('A');
        udi_cdc_getc();
  }
 }
}

Das Flag in der if-Abfrage my_flag_autorize_cdc_transfert wird über zwei 
Callback-Funktion gesetzt bzw. gelöscht. Allerdings habe ich keine Idee 
wie ich die conf_usb.h anpassen muss damit die Callback-Funktionen 
aufgerufen werden.

Aktuell habe ich die Callback-Funktionen aus dem obigen Link in meinem 
main.c -File reinkopiert. Allerdings werden diese nicht aufgerufen. Ich 
bin mir sicher das der Fehler in der conf_usf.h liegt.

Hab' meine conf_usb.h wie folgt konfiguiert.

//! Interface callback definition
//#define  UDI_CDC_ENABLE_EXT(port)          true
//#define  UDI_CDC_DISABLE_EXT(port)
#define  UDI_CDC_RX_NOTIFY(port)
#define  UDI_CDC_TX_EMPTY_NOTIFY(port)
#define  UDI_CDC_SET_CODING_EXT(port,cfg)
#define  UDI_CDC_SET_DTR_EXT(port,set)
#define  UDI_CDC_SET_RTS_EXT(port,set)

#define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable()
extern bool my_callback_cdc_enable(void);
#define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable()
extern void my_callback_cdc_disable(void);

Leider komme ich aber einfach nicht in die 
my_callback_cdc_enable-Funktion rein...

Irgendwelche Tipps?!

Danke,
Michael

von Mihcael (Gast)


Lesenswert?

Keiner eine Idee?! Häng immer noch :-(

von Martin J. (bluematrix) Benutzerseite


Lesenswert?

häng doch mal dein ganzen Projekt an

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

im Anhang mein Projekt. Der USB-Port wird nicht zuverlässig erkannt. Und 
in die callback Funktionen komme ich auch nicht rein.

Würde mich sehr freuen, wenn sich einer mal die Zeit nimmt und mir 
weiterhilft.

Mit besten Grüßen,
Michael Bittner

von Basti (Gast)


Lesenswert?

teil der config:
1
//! Number of communication port used (1 to 7)
2
#define  UDI_CDC_PORT_NB 1
3
4
//! Interface callback definition
5
#define  UDI_CDC_ENABLE_EXT(port)          usb_handle_cdc_enable()
6
#define  UDI_CDC_DISABLE_EXT(port)       usb_handle_cdc_disable()
7
#define  UDI_CDC_RX_NOTIFY(port)
8
#define  UDI_CDC_SET_CODING_EXT(port,cfg)
9
#define  UDI_CDC_SET_DTR_EXT(port,set)
10
#define  UDI_CDC_SET_RTS_EXT(port,set)
11
12
#define UDI_CDC_ENABLE_EXT(port) usb_handle_cdc_enable()
13
extern bool usb_handle_cdc_enable(void);
14
#define UDI_CDC_DISABLE_EXT(port) usb_handle_cdc_disable()
15
extern void usb_handle_cdc_disable(void);
16
/* #define  UDI_CDC_RX_NOTIFY(port) my_callback_rx_notify(port)
17
 * extern void my_callback_rx_notify(uint8_t port);
18
 * #define  UDI_CDC_SET_CODING_EXT(port,cfg) my_callback_config(port,cfg)
19
 * extern void my_callback_config(uint8_t port, usb_cdc_line_coding_t * cfg); 
20
 * #define  UDI_CDC_SET_DTR_EXT(port,set) my_callback_cdc_set_dtr(port,set)
21
 * extern void my_callback_cdc_set_dtr(uint8_t port, bool b_enable);
22
 * #define  UDI_CDC_SET_RTS_EXT(port,set) my_callback_cdc_set_rts(port,set)
23
 * extern void my_callback_cdc_set_rts(uint8_t port, bool b_enable); 
24
 */
25
26
//! Define it when the transfer CDC Device to Host is a low rate (<512000 bauds)
27
//! to reduce CDC buffers size
28
#define  UDI_CDC_LOW_RATE
29
30
//! Default configuration of communication port
31
#define  UDI_CDC_DEFAULT_RATE             115200
32
#define  UDI_CDC_DEFAULT_STOPBITS         CDC_STOP_BITS_1
33
#define  UDI_CDC_DEFAULT_PARITY           CDC_PAR_NONE
34
#define  UDI_CDC_DEFAULT_DATABITS         8
35
//@}
36
//@}
37
38
39
/**
40
 * USB Device Driver Configuration
41
 * @{
42
 */
43
//@}
44
45
//! The includes of classes and other headers must be done at the end of this file to avoid compile error
46
#include "udi_cdc_conf.h"
47
#include "usb_handle.h"

Callbacks:
1
volatile bool main_b_cdc_enable = false;
2
3
void usb_handle_suspend_action(void)
4
{
5
  
6
}
7
8
void usb_handle_resume_action(void)
9
{
10
  
11
}
12
13
bool usb_handle_cdc_enable()
14
{
15
  main_b_cdc_enable = true;
16
  return true;
17
}
18
19
void usb_handle_cdc_disable()
20
{
21
  main_b_cdc_enable = false;
22
}

Das enable Flag ist nach ASF Beispiel so verwendet (die solltest du dir 
jedenfalls immer mal anschauen), leider funktioniert es nicht bzw. nicht 
immer....
Meist läuft der interene USB Buffer beim Senden voll und das Programm 
bleibt in der udi_cdc_write_buf hängen... WTF!
Da hilft es auch nicht dieses enable Flag zu benutzen...

von kderh (Gast)


Lesenswert?

-Vielleicht testweise die Callback-Funktion mit gleichen Parametern 
(port) ausstatten (sollte aber egal sein da der Aufruf nur durch define 
ersetzt wird)

-Zum Verhindern des Puffer-Überlaufs (=Sendefunktion hängt):
DTR-Signal auswerten und nur senden wenn aktiv (das Signal von der 
PC-Software steuern). Ist besser als die CDC-Enable-Signale.

-Allgemeiner Tip falls es nicht geht oder am PC "USB-Gerät nicht 
erkannt" kommt:
Vor dem USB-Anschalten den 32kHz-Oszillator deaktivieren (hilft 
wirklich, kein Witz)

von kderh (Gast)


Lesenswert?

Und natürlich die Clock richtig einstellen, am besten mit Autocal-Quelle 
USB-Clock (Oszi RC32 so auf 48MHz setzen und dann runterteilen z.B. 
24Mhz).

von kderh (Gast)


Lesenswert?

Äh ja also die letzten beiden Posts waren jetzt nur allgemeine 
XMEGA-USB-Tips hab das spezielle Projekt nicht angeschaut deshalb k.A. 
was zutrifft!

Trotzdem habe ich damals als ich mal sowas gemacht hab ewig dran 
rumgebastelt bis es zuverlässig lief, vielleicht hilft es ja jemandem :)

von Basti (Gast)


Lesenswert?

@kderh danke für die Tipps... ich verwende auch schon seit einer ganzen 
Weile die ASF... Habe einfach die Write Funktion so abgeändert, dass 
diese nicht mehr im Endlos Loop hängt... find leider das Projekt nicht 
mehr...

Was ich aber eigentlich in jedem Projekt mache, ist die read_buf 
Funktion ändern... USB funktioniert nur mit 5 MBit auf dem 8 Bitter, 
wenn man die buf Funktionen nimmt und nicht jedes Zeichen einzeln 
holt... leider ist die ASF Funktion dafür total dämlich geschrieben... 
die wartet nämlich immer bis die erhoffte Anzahl Zeichen eingetroffen 
ist... wieder mal -> WTF...

Wer sich das ersparen möchte, schreibt die einfach so um:
(geht sicher noch optimaler)
1
iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size)
2
{
3
  uint8_t *ptr_buf = (uint8_t *)buf;
4
  iram_size_t copy_nb;
5
  uint16_t pos;
6
  uint8_t buf_sel;
7
  uint16_t size2 = size;
8
9
  #if UDI_CDC_PORT_NB == 1 // To optimize code
10
  port = 0;
11
  #endif
12
13
  udi_cdc_read_buf_loop_wait:
14
  // Check available data
15
  pos = udi_cdc_rx_pos[port];
16
  buf_sel = udi_cdc_rx_buf_sel[port];
17
  while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) {
18
19
    return size2-size;
20
    //goto udi_cdc_read_buf_loop_wait;
21
  }
22
23
  // Read data
24
  copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos;
25
  if (copy_nb>size) {
26
    copy_nb = size;
27
  }
28
  memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb);
29
  udi_cdc_rx_pos[port] += copy_nb;
30
  ptr_buf += copy_nb;
31
  size -= copy_nb;
32
  udi_cdc_rx_start(port);
33
34
  return size2-size;
35
}

Die Funktion funktioniert natürlich nun komplett anders... also holt bis 
max buffer alles raus und gibt immer die geholten Zeichenanzahl als 
return zurück...

Grüße

Basti

von Michael (Gast)


Lesenswert?

Hallo zusammen,

bin leider heute nicht mehr dazugekommen weiter an der USB-Schnittstelle 
zu basteln. Aber das nächste Wochenende ist nah :-).

@Basti:
In Deiner conf_usb.h kommt folgende Define zweimal vor:
#define  UDI_CDC_ENABLE_EXT(port)          usb_handle_cdc_enable()

Absicht?

Wie sieht bei Dir die Datei-Struktur aus. Sind Deine Callback-Funktionen 
in
usb_handle.h definiert?

Bei mir werden die Callback-Funktionen gar nicht erst angesprungen. Die 
Callback-Funktionen habe ich einfach in main.c unten angehängt.

VG,
Michael

von Basti (Gast)


Lesenswert?

Jetzt wo du es sagst...

Aber die sind ja gleich definiert... da ists egal...

Würde den unteren Teil mit dem extern raus schmeißen... da ich, wie du 
schon recht hast, die extern schon in der usb_handle.h bekannt gemacht 
habe und in der usb_handle.c abarbeite...
Das kannste dir sparen, wenn du die in der main.h hast und das extern in 
die conf_usb.h bringst... wie oben gezeigt...


Grüße

Basti

von Michael (Gast)


Lesenswert?

Hallo zusammen,

nachdem ich jetzt (endlich) mal wieder für mein Projekt Zeit gefunden 
habe, muss ich langsam resigniert bzgl. dem ASF-USB Stack aufgeben.

Sobald ich die callback Funktionen mit in mein Programm aufnehme wird 
meine HW nicht mehr von Windows richtig erkannt. Folglich habe ich auch 
keine virtuelle COM-Schnittstelle, dafür ein nicht erkanntes Device im 
Geräte-Manager.

Wenn ich überhaupt keine eigene callback Funktion implementiere und 
einfach nur Zeichen über die USB-Schnittstelle sende, dann funktioniert 
dies zumindest. Allerdings, wenn ich den USB-Stecker abstecke und dann 
wieder einstecke, dann wird meine HW auch nicht mehr richtig vom PC 
erkannt.

Also langsam habe ich das Gefühl, der Stack ist der letzte Schrott oder 
ich bin zu blöd. Über Tipps wäre ich sehr dankbar.

VG,
Michael

PS: Wie einfach ist das alles mit FTDI

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.