--- /dev/null
+
+[writeRegister(0x00, 0x29)]: IOCFG2
+[writeRegister(0x01, 0x2e)]: IOCFG1
+[writeRegister(0x02, 0x3e)]: IOCFG0: 0x3F (default) -> 0x3E => CLK_XOSC/192 -> CLK_XOSC/128
+[writeRegister(0x03, 0x47)] FIFTHR; FIFO_THR=7 -> Threshold: TX-FIFO: 33 Bytes, RX_FIFO: 32 Bytes
"cSpell.words": [],
"cSpell.ignorePaths": [
"**/*.json", "**/*.c", "**/*.h", "**/*.cpp", "**/*.hpp", "**/Makefile"
+ ],
+ "java.project.sourcePaths": [
+ "src/units"
]
}
gdb: sim/$(NAME).elf
avr-gdb $<
+
flash: dist/$(NAME).elf all
avrdude -c arduino -P /dev/ttyUSB0 -p m644p -e -U flash:w:$<
+flash0: dist/$(NAME).elf all
+ avrdude -c arduino -P /dev/ttyUSB0 -p m644p -e -U flash:w:$<
+
+flash1: dist/$(NAME).elf all
+ avrdude -c arduino -P /dev/ttyUSB1 -p m644p -e -U flash:w:$<
+
+flash2: dist/$(NAME).elf all
+ avrdude -c arduino -P /dev/ttyUSB2 -p m644p -e -U flash:w:$<
+
+picocom:
+ # picocom sends CR for ENTER -> convert cr (\r) to lf (\n)
+ picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0
+
+picocom0:
+ picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0
+
+picocom1:
+ picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB1
+
+picocom2:
+ picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB2
+
+
isp-644p:
avrdude -c usbasp -p m644p
avrdude -c arduino -p m644p -P /dev/ttyUSB0 -b 115200 -e -U flash:w:$<
-picocom:
- # picocom sends CR for ENTER -> convert cr (\r) to lf (\n)
- picocom -b 115200 --omap crlf --raise-dtr /dev/ttyUSB0
-
isp-fuse-644p:
avrdude -c usbasp -p m644p -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xFF:m -U lock:w:0xFF:m
#include "units/modbus.hpp"
#include "units/rtc8563.hpp"
#include "units/cc1101.hpp"
+#include "units/cc1101new.hpp"
extern "C" {
void __cxa_pure_virtual () {}
Rtc8563 rtc8563;
Cc1101 cc1101Send(Cc1101::Send);
Cc1101 cc1101Receive(Cc1101::Receive);
+ Cc1101New cc1101New(Cc1101New::Test);
}
#ifdef __AVR_ATmega644P__
TestUnit *unit[] = {
&led, &sw, &rgb, &seg7, &poti, &encoder, &r2r, &motor, &portExp, &lcd, &uart1, &modbus, &ieee485,
- &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101Send, &cc1101Receive
+ &i2cMaster, &i2cSlave, &i2cSparkfun, &rtc8563, &cc1101Send, &cc1101Receive, &cc1101New
};
#endif
i2cSparkfun.tick1ms();
cc1101Send.tick1ms();
cc1101Receive.tick1ms();
+ cc1101New.tick1ms();
#ifdef __AVR_ATmega644P__
if (timerFlashRedLed > 0) {
if (--timerFlashRedLed < 128) {
CC1101_FSCAL2, 0x2A, // Frequency Synthesizer Calibration
CC1101_FSCAL1, 0x00, // Frequency Synthesizer Calibration
CC1101_FSCAL0, 0x11, // Frequency Synthesizer Calibration
- // CC1101_FSTEST, 0x59, // Frequency Synthesizer Calibration Control
- // CC1101_TEST2, 0x81, // Various Test Settings
- // CC1101_TEST1, 0x35, // Various Test Settings
- // CC1101_TEST0, 0x09, // Various Test Settings
+ CC1101_FSTEST, 0x59, // Frequency Synthesizer Calibration Control
+ CC1101_TEST2, 0x81, // Various Test Settings
+ CC1101_TEST1, 0x35, // Various Test Settings
+ CC1101_TEST0, 0x09, // Various Test Settings
CC1101_IOCFG2, 0x0B, // GDO2 Output Pin Configuration -> Serial Clock. Synchronous to the data in synchronous serial mode.
CC1101_IOCFG0, 0x06, // GDO0 Output Pin Configuration -> Asserts when sync word has been sent / received, and de-asserts at the end of the packet.
CC1101_PKTCTRL1, 0x04, // Packet Automation Control
CC1101_PKTCTRL0, 0x05, // serial clock.synchronous to the data in synchronous serial mode
CC1101_ADDR, 0x00, // asserts when sync word has been sent/received, and de-asserts at the end of the packet
- CC1101_PKTLEN, 0x3D, // two status bytes will be appended to the payload of the packet,including RSSI LQI and CRC OK
- CC1101_PKTCTRL0, 0x05, // whitening off; normal mode, CRC enabled, variable packet length
- CC1101_ADDR, 0x00, // address used for packet filtration.
- CC1101_PKTLEN, 0x3D // 61 bytes max length
+ CC1101_PKTLEN, 0x3D // two status bytes will be appended to the payload of the packet,including RSSI LQI and CRC OK
};
bool Cc1101::writeRegisters (uint8_t addr, uint8_t *buffer, uint8_t length) {
bool ok = true;
+ printf_P(PSTR(" [writeRegisters(0x%02x): "), addr);
+ for (uint8_t i = 0; i < length; i++) {
+ printf_P(PSTR(" 0x%02x"), buffer[i]);
+ }
+ printf_P(PSTR("] "));
+
addr |= WRITE_BURST;
setChipEnableLow();
ok &= waitForMisoLow();
SPCR = 0;
setChipEnableLow();
- _delay_us(20);
+ _delay_ms(1); // _delay_us(20); //?
setChipEnableHigh();
- _delay_us(30);
+ _delay_ms(1); //_delay_us(30); //?
setChipEnableLow();
timer = 10;
ok &= waitForMisoLow();
ok &= waitForMisoLow();
setChipEnableHigh();
- PORTB |= (1 << PB0);
-
+ _delay_ms(5); // ?
ok &= initModemConfig(MHZ868);
uint8_t pa_table[8];
memcpy_P(pa_table, PMEM_CC1101_PA_TABLE, 8);
ok &= writeRegisters(CC1101_PATABLE, pa_table, 8);
- PORTB &= ~(1 << PB0);
return ok;
}
bool Cc1101::initModemConfig (InitFrequency f) {
bool ok = true;
- ok &= writeRegister(CC1101_FSCTRL1, 0x08); // frequency synthesizer control 1 (RX frequency)
ok &= writeRegister(CC1101_FSCTRL1, 0x08); // frequency synthesizer control 1 (RX frequency)
ok &= writeRegister(CC1101_FSCTRL0, 0x00); // frequency synthesizer control 0 (RX frequency offset)
class Cc1101 : public TestUnit {
public:
typedef enum { MHZ915, MHZ433, MHZ868 } InitFrequency;
- typedef enum { Send, Receive } Cc1101Mode;
+ typedef enum { Send, Receive, Test } Cc1101Mode;
public:
Cc1101 (Cc1101Mode mode) { this->mode = mode; };
--- /dev/null
+#include <stdio.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <util/delay.h>
+
+#include "cc1101new.hpp"
+#include "../main.hpp"
+
+// 868MHz Modem E07-900MM1DS (chipset CC1101)
+// https://jlcpcb.com/partdetail/Chengdu_Ebyte_ElecTech-E07900MM10S/C5844212
+
+#ifdef __AVR_ATmega328P__
+
+ // Arduino-Nano-5V
+ // ------------------------------------
+ // not available
+
+ void Cc1101New::init () {}
+ void Cc1101New::cleanup () {}
+ void Cc1101New::setChipEnable () {}
+ void Cc1101New::clearChipEnable () {}
+
+#endif
+
+
+#ifdef __AVR_ATmega644P__
+
+ // Nano-644
+ // --------------------------------------------------------
+ // PA4 ... nCS
+ // PB4 ... nSS (not used, but must be high, otherwise AVR SPI master not working)
+ // PB5 ... MOSI
+ // PB6 ... MISO
+ // PB7 ... SCK
+
+ int8_t Cc1101New::run (uint8_t subtest) {
+ while (wait(0) == EOF) {
+ }
+ return -1;
+ }
+
+ // --------------------------------------------------------
+
+ const Cc1101New::Register_t PMEM_CC1101_REGISTER_INIT PROGMEM = {
+ { Cc1101New::CHIP_NOT_READY, 0, 0 }, // iocfg2 (GDO2)
+ { Cc1101New::HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH, 0, 0 }, // iocfg1 (GDO1/MISO)
+ { Cc1101New::CLK_XOSC_DIV_128, 0, 0 }, // iocfg0 (GDO0)
+ { 7, 0, 1, 0 }, // fifothr (fifo_thr = 7, close_in_rx=0, adc_retention = 1)
+ // { 0x91, 0xd3 }, // sync word = 0xd391
+ { 0x7a, 0x0e }, // sync word = 0xd391
+
+ };
+
+
+// const uint8_t PMEM_CC1101_INIT[] PROGMEM = {
+// CC1101_MDMCFG4, 0x5B, // modem config 4 -> ADC decimation rate, symbol rate exponent
+// CC1101_MDMCFG3, 0xF8, // modem config 3 -> symbol rate mantissa
+// CC1101_MDMCFG2, 0x03, // modem config 2 -> DC blocking filter, modulation type, manchaster enoding, sync-mode,
+// CC1101_MDMCFG1, 0x22, // modem config 1 -> forw error correction, min number of preamble bytes, channel spacing exponent
+// CC1101_MDMCFG0, 0xF8, // modem config 0 -> channel spacing mantissa
+// CC1101_CHANNR, 0x00, // channel number
+// CC1101_DEVIATN, 0x47, // modem deviation setting
+// CC1101_FREND1, 0xB6, // front end RX configuration
+// CC1101_FREND0, 0x10, // front end TX configuration
+// CC1101_MCSM0 , 0x18, // Main Radio Control State Machine Configuration
+// CC1101_FOCCFG, 0x1D, // Frequency Offset Compensation Configuration
+// CC1101_BSCFG, 0x1C, // Bit Synchronization Configuration
+// CC1101_AGCCTRL2, 0xC7, // AGC Control
+// CC1101_AGCCTRL1, 0x00, // AGC Control
+// CC1101_AGCCTRL0, 0xB2, // AGC Control
+// CC1101_FSCAL3, 0xEA, // Frequency Synthesizer Calibration
+// CC1101_FSCAL2, 0x2A, // Frequency Synthesizer Calibration
+// CC1101_FSCAL1, 0x00, // Frequency Synthesizer Calibration
+// CC1101_FSCAL0, 0x11, // Frequency Synthesizer Calibration
+// CC1101_FSTEST, 0x59, // Frequency Synthesizer Calibration Control
+// CC1101_TEST2, 0x81, // Various Test Settings
+// CC1101_TEST1, 0x35, // Various Test Settings
+// CC1101_TEST0, 0x09, // Various Test Settings
+// CC1101_IOCFG2, 0x0B, // GDO2 Output Pin Configuration -> Serial Clock. Synchronous to the data in synchronous serial mode.
+// CC1101_IOCFG0, 0x06, // GDO0 Output Pin Configuration -> Asserts when sync word has been sent / received, and de-asserts at the end of the packet.
+// CC1101_PKTCTRL1, 0x04, // Packet Automation Control
+// CC1101_PKTCTRL0, 0x05, // serial clock.synchronous to the data in synchronous serial mode
+// CC1101_ADDR, 0x00, // asserts when sync word has been sent/received, and de-asserts at the end of the packet
+// CC1101_PKTLEN, 0x3D // two status bytes will be appended to the payload of the packet,including RSSI LQI and CRC OK
+// };
+
+ uint8_t Cc1101New::sendSpiByte (uint8_t b) {
+ SPDR = b;
+ while (!(SPSR & (1<<SPIF))) {}
+ return SPDR;
+ }
+
+ void Cc1101New::triggerOn () {
+ PORTB |= (1 << PB0);
+ }
+
+ void Cc1101New::triggerOff () {
+ PORTB &= ~(1 << PB0);
+ }
+
+ PGM_P Cc1101New::getName () {
+ switch (mode) {
+ case Test: return PSTR("CC-1101-New-Test");
+ default: return PSTR("CC-1101-New-?");
+ }
+ }
+
+ void Cc1101New::init () {
+ // trigger for debugging
+ PORTB &= ~(1 << PB0);
+ DDRB |= ( 1 << PB0);
+
+ PRR &= (1 << PRSPI);
+
+ // nCs
+ PORTA |= (1 << PA4);
+ DDRA |= (1 << PA4);
+ // PORTB/DDRB must be configured before SPCR !!
+
+ PORTB |= (1 << PB4); // nSS must be HIGH, otherwise SPI master will not become active!!
+ DDRB &= ~(1 << PB6); // MISO
+ DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); // SPI SCK (=PB7) and SPI MOSI (=PB5)
+
+ // SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); // SPI enable , Master, f=12MHz/128=93,75kHz
+ SPCR = (1 << SPE) | (1 << MSTR); // SPI enable , Master, f=12MHz/4 = 3MHz
+
+ // GDO0
+ PORTA |= (1 << PA5);
+ DDRA &= ~(1 << PA5);
+
+ printf_P(PSTR(" reset CC1101 ... "));
+ if (!resetCC1101()) {
+ printf_P(PSTR("fails"));
+ return;
+ }
+ printf_P(PSTR("OK, init register ... "));;
+ if (!initRegister()) {
+ printf_P(PSTR("fails"));
+ return;
+ }
+ printf_P(PSTR("OK"));
+ }
+
+ void Cc1101New::cleanup () {
+ // trigger for debugging
+ PORTB &= ~(1 << PB0);
+ DDRB &= ~( 1 << PB0);
+
+ SPCR = 0;
+ PORTB &= ~(1 << PB4);
+ DDRB &= ~((1 << PB7) | (1 << PB6) | (1 << PB5) | (1 << PB4));
+ DDRA &= ~((1 << PA5) | (1 << PA4));
+ PORTA &= ~((1 << PA5) | (1 << PA4));
+ }
+
+ void Cc1101New::setChipEnableLow () {
+ PORTA &= ~(1 << PA4);
+ }
+
+ void Cc1101New::setChipEnableHigh () {
+ PORTA |= (1 << PA4);
+ }
+
+ bool Cc1101New::isMisoHigh () {
+ return (PINB & (1 << PB6)) != 0;
+ }
+
+ bool Cc1101New::isGd0High () {
+ return (PINA & (1 << PA5)) != 0;
+ }
+
+ bool Cc1101New::waitForMisoLow () {
+ timer = 10;
+ while (isMisoHigh()) {
+ if (timer == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool Cc1101New::strobe (StrobeCommand_t command) {
+ bool ok = true;
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ sendSpiByte(command & 0x3f);
+ setChipEnableHigh();
+ return ok;
+ }
+
+ bool Cc1101New::writeRegister (uint8_t addr, uint8_t value) {
+ bool ok = true;
+ printf_P(PSTR(" [writeRegister(0x%02x, 0x%02x)] "), addr, value);
+ timer = 10;
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ sendSpiByte(addr);
+ sendSpiByte(value);
+ setChipEnableHigh();
+ return ok;
+ }
+
+ bool Cc1101New::resetCC1101 () {
+ bool ok = true;
+ setChipEnableLow();
+ _delay_us(10);
+ setChipEnableHigh();
+ _delay_us(50);
+ setChipEnableLow();
+ ok &= waitForMisoLow();
+ ok &= strobe(SRES);
+ ok &= waitForMisoLow();
+
+
+ return ok;
+ }
+
+ bool Cc1101New::initRegister () {
+ const Register_t *regValues = &PMEM_CC1101_REGISTER_INIT;
+ bool ok = true;
+ triggerOn();
+ for (uint8_t addr = 0; ok && addr < sizeof(Register_t); addr++) {
+ uint8_t regValue;
+ memcpy_P(®Value, ((const uint8_t *)regValues) + addr, 1);
+ ok &= writeRegister(addr, regValue);
+ }
+ triggerOff();
+ return ok;
+ }
+
+#endif
+
+
--- /dev/null
+#ifndef CC1101NEW_HPP
+#define CC1101NEW_HPP
+
+#include <stdint.h>
+#include "../main.hpp"
+#include <avr/pgmspace.h>
+
+class Cc1101New : public TestUnit {
+ public:
+ typedef enum { MHZ915, MHZ433, MHZ868 } InitFrequency;
+ typedef enum { Test } Cc1101Mode;
+
+
+ public:
+ Cc1101New (Cc1101Mode mode) { timer = 0; this->mode = mode; };
+ virtual void init ();
+ virtual void cleanup ();
+ virtual int8_t run (uint8_t subtest);
+ virtual PGM_P getName ();
+
+ public:
+ void tick1ms () { if (timer > 0) timer--; };
+
+ private:
+ typedef enum { SRES = 0x30, SCAL = 0x33, SRX = 0x34, STX = 0x35, SIDLE = 0x36 } StrobeCommand_t;
+
+ private:
+ uint8_t sendSpiByte (uint8_t b);
+ void triggerOn();
+ void triggerOff();
+ void setChipEnableLow ();
+ void setChipEnableHigh ();
+ bool isMisoHigh ();
+ bool isGd0High ();
+ bool waitForMisoLow ();
+ bool strobe (StrobeCommand_t strobe);
+ bool writeRegister (uint8_t addr, uint8_t value);
+ bool resetCC1101 ();
+ bool initRegister ();
+
+
+ private:
+ Cc1101Mode mode;
+ uint8_t timer;
+
+
+ public:
+ typedef enum {
+ IOCFG2 = 0x00, IOCFG1 = 0x01, IOCFG0 = 0x02,
+ FIFOTHR = 0x03
+ } RegisterAddress_t;
+
+ typedef enum {
+ RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x00,
+ RX_FIFO_FILLED_OR_ABOVE_THRESHHOLD_OR_END_OF_PACKAGE_UNTIL_FIFO_EMPTY = 0x01,
+ TX_FIFO_FILLED_OR_ABOVE_THRESHHOLD = 0x02,
+ TX_FIFO_FULL_UNTIL_BELOW_THRESHHOLD = 0x03,
+ RX_FIFO_OVERFLOW_UNTIL_FIFO_FLUSHED = 0x04,
+ TX_FIFO_UNDERFLOW_UNTIL_FIFO_FLUSHED = 0x05,
+ SYNC_SENT_OR_RECEIVED_UNTIL_END_OF_PACKET = 0x06,
+ PACKET_RECEIVED_WITH_CRC_OK_UNTIL_FIRST_BYTE_READ_FROM_RXFIFO = 0x07,
+ PREAMBLE_QUALITY_REACHED_UNTIL_REENTER_RX = 0x08,
+ RSSI_LEVEL_BELOW_THRESHOLD = 0x09,
+ LOCK_DETECTOR_OUTPUT = 0x0a,
+ SERIAL_CLOCK = 0x0b,
+ SERIAL_SYNCHRONOUS_DATA_OUTPUT = 0x0c,
+ SERIAL_ASYNC_DATA_OUTPUT = 0x0d,
+ CARRIER_DETECTED_UNTIL_ENTER_IDLE = 0x0e,
+ CRC_OK_UNTIL_REENTER_RX = 0x0f,
+ RX_HARD_DATA_1 = 0x16,
+ RX_HARD_DATA_0 = 0x17,
+ PA_PD = 0x1b,
+ LNA_PD = 0x1c,
+ RX_SYMBOL_TICK = 0x1d,
+ WAKEUP_ON_RECEIVE_EVENT0 = 0x24,
+ WAKEUP_ON_RECEIVE_EVENT1 = 0x25,
+ CLK_256 = 0x26,
+ CLK_32K = 0x27,
+ CHIP_NOT_READY = 0x29,
+ XOSC_STABLE = 0x2b,
+ HIGH_IMPEDANCE_WHEN_CHIP_SELECT_HIGH = 0x2e,
+ HW_TO_0 = 0x2f,
+ CLK_XOSC = 0x30,
+ CLK_XOSC_DIV_1P5 = 0x31,
+ CLK_XOSC_DIV_2 = 0x32,
+ CLK_XOSC_DIV_3 = 0x33,
+ CLK_XOSC_DIV_4 = 0x34,
+ CLK_XOSC_DIV_6 = 0x35,
+ CLK_XOSC_DIV_8 = 0x36,
+ CLK_XOSC_DIV_12 = 0x37,
+ CLK_XOSC_DIV_16 = 0x38,
+ CLK_XOSC_DIV_24 = 0x39,
+ CLK_XOSC_DIV_32 = 0x3a,
+ CLK_XOSC_DIV_48 = 0x3b,
+ CLK_XOSC_DIV_64 = 0x3c,
+ CLK_XOSC_DIV_96 = 0x3d,
+ CLK_XOSC_DIV_128 = 0x3e,
+ CLK_XOSC_DIV_192 = 0x3f
+ } GDOx_CFG_t;
+
+ typedef struct { GDOx_CFG_t gdo0_cfg:6; uint8_t gdo0_inv:1; uint8_t bit7:1; } IOCFG0_t;
+ typedef struct { GDOx_CFG_t gdo1_cfg:6; uint8_t gdo1_inv:1; uint8_t bit7:1; } IOCFG1_t;
+ typedef struct { GDOx_CFG_t gdo2_cfg:6; uint8_t gdo2_inv:1; uint8_t bit7:1; } IOCFG2_t;
+ typedef struct { uint8_t fifo_thr:4; uint8_t close_in_rx:2; uint8_t adc_retention:1; uint8_t bit7:1; } FIFOTHR_t;
+ typedef struct { uint8_t lowByte; uint8_t highByte; } SYNC_t;
+
+ typedef struct {
+ IOCFG2_t iocfg2;
+ IOCFG1_t iocfg1;
+ IOCFG0_t iocfg0;
+ FIFOTHR_t fifothr;
+ SYNC_t sync;
+ } Register_t;
+
+
+
+};
+
+#endif
\ No newline at end of file