TI Launchpad with MSP430G2553 @ 1 MHz and AIR Booster Pack with Anaren LR09A (CC110L [the light version of CC1101] with 27 MHz xtal and 900 MHz PCB antenna).
The following code is supposed to send a single byte with OOK at 868 MHz.
After choosing the correct XTAL frequency and removing "hidden" settings CRC_EN and APPEND_STATUS from the output of SMARTRF Studio 7 (note it also outputs invalid value 0x127 for RESERVED @ 0x2A -> see the datasheet, the default 0x7F is erroneously output as decimal), the byte is being sent, but if the last bit is set, an additional bit is added to that it has twice the intended bit time.
See the attached resulting waveform for 0xB1 (0b10110001), recorded as AF with rtl-sdr / SDR# and shown in Audacity.
Are there any settings that could cause this? Am I doing anything wrong? The Errata only mention sending a byte twice.
#include <msp430.h>
#include "stdint.h"
#include "stdbool.h"
// Anaren AIR booster pack with LR09A (868/9xx MHz)
// CC110L
#define GDO2_BIT BIT0 // P1
#define SCLK_BIT BIT5 // P1
#define MISO_BIT BIT6 // P1
#define MOSI_BIT BIT7 // P1
#define GDO0_BIT BIT6 // P2
#define CSN_BIT BIT7 // P2
// 2553
//#define LEDrd_BIT BIT0 // P1
#define RX_BIT BIT1 // P1
#define TX_BIT BIT2 // P1
#define button_BIT BIT3 // P1
//#define LEDgn_BIT BIT6 // P1
uint8_t status;
uint8_t test;
uint8_t
softSPI(
uint8_t write
)
{
uint8_t read = 0;
P1OUT &= ~(SCLK_BIT);
uint8_t n;
for(n=8; n--;){
// OUT
if (write & 1<<n){
P1OUT |= MOSI_BIT;
}
else{
P1OUT &= ~(MOSI_BIT);
}
// CLOCK
P1OUT |= SCLK_BIT;
// IN
if (P1IN & MISO_BIT){
read |= 1<<n;
}
P1OUT &= ~(SCLK_BIT);
}
return read;
}
uint8_t
CC(
bool rw,
bool burst,
uint8_t address,
uint8_t data
)
{
uint8_t header =
(rw<<7) //
|(burst<<6) //
|(address & 0x3F) // 0x00 to 0x2E.
;
P2OUT &= ~(CSN_BIT);
while(P1IN & MISO_BIT);
/*uint8_t*/ status = softSPI(header);
uint8_t read = softSPI(data);
P2OUT |= CSN_BIT;
return read;
}
uint8_t CS(
bool rw,
uint8_t address
)
{
uint8_t header =
(rw<<7) //
//|(0<<6) //
|(address & 0x3D) // 0x30 through 0x3D).
;
P2OUT &= ~(CSN_BIT);
while(P1IN & MISO_BIT);
uint8_t status = softSPI(header);
P2OUT |= CSN_BIT;
return status;
}
int main(void) {
// Stop watchdog timer
WDTCTL = WDTPW | WDTHOLD;
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
// serial
P1DIR = TX_BIT;
P2DIR = 0;
// CC110x soft-SPI
P1DIR |= (MOSI_BIT | SCLK_BIT);
P2OUT |= CSN_BIT;
P2DIR |= (CSN_BIT);
P2SEL &= ~(CSN_BIT);
P2SEL2 &= ~(CSN_BIT);
// Manual Reset
// Set SCLK = 1 and SI = 0.
P1OUT |= (SCLK_BIT);
P1OUT &= ~(MOSI_BIT);
// Strobe CSn low / high.
//P2OUT &= ~(CSN_BIT);
//P2OUT |= CSN_BIT;
// Hold CSn low and then high for at least 40 µs relative to pulling CSn low
P2OUT &= ~(CSN_BIT);
P2OUT |= CSN_BIT;
uint8_t n;
for(n=10; n; n--);
// Pull CSn low and wait for SO to go low ( CHIP_RDYn).
P2OUT &= ~(CSN_BIT);
while(P1IN & MISO_BIT);
// Issue the SRES strobe on the SI line.
CS(0, 0x30); // Reset
CS(0, 0x30); // Reset
CS(0, 0x30); // Reset
// When SO goes low again, reset is complete and the chip is in the IDLE state.
CS(0, 0x3D); // NOP, TX FIFO free
CS(1, 0x3D); // NOP, RX FIFO bytes
CC(true, true, 0x30, 0); // chip
CC(true, true, 0x31, 0); // version
CS(1, 0x3A); // flush RX FIFO
CS(1, 0x3B); // flush TX FIFO
//PATABLE
P2OUT &= ~(CSN_BIT);
while(P1IN & MISO_BIT);
softSPI( (0<<7)|(1<<6)|0x3E );
softSPI(0x00);
softSPI(0x50);
P2OUT |= CSN_BIT;
P2OUT &= ~(CSN_BIT);
while(P1IN & MISO_BIT);
softSPI( (1<<7)|(1<<6)|0x3E );
softSPI( (1<<7)|0x00);
softSPI( (1<<7)|0x00);
P2OUT |= CSN_BIT;
// Rf settings for CC110L
CC(false, false, 0x0000, 0x29); // IOCFG2 GDO2 Output Pin Configuration
CC(false, false, 0x0001, 0x2E); // IOCFG1 GDO1 Output Pin Configuration
CC(false, false, 0x0002, 0x06); // IOCFG0 GDO0 Output Pin Configuration
CC(false, false, 0x0003, 0x47); // FIFOTHR RX FIFO and TX FIFO Thresholds
CC(false, false, 0x0004, 0xD3); // SYNC1 Sync Word, High Byte
CC(false, false, 0x0005, 0x91); // SYNC0 Sync Word, Low Byte
CC(false, false, 0x0006, 0x01); // PKTLEN Packet Length
CC(false, false, 0x0007, 0x00); // PKTCTRL1 Packet Automation Control
CC(false, false, 0x0008, 0x00); // PKTCTRL0 Packet Automation Control
CC(false, false, 0x0009, 0x00); // ADDR Device Address
CC(false, false, 0x000A, 0x00); // CHANNR Channel number
CC(false, false, 0x000B, 0x06); // FSCTRL1 Frequency Synthesizer Control
CC(false, false, 0x000C, 0x00); // FSCTRL0 Frequency Synthesizer Control
CC(false, false, 0x000D, 0x20); // FREQ2 Frequency Control Word, High Byte
CC(false, false, 0x000E, 0x28); // FREQ1 Frequency Control Word, Middle Byte
CC(false, false, 0x000F, 0xC5); // FREQ0 Frequency Control Word, Low Byte
CC(false, false, 0x0010, 0xF6); // MDMCFG4 Modem Configuration
CC(false, false, 0x0011, 0x84); // MDMCFG3 Modem Configuration
CC(false, false, 0x0012, 0x30); // MDMCFG2 Modem Configuration
CC(false, false, 0x0013, 0x22); // MDMCFG1 Modem Configuration
CC(false, false, 0x0014, 0xE5); // MDMCFG0 Modem Configuration
CC(false, false, 0x0015, 0x14); // DEVIATN Modem Deviation Setting
CC(false, false, 0x0016, 0x07); // MCSM2 Main Radio Control State Machine Configuration
CC(false, false, 0x0017, 0x30); // MCSM1 Main Radio Control State Machine Configuration
CC(false, false, 0x0018, 0x18); // MCSM0 Main Radio Control State Machine Configuration
CC(false, false, 0x0019, 0x16); // FOCCFG Frequency Offset Compensation Configuration
CC(false, false, 0x001A, 0x6C); // BSCFG Bit Synchronization Configuration
CC(false, false, 0x001B, 0x03); // AGCCTRL2 AGC Control
CC(false, false, 0x001C, 0x40); // AGCCTRL1 AGC Control
CC(false, false, 0x001D, 0x91); // AGCCTRL0 AGC Control
CC(false, false, 0x0020, 0xFB); // RESERVED_0X20 Use setting from SmartRF Studio
CC(false, false, 0x0021, 0x56); // FREND1 Front End RX Configuration
CC(false, false, 0x0022, 0x11); // FREND0 Front End TX Configuration
CC(false, false, 0x0023, 0xE9); // FSCAL3 Frequency Synthesizer Calibration
CC(false, false, 0x0024, 0x2A); // FSCAL2 Frequency Synthesizer Calibration
CC(false, false, 0x0025, 0x00); // FSCAL1 Frequency Synthesizer Calibration
CC(false, false, 0x0026, 0x1F); // FSCAL0 Frequency Synthesizer Calibration
CC(false, false, 0x0029, 0x89); // RESERVED_0X29 Use setting from SmartRF Studio
CC(false, false, 0x002A, 0x127); // RESERVED_0X2A Use setting from SmartRF Studio
CC(false, false, 0x002B, 0x63); // RESERVED_0X2B Use setting from SmartRF Studio
CC(false, false, 0x002C, 0x81); // TEST2 Various Test Settings
CC(false, false, 0x002D, 0x35); // TEST1 Various Test Settings
CC(false, false, 0x002E, 0x09); // TEST0 Various Test Settings
test = CC(false, false, 0x3F, 0xB1);
CS(0, 0x35); // TX strobe
for(;;)
CS(0, 0x3D); // NOP, TX FIFO free
LPM0;
for(;;);
}