Hallo, vielleicht weiss ja jemand auf dem Stehgreif heraus, warum ich folgenden Effekt habe: Der Aufruf RF_SendPaypload((uint8_t*)&rf_data,PAYLOAD_SIZE) aus dem Hauptprogramm heraus läuft so wie er soll, Datenpaket geht raus, in dem Falk kommt kein ACK und im Status Struct steht MAX_RT = True. Rufe ich es aber aus dem Interruthandler heraus auf, unmittelbar nachdem ich ein Paket empfangen habe bleibt das programm in der Senderoutine bei der Abfrage der Flags hängen. Weder TD_DS noch MAX_RT wird jemals 1. Der Interrupt wird vom INT Pin des Funkmoduls angesteuert. Ich kann mir das so nicht erklären :-( Source Code is angehängt.
Sorry, nun eingeloggt: Geht um die Stelle hier:
1 | /* Rückmeldung senden */
|
2 | GPIO_SetBits(TM_DISCO_LED_PORT,LED_BLUE); |
3 | if (RF_SendPaypload((uint8_t*)&rf_data,PAYLOAD_SIZE) == ERROR) |
4 | RF_FlushTX(); |
5 | GPIO_ResetBits(TM_DISCO_LED_PORT,LED_BLUE); |
Wenn etwas im Main läuft, dann sollte es das doch auf in einer ISR, wobei ich es tunlichst vermieden habe, da irgendwelche Delays reinzubringen, die ihrerseits wieder Interrupt Basiert sind und "einfrieren", weil globale Ints gesperrt sind, solange die ISR läuft. Keine Funktion die im INT aufgerufen wird, wird sonstwo im Main aufgerufen. Ich denke der Compiler weiss, dass er da dann Maßnahmen treffen muss Reentranz zu verhindern.
In der ISR rufst du erst ganz am Schluss EXTI_ClearITPendingBit(EXTI_Line1) auf. Das ist problematisch, da die Anbindung der Peripherie beim STM32F4 etwas langsam ist. Das Rücksetzen des Flags erfolgt erst verspätet, so dass beim Verlassen der ISR das Bit noch gesetzt sein kann und die ISR sofort wieder auslöst. Setz den Aufruf mal an den Anfang unterhalb des ersten if(). pitschu
pitschu schrieb: > In der ISR rufst du erst ganz am Schluss > EXTI_ClearITPendingBit(EXTI_Line1) auf. Das ist problematisch, da die > Anbindung der Peripherie beim STM32F4 etwas langsam ist. Was hat das denn mit dem Status Byte des SPI Gerätes zu tun? Das Gerät löst den Int aus, indem es einen Pin hochnimmt. Ob das Funkmodul wirklich sendet ist nicht ermittelbar, nur der Umstand dass es keinen Status liefert ist auffällig. Wobei die unteren 3 Bit ok sind, also antwortet es aber es setzt nicht die Bits "Sendung ging raus". Da es das aber ganz sicher macht, wenn die Routine aus Main aufgerufen wird muss die Routine ja ok sein. Wie wird das überhaupt gehandhabt, wenn eine Routine sowohl im Interrupt aufgerufen wird, aber auch im Hauptprogramm? Setzt der Compiler da automatisch Blocker, damit keine Rekursion auftritt?
Christian J. schrieb: > Ich kann mir das so nicht erklären :-( Da kann sich auch der NRF chip vertüddeln.Schau mal bei den mbed Leuten die lesen so: int nRF24L01P::read(int pipe, char *data, int count) { if ( ( pipe < NRF24L01P_PIPE_P0 ) || ( pipe > NRF24L01P_PIPE_P5 ) ) { error( "nRF24L01P: Invalid read pipe number %d\r\n", pipe ); return -1; } if ( count <= 0 ) return 0; if ( count > _NRF24L01P_RX_FIFO_SIZE ) count = _NRF24L01P_RX_FIFO_SIZE; if ( readable(pipe) ) { nCS_ = 0; int status = spi_.write(_NRF24L01P_SPI_CMD_R_RX_PL_WID); int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); nCS_ = 1; if ( ( rxPayloadWidth < 0 ) || ( rxPayloadWidth > _NRF24L01P_RX_FIFO_SIZE ) ) { // Received payload error: need to flush the FIFO nCS_ = 0; int status = spi_.write(_NRF24L01P_SPI_CMD_FLUSH_RX); int rxPayloadWidth = spi_.write(_NRF24L01P_SPI_CMD_NOP); nCS_ = 1; // // At this point, we should retry the reception, // but for now we'll just fall through... // } else { if ( rxPayloadWidth < count ) count = rxPayloadWidth; nCS_ = 0; int status = spi_.write(_NRF24L01P_SPI_CMD_RD_RX_PAYLOAD); for ( int i = 0; i < count; i++ ) { *data++ = spi_.write(_NRF24L01P_SPI_CMD_NOP); } nCS_ = 1; // Clear the Status bit setRegister(_NRF24L01P_REG_STATUS, _NRF24L01P_STATUS_RX_DR); return count; } } else { // // What should we do if there is no 'readable' data? // We could wait for data to arrive, but for now, we'll // just return with no data. // return 0; } // // We get here because an error condition occured; // We could wait for data to arrive, but for now, we'll // just return with no data. // return -1; }
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.