CC1120 + Arduino Due

port3.jpg

#include <SPI.h>
#include "cc1120.h"

#define PRINT_INFO  1
#define RX_ARR_SIZE 1536
#define RX_OK       "RX done"
#define TX_OK       "TX done"
#define TX          "TX"
#define RX          "RX"
#define TX_WAIT     "Waiting for 4 seconds"

volatile int8_t rx_arr[RX_ARR_SIZE];
volatile uint16_t rx_arr_index = 0;
volatile uint8_t radio_state = 0;

void setup() {
  Serial.begin(9600);
  pinMode(RESET_PIN, OUTPUT);
  pinMode(SS_PIN, OUTPUT);
  pinMode(GDO0_PIN, INPUT);
  pinMode(GDO3_PIN, INPUT);
  digitalWrite(SS_PIN, HIGH);
  digitalWrite(RESET_PIN, HIGH);
 
  SPI.begin();
  strobeSPI(SNOP);

  // Preamble off
  uint8_t v = readSPI(PREAMBLE_CFG0);
  bitClear(v, 5);
  writeSPI(PREAMBLE_CFG0, v);
  // Sync off
  v = readSPI(SYNC_CFG0);
  v &= B11100011;
  writeSPI(SYNC_CFG0, v);
  // CRC off
  v = readSPI(PKT_CFG1);
  v &= B11110011;
  writeSPI(PKT_CFG1, v);

  writeSPI(IOCFG0, CARRIER_SENSE);
  writeSPI(IOCFG3, CLKEN_CFM);
  writeSPI(SYNC_CFG1, SMARTRF_SETTING_SYNC_CFG1);
  writeSPI(DEVIATION_M, SMARTRF_SETTING_DEVIATION_M);
  writeSPI(MODCFG_DEV_E, SMARTRF_SETTING_MODCFG_DEV_E);
  writeSPI(DCFILT_CFG, SMARTRF_SETTING_DCFILT_CFG);
  writeSPI(PREAMBLE_CFG1, SMARTRF_SETTING_PREAMBLE_CFG1);
  writeSPI(IQIC, SMARTRF_SETTING_IQIC);
  writeSPI(CHAN_BW, SMARTRF_SETTING_CHAN_BW);
  writeSPI(MDMCFG0, SMARTRF_SETTING_MDMCFG0);
  writeSPI(MDMCFG1, SMARTRF_SETTING_MDMCFG1);
  writeSPI(SYMBOL_RATE2, SMARTRF_SETTING_SYMBOL_RATE2);
  writeSPI(SYMBOL_RATE1, SMARTRF_SETTING_SYMBOL_RATE1);
  writeSPI(SYMBOL_RATE0, SMARTRF_SETTING_SYMBOL_RATE0);
  writeSPI(AGC_REF, SMARTRF_SETTING_AGC_REF);
  writeSPI(AGC_CS_THR, SMARTRF_SETTING_AGC_CS_THR);
  writeSPI(AGC_CFG1, SMARTRF_SETTING_AGC_CFG1);
  writeSPI(AGC_CFG0, SMARTRF_SETTING_AGC_CFG0);
  writeSPI(FIFO_CFG, SMARTRF_SETTING_FIFO_CFG);
  writeSPI(FS_CFG, SMARTRF_SETTING_FS_CFG);
  writeSPI(PA_CFG2, SMARTRF_SETTING_PA_CFG2);
  writeSPI(PA_CFG0, SMARTRF_SETTING_PA_CFG0);
  writeSPI(PKT_CFG2, SMARTRF_SETTING_PKT_CFG2);
  writeSPI(PKT_LEN, SMARTRF_SETTING_PKT_LEN);

  // Burst address increment disable
  writeExtAddrSPI(EXT_CTRL, EXT_CTRL_SETTTING);
  // Custom frequency modulation enable
  writeExtAddrSPI(CFM_DATA_CFG, CFM_DATA_CFG_SETTING);
 
  writeExtAddrSPI(IF_MIX_CFG, SMARTRF_SETTING_IF_MIX_CFG);
  writeExtAddrSPI(FREQOFF_CFG, SMARTRF_SETTING_FREQOFF_CFG);
  writeExtAddrSPI(FREQ2, SMARTRF_SETTING_FREQ2);
  writeExtAddrSPI(FREQ1, SMARTRF_SETTING_FREQ1);
  writeExtAddrSPI(FREQ0, SMARTRF_SETTING_FREQ0);
  writeExtAddrSPI(FS_DIG1, SMARTRF_SETTING_FS_DIG1);
  writeExtAddrSPI(FS_DIG0, SMARTRF_SETTING_FS_DIG0);
  writeExtAddrSPI(FS_CAL1, SMARTRF_SETTING_FS_CAL1);
  writeExtAddrSPI(FS_CAL0, SMARTRF_SETTING_FS_CAL0);
  writeExtAddrSPI(FS_DIVTWO, SMARTRF_SETTING_FS_DIVTWO);
  writeExtAddrSPI(FS_DSM0, SMARTRF_SETTING_FS_DSM0);
  writeExtAddrSPI(FS_DVC0, SMARTRF_SETTING_FS_DVC0);
  writeExtAddrSPI(FS_PFD, SMARTRF_SETTING_FS_PFD);
  writeExtAddrSPI(FS_PRE, SMARTRF_SETTING_FS_PRE);
  writeExtAddrSPI(FS_REG_DIV_CML, SMARTRF_SETTING_FS_REG_DIV_CML);
  writeExtAddrSPI(FS_SPARE, SMARTRF_SETTING_FS_SPARE);
  writeExtAddrSPI(FS_VCO0, SMARTRF_SETTING_FS_VCO0);
  writeExtAddrSPI(XOSC5, SMARTRF_SETTING_XOSC5);
  writeExtAddrSPI(XOSC1, SMARTRF_SETTING_XOSC1);

#ifdef PRINT_INFO
  v = readExtAddrSPI(PARTVERSION);
  Serial.print(F("PARTVERSION "));
  Serial.println(v, HEX);
  v = readExtAddrSPI(PARTNUMBER);
  Serial.print(F("PARTNUMBER "));
  Serial.println(v, HEX);
#endif

  strobeSPI(SRX);
  delay(50);

#ifdef PRINT_INFO
  v = readExtAddrSPI(MARCSTATE);
  Serial.print(F("MARCSTATE "));
  Serial.println(v, BIN);
  Serial.flush();
#endif

  Serial.println(F(RX));
  digitalWrite(SS_PIN, LOW);
  SPI.transfer(R_BIT | BURST_BIT | EXT_ADDR);
  attachInterrupt(digitalPinToInterrupt(GDO3_PIN), isrRX, RISING);
}

void loop() {
  if (radio_state == 1) {
    Serial.println(F(RX_OK));
    radio_state = 2;
    detachInterrupt(digitalPinToInterrupt(GDO3_PIN));
    digitalWrite(SS_PIN, HIGH);
    strobeSPI(SIDLE);
    Serial.println(F(TX_WAIT));
    delay(4000);
    if (rx_arr_index > 0) {
      Serial.println(F(TX));
      writeSPI(IOCFG3, CFM_TX_DATA_CLK);
      writeExtAddrSPI(FREQ2, SMARTRF_SETTING_TX_FREQ2);
      writeExtAddrSPI(FREQ1, SMARTRF_SETTING_TX_FREQ1);
      writeExtAddrSPI(FREQ0, SMARTRF_SETTING_TX_FREQ0);
      strobeSPI(STX);
      delay(50);
      digitalWrite(SS_PIN, LOW);
      SPI.transfer(BURST_BIT | EXT_ADDR);
      SPI.transfer(CFM_TX_DATA_IN);
      radio_state = 3;
      attachInterrupt(digitalPinToInterrupt(GDO3_PIN), isrTX, RISING);
    }
  }
  else if (radio_state == 4) {
    detachInterrupt(digitalPinToInterrupt(GDO3_PIN));
    digitalWrite(SS_PIN, HIGH);
    strobeSPI(SIDLE);
    radio_state = 5;
    Serial.println(F(TX_OK));
  }
}

void isrRX() {
  if (radio_state == 0) {
    // Carrier sense
    if (bitRead(PIOC->PIO_PDSR, 25)) {
      SPI.transfer(CFM_RX_DATA_OUT);
      rx_arr[rx_arr_index] = SPI.transfer(0xff);
      if (rx_arr_index == RX_ARR_SIZE) {
        radio_state = 1;
      }
      else {
        rx_arr_index++;
      }
    }
  }
}

void isrTX() {
  static uint16_t i = 0;
  if (radio_state == 3) {
    if (i < rx_arr_index) {
      SPI.transfer(rx_arr[i]);
      i++;
    }
    else {
      radio_state = 4;
    }
  }
}

uint8_t readSPI(uint8_t addr) {
  digitalWrite(SS_PIN, LOW);
  SPI.transfer(R_BIT | addr);
  uint8_t v = SPI.transfer(0x00);
  digitalWrite(SS_PIN, HIGH);
  return v;
}

void writeSPI(uint8_t addr, uint8_t value) {
  digitalWrite(SS_PIN, LOW);
  SPI.transfer(addr);
  SPI.transfer(value);
  digitalWrite(SS_PIN, HIGH);
}

void strobeSPI(uint8_t cmd)
{
  digitalWrite(SS_PIN, LOW);
  SPI.transfer(R_BIT | cmd);
  digitalWrite(SS_PIN, HIGH);
}

uint8_t readExtAddrSPI(uint8_t addr) {
  uint8_t v;
  digitalWrite(SS_PIN, LOW);
  SPI.transfer(R_BIT | EXT_ADDR);
  SPI.transfer(addr);
  v = SPI.transfer(0xff);
  digitalWrite(SS_PIN, HIGH);
  return v;
}

void writeExtAddrSPI(uint8_t addr, uint8_t value) {
  digitalWrite(SS_PIN, LOW);
  SPI.transfer(EXT_ADDR);
  SPI.transfer(addr);
  SPI.transfer(value);
  digitalWrite(SS_PIN, HIGH);
}

#ifndef SMARTRF_CC1120_H
#define SMARTRF_CC1120_H

#define SMARTRF_RADIO_CC1120
#define SMARTRF_SETTING_SYNC_CFG1        0x0B
// 2.494812 kHz 0x47
// 2.380371 kHz 0x38
#define SMARTRF_SETTING_DEVIATION_M      0x47
#define SMARTRF_SETTING_MODCFG_DEV_E     0x02
#define SMARTRF_SETTING_DCFILT_CFG       0x1C
#define SMARTRF_SETTING_PREAMBLE_CFG1    0x18
#define SMARTRF_SETTING_IQIC             0xC6
// 0x14 = 10 kHz
// 0x10 = 12.5 kHz
#define SMARTRF_SETTING_CHAN_BW          0x10
#define SMARTRF_SETTING_MDMCFG0          0x0A
#define SMARTRF_SETTING_MDMCFG1          0x86
// 4.8 kbps 0x63 0xA9 0x2A
// 6   kbps 0x68 0x93 0x75
// 6.8 kbps 0x6B 0xDA 0x51
// 8   kbps 0x70 0x62 0x4E
// 1.2 kbps 0x43 0xA9 0x2A
#define SMARTRF_SETTING_SYMBOL_RATE2     0x63
#define SMARTRF_SETTING_SYMBOL_RATE1     0xA9
#define SMARTRF_SETTING_SYMBOL_RATE0     0x2A
#define SMARTRF_SETTING_AGC_REF          0x20
#define SMARTRF_SETTING_AGC_CS_THR       0x10
#define SMARTRF_SETTING_AGC_CFG1         0xA9
#define SMARTRF_SETTING_AGC_CFG0         0xCF
#define SMARTRF_SETTING_FIFO_CFG         0x00
#define SMARTRF_SETTING_FS_CFG           0x14
//#define SMARTRF_SETTING_PA_CFG2          0x29
#define SMARTRF_SETTING_PA_CFG2          0x28
#define SMARTRF_SETTING_PA_CFG0          0x7E
#define SMARTRF_SETTING_PKT_CFG2         0x07
#define SMARTRF_SETTING_PKT_LEN          0x21
#define SMARTRF_SETTING_IF_MIX_CFG       0x00
#define SMARTRF_SETTING_FREQOFF_CFG      0x22
// 446.06875 MHz CH6 0x6F 0x84 0x66
// 446.08125 MHz CH7 0x6F 0x85 0x33
// 446.09375 MHz CH8 0x6F 0x86 0x00
// 436.999634 MHz 0x6D 0x3F 0xFA
#define SMARTRF_SETTING_FREQ2            0x6F
#define SMARTRF_SETTING_FREQ1            0x84
#define SMARTRF_SETTING_FREQ0            0x66
// tx freq 436 MHz
#define SMARTRF_SETTING_TX_FREQ2         0x6D
#define SMARTRF_SETTING_TX_FREQ1         0x00
#define SMARTRF_SETTING_TX_FREQ0         0x00

#define SMARTRF_SETTING_FS_DIG1          0x00
#define SMARTRF_SETTING_FS_DIG0          0x5F
#define SMARTRF_SETTING_FS_CAL1          0x40
#define SMARTRF_SETTING_FS_CAL0          0x0E
#define SMARTRF_SETTING_FS_DIVTWO        0x03
#define SMARTRF_SETTING_FS_DSM0          0x33
#define SMARTRF_SETTING_FS_DVC0          0x17
#define SMARTRF_SETTING_FS_PFD           0x50
#define SMARTRF_SETTING_FS_PRE           0x6E
#define SMARTRF_SETTING_FS_REG_DIV_CML   0x14
#define SMARTRF_SETTING_FS_SPARE         0xAC
#define SMARTRF_SETTING_FS_VCO0          0xB4
#define SMARTRF_SETTING_XOSC5            0x0E
#define SMARTRF_SETTING_XOSC1            0x03

// Pins
#define GDO0_PIN              5
#define GDO3_PIN              6
#define RESET_PIN             7
#define SS_PIN                10

#define CARRIER_SENSE_VALID   16
#define CARRIER_SENSE         17
#define CLKEN_CFM             29
#define CFM_TX_DATA_CLK       30

#define EXT_CTRL_SETTTING     0x00
#define CFM_DATA_CFG_SETTING  0x01

#define R_BIT                 0x80
#define BURST_BIT             0x40

// CC1120 registers
#define IOCFG3          0x00
#define IOCFG2          0x01
#define IOCFG1          0x02
#define IOCFG0          0x03
#define SYNC3           0x04
#define SYNC2           0x05
#define SYNC1           0x06
#define SYNC0           0x07
#define SYNC_CFG1       0x08
#define SYNC_CFG0       0x09
#define DEVIATION_M     0x0A
#define MODCFG_DEV_E    0x0B
#define DCFILT_CFG      0x0C
#define PREAMBLE_CFG1   0x0D
#define PREAMBLE_CFG0   0x0E
#define FREQ_IF_CFG     0x0F
#define IQIC            0x10
#define CHAN_BW         0x11
#define MDMCFG1         0x12
#define MDMCFG0         0x13
#define SYMBOL_RATE2    0x02
#define SYMBOL_RATE1    0x9F
#define SYMBOL_RATE0    0x14
#define AGC_REF         0x17
#define AGC_CS_THR      0x18
#define AGC_GAIN_ADJUST 0x19
#define AGC_CFG3        0x1A
#define AGC_CFG2        0x1B
#define AGC_CFG1        0x1C
#define AGC_CFG0        0x1D
#define FIFO_CFG        0x1E
#define DEV_ADDR        0x1F
#define SETTLING_CFG    0x20
#define FS_CFG          0x21
#define WOR_CFG1        0x22
#define WOR_CFG0        0x23
#define WOR_EVENT0_MSB  0x24
#define WOR_EVENT0_LSB  0x25
#define PKT_CFG2        0x26
#define PKT_CFG1        0x27
#define PKT_CFG0        0x28
#define RFEND_CFG1      0x29
#define RFEND_CFG2      0x2A
#define PA_CFG2         0x2B
#define PA_CFG1         0x2C
#define PA_CFG0         0x2D
#define PKT_LEN         0x2E
#define EXT_ADDR        0x2F
#define FIFO            0x3F

// Extended register space
#define IF_MIX_CFG        0x00
#define FREQOFF_CFG       0x01
#define CFM_DATA_CFG      0x05
#define EXT_CTRL          0x06
#define FREQ2             0x0C
#define FREQ1             0x0D
#define FREQ0             0x0E
#define FS_DIG1           0x12
#define FS_DIG0           0x13
#define FS_CAL1           0x16
#define FS_CAL0           0x17
#define FS_DIVTWO         0x19
#define FS_DSM0           0x1B
#define FS_DVC0           0x1D
#define FS_PFD            0x1F
#define FS_PRE            0x20
#define FS_REG_DIV_CML    0x21
#define FS_SPARE          0x22
#define FS_VCO0           0x27
#define XOSC5             0x32
#define XOSC1             0x36
#define RSSI1             0x71
#define RSSI0             0x72
#define MARCSTATE         0x73
#define CFM_RX_DATA_OUT   0x7D
#define CFM_TX_DATA_IN    0x7E
#define PARTNUMBER        0x8F
#define PARTVERSION       0x90
#define SERIAL_STATUS     0x91
#define MODEM_STATUS1     0x92
#define MODEM_STATUS0     0x93
#define MARC_STATUS1      0x94
#define MARC_STATUS0      0x95
#define NUM_RXBYTES       0xD7
#define FIFO_NUM_RXBYTES  0xD9

// CC1120 command strobes
#define SRES            0x30
#define SFSTXON         0x31
#define SXOFF           0x32
#define SCAL            0x33
#define SRX             0x34
#define STX             0x35
#define SIDLE           0x36
#define SAFC            0x37
#define SWOR            0x38
#define SPWD            0x39
#define SFRX            0x3A
#define SFTX            0x3B
#define SWORRST         0x3C
#define SNOP            0x3D

#endif // CC1120_H

offtopic:
Quite interesting, it seems that in Wirwe network (visitor) ASSI numbers are not random, same numbers are assigned to different SSI numbers (not at the same time on same LAC* ?)

* update 2021-06-29 also seen on the same LAC