Commit 292b45fd771984d6ebd97686ed66234d977df66f
receivedWed, 14. Aug 2024, 17:09:23 (by user sx)
Wed, 14 Aug 2024 15:09:23 +0000 (17:09 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Wed, 14 Aug 2024 15:08:35 +0000 (17:08 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Wed, 14 Aug 2024 15:08:35 +0000 (17:08 +0200)
3 files changed:
software/nano-644/test_2024-07-23/src/units/cc1101.cpp
software/nano-644/test_2024-07-23/src/units/cc1101new.cpp
software/nano-644/test_2024-07-23/src/units/cc1101new.hpp

index 9516b455715243d5895e185199e3b6794131cc6e..31d335d539dadf60d6ec9c5c5d7f35bf1fabafe9 100644 (file)
@@ -456,7 +456,7 @@ int8_t Cc1101::run (uint8_t subtest) {
             if (wait(0) != EOF) {
                printf_P(PSTR("cancelled"));
                _delay_ms(500);
-               break;
+               return -1;
             }
             if (state == IDLE) {
                printf_P(PSTR("? (IDLE)"));
index 00342d24fe3704cf370a1bd9c20dc9fdb1f68544..cf1db428dac9c176e8dc137e5f8ec0a57165fdfb 100644 (file)
       uint16_t cnt = 0;
       do {
          MainRadioControlState state = UNKNOWN;
-         uint8_t data[20];
+         uint8_t data[PACKET_LENGTH];
          printf_P(PSTR("\n [%04x]: state="), cnt++);
          if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
             printf_P(PSTR("E1"));
          } else {
             printf_P(PSTR("0x%02x"), state);
          }
+         printf_P(PSTR(" --> send %d bytes (HEX:"), sizeof(data));
          for (uint8_t i = 0; i < sizeof(data); i++) {
-            data[i] = i;
+            data[i] = uint8_t((cnt + i) & 0xff);
+            printf_P(PSTR(" %02X"), data[i]);
          }
-         printf_P(PSTR(" --> send %d bytes ... "), sizeof(data));
+         printf_P(PSTR("] -> "));
+
          if (!sendData(data, sizeof(data))) {
             flashRedLed(100);
             printf_P(PSTR("E1"));
             continue;
          }
          flashGreenLed(100);
-         printf_P(PSTR("OK -> state="));
-         if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
-            printf_P(PSTR("E1"));
-         } else {
-            printf_P(PSTR("0x%02x"), state);
-         }
+         printf_P(PSTR("OK"));
       } while (wait(2000) == EOF);
 
       return 0;
    }
 
    int8_t Cc1101New::runReceive (uint8_t subtest) {
-      if (subtest > 0) {
+      if (subtest == 0) {
+         bool ok = true;
+         GDOx_CFG_t cfg0 = SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET;
+         ok &= writeRegister(0x02, cfg0);
+         return ok;
+      } else if (subtest > 1) {
          return -1;
       }
 
          if (state != RX && state != RXFIFO_OVERFLOW) {
             continue;
          }
-
          printf_P(PSTR("OK, receive ... "));
 
+         uint8_t length;
+         uint8_t lastLength = 0xff;
          do {
-            uint8_t length;
-            uint8_t data[16];
+            uint8_t data[PACKET_LENGTH];
             if (!readStatusRegister(MARCSTATE, (uint8_t *)&state)) {
                printf_P(PSTR("E2"));
                _delay_ms(500);
             if (wait(0) != EOF) {
                printf_P(PSTR("cancelled"));
                _delay_ms(500);
+               return -1;
+            }
+            if (!readStatusRegister(RXBYTES, (uint8_t *)&length)) {
+               printf_P(PSTR("E2"));
+               _delay_ms(500);
                continue;
             }
-            if (receiveData(data, &length, sizeof(data))) {
-               flashGreenLed(100);
-               printf_P(PSTR("OK, %d bytes received: "), length);
-               for (uint8_t i = 0; i < length; i++) {
-                  printf_P(PSTR(" 0x%02x"), data[i]);
+            if (lastLength != length) {
+               lastLength = length;
+            }
+            if (length >= PACKET_LENGTH) {
+               if (receiveData(data, &length, sizeof(data))) {
+                  if (length > 0) {
+                     flashGreenLed(100);
+                     printf_P(PSTR(" -> "));
+                     if (status.receivePacketStatusValid) {
+                        printf_P(PSTR(" RSSI=%d, LQI=%d, CRC "), status.receivedPacketStatus.value.rssi, status.receivedPacketStatus.value.lqi);
+                        if (status.receivedPacketStatus.value.crcOk) {
+                           printf_P(PSTR("OK, "));
+                        } else {
+                           printf_P(PSTR("ERROR, "));
+                        }
+                     }
+                     printf_P(PSTR("%d data bytes (HEX): "), length);
+                     for (uint8_t i = 0; i < length; i++) {
+                        printf_P(PSTR(" %02X"), data[i]);
+                     }
+                     printf_P(PSTR(" ... "));
+                  }
                }
-               printf_P(PSTR(" ... "));
             }
 
          } while (state == RX || state == RXFIFO_OVERFLOW);
       /* 0x03: fifothr   0x47 (0x07) */ { 7, 0, 1, 0 }, // fifo_thr = 0b111, close_in_rx=0, adc_retention = 1, (bit7=0)
       /* 0x04: sync1     0x7a (0xd3) */ 0x7a,
       /* 0x05: sync0     0x0e (0x91) */ 0x0e,
-      /* 0x06: pktlen    0x14 (0x3d) */ 0x14,
+      /* 0x06: pktlen    0x14 (0x3d) */ PACKET_LENGTH,
       /* 0x07: pktctrl1  0x04 (----) */ { Cc1101New::NO_ADDR_CHECK, 1, 0, 0, 0 }, // adr_chk=0b00, append_status=1, crc_autoflush=0, (bit4=0), pqt=0b000
       /* 0x08: pktctrl0  0x05 (----) */ { Cc1101New::FIXED, 1, 0, Cc1101New::NORMAL_USE_FIFO, 0, 0 }, // length_config=0b01, crc_en=1, (bit3=0), pkt_format=0b00, white_data=0, (bit7=0)
       /* 0x09: addr      0x00 (----) */ 0x00,
       PORTB &= ~(1 << PB0);
    }
 
+   void Cc1101New::triggerToggle () {
+      PORTB ^= (1 << PB0);
+   }
+
    PGM_P Cc1101New::getName () {
       switch (mode) {
          case Send: return PSTR("CC-1101-New-Send");
       setChipEnableLow();
       ok &= waitForMisoLow();
       sendSpiByte(addr);
-      status.byte = sendSpiByte(value);
+      status.spiResponse.byte = sendSpiByte(value);
+      status.spiResponseValid = 1;
       setChipEnableHigh();
       
       if (debugPrint.print.writeRegister) {
          printf_P(PSTR("\n [writeRegister(0x%02x, 0x%02x) -> "), addr, value);
-         if (ok) {
-            printf_P(PSTR("status=0x%02x]"), status.byte);
+         if (ok && status.receivePacketStatusValid) {
+            printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte);
          } else {
             printf_P(PSTR("ERR]"));
          }
             printf_P(PSTR(" 0x%02x"), *p++);
          }
          printf_P(PSTR(" -> "));
-         if (ok) {
-            printf_P(PSTR("status=0x%02x]"), status.byte);
+         if (ok && status.receivePacketStatusValid) {
+            printf_P(PSTR("status=0x%02x]"), status.spiResponse.byte);
          } else {
             printf_P(PSTR("ERR]"));
          }
       addr = (addr & 0x3f) | 0x80;
       setChipEnableLow();
       ok &= waitForMisoLow();
-      status.byte = sendSpiByte(addr);
+      status.spiResponse.byte = sendSpiByte(addr);
+      status.spiResponseValid = 1;
       *value = sendSpiByte(0);
       setChipEnableHigh();
 
       if (debugPrint.print.readRegister) {
          printf_P(PSTR("\n [readRegister(0x%02x) -> "), addr & 0x3f);
-         if (ok) {
-            printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.byte);
+         if (ok && status.spiResponseValid) {
+            printf_P(PSTR("0x%02x,status=0x%02x]"), *value, status.spiResponse.byte);
          } else {
             printf_P(PSTR("ERR]"));
          }
    }
 
    bool Cc1101New::sendData (uint8_t *buffer, uint8_t length) {
-      bool ok = true;
+      timer = 10;
+      uint8_t ok = true;
       uint8_t txbytes;
+      uint8_t states[16]; uint8_t statesIndex = 0;
       // ok &= writeRegister(0x3f, length);
       ok &= writeRegisters(0x3f, buffer, length);
       ok &= readStatusRegister(TXBYTES, &txbytes);
       ok &= (txbytes == 20);
-      timer = 10;
       if (ok) {
-         triggerOn();
          ok &= strobe(STX);    // start sending bytes
          // ok &= waitForGD0High(); // wait for start of SYNC
          if (ok) {
+            uint8_t lastState = 0;
             uint8_t state;
             do {
                ok &= readStatusRegister(MARCSTATE, &state);
+               if (state != lastState && statesIndex < 16) {
+                  states[statesIndex++] = state;
+               }
+               lastState = state;
             } while (ok && state != 0x13 && timer > 0);
             ok &= state == 0x13; // check if in state TX
          }
          if (ok) {
+            uint8_t lastTxbytes = 20;
             do {
                ok &= readStatusRegister(TXBYTES, &txbytes);
+               if (lastTxbytes != txbytes) {
+                  lastTxbytes = txbytes;
+               }
             } while (ok && txbytes > 0 && timer > 0);
             ok &= txbytes == 0;
          }
       }
       if (!ok) {
          strobe(SFTX); // flush TXfifo
+      } else {
+         uint8_t state;
+         uint8_t lastState = 0;
+         do {
+            ok &= readStatusRegister(MARCSTATE, &state);
+            if (lastState != state) {
+               lastState = state;
+            }
+         } while (ok && state != 0x01 && timer > 0);
+         ok &= state == 0x01; // check if in state IDLE
       }
       // ok &= waitForGD0Low(); // wait for end of package
-      triggerOff();
 
-      // if (ok) {
-      //    printf_P(PSTR(" -> ? %02x %02x %02x %02x? "), state, txbytes[0], txbytes[1], txbytes[2]);
-      // }
+      if (ok) {
+         printf_P(PSTR(" States["));
+         for (uint8_t i = 0; i < statesIndex; i++) {
+            printf_P(PSTR(" 0x%02X"), states[i]);
+         }
+         printf_P(PSTR("] "));
+      }
 
       return ok;
    }
    bool Cc1101New::receiveData (uint8_t *buffer, uint8_t *receivedLength, uint8_t maxBufferSize) {
       bool ok = true;
       STATUS_RXBYTES_t status;
+      uint8_t lastLength = 0;
+      uint8_t length = 0;
+      *receivedLength = 0;
+      timer = 50;
 
+      this->status.receivePacketStatusValid = 0;
       ok &= readStatusRegister(RXBYTES, &status.byte);
       if (ok && status.rxbytes.num_rxbytes > 0) {
-         uint8_t length = status.rxbytes.num_rxbytes;
-         ok &= readStatusRegister(RXBYTES, &status.byte);
-         if (ok && status.rxbytes.num_rxbytes == length) {
-            // ok &= readRegister(RXFIFO, &length);
-            if (length <= maxBufferSize) {
-               ok &= readRegisters(0xff, buffer, length);
-            } else {
-               ok = false;
-            }
-            ok &= strobe(SFRX);
+         length = status.rxbytes.num_rxbytes;
+         
+         do {
+            _delay_us(400); // 20 Bytes in 4ms -> 200us/Byte -> CC1101 datasheet page 56: "twice that of which RF bytes are recived"
+            lastLength = length;
+            ok &= readStatusRegister(RXBYTES, &status.byte);
             if (ok) {
-               *receivedLength = length;
-               return ok;
+               // printf_P(PSTR(" [rxbytes=%d] "), status.byte);
+               length = status.byte & 0x7f;
+            }
+            ok &= timer > 0;
+         } while (ok && lastLength != length);
+         
+         if (ok) {
+            uint8_t extraBytesCount = this->status.receivePacketStatusEnabled ? 2 : 0;
+            if ((PACKET_LENGTH + extraBytesCount) != length) {
+               printf_P(PSTR(" ERROR[receive %d bytes, expect %d bytes] "), *receivedLength, PACKET_LENGTH + extraBytesCount);
+               *receivedLength = 0;
+               ok = false;
+            } else {
+               printf_P(PSTR(" OK[receive %d bytes] "), length);
+               *receivedLength = PACKET_LENGTH < maxBufferSize ? length - extraBytesCount : maxBufferSize;
+               ok &= readRegisters(0xff, buffer, *receivedLength);
+               if (!ok) {
+                  *receivedLength = 0;
+               } else {
+                  length -= *receivedLength;
+                  if (length > extraBytesCount) {
+                     printf_P(PSTR(" [WARN: buffer to small] "));
+                     while (length > extraBytesCount) {
+                        uint8_t byte;
+                        ok &= readRegister(0xff, &byte);
+                        ok = false;
+                        length--;
+                     }
+                  }
+                  if (length > 0) {
+                     ok &= readRegisters(0xff, this->status.receivedPacketStatus.byte, 2);
+                     if (ok) {
+                        this->status.receivePacketStatusValid = 1;
+                     }                     
+                  }
+               }
             }
          }
       }
-      strobe(SFRX);
-      *receivedLength = 0;
-      return false;
+      ok &= strobe(SFRX);
+     
+      return ok;
    }
 
 
          uint8_t regValue;
          memcpy_P(&regValue, ((const uint8_t *)regValues) + addr, 1);
          ok &= writeRegister(addr, regValue);
+         if ((addr == 0x07) && (regValue & 0x04)) {
+            status.receivePacketStatusEnabled = true;
+         }
       }
 
       printRegisters();
index 807c09c29dc99acae92aef20606072b9956c506b..516baa63cdc2ca22abfc92f85bdbd1ad2a6d0df1 100644 (file)
@@ -6,17 +6,33 @@
 #include <avr/pgmspace.h>
 
 class Cc1101New : public TestUnit {
+   public:
+      #define PACKET_LENGTH 20
+
    public:
       typedef enum { Test, Send, Receive  } Cc1101Mode;
       typedef enum { _IDLE = 0, _RX = 1, _TX = 2, _FSTXON = 3, _CALIBRATE = 4, _SETTLING = 5, _RXFIFO_OVFL = 6, _TXFIFO_UNFL = 7 } StatusState_t;
       typedef struct { uint8_t fifoBytes:4; StatusState_t state:3; uint8_t chipNotReady:1; } Status_t;
+      typedef struct { uint8_t rssi:8; uint8_t lqi:7; uint8_t crcOk:1; } ReceivedPacketStatus_t; // CC1101 datasheet page 37
       union {
-         Status_t status;
-         uint8_t byte;
+         struct {
+            union { 
+               Status_t value;
+               uint8_t byte;
+            } spiResponse;
+            union {
+               ReceivedPacketStatus_t value;
+               uint8_t byte [2];
+            } receivedPacketStatus;
+            uint8_t spiResponseValid: 1;
+            uint8_t receivePacketStatusEnabled:1;
+            uint8_t receivePacketStatusValid:1;
+         };
+         uint32_t dword;
       } status;
 
    public:
-      Cc1101New (Cc1101Mode mode) { timer = 0; this->mode = mode; status.byte = 0x80; debugPrint.byte = 0; }
+      Cc1101New (Cc1101Mode mode) { timer = 0; this->mode = mode; status.dword = 0; }
       virtual void init ();
       virtual void cleanup ();
       virtual int8_t run (uint8_t subtest);
@@ -27,7 +43,7 @@ class Cc1101New : public TestUnit {
 
    private:
       typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SFRX = 0x3a, SFTX = 0x3b, SIDLE = 0x36 } StrobeCommand_t;
-      typedef enum { MARCSTATE = 0x35, TXBYTES = 0x3a, RXBYTES = 0x3b } StatusAddress_t;
+      typedef enum { MARCSTATE = 0x35, TXBYTES = 0x3A, RXBYTES = 0x3B } StatusAddress_t;
       typedef struct { uint8_t writeRegister:1; uint8_t writeRegisters:1; uint8_t readRegister:1; uint8_t readRegisters:1; } DebugPrint_t;
 
    private:
@@ -37,6 +53,7 @@ class Cc1101New : public TestUnit {
       uint8_t sendSpiByte (uint8_t b);
       void triggerOn();
       void triggerOff();
+      void triggerToggle ();
       void setChipEnableLow ();
       void setChipEnableHigh ();
       bool isMisoHigh ();