CC1120 + MikroElektronika ccRF3 click board
Arduino Due
I/Q data after channel filter is 19-bit, datasheet does not state if it is in 2's complement format. Assuming format is 2's complement.
Changed transparent serial mode to synchronous serial mode, more convenient serial print for further processing in Python and fixed decimal conversion bug in Arduino code.
Python code (Due connected to COM4). Assuming CC1120 channel filter I/Q data sample rate is 4x channel filter bandwidth (12500 Hz x 4)
import serial
import numpy as np
import matplotlib.pyplot as plt
count = 0
sd = []
with serial.Serial('COM4', 115200, timeout=1) as ser:
print(ser.name)
line = ser.readline().decode('utf-8').replace("\r\n", "")
while line != "EOF":
if line != "":
sd.append(line)
count = count + 1
line = ser.readline().decode('utf-8').replace("\r\n", "")
ser.close()
tmp = np.array(sd, dtype=float)
iq = np.divide(tmp, 262144)
plt.psd(iq, NFFT=1024, Fs=50000/1e6, Fc=0)
#samples = np.fft.fft(iq)
#l = np.arange(count)
#S_mag = np.abs(samples)
#S_phase = np.angle(samples)
#plt.plot(l, S_phase, '.-')
plt.show()
#include <SPI.h>
#include "cc1120.h"
#define PRINT_INFO
#undef PRINT_INFO
#define BURST R_BIT | BURST_BIT | EXT_ADDR
#define IQ_SIZE 61440
uint8_t iq_data[IQ_SIZE];
uint16_t idx = 0;
bool printData = true;
void setup() {
Serial.begin(115200);
pinMode(RESET_PIN, OUTPUT);
pinMode(SS_PIN, OUTPUT);
pinMode(GDO3_PIN, INPUT); // carrier sense GDO3
digitalWrite(SS_PIN, HIGH);
digitalWrite(RESET_PIN, HIGH);
SPI.begin();
strobeSPI(SNOP);
// Sync off
uint8_t v = readSPI(SYNC_CFG0);
v &= B11100011;
writeSPI(SYNC_CFG0, v);
writeSPI(IOCFG3, CARRIER_SENSE);
writeSPI(SYNC_CFG1, SMARTRF_SETTING_SYNC_CFG1);
writeSPI(MODCFG_DEV_E, SMARTRF_SETTING_MODCFG_DEV_E);
writeSPI(DEVIATION_M, SMARTRF_SETTING_DEVIATION_M);
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(MDMCFG1, SMARTRF_SETTING_MDMCFG1);
writeSPI(MDMCFG0, SMARTRF_SETTING_MDMCFG0);
writeSPI(AGC_REF, SMARTRF_SETTING_AGC_REF);
// -102 dBm + 0x10 = -86 dBm carrier sense rssi threshold
writeSPI(AGC_CS_THR, SMARTRF_SETTING_AGC_CS_THR);
writeSPI(AGC_CFG1, SMARTRF_SETTING_AGC_CFG1);
writeSPI(AGC_CFG0, SMARTRF_SETTING_AGC_CFG0);
writeSPI(FS_CFG, SMARTRF_SETTING_FS_CFG);
writeSPI(PKT_CFG2, SMARTRF_SETTING_PKT_CFG2);
writeSPI(PKT_CFG1, SMARTRF_SETTING_PKT_CFG1);
writeSPI(PKT_CFG0, SMARTRF_SETTING_PKT_CFG0);
writeSPI(PA_CFG2, SMARTRF_SETTING_PA_CFG2);
writeSPI(PA_CFG0, SMARTRF_SETTING_PA_CFG0);
// Burst address increment disable
//writeExtAddrSPI(EXT_CTRL, EXT_CTRL_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);
writeExtAddrSPI(SERIAL_STATUS, SMARTRF_SETTING_SERIAL_STATUS);
#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(80);
#ifdef PRINT_INFO
v = readExtAddrSPI(MARCSTATE);
Serial.print(F("MARCSTATE "));
Serial.println(v, BIN);
#endif
}
void loop() {
// DUE direct port access
uint32_t r = PIOC->PIO_PDSR;
if (bitRead(r, 24)) {
//digitalWrite(SS_PIN, LOW);
PIOC->PIO_CODR = 1 << 29;
SPI.transfer(BURST);
SPI.transfer(CHFILT_I2);
iq_data[idx++] = SPI.transfer(0xff);
iq_data[idx++] = SPI.transfer(0xff);
iq_data[idx++] = SPI.transfer(0xff);
iq_data[idx++] = SPI.transfer(0xff);
iq_data[idx++] = SPI.transfer(0xff);
iq_data[idx++] = SPI.transfer(0xff);
//digitalWrite(SS_PIN, HIGH);
PIOC->PIO_SODR = 1 << 29;
if (idx >= IQ_SIZE) {
if (printData) {
printData = false;
uint16_t r = 0;
while (r <= IQ_SIZE) {
iq_data[r] &= 0x07;
iq_data[r + 3] &= 0x07;
int32_t i = ((int32_t) iq_data[r] << 16) | (iq_data[r + 1] << 8) | iq_data[r + 2];
int32_t q = ((int32_t) iq_data[r + 3] << 16) | (iq_data[r + 4] << 8) | iq_data[r + 5];
if (bitRead(i, 18)) {
i = ~i;
i &= 0x7FFFFul;
i += 1;
i = -i;
}
if (bitRead(q, 18)) {
q = ~q;
q &= 0x7FFFFul;
q += 1;
q = -q;
}
r += 6;
Serial.println(i);
Serial.println(q);
}
Serial.println(F("EOF"));
}
idx = 0;
}
}
}
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);
}
/* Address Config = No address check */
/* Carrier Frequency = 420.0125 MHz */
/* Device Address = 0 */
/* Manchester Enable = false */
/* Modulation Format = 4-FSK */
/* PA Ramping = false */
/* Performance Mode = High Performance */
/* RX Filter BW = 12.5 kHz */
/* Whitening = false */
#ifndef SMARTRF_CC1120_H
#define SMARTRF_CC1120_H
#define SMARTRF_RADIO_CC1120
#define SMARTRF_SETTING_IOCFG3 0xB0
#define SMARTRF_SETTING_IOCFG2 0x06
#define SMARTRF_SETTING_IOCFG1 0xB0
#define SMARTRF_SETTING_IOCFG0 0x40
#define SMARTRF_SETTING_SYNC_CFG1 0x1F
#define SMARTRF_SETTING_MODCFG_DEV_E 0x23
#define SMARTRF_SETTING_DEVIATION_M 0x06
#define SMARTRF_SETTING_DCFILT_CFG 0x1C
#define SMARTRF_SETTING_PREAMBLE_CFG1 0x00
#define SMARTRF_SETTING_IQIC 0xC6
#define SMARTRF_SETTING_CHAN_BW 0x10
#define SMARTRF_SETTING_MDMCFG1 0x06
#define SMARTRF_SETTING_MDMCFG0 0x0A
#define SMARTRF_SETTING_SYMBOL_RATE2 0x11
#define SMARTRF_SETTING_SYMBOL_RATE1 0x9D
#define SMARTRF_SETTING_SYMBOL_RATE0 0xB7
#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_PKT_CFG2 0x05
#define SMARTRF_SETTING_PKT_CFG1 0x00
#define SMARTRF_SETTING_PKT_CFG0 0x20
#define SMARTRF_SETTING_PA_CFG2 0x29
#define SMARTRF_SETTING_PA_CFG0 0x7E
#define SMARTRF_SETTING_PKT_LEN 0x21
#define SMARTRF_SETTING_IF_MIX_CFG 0x00
#define SMARTRF_SETTING_FREQOFF_CFG 0x22
#define SMARTRF_SETTING_FREQ2 0x69
#define SMARTRF_SETTING_FREQ1 0x00
#define SMARTRF_SETTING_FREQ0 0xCD
#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
#define SMARTRF_SETTING_SERIAL_STATUS 0x08
// Pins
#define RESET_PIN 7
#define SS_PIN 10
#define GDO3_PIN 6
#define R_BIT 0x80
#define BURST_BIT 0x40
#define CARRIER_SENSE_VALID 0x10
#define CARRIER_SENSE 0x11
#define EXT_CTRL_SETTING 0x00
// 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 0x14
#define SYMBOL_RATE1 0x15
#define SYMBOL_RATE0 0x16
#define AGC_REF 0x17
#define AGC_CS_THR 0x10
#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 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 ASK_SOFT_RX_DATA 0x7F
#define MAGN2 0x81
#define MAGN1 0x82
#define MAGN0 0x83
#define ANG0 0x85
#define ANG1 0x84
#define CHFILT_I2 0x86
#define CHFILT_I1 0x87
#define CHFILT_I0 0x88
#define CHFILT_Q2 0x89
#define CHFILT_Q1 0x8A
#define CHFILT_Q0 0x8B
#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
Kommentit
Tämän blogin kommentit tarkistetaan ennen julkaisua.