From: Manfred Steiner Date: Wed, 14 Aug 2024 15:08:35 +0000 (+0200) Subject: modem CC1101 send/receive OK X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=292b45fd771984d6ebd97686ed66234d977df66f;p=nano-x-base.git modem CC1101 send/receive OK --- diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101.cpp b/software/nano-644/test_2024-07-23/src/units/cc1101.cpp index 9516b45..31d335d 100644 --- a/software/nano-644/test_2024-07-23/src/units/cc1101.cpp +++ b/software/nano-644/test_2024-07-23/src/units/cc1101.cpp @@ -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)")); diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp b/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp index 00342d2..cf1db42 100644 --- a/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp +++ b/software/nano-644/test_2024-07-23/src/units/cc1101new.cpp @@ -48,36 +48,39 @@ 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; } @@ -110,12 +113,12 @@ 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); @@ -124,15 +127,36 @@ 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); @@ -169,7 +193,7 @@ /* 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, @@ -226,6 +250,10 @@ PORTB &= ~(1 << PB0); } + void Cc1101New::triggerToggle () { + PORTB ^= (1 << PB0); + } + PGM_P Cc1101New::getName () { switch (mode) { case Send: return PSTR("CC-1101-New-Send"); @@ -347,13 +375,14 @@ 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]")); } @@ -382,8 +411,8 @@ 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]")); } @@ -398,14 +427,15 @@ 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]")); } @@ -452,40 +482,62 @@ } 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; } @@ -493,28 +545,63 @@ 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; } @@ -561,6 +648,9 @@ uint8_t regValue; memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1); ok &= writeRegister(addr, regValue); + if ((addr == 0x07) && (regValue & 0x04)) { + status.receivePacketStatusEnabled = true; + } } printRegisters(); diff --git a/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp b/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp index 807c09c..516baa6 100644 --- a/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp +++ b/software/nano-644/test_2024-07-23/src/units/cc1101new.hpp @@ -6,17 +6,33 @@ #include 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 ();