Hallo Frank!
edit: Fehler entdeckt, siehe unten!
Das hatte ich mir auch überlegt, aber mit dem Einfügen (und Modifizieren
auf den benötigten USART) der Zeilen ist es leider nicht getan. Es
ändert sich nichts.
Beim Definieren (also dem Aufruf der Aktivierung des USART)
1 | #define CONF_BOARD_ENABLE_USARTC0
|
wird im ASF
1 | #ifdef CONF_BOARD_ENABLE_USARTC0
|
2 | ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 3), IOPORT_DIR_OUTPUT
|
3 | | IOPORT_INIT_HIGH);
|
4 | ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 2), IOPORT_DIR_INPUT);
|
5 | #endif
|
definiert.
Mit dem Aufruf von usart_init() in main() wird im Programmteil
usart_diff_modes.c die Funktion usart_init_rs232 aufgerufen und alle
Parameter übergeben. In der usart.c wird nun folgendes ausgeführt:
1 | void usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt)
|
2 | {
|
3 | usart_enable_module_clock(usart);
|
4 | usart_set_mode(usart, USART_CMODE_ASYNCHRONOUS_gc);
|
5 | usart_format_set(usart, opt->charlength, opt->paritytype,
|
6 | opt->stopbits);
|
7 | usart_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz());
|
8 | usart_tx_enable(usart);
|
9 | usart_rx_enable(usart);
|
10 | }
|
Die erste Anweisung führt nun folgendes aus:
1 | static inline void usart_enable_module_clock(USART_t *usart)
|
2 | {
|
3 | #ifdef USARTC0
|
4 | if ((uintptr_t)usart == (uintptr_t)&USARTC0) {
|
5 | sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0);
|
6 | }
|
7 | #endif
|
8 | ...
|
was der oben genannten Zeile:
1 | sysclk_enable_module(SYSCLK_PORT,PR_USART0_bm);
|
entsprechen sollte?!
Nun initialisiere ich den PMIC mit:
1 | pmic_init();
|
2 |
|
3 | siehe ASF Code:
|
4 |
|
5 | //Enables all interrupt levels
|
6 | static inline void pmic_init(void)
|
7 | {
|
8 | PMIC.CTRL = PMIC_LVL_LOW | PMIC_LVL_MEDIUM |
|
9 | PMIC_LVL_HIGH;
|
10 | }
|
was dem unten Stehenden doch entsprechen sollte, obwohl ich die
Kombination aus Low Level Execution BitMask und Hi Level Enable BitMask
nicht wirklich verstehe:
1 | PMIC.CTRL |= PMIC_LOLVLEX_bm | PMIC_HILVLEN_bm;
|
Um das Interruptlevel im Code für den USART zu setzen habe ich in der
usart_init() folgenden Code stehen:
1 | // Set the Level of PMIC to the initialized USART
|
2 | usart_set_rx_interrupt_level(&USARTC0,PMIC_LVL_LOW);
|
Jetzt sehe ich grade, dass der zweite Parameter recht unterschiedlich
ist.
1 | usart_set_rx_interrupt_level(UART, USART_RXCINTLVL_LO_gc);
|
2 | usart_set_tx_interrupt_level(UART, USART_TXCINTLVL_LO_gc);
|
Das war auch schon der Fehler: PMIC_LVL_LOW ist anscheinend nicht dafür
gedacht, ein Level zu setzen, sondern nur um das entsprechende Level ein
oder auszuschalten.
Das macht mich aber sehr stutzig, denn die Funktion
usart_set_rx_interrupt_level() erwartet folgendes:
1 | static inline void usart_set_tx_interrupt_level(USART_t *usart,
|
2 | enum pmic_level level)
|
und das enum ist definiert zu:
1 | enum pmic_level {
|
2 | PMIC_LVL_LOW = PMIC_LOLVLEN_bm, //!< Low-level interrupts
|
3 | PMIC_LVL_MEDIUM = PMIC_MEDLVLEN_bm, //!< Medium-level interrupts
|
4 | PMIC_LVL_HIGH = PMIC_HILVLEN_bm, //!< High-level interrupts
|
5 | /**
|
6 | * \brief Non-maskable interrupts
|
7 | * \note These cannot be enabled nor disabled.
|
8 | */
|
9 | PMIC_LVL_NMI = PMIC_NMIEX_bp,
|
10 | };
|
Somit dachte ich dass ich eben das Level mit PMIC_LVL_L/M/H festlegen
muss.
Vielleicht kann mir das jemand nochmal erklären, ebenso was die _gc
Maske für das Register denn nun macht, bzw wofür _gc steht.
Vielen Dank für all die Vorschläge.
Ich hoffe ja, dass sich bald noch mehr Leute mit dem Software Framework
beschäftigen :-)
Gruß Felix