Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- captaingoujon
- Date:
- 2015-08-18
- Branch:
- dev-RFM69
- Revision:
- 11:8f3e72f6a1e0
- Parent:
- 10:6fe476ec05aa
File content as of revision 11:8f3e72f6a1e0:
#include "mbed.h"
#define FSTEP 61
#define FXOSC 32000000
enum Registers{
REG_FIFO = 0x00,
REG_OP_MODE = 0x01,
REG_DATA_MODULATION = 0x02,
REG_BITRATE_MSB = 0x03,
REG_BITRATE_LSB = 0x04,
REG_FDEV_MSB = 0x05,
REG_FDEV_LSB = 0x06,
REG_FREQ_MSB = 0x07,
REG_FREQ_MID = 0x08,
REG_FREQ_LSB = 0x09,
REG_OSC1 = 0x0A,
REG_AFC_CTRL = 0x0B,
REG_LISTEN_1 = 0x0D,
REG_LISTEN_2 = 0x0E,
REG_LISTEN_3 = 0x0F,
REG_VERSION = 0x10,
REG_PA_LEVEL = 0x11,
REG_PA_RAMP = 0x12,
REG_OCP = 0x13,
REG_LNA = 0x18,
REG_RX_BW = 0x19,
REG_AFC_BW = 0x1A,
REG_OOK_PEAK = 0x1B,
REG_OOK_AVG = 0x1C,
REG_OOK_FIX = 0x1D,
REG_AFC_FEI = 0x1E,
REG_AFC_MSB = 0x1F,
REG_AFC_LSB = 0x20,
REG_FEI_MSB = 0x21,
REG_FEI_LSB = 0x22,
REG_RSSI_CONFIG = 0x23,
REG_RSSI_VALUE = 0x24,
REG_DIO_MAPPING_1 = 0x25,
REG_DIO_MAPPING_2 = 0x26,
REG_IRQ_FLAGS_1 = 0x27,
REG_IRQ_FLAGS_2 = 0x28,
REG_RSSI_THRESH = 0x29,
REG_RX_TIMEOUT_1 = 0x2A,
REG_RX_TIMEOUT_2 =0x2B,
REG_PREAMBLE_MSB = 0x2C,
REG_PREAMBLE_LSB = 0x2D,
REG_SYNC_CONFIG = 0x2E,
REG_SYNC_VALUE_1 = 0x2F,
REG_SYNC_VALUE_2 = 0x30,
REG_SYNC_VALUE_3 = 0x31,
REG_SYNC_VALUE_4 = 0x32,
REG_SYNC_VALUE_5 = 0x33,
REG_SYNC_VALUE_6 = 0x34,
REG_SYNC_VALUE_7 = 0x35,
REG_SYNC_VALUE_8 = 0x36,
REG_PACKET_CONFIG_1 = 0x37,
REG_PAYLOAD_LENGTH = 0x38,
REG_NODE_ADRS = 0x39,
REG_BROADCAST_ADRS = 0x3A,
REG_AUTO_MODES = 0x3B,
REG_FIFO_THRESH = 0x3C,
REG_PACKET_CONFIG_2 = 0x3D,
REG_AES_KEY_1 = 0x3E,
REG_AES_KEY_2 = 0x3F,
REG_AES_KEY_3 = 0x40,
REG_AES_KEY_4 = 0x41,
REG_AES_KEY_5 = 0x42,
REG_AES_KEY_6 = 0x43,
REG_AES_KEY_7 = 0x44,
REG_AES_KEY_8 = 0x45,
REG_AES_KEY_9 = 0x46,
REG_AES_KEY_10 = 0x47,
REG_AES_KEY_11 = 0x48,
REG_AES_KEY_12 = 0x49,
REG_AES_KEY_13 = 0x4A,
REG_AES_KEY_14 = 0x4B,
REG_AES_KEY_15 = 0x4C,
REG_AES_KEY_16 = 0x4D,
REG_TEMP_1 = 0x4E,
REG_TEMP_2 = 0x4F
};
enum DataMode{
MODE_PACKET = 0x00,
MODE_CONTINUOUS_SYNC = 0x02,
MODE_CONTINUOUS_NOSYNC = 0x03
};
enum Modulation{
MODULATION_FSK = 0x00,
MODULATION_OOK = 0x01
};
enum Shaping{
SHAPING_NONE = 0x00,
SHAPING_GAUSSIAN_FULL = 0x01,
SHAPING_GAUSSIAN_HALF = 0x02,
SHAPING_GAUSSIAN_THIRD = 0x03
};
enum OperatingMode{
MODE_SLEEP = 0x00,
MODE_STDBY = 0x01,
MODE_FS = 0x02,
MODE_TX = 0x03,
MODE_RX = 0x04
};
struct ModulationSetting{
char mode;
char modulation;
char shaping;
};
struct ocpSetting{
bool enabled;
char maxCurrent;
};
struct lnaSetting{
char ZIn;
bool agc;
char gain;
};
struct syncSetting{
bool syncOn;
bool fifoFillCondition;
char syncSize;
char syncTol;
};
struct packetSetting{
bool variableLength;
char dcFree;
bool crcOn;
bool crcAutoClearOff;
char addressFiltering;
char interPacketRxDelay;
bool restartRx;
bool autoRxRestartOn;
bool aesOn;
};
struct fifoThresholdSetting{
char txStartCondition;
char threshold;
};
SPI radio(PB_15, PB_14, PB_13);
DigitalOut radioCS(PB_12,1);
DigitalOut led(LED1);
Serial pc(USBTX,USBRX);
InterruptIn dio2(PA_8);
DigitalIn fifoNE(PA_8);
int getVersion(){
int version;
radioCS = 0;
radio.write(REG_VERSION);
version = radio.write(0x00);
radioCS = 1;
return version;
}
void setFreq(int freq){
freq /= FSTEP;
radioCS = 0;
radio.write(REG_FREQ_MSB | 0x80);
radio.write((freq>>16)&0xFF);
radio.write((freq>>8)&0xFF);
radio.write((freq)&0xFF);
radioCS=1;
}
int getFreq(){
int freq;
radioCS = 0;
radio.write(REG_FREQ_MSB);
freq = radio.write(0x00)<<16;
freq|= radio.write(0x00)<<8;
freq|= radio.write(0x00);
radioCS = 1;
return freq*FSTEP;
}
char getMode(){
char mode;
radioCS = 0;
radio.write(REG_OP_MODE);
mode = radio.write(0x00);
radioCS = 1;
return mode;
}
int getFlags(){
int flags;
radioCS = 0;
radio.write(REG_IRQ_FLAGS_1);
flags = radio.write(0x00)<<8;
radioCS = 1;
wait_ms(1);
radioCS = 0;
radio.write(REG_IRQ_FLAGS_2);
flags |= radio.write(0x00);
radioCS = 1;
return flags;
}
void setMode(char mode){
char localMode = getMode();
radioCS = 0;
radio.write(REG_OP_MODE|0x80);
radio.write((localMode&0xE3) | (mode<<2));
radioCS = 1;
if(mode!=0x00){
while(true){
if(mode == MODE_RX && getFlags()&0x8000){
break;
}
if(mode == MODE_TX && getFlags()&0x2000){
break;
}
pc.printf("Target:%02x,Current:%02x,FLags:%04x\n\r",mode,getMode(),getFlags());
wait_ms(1000);
}
}else{
pc.printf("%02x,%02x,%04x\n\r",mode,getMode(),getFlags());
}
}
void setFdev(int fdev){
fdev /= FSTEP;
radioCS = 0;
radio.write(REG_FDEV_MSB | 0x80);
radio.write((fdev >> 8) & 0x1F);
radio.write(fdev & 0xFF);
radioCS = 1;
}
int getFdev(){
int fdev;
radioCS = 0;
radio.write(REG_FDEV_MSB);
fdev = radio.write(0x00)<<8;
fdev |= radio.write(fdev)&0xFF;
radioCS = 1;
fdev *= FSTEP;
return fdev;
}
void setModulation(ModulationSetting settings){
radioCS = 0;
radio.write(REG_DATA_MODULATION | 0x80);
radio.write((settings.mode << 5)&0x60 | ((settings.modulation <<3)&0x18) | (settings.shaping&0x03));
radioCS = 1;
}
ModulationSetting getModulation(){
ModulationSetting settings;
char reg;
radioCS = 0;
radio.write(REG_DATA_MODULATION);
reg= radio.write(0x00)&0xFF;
radioCS = 1;
settings.mode = (reg&0x60) >> 5;
settings.modulation = (reg&0x18) >>3;
settings.shaping = (reg&0x03);
return settings;
}
void setBitrate(int bitrate){
bitrate /= FXOSC;
radioCS = 1;
radio.write(REG_BITRATE_MSB | 0x80);
radio.write((bitrate>>8)&0xFF);
radio.write(bitrate&0xFF);
radioCS = 1;
}
int getBitrate(){
int bitrate;
radioCS = 1;
radio.write(REG_BITRATE_MSB);
bitrate = radio.write(0x00)<<8;
bitrate |= radio.write(0x00)&0xFF;
radioCS = 1;
bitrate *= FXOSC;
return bitrate;
}
void setPALevel(int level){
char regPALevel;
if(level <= -2){//PA0
regPALevel = 0x80;
regPALevel |= (level + 18)&0xFF;
}else if(level <= 13){//PA1
regPALevel = 0x40;
regPALevel |= (level + 18)&0x1F;
}else if(level<=17){//PA1,PA2
regPALevel = 0xA0;
regPALevel |= (level + 14)&0xFF;
}else{
return;
}
radioCS = 0;
radio.write(REG_PA_LEVEL | 0x80);
radio.write(regPALevel);
radioCS = 1;
}
int getPALevel(){
//int level = 0;
char regPALevel;
radioCS = 0;
radio.write(REG_PA_LEVEL);
regPALevel = radio.write(0x00);
radioCS = 1;
/*if((regPALevel&0x80) || (regPALevel&0x40)){//PA1,PA2
regPALevel = 0xA0;
regPALevel |= (level + 14)&0xFF;
}else if(regPALevel&0x80){//PA0
level |= (regPALevel&0x1F - 18);
}else if(regPALevel&0x40){//PA1
regPALevel = 0x40;
regPALevel |= (level&0x1F - 18);
}else{
return 0;
}*/
return regPALevel;
}
void setOCP(ocpSetting ocp){
char regOCP = 0;
if(ocp.enabled){
regOCP = 0x10;
}
regOCP |= ((ocp.maxCurrent - 45)/5) & 0x0F;
radioCS = 0;
radio.write(REG_OCP | 0x80);
radio.write(regOCP);
radioCS = 1;
}
ocpSetting getOCP(){
char reg;
ocpSetting ocp;
radioCS = 0;
radio.write(REG_OCP);
reg = radio.write(0x00);
radioCS = 1;
ocp.enabled = reg>>4;
ocp.maxCurrent = (reg & 0x0F)*5+45;
return ocp;
}
void setLNA(lnaSetting lna){
char regLNA = 0;
if(lna.ZIn == 200){
regLNA = 0x80;
}
if(!lna.agc){
if(lna.gain>48){
regLNA |= 0x00;
}else{
regLNA |= (lna.gain&0x07);
}
}
radioCS = 0;
radio.write(REG_LNA | 0x80);
radio.write(regLNA);
radioCS = 1;
}
lnaSetting getLNA(){
char reg;
lnaSetting lna;
radioCS = 0;
radio.write(REG_LNA);
reg = radio.write(0x00);
radioCS = 1;
if(reg&0x80){
lna.ZIn = 200;
}else{
lna.ZIn = 50;
}
if(reg&0x07==0){
lna.agc = 1;
}else{
lna.agc = 0;
}
lna.gain = (reg&0x1A)>>3;
return lna;
}
void setDIOMapping(int regValue){
radioCS = 0;
radio.write(REG_DIO_MAPPING_1|0x80);
radio.write((regValue>>8)&0xFF);
radio.write(regValue&0xFF);
radioCS = 1;
}
int getDIOMapping(){
int regValue;
radioCS = 0;
radio.write(REG_DIO_MAPPING_1);
regValue = radio.write(0x00)<<8;
regValue |= radio.write(0x00)&0xFF;
radioCS = 1;
return regValue;
}
void setSyncConfig(syncSetting sync){
char regSync = 0;
if(sync.syncOn){
regSync |= 0x80;
}
if(sync.fifoFillCondition){
regSync |= 0x40;
}
regSync |= ((sync.syncSize&0x07)<<3);
regSync |= (sync.syncTol&0x07);
radioCS = 0;
radio.write(REG_SYNC_CONFIG);
radio.write(regSync);
radioCS = 1;
}
syncSetting getSyncConfig(){
char reg;
syncSetting sync;
radioCS = 0;
radio.write(REG_SYNC_CONFIG);
reg = radio.write(0x00);
radioCS = 1;
if(reg &= 0x80){
sync.syncOn = 1;
}else{
sync.syncOn = 0;
}
if(reg&0x40){
sync.fifoFillCondition = 1;
}else{
sync.fifoFillCondition = 0;
}
sync.syncSize = (reg&0x1A)>>3;
sync.syncTol = (reg&0x07);
return sync;
}
void setSyncValue(unsigned long long value){
radioCS = 0;
radio.write(REG_SYNC_VALUE_1 | 0x80);
radio.write((value>>56)&0xFF);
radio.write((value>>48)&0xFF);
radio.write((value>>40)&0xFF);
radio.write((value>>32)&0xFF);
radio.write((value>>24)&0xFF);
radio.write((value>>16)&0xFF);
radio.write((value>>8)&0xFF);
radio.write((value)&0xFF);
radioCS = 1;
}
unsigned long long getSyncValue(){
unsigned long long value;
radioCS = 0;
radio.write(REG_SYNC_VALUE_1);
value = (radio.write(0x00)&0xFF)<<55;
value |= (radio.write(0x00)&0xFF)<<47;
value |= (radio.write(0x00)&0xFF)<<39;
value |= (radio.write(0x00)&0xFF)<<31;
value |= (radio.write(0x00)&0xFF)<<23;
value |= (radio.write(0x00)&0xFF)<<15;
value |= (radio.write(0x00)&0xFF)<<7;
value |= (radio.write(0x00)&0xFF);
radioCS = 1;
return value;
}
void setPacketConfig(packetSetting packetConfig){
char regPacketConfig1 = 0x00;
char regPacketConfig2 = 0x00;
if(packetConfig.variableLength){
regPacketConfig1 |= 0x80;
}
regPacketConfig1 |= (packetConfig.dcFree&0x03)<<5;
if(packetConfig.crcOn){
regPacketConfig1 |= 0x10;
}
if(packetConfig.crcAutoClearOff){
regPacketConfig1 |= 0x08;
}
regPacketConfig1 |= ((packetConfig.addressFiltering & 0x03)<<1);
radioCS = 0;
radio.write(REG_PACKET_CONFIG_1|0x80);
radio.write(regPacketConfig1);
radioCS = 1;
regPacketConfig2 |= ((packetConfig.interPacketRxDelay&0x0F)<<4);
if(packetConfig.restartRx){
regPacketConfig2 |= (1<<2);
}
if(packetConfig.autoRxRestartOn){
regPacketConfig2 |= (1<<1);
}
if(packetConfig.aesOn){
regPacketConfig2 |= 0x01;
}
radioCS = 0;
radio.write(REG_PACKET_CONFIG_2|0x80);
radio.write(regPacketConfig2);
radioCS = 1;
}
packetSetting getPacketConfig(){
packetSetting packetConfig;
char regPacketConfig1;
char regPacketConfig2;
radioCS = 0;
radio.write(REG_PACKET_CONFIG_1);
regPacketConfig1 = radio.write(0x00);
radioCS = 1;
radioCS = 0;
radio.write(REG_PACKET_CONFIG_2);
regPacketConfig2 = radio.write(0x00);
radioCS = 1;
if(regPacketConfig1 & 0x80){
packetConfig.variableLength = 1;
}else{
packetConfig.variableLength = 0;
}
packetConfig.dcFree = (regPacketConfig1&0x60)>>5;
if(regPacketConfig1 & 0x10){
packetConfig.crcOn = 1;
}else{
packetConfig.crcOn = 0;
}
if(regPacketConfig1 & 0x08){
packetConfig.crcAutoClearOff = 1;
}else{
packetConfig.crcAutoClearOff = 1;
}
packetConfig.addressFiltering = (regPacketConfig1&0x06)>>1;
packetConfig.interPacketRxDelay = (regPacketConfig2&0xF0)>>4;
if(regPacketConfig2 & 0x04){
packetConfig.restartRx = 1;
}else{
packetConfig.restartRx = 0;
}
if(regPacketConfig2 & 0x02){
packetConfig.autoRxRestartOn = 1;
}else{
packetConfig.autoRxRestartOn = 0;
}
if(regPacketConfig2 & 0x01){
packetConfig.aesOn = 1;
}else{
packetConfig.aesOn = 0;
}
return packetConfig;
}
void setPayloadLength(char payloadLength){
radioCS = 0;
radio.write(REG_PAYLOAD_LENGTH | 0x80);
radio.write(payloadLength);
radioCS = 1;
}
char setPayloadLength(){
char payloadLength;
radioCS = 0;
radio.write(REG_PAYLOAD_LENGTH);
payloadLength = radio.write(0x00);
radioCS = 1;
return payloadLength;
}
void setFifoThreshold(fifoThresholdSetting fifo){
radioCS = 0;
radio.write(REG_FIFO_THRESH | 0x80);
radio.write((fifo.txStartCondition<<7)|(fifo.threshold&0x7F));
radioCS = 1;
}
fifoThresholdSetting getFifoThreshold(){
fifoThresholdSetting fifo;
char reg;
radioCS = 0;
radio.write(REG_FIFO_THRESH);
reg = radio.write(0x00);
radioCS = 1;
fifo.txStartCondition = reg >> 7;
fifo.threshold = reg &0x7F;
return fifo;
}
void writeFifo(char value){
radioCS = 0;
radio.write(REG_FIFO | 0x80);
radio.write(value);
radioCS = 1;
}
char readFifo(){
char value;
radioCS = 0;
radio.write(REG_FIFO);
value = radio.write(0x00);
radioCS = 1;
return value;
}
int getRSSI(){
int RSSI;
bool success = false;
char retryCount=0;
radioCS = 0;
radio.write(REG_RSSI_CONFIG|0x80);
radio.write(0x01);
radioCS = 1;
wait_ms(10);/*
while(retryCount<10){
radioCS = 0;
radio.write(REG_RSSI_CONFIG);
RSSI = radio.write(0x00);
radioCS = 1;
if(RSSI & 0x02){*/
radioCS = 0;
radio.write(REG_RSSI_VALUE);
RSSI = radio.write(0x00);
radioCS = 1;/*
success = true;
break;
}
retryCount++;
wait_ms(100);
}
if(success){*/
return RSSI;/*
}else{
return -999;
}*/
}
void setRSSIThreshold(signed char rssiThresh){
char local = rssiThresh * (-2);
radioCS = 0;
radio.write(REG_RSSI_THRESH | 0x80);
radio.write(local);
radioCS = 1;
}
signed char getRSSIThreshold(){
signed char local;
radioCS = 0;
radio.write(REG_RSSI_THRESH);
local = radio.write(0x00);
radioCS = 1;
return local / (-2);
}
void setPreamble(int preambleLength){
radioCS = 0;
radio.write(REG_PREAMBLE_MSB | 0x80);
radio.write((preambleLength>>8)&0xFF);
radio.write(preambleLength&0xFF);
radioCS = 1;
}
int getPreamble(){
int preambleLength;
radioCS = 0;
radio.write(REG_PREAMBLE_MSB);
preambleLength = radio.write(0x00)<<8;
preambleLength |= radio.write(0x00);
radioCS = 1;
return preambleLength;
}
char pcInBuff[255];
char radioInBuff[255];
void printRegisters(){
radioCS = 0;
radio.write(0x01);
for(int i=1;i<=0x4F;i++){
pc.printf("%02x,%02x\n\r",i,radio.write(0x00));
}
radioCS = 1;
}
void radioInit(){
ModulationSetting modSet;
modSet.mode = MODE_PACKET;
modSet.modulation = MODULATION_FSK;
modSet.shaping = SHAPING_NONE;
setModulation(modSet);
modSet = getModulation();
pc.printf("Modulation: %d,%d,%d\n\r",modSet.mode,modSet.modulation,modSet.shaping);
setBitrate(2000);
pc.printf("Bitrate: %d\n\r",getBitrate());
setFdev(5000);
pc.printf("Fdev: %d\n\r",getFdev());
setFreq(434600000);
pc.printf("Frequency: %d\n\r",getFreq());
//setPALevel(10);
pc.printf("PA Level: %02x\n\r",getPALevel());
ocpSetting ocpSet;
ocpSet.enabled = true;
ocpSet.maxCurrent = 95;
setOCP(ocpSet);
ocpSet= getOCP();
pc.printf("OCP: %d,%d\n\r",ocpSet.enabled,ocpSet.maxCurrent);
lnaSetting lnaSet;
lnaSet.ZIn = 50;
lnaSet.agc = false;
lnaSet.gain = 24;
setLNA(lnaSet);
lnaSet=getLNA();
pc.printf("LNA: %d,%d,%d\n\r",lnaSet.ZIn,lnaSet.agc,lnaSet.gain);
setDIOMapping(0x07);
pc.printf("DIO: %02x\n\r",getDIOMapping());
syncSetting syncSet;
syncSet.syncOn = true;
syncSet.fifoFillCondition = true;
syncSet.syncSize = 3;
syncSet.syncTol = 0;
setSyncConfig(syncSet);
setSyncValue(0xFECFECFECFECFECA);
syncSet = getSyncConfig();
pc.printf("Sync: %d,%d,%d,%d,%d\n\r",syncSet.syncOn,syncSet.fifoFillCondition,syncSet.syncSize,syncSet.syncTol,getSyncValue());
packetSetting packetSet;
packetSet.variableLength = true;
packetSet.dcFree = 0;
packetSet.crcOn = true;
packetSet.crcAutoClearOff = 0;
packetSet.addressFiltering = 0;
packetSet.interPacketRxDelay = 0;
packetSet.restartRx = false;
packetSet.autoRxRestartOn = true;
packetSet.aesOn = false;
setPacketConfig(packetSet);
packetSet=getPacketConfig();
pc.printf("Packet: %d,%d,%d,%d,%d,%d,%d,%d,%d\n\r",packetSet.variableLength,packetSet.dcFree,packetSet.crcOn,packetSet.crcAutoClearOff,packetSet.addressFiltering,packetSet.interPacketRxDelay,packetSet.restartRx,packetSet.autoRxRestartOn,packetSet.aesOn);
setRSSIThreshold(-3);
setMode(MODE_RX);
pc.printf("Mode: %02x\n\r",getMode());
printRegisters();
}
void radioTransmit(char* stringToSend, unsigned char length){
//dio2.disable_irq();
//set length
setPayloadLength(length);
//set tx mode
pc.printf("TX ");
setMode(MODE_TX);
//write to fifo
//add length
writeFifo(length);
for(int i=0;i<length;i++){
pc.putc(stringToSend[i]);
writeFifo(stringToSend[i]);
}
while(getFlags()&0x04);
//set rx mode
pc.printf(" RX\n\r");
setMode(MODE_RX);
//dio2.enable_irq();
}
void pcRxISR(){
char character = pc.getc();
static char counter=0;
pc.putc(character);
if(character == 13){
pcInBuff[counter] = 0;
pc.printf("%s\n\r",pcInBuff);
radioTransmit(pcInBuff,counter);
counter = 0;
}else{
pcInBuff[counter] = character;
counter++;
}
}
void radioReceive(){
static char counter=0;
while(fifoNE){
//char character =
pc.putc(readFifo());
/*if(character == 13){
radioInBuff[counter] = 0;
counter = 0;
pc.printf("\n\rString: %s\n\r",radioInBuff);
}else{
radioInBuff[counter] = character;
counter++;
}*/
}
}
int main(){
//Radio Dev branch
pc.attach(&pcRxISR,Serial::RxIrq);
//dio2.rise(radioReceive);
//setup radio
radioInit();
//dio2.enable_irq();
while(1){
//pc.printf("Mode: %02x,Flags: %04x, RSSI: %d\n\r",getMode(),getFlags(),getRSSI());
if((getFlags()&0x04)){
led = 1;
radioReceive();
}else{
led=0;
}
wait(1);
//__WFI();
}
}

