Moin,
Setup:
- ATmega128RFA1 auf nem Dresden Elektronik Board, sitzt auf:
- PCB mit USB-Versorgung, LDO zu 3.3V, LiPo Backup
- FT232RQ zum PC
Firmware:
Ein Board agiert als PAN Coordinator (=Master) und gibt empfangene
Funkdaten der Nodes (=Slaves) über USART0 => FT232 => PC Terminal aus
- Funkdaten empfangen => in Buffer kopieren, überprüfen => teilweise in
Buffer für USART0 Ausgabe kopieren => USART0 Ausgabe mit TXC Interrupt
- mit Codevision erstellt
- alle nötigen Interrupts für Transceiver und USART0 werden verwendet
(habe die ISRs aufs reine Flag-setzen ausgedünnt)
*Problem:*
Nach etwa einer halben Stunde Laufzeit gibt's einen Reset.
Das Reset Register nach Neustart sagt: Reset Source extern.
Hardware macht das aber nicht, habe Spannung und externen Reset
Controller (TCM809) überprüft, da passiert nix.
Watchdog scheidet auch aus.
=> Vermutung: Irgendwie springt der Program Counter auf $0000 = Reset.
Aber wie kann das passieren?
Ich arbeite viel mit Zeigern, auch auf konstante Strings im Flash. Kann
dort etwas faul sein?
Hier mal ein paar Code-Auszüge:
Beispiel für pointer ins flash, kopiert in globalen
TX_buffer für RS232, mit Beispiel String im Flash.
Hmm, eigentlich funktioniert's ja für einige 1000e Zeichen...
1 | flash char str_ohyeah[] = "Oh Yeah!";
|
2 |
|
3 | string2TXbuf(str_ohyeah);
|
4 |
|
5 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
6 | // put string array into TX_buffer, end with null termination \0 = NUL = 0x00
|
7 | void string2TXbuf(flash char *ptr_str)
|
8 | {
|
9 | unsigned char i = 0;
|
10 |
|
11 | for( i = 0; i < STRING_MAX_LEN; i++ )
|
12 | {
|
13 | if ( *(ptr_str + i) == '\0' ) break; // end of string
|
14 | else TX_buffer[TX_length++] = *(ptr_str + i);
|
15 | }
|
16 | }
|
Und wenn TX_buffer gefüllt ist:
1 | ....
|
2 | string2TXbuf(str_ohyeah);
|
3 | TX_buffer[TX_length++] = LF;
|
4 | TX_buffer[TX_length++] = CR;
|
5 |
|
6 | // Ready to send TX_buffer:
|
7 |
|
8 | TX0_bts2send = TX_length;
|
9 | TX0_go = 1;
|
10 |
|
11 | // Trigger transmission by sending first byte, rest is done auto with ISR
|
12 | TX0_byte(TX_buffer[0]);
|
13 | }
|
14 |
|
15 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
16 | // USART0 Transmitter interrupt service routine
|
17 | interrupt [USART0_TXC] void usart0_tx_isr(void)
|
18 | {
|
19 | static unsigned char bytes_sent = 0;
|
20 |
|
21 | // TXC flag auto resets here
|
22 |
|
23 | bytes_sent++;
|
24 |
|
25 | if ( TX0_go == 1 && bytes_sent < TX0_bts2send )
|
26 | {
|
27 | UDR0 = TX_buffer[bytes_sent];
|
28 | }
|
29 | else
|
30 | {
|
31 | TX0_go = 0;
|
32 | bytes_sent = 0;
|
33 | }
|
34 | }
|