intercom: Transmit/receive from/to temporary packets.

Fixes that the packet could be changed during transmit. And only values from packets with correct checksum are used.
This commit is contained in:
Markus Amsler 2011-02-21 15:52:16 +11:00 committed by Michael Moon
parent 5e56784ac1
commit fa2a4389fc
2 changed files with 58 additions and 18 deletions

View File

@ -41,8 +41,10 @@ typedef union {
uint8_t data[sizeof(intercom_packet_t)]; uint8_t data[sizeof(intercom_packet_t)];
} intercom_packet; } intercom_packet;
intercom_packet tx; intercom_packet tx; // this packet will be send
intercom_packet rx; intercom_packet rx; // the last received packet with correct checksum
intercom_packet _tx; // current packet in transmission
intercom_packet _rx; // receiving packet
uint8_t packet_pointer; uint8_t packet_pointer;
uint8_t rxcrc; uint8_t rxcrc;
@ -116,7 +118,6 @@ void start_send(void) {
uint8_t sreg = SREG; uint8_t sreg = SREG;
cli(); cli();
intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS; intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS;
SREG = sreg;
// set start byte // set start byte
tx.packet.start = START; tx.packet.start = START;
@ -127,6 +128,12 @@ void start_send(void) {
} }
tx.packet.crc = txcrc; tx.packet.crc = txcrc;
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
_tx.data[i] = tx.data[i];
}
SREG = sreg;
// enable transmit pin // enable transmit pin
enable_transmit(); enable_transmit();
delay_us(15); delay_us(15);
@ -164,7 +171,7 @@ ISR(USART_RX_vect)
// are we waiting for a start byte? is this one? // are we waiting for a start byte? is this one?
if ((packet_pointer == 0) && (c == START)) { if ((packet_pointer == 0) && (c == START)) {
rxcrc = rx.packet.start = START; rxcrc = _rx.packet.start = START;
packet_pointer = 1; packet_pointer = 1;
intercom_flags |= FLAG_RX_IN_PROGRESS; intercom_flags |= FLAG_RX_IN_PROGRESS;
} }
@ -174,16 +181,29 @@ ISR(USART_RX_vect)
if (packet_pointer < (sizeof(intercom_packet_t) - 1)) if (packet_pointer < (sizeof(intercom_packet_t) - 1))
rxcrc ^= c; rxcrc ^= c;
// stuff byte into structure // stuff byte into structure
rx.data[packet_pointer++] = c; _rx.data[packet_pointer++] = c;
// last byte? // last byte?
if (packet_pointer >= sizeof(intercom_packet_t)) { if (packet_pointer >= sizeof(intercom_packet_t)) {
// reset pointer // reset pointer
packet_pointer = 0; packet_pointer = 0;
#ifndef HOST
if (rxcrc == _rx.packet.crc &&
_rx.packet.controller_num == THIS_CONTROLLER_NUM){
#else
if (rxcrc == _rx.packet.crc){
#endif
// correct crc copy packet
static uint8_t i;
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
rx.data[i] = _rx.data[i];
}
}
intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX; intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX;
#ifndef HOST #ifndef HOST
if (rx.packet.controller_num == THIS_CONTROLLER_NUM) { if (_rx.packet.controller_num == THIS_CONTROLLER_NUM) {
if (rxcrc != rx.packet.crc) if (rxcrc != _rx.packet.crc)
tx.packet.err = ERROR_BAD_CRC; tx.packet.err = ERROR_BAD_CRC;
// not sure why exactly this delay is needed, but wihtout it first byte never arrives. // not sure why exactly this delay is needed, but wihtout it first byte never arrives.
delay_us(150); delay_us(150);
@ -221,9 +241,9 @@ ISR(USART_UDRE_vect)
#endif #endif
{ {
#ifdef HOST #ifdef HOST
UDR1 = tx.data[packet_pointer++]; UDR1 = _tx.data[packet_pointer++];
#else #else
UDR0 = tx.data[packet_pointer++]; UDR0 = _tx.data[packet_pointer++];
#endif #endif
if (packet_pointer >= sizeof(intercom_packet_t)) { if (packet_pointer >= sizeof(intercom_packet_t)) {

View File

@ -41,8 +41,10 @@ typedef union {
uint8_t data[sizeof(intercom_packet_t)]; uint8_t data[sizeof(intercom_packet_t)];
} intercom_packet; } intercom_packet;
intercom_packet tx; intercom_packet tx; // this packet will be send
intercom_packet rx; intercom_packet rx; // the last received packet with correct checksum
intercom_packet _tx; // current packet in transmission
intercom_packet _rx; // receiving packet
uint8_t packet_pointer; uint8_t packet_pointer;
uint8_t rxcrc; uint8_t rxcrc;
@ -116,7 +118,6 @@ void start_send(void) {
uint8_t sreg = SREG; uint8_t sreg = SREG;
cli(); cli();
intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS; intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS;
SREG = sreg;
// set start byte // set start byte
tx.packet.start = START; tx.packet.start = START;
@ -127,6 +128,12 @@ void start_send(void) {
} }
tx.packet.crc = txcrc; tx.packet.crc = txcrc;
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
_tx.data[i] = tx.data[i];
}
SREG = sreg;
// enable transmit pin // enable transmit pin
enable_transmit(); enable_transmit();
delay_us(15); delay_us(15);
@ -164,7 +171,7 @@ ISR(USART_RX_vect)
// are we waiting for a start byte? is this one? // are we waiting for a start byte? is this one?
if ((packet_pointer == 0) && (c == START)) { if ((packet_pointer == 0) && (c == START)) {
rxcrc = rx.packet.start = START; rxcrc = _rx.packet.start = START;
packet_pointer = 1; packet_pointer = 1;
intercom_flags |= FLAG_RX_IN_PROGRESS; intercom_flags |= FLAG_RX_IN_PROGRESS;
} }
@ -174,16 +181,29 @@ ISR(USART_RX_vect)
if (packet_pointer < (sizeof(intercom_packet_t) - 1)) if (packet_pointer < (sizeof(intercom_packet_t) - 1))
rxcrc ^= c; rxcrc ^= c;
// stuff byte into structure // stuff byte into structure
rx.data[packet_pointer++] = c; _rx.data[packet_pointer++] = c;
// last byte? // last byte?
if (packet_pointer >= sizeof(intercom_packet_t)) { if (packet_pointer >= sizeof(intercom_packet_t)) {
// reset pointer // reset pointer
packet_pointer = 0; packet_pointer = 0;
#ifndef HOST
if (rxcrc == _rx.packet.crc &&
_rx.packet.controller_num == THIS_CONTROLLER_NUM){
#else
if (rxcrc == _rx.packet.crc){
#endif
// correct crc copy packet
static uint8_t i;
for (i = 0; i < (sizeof(intercom_packet_t) ); i++) {
rx.data[i] = _rx.data[i];
}
}
intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX; intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX;
#ifndef HOST #ifndef HOST
if (rx.packet.controller_num == THIS_CONTROLLER_NUM) { if (_rx.packet.controller_num == THIS_CONTROLLER_NUM) {
if (rxcrc != rx.packet.crc) if (rxcrc != _rx.packet.crc)
tx.packet.err = ERROR_BAD_CRC; tx.packet.err = ERROR_BAD_CRC;
// not sure why exactly this delay is needed, but wihtout it first byte never arrives. // not sure why exactly this delay is needed, but wihtout it first byte never arrives.
delay_us(150); delay_us(150);
@ -221,9 +241,9 @@ ISR(USART_UDRE_vect)
#endif #endif
{ {
#ifdef HOST #ifdef HOST
UDR1 = tx.data[packet_pointer++]; UDR1 = _tx.data[packet_pointer++];
#else #else
UDR0 = tx.data[packet_pointer++]; UDR0 = _tx.data[packet_pointer++];
#endif #endif
if (packet_pointer >= sizeof(intercom_packet_t)) { if (packet_pointer >= sizeof(intercom_packet_t)) {