driver for SX1232 transceiver

Dependents:   chat_sx1232

summary

The SX1232 is a fully integrated ISM band transceiver optimized for use in the (EN 300 220-1) 868 MHz band in Europe and the (FCC Part 15) 915 MHz band in the US with a minimum of external components. It offers a combination of high link budget and low current consumption in all operating modes.

features

This part offers similar functionality to XBee PRO 900 modules, except RF performance would be improved, especially at slower data-rates. This is due to available narrower receiver bandwidths, and higher TX power, among other things. Additionally, its probably redundant to have a microcontroller on your wireless module, since the mbed cpu can drive radio directly.

This version of driver library supports packet size up to FIFO size (64bytes) to keep it simple and small. For larger packet sizes, a different driver could support the FIFO flow control pins.

wiring connections

Minimum required connections are SPI: mosi, miso, sclk, cs, one interrupt pin, and optional hardware reset pin.

example code

For example usage see Demo Chat Application.

specification of chip

Information on device. /media/uploads/dudmuck/sm1232.png

Committer:
dudmuck
Date:
Wed May 01 23:40:33 2013 +0000
Revision:
0:06cc2cd9f340
Child:
1:67a841d57890
driver for sx1232 transceiver. first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:06cc2cd9f340 1 #include "sx1232.h"
dudmuck 0:06cc2cd9f340 2
dudmuck 0:06cc2cd9f340 3 SX1232::SX1232(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0) : m_spi(mosi, miso, sclk), m_cs(cs), reset_pin(rst), dio0(dio_0)
dudmuck 0:06cc2cd9f340 4 {
dudmuck 0:06cc2cd9f340 5 dio0.rise(this, &SX1232::dio0_callback);
dudmuck 0:06cc2cd9f340 6 reset_pin.input();
dudmuck 0:06cc2cd9f340 7 m_cs = 1;
dudmuck 0:06cc2cd9f340 8 m_spi.format(8, 0);
dudmuck 0:06cc2cd9f340 9 m_spi.frequency(1000000);
dudmuck 0:06cc2cd9f340 10
dudmuck 0:06cc2cd9f340 11 init();
dudmuck 0:06cc2cd9f340 12 service_action = SERVICE_NONE;
dudmuck 0:06cc2cd9f340 13 }
dudmuck 0:06cc2cd9f340 14
dudmuck 0:06cc2cd9f340 15 SX1232::~SX1232()
dudmuck 0:06cc2cd9f340 16 {
dudmuck 0:06cc2cd9f340 17 set_opmode(RF_OPMODE_SLEEP);
dudmuck 0:06cc2cd9f340 18 }
dudmuck 0:06cc2cd9f340 19
dudmuck 0:06cc2cd9f340 20 void SX1232::init()
dudmuck 0:06cc2cd9f340 21 {
dudmuck 0:06cc2cd9f340 22 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:06cc2cd9f340 23 RegPktConfig1.octet = read_reg(REG_PACKETCONFIG1);
dudmuck 0:06cc2cd9f340 24 RegPktConfig2.octet = read_reg(REG_PACKETCONFIG2);
dudmuck 0:06cc2cd9f340 25 RegDioMapping1.octet = read_reg(REG_DIOMAPPING1);
dudmuck 0:06cc2cd9f340 26 RegDioMapping2.octet = read_reg(REG_DIOMAPPING2);
dudmuck 0:06cc2cd9f340 27 RegPayloadLength = read_reg(REG_PAYLOADLENGTH);
dudmuck 0:06cc2cd9f340 28 RegPaConfig.octet = read_reg(REG_PACONFIG);
dudmuck 0:06cc2cd9f340 29 RegOokPeak.octet = read_reg(REG_OOKPEAK);
dudmuck 0:06cc2cd9f340 30 RegRxConfig.octet = read_reg(REG_RXCONFIG);
dudmuck 0:06cc2cd9f340 31 RegLna.octet = read_reg(REG_LNA);
dudmuck 0:06cc2cd9f340 32 RegTimerResol.octet = read_reg(REG_TIMERRESOL);
dudmuck 0:06cc2cd9f340 33 RegSeqConfig1.octet = read_reg(REG_SEQCONFIG1);
dudmuck 0:06cc2cd9f340 34 RegSeqConfig2.octet = read_reg(REG_SEQCONFIG2);
dudmuck 0:06cc2cd9f340 35 RegAfcFei.octet = read_reg(REG_AFCFEI);
dudmuck 0:06cc2cd9f340 36
dudmuck 0:06cc2cd9f340 37 RegPreambleDetect.octet = read_reg(REG_PREAMBLEDETECT);
dudmuck 0:06cc2cd9f340 38 if (RegPreambleDetect.octet != 0xaa) {
dudmuck 0:06cc2cd9f340 39 RegPreambleDetect.octet = 0xaa;
dudmuck 0:06cc2cd9f340 40 write_reg(REG_PREAMBLEDETECT, RegPreambleDetect.octet);
dudmuck 0:06cc2cd9f340 41 }
dudmuck 0:06cc2cd9f340 42
dudmuck 0:06cc2cd9f340 43 RegSyncConfig.octet = read_reg(REG_SYNCCONFIG);
dudmuck 0:06cc2cd9f340 44 RegSyncConfig.bits.SyncSize = 2; // actual size is this+1
dudmuck 0:06cc2cd9f340 45 RegSyncConfig.bits.AutoRestartRxMode = 1; // restart Rx after fifo emptied. 2 is for frequency hopping
dudmuck 0:06cc2cd9f340 46 write_reg(REG_SYNCCONFIG, RegSyncConfig.octet);
dudmuck 0:06cc2cd9f340 47 write_reg(REG_SYNCVALUE1, 0xaa);
dudmuck 0:06cc2cd9f340 48 write_reg(REG_SYNCVALUE1, 0x90); // 802.15.4g examples: 0x7bc9, 0x904e, 0xc9c2, 0x7a0e
dudmuck 0:06cc2cd9f340 49 write_reg(REG_SYNCVALUE2, 0x4e);
dudmuck 0:06cc2cd9f340 50
dudmuck 0:06cc2cd9f340 51 RegFifoThreshold.octet = read_reg(REG_FIFOTHRESH);
dudmuck 0:06cc2cd9f340 52 if (!RegFifoThreshold.bits.TxStartCondition) { // is start condition at fifoThreshold?
dudmuck 0:06cc2cd9f340 53 RegFifoThreshold.bits.TxStartCondition = 1; // make it start tx on FifoNotEmpty
dudmuck 0:06cc2cd9f340 54 write_reg(REG_FIFOTHRESH, RegFifoThreshold.octet);
dudmuck 0:06cc2cd9f340 55 }
dudmuck 0:06cc2cd9f340 56 }
dudmuck 0:06cc2cd9f340 57
dudmuck 0:06cc2cd9f340 58 void SX1232::hw_reset()
dudmuck 0:06cc2cd9f340 59 {
dudmuck 0:06cc2cd9f340 60 /* only a french-swiss design would have hi-Z deassert */
dudmuck 0:06cc2cd9f340 61 reset_pin.output();
dudmuck 0:06cc2cd9f340 62 reset_pin.write(1);
dudmuck 0:06cc2cd9f340 63 wait(0.05);
dudmuck 0:06cc2cd9f340 64 reset_pin.input();
dudmuck 0:06cc2cd9f340 65 wait(0.05);
dudmuck 0:06cc2cd9f340 66 }
dudmuck 0:06cc2cd9f340 67
dudmuck 0:06cc2cd9f340 68 // variable-length pkt is only 255byte max
dudmuck 0:06cc2cd9f340 69 // fixed-length packet could be larger than 255 bytes
dudmuck 0:06cc2cd9f340 70 int SX1232::read_fifo()
dudmuck 0:06cc2cd9f340 71 {
dudmuck 0:06cc2cd9f340 72 /* no blocking code or printf in an ISR */
dudmuck 0:06cc2cd9f340 73 int i, len;
dudmuck 0:06cc2cd9f340 74
dudmuck 0:06cc2cd9f340 75 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 0:06cc2cd9f340 76 m_cs = 0;
dudmuck 0:06cc2cd9f340 77 m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 0:06cc2cd9f340 78 len = m_spi.write(0);
dudmuck 0:06cc2cd9f340 79 m_cs = 1;
dudmuck 0:06cc2cd9f340 80 } else
dudmuck 0:06cc2cd9f340 81 len = get_PayloadLength();
dudmuck 0:06cc2cd9f340 82
dudmuck 0:06cc2cd9f340 83 m_cs = 0;
dudmuck 0:06cc2cd9f340 84 m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 0:06cc2cd9f340 85 for (i = 0; i < len; i++) {
dudmuck 0:06cc2cd9f340 86 // todo: flow control for pkt bigger than fifo (need ISR on FifoTreshold)
dudmuck 0:06cc2cd9f340 87 rx_buf[i] = m_spi.write(0);
dudmuck 0:06cc2cd9f340 88 }
dudmuck 0:06cc2cd9f340 89 m_cs = 1;
dudmuck 0:06cc2cd9f340 90 //_callback_rx.call();
dudmuck 0:06cc2cd9f340 91 return len;
dudmuck 0:06cc2cd9f340 92 }
dudmuck 0:06cc2cd9f340 93
dudmuck 0:06cc2cd9f340 94 void SX1232::dio0_callback()
dudmuck 0:06cc2cd9f340 95 {
dudmuck 0:06cc2cd9f340 96 /* no printf allowed here in ISR */
dudmuck 0:06cc2cd9f340 97 switch (RegDioMapping1.bits.Dio0Mapping) {
dudmuck 0:06cc2cd9f340 98 case 0:
dudmuck 0:06cc2cd9f340 99 if (RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 0:06cc2cd9f340 100 service_action = SERVICE_READ_FIFO;
dudmuck 0:06cc2cd9f340 101 } else if (RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 0:06cc2cd9f340 102 set_opmode(RF_OPMODE_STANDBY); // this should be quick enough for ISR
dudmuck 0:06cc2cd9f340 103 }
dudmuck 0:06cc2cd9f340 104 break;
dudmuck 0:06cc2cd9f340 105 case 1:
dudmuck 0:06cc2cd9f340 106 service_action = SERVICE_READ_FIFO;
dudmuck 0:06cc2cd9f340 107 break;
dudmuck 0:06cc2cd9f340 108 default:
dudmuck 0:06cc2cd9f340 109 service_action = SERVICE_ERROR;
dudmuck 0:06cc2cd9f340 110 break;
dudmuck 0:06cc2cd9f340 111 }
dudmuck 0:06cc2cd9f340 112
dudmuck 0:06cc2cd9f340 113 }
dudmuck 0:06cc2cd9f340 114
dudmuck 0:06cc2cd9f340 115 void SX1232::set_opmode(chip_mode_e mode)
dudmuck 0:06cc2cd9f340 116 {
dudmuck 0:06cc2cd9f340 117 RegOpMode.bits.Mode = mode;
dudmuck 0:06cc2cd9f340 118 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:06cc2cd9f340 119 }
dudmuck 0:06cc2cd9f340 120
dudmuck 0:06cc2cd9f340 121 float SX1232::get_frf_MHz(void)
dudmuck 0:06cc2cd9f340 122 {
dudmuck 0:06cc2cd9f340 123 uint32_t frf;
dudmuck 0:06cc2cd9f340 124 uint8_t lsb, mid, msb;
dudmuck 0:06cc2cd9f340 125 msb = read_reg(REG_FRFMSB);
dudmuck 0:06cc2cd9f340 126 mid = read_reg(REG_FRFMID);
dudmuck 0:06cc2cd9f340 127 lsb = read_reg(REG_FRFLSB);
dudmuck 0:06cc2cd9f340 128 frf = msb;
dudmuck 0:06cc2cd9f340 129 frf <<= 8;
dudmuck 0:06cc2cd9f340 130 frf += mid;
dudmuck 0:06cc2cd9f340 131 frf <<= 8;
dudmuck 0:06cc2cd9f340 132 frf += lsb;
dudmuck 0:06cc2cd9f340 133 return frf * FREQ_STEP_MHZ;
dudmuck 0:06cc2cd9f340 134 }
dudmuck 0:06cc2cd9f340 135
dudmuck 0:06cc2cd9f340 136 void SX1232::set_bitrate(uint32_t bps)
dudmuck 0:06cc2cd9f340 137 {
dudmuck 0:06cc2cd9f340 138 uint8_t lsb, msb;
dudmuck 0:06cc2cd9f340 139 uint16_t br = XTAL_FREQ / bps;
dudmuck 0:06cc2cd9f340 140 msb = br >> 8;
dudmuck 0:06cc2cd9f340 141 lsb = br & 0xff;
dudmuck 0:06cc2cd9f340 142 write_reg(REG_BITRATEMSB, msb);
dudmuck 0:06cc2cd9f340 143 write_reg(REG_BITRATELSB, lsb);
dudmuck 0:06cc2cd9f340 144 }
dudmuck 0:06cc2cd9f340 145
dudmuck 0:06cc2cd9f340 146 uint32_t SX1232::get_bitrate()
dudmuck 0:06cc2cd9f340 147 {
dudmuck 0:06cc2cd9f340 148 uint16_t br;
dudmuck 0:06cc2cd9f340 149
dudmuck 0:06cc2cd9f340 150 br = read_reg(REG_BITRATEMSB);
dudmuck 0:06cc2cd9f340 151 br <<= 8;
dudmuck 0:06cc2cd9f340 152 br += read_reg(REG_BITRATELSB);
dudmuck 0:06cc2cd9f340 153
dudmuck 0:06cc2cd9f340 154 return XTAL_FREQ / br;
dudmuck 0:06cc2cd9f340 155 }
dudmuck 0:06cc2cd9f340 156
dudmuck 0:06cc2cd9f340 157 void SX1232::set_tx_fdev_hz(uint32_t hz)
dudmuck 0:06cc2cd9f340 158 {
dudmuck 0:06cc2cd9f340 159 uint16_t fdev = hz / FREQ_STEP_HZ;
dudmuck 0:06cc2cd9f340 160 uint8_t lsb, msb;
dudmuck 0:06cc2cd9f340 161 msb = fdev >> 8;
dudmuck 0:06cc2cd9f340 162 lsb = fdev & 0xff;
dudmuck 0:06cc2cd9f340 163 write_reg(REG_FDEVMSB, msb);
dudmuck 0:06cc2cd9f340 164 write_reg(REG_FDEVLSB, lsb);
dudmuck 0:06cc2cd9f340 165 }
dudmuck 0:06cc2cd9f340 166
dudmuck 0:06cc2cd9f340 167 uint32_t SX1232::get_tx_fdev_hz(void)
dudmuck 0:06cc2cd9f340 168 {
dudmuck 0:06cc2cd9f340 169 uint16_t fdev;
dudmuck 0:06cc2cd9f340 170
dudmuck 0:06cc2cd9f340 171 fdev = read_reg(REG_FDEVMSB);
dudmuck 0:06cc2cd9f340 172 fdev <<= 8;
dudmuck 0:06cc2cd9f340 173 fdev += read_reg(REG_FDEVLSB);
dudmuck 0:06cc2cd9f340 174
dudmuck 0:06cc2cd9f340 175 return fdev * FREQ_STEP_HZ;
dudmuck 0:06cc2cd9f340 176 }
dudmuck 0:06cc2cd9f340 177
dudmuck 0:06cc2cd9f340 178 void SX1232::set_frf_MHz( float MHz )
dudmuck 0:06cc2cd9f340 179 {
dudmuck 0:06cc2cd9f340 180 uint32_t frf;
dudmuck 0:06cc2cd9f340 181 uint8_t lsb, mid, msb;
dudmuck 0:06cc2cd9f340 182
dudmuck 0:06cc2cd9f340 183 frf = MHz / FREQ_STEP_MHZ;
dudmuck 0:06cc2cd9f340 184 msb = frf >> 16;
dudmuck 0:06cc2cd9f340 185 mid = (frf >> 8) & 0xff;
dudmuck 0:06cc2cd9f340 186 lsb = frf & 0xff;
dudmuck 0:06cc2cd9f340 187 write_reg(REG_FRFMSB, msb);
dudmuck 0:06cc2cd9f340 188 write_reg(REG_FRFMID, mid);
dudmuck 0:06cc2cd9f340 189 write_reg(REG_FRFLSB, lsb);
dudmuck 0:06cc2cd9f340 190 }
dudmuck 0:06cc2cd9f340 191
dudmuck 0:06cc2cd9f340 192 void SX1232::ComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
dudmuck 0:06cc2cd9f340 193 {
dudmuck 0:06cc2cd9f340 194 uint8_t tmpExp, tmpMant;
dudmuck 0:06cc2cd9f340 195 double tmpRxBw;
dudmuck 0:06cc2cd9f340 196 double rxBwMin = 10e6;
dudmuck 0:06cc2cd9f340 197
dudmuck 0:06cc2cd9f340 198 for( tmpExp = 0; tmpExp < 8; tmpExp++ ) {
dudmuck 0:06cc2cd9f340 199 for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) {
dudmuck 0:06cc2cd9f340 200 tmpRxBw = ComputeRxBw(tmpMant, tmpExp);
dudmuck 0:06cc2cd9f340 201 if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) {
dudmuck 0:06cc2cd9f340 202 rxBwMin = fabs( tmpRxBw - rxBwValue );
dudmuck 0:06cc2cd9f340 203 *mantisse = tmpMant;
dudmuck 0:06cc2cd9f340 204 *exponent = tmpExp;
dudmuck 0:06cc2cd9f340 205 }
dudmuck 0:06cc2cd9f340 206 }
dudmuck 0:06cc2cd9f340 207 }
dudmuck 0:06cc2cd9f340 208 }
dudmuck 0:06cc2cd9f340 209
dudmuck 0:06cc2cd9f340 210 uint32_t SX1232::ComputeRxBw( uint8_t mantisse, uint8_t exponent ) {
dudmuck 0:06cc2cd9f340 211 // rxBw
dudmuck 0:06cc2cd9f340 212 if (RegOpMode.bits.ModulationType == 0)
dudmuck 0:06cc2cd9f340 213 return XTAL_FREQ / (mantisse * (1 << exponent+2));
dudmuck 0:06cc2cd9f340 214 else
dudmuck 0:06cc2cd9f340 215 return XTAL_FREQ / (mantisse * (1 << exponent+3));
dudmuck 0:06cc2cd9f340 216 }
dudmuck 0:06cc2cd9f340 217
dudmuck 0:06cc2cd9f340 218 void SX1232::set_rx_dcc_bw_hz(uint32_t dccValue, uint32_t bw_hz )
dudmuck 0:06cc2cd9f340 219 {
dudmuck 0:06cc2cd9f340 220 uint8_t mantisse = 0;
dudmuck 0:06cc2cd9f340 221 uint8_t exponent = 0;
dudmuck 0:06cc2cd9f340 222 uint8_t reg;
dudmuck 0:06cc2cd9f340 223
dudmuck 0:06cc2cd9f340 224 reg = ( uint8_t )dccValue & 0x60;
dudmuck 0:06cc2cd9f340 225 ComputeRxBwMantExp( bw_hz, &mantisse, &exponent );
dudmuck 0:06cc2cd9f340 226 switch( mantisse ) {
dudmuck 0:06cc2cd9f340 227 case 16:
dudmuck 0:06cc2cd9f340 228 reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) );
dudmuck 0:06cc2cd9f340 229 break;
dudmuck 0:06cc2cd9f340 230 case 20:
dudmuck 0:06cc2cd9f340 231 reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) );
dudmuck 0:06cc2cd9f340 232 break;
dudmuck 0:06cc2cd9f340 233 case 24:
dudmuck 0:06cc2cd9f340 234 reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) );
dudmuck 0:06cc2cd9f340 235 break;
dudmuck 0:06cc2cd9f340 236 default:
dudmuck 0:06cc2cd9f340 237 // Something went terribely wrong
dudmuck 0:06cc2cd9f340 238 printf("maintisse:%d\r\n", mantisse);
dudmuck 0:06cc2cd9f340 239 break;
dudmuck 0:06cc2cd9f340 240 }
dudmuck 0:06cc2cd9f340 241
dudmuck 0:06cc2cd9f340 242 write_reg(REG_RXBW, reg);
dudmuck 0:06cc2cd9f340 243 }
dudmuck 0:06cc2cd9f340 244
dudmuck 0:06cc2cd9f340 245 uint32_t SX1232::get_rx_bw_hz(uint8_t addr)
dudmuck 0:06cc2cd9f340 246 {
dudmuck 0:06cc2cd9f340 247 uint8_t mantisse = 0;
dudmuck 0:06cc2cd9f340 248 uint8_t reg = read_reg(REG_RXBW);
dudmuck 0:06cc2cd9f340 249 switch( ( reg & 0x18 ) >> 3 )
dudmuck 0:06cc2cd9f340 250 {
dudmuck 0:06cc2cd9f340 251 case 0:
dudmuck 0:06cc2cd9f340 252 mantisse = 16;
dudmuck 0:06cc2cd9f340 253 break;
dudmuck 0:06cc2cd9f340 254 case 1:
dudmuck 0:06cc2cd9f340 255 mantisse = 20;
dudmuck 0:06cc2cd9f340 256 break;
dudmuck 0:06cc2cd9f340 257 case 2:
dudmuck 0:06cc2cd9f340 258 mantisse = 24;
dudmuck 0:06cc2cd9f340 259 break;
dudmuck 0:06cc2cd9f340 260 default:
dudmuck 0:06cc2cd9f340 261 break;
dudmuck 0:06cc2cd9f340 262 }
dudmuck 0:06cc2cd9f340 263 return ComputeRxBw( mantisse, ( uint8_t )reg & 0x07 );
dudmuck 0:06cc2cd9f340 264 }
dudmuck 0:06cc2cd9f340 265
dudmuck 0:06cc2cd9f340 266 uint16_t SX1232::get_PayloadLength()
dudmuck 0:06cc2cd9f340 267 {
dudmuck 0:06cc2cd9f340 268 uint16_t ret;
dudmuck 0:06cc2cd9f340 269
dudmuck 0:06cc2cd9f340 270 RegPktConfig2.octet = read_reg(REG_PACKETCONFIG2);
dudmuck 0:06cc2cd9f340 271 RegPayloadLength = read_reg(REG_PAYLOADLENGTH);
dudmuck 0:06cc2cd9f340 272
dudmuck 0:06cc2cd9f340 273 ret = RegPktConfig2.bits.PayloadLengthHi;
dudmuck 0:06cc2cd9f340 274 ret <<= 8;
dudmuck 0:06cc2cd9f340 275 ret += RegPayloadLength;
dudmuck 0:06cc2cd9f340 276
dudmuck 0:06cc2cd9f340 277 return ret;
dudmuck 0:06cc2cd9f340 278 }
dudmuck 0:06cc2cd9f340 279
dudmuck 0:06cc2cd9f340 280 void SX1232::set_RegPayloadLength(uint16_t len)
dudmuck 0:06cc2cd9f340 281 {
dudmuck 0:06cc2cd9f340 282 RegPktConfig2.bits.PayloadLengthHi = len >> 8;
dudmuck 0:06cc2cd9f340 283 write_reg(REG_PACKETCONFIG2, RegPktConfig2.octet);
dudmuck 0:06cc2cd9f340 284 RegPayloadLength = len & 0xff;
dudmuck 0:06cc2cd9f340 285 write_reg(REG_PAYLOADLENGTH, RegPayloadLength);
dudmuck 0:06cc2cd9f340 286 }
dudmuck 0:06cc2cd9f340 287
dudmuck 0:06cc2cd9f340 288 void SX1232::enable_afc(char en)
dudmuck 0:06cc2cd9f340 289 {
dudmuck 0:06cc2cd9f340 290 if (en) {
dudmuck 0:06cc2cd9f340 291 RegRxConfig.bits.AfcAutoOn = 1;
dudmuck 0:06cc2cd9f340 292 RegRxConfig.bits.RxTrigger = 6; // 6: trigger on preamble detect
dudmuck 0:06cc2cd9f340 293
dudmuck 0:06cc2cd9f340 294 if (RegSyncConfig.bits.AutoRestartRxMode != 1) {
dudmuck 0:06cc2cd9f340 295 // 2 is for frequency hopping application
dudmuck 0:06cc2cd9f340 296 // if 0 then manual RestartRx in RxConfig required
dudmuck 0:06cc2cd9f340 297 RegSyncConfig.bits.AutoRestartRxMode = 1;
dudmuck 0:06cc2cd9f340 298 }
dudmuck 0:06cc2cd9f340 299 // preamble detector triggers AFC
dudmuck 0:06cc2cd9f340 300 if (!RegPreambleDetect.bits.PreambleDetectorOn) {
dudmuck 0:06cc2cd9f340 301 RegPreambleDetect.bits.PreambleDetectorOn = 1;
dudmuck 0:06cc2cd9f340 302 RegPreambleDetect.bits.PreambleDetectorTol = 10; // chips
dudmuck 0:06cc2cd9f340 303 RegPreambleDetect.bits.PreambleDetectorSize = 1; // bytes
dudmuck 0:06cc2cd9f340 304 write_reg(REG_PREAMBLEDETECT, RegPreambleDetect.octet);
dudmuck 0:06cc2cd9f340 305 }
dudmuck 0:06cc2cd9f340 306 // set DIO4 output. not required, only for monitoring
dudmuck 0:06cc2cd9f340 307 if ((RegDioMapping2.bits.Dio4Mapping != 3) || !RegDioMapping2.bits.MapPreambleDetect) {
dudmuck 0:06cc2cd9f340 308 RegDioMapping2.bits.Dio4Mapping = 3;
dudmuck 0:06cc2cd9f340 309 RegDioMapping2.bits.MapPreambleDetect = 1;
dudmuck 0:06cc2cd9f340 310 write_reg(REG_DIOMAPPING2, RegDioMapping2.octet);
dudmuck 0:06cc2cd9f340 311 }
dudmuck 0:06cc2cd9f340 312 } else {
dudmuck 0:06cc2cd9f340 313 RegRxConfig.bits.AfcAutoOn = 0;
dudmuck 0:06cc2cd9f340 314 RegRxConfig.bits.RxTrigger = 0;
dudmuck 0:06cc2cd9f340 315 }
dudmuck 0:06cc2cd9f340 316 write_reg(REG_RXCONFIG, RegRxConfig.octet);
dudmuck 0:06cc2cd9f340 317 }
dudmuck 0:06cc2cd9f340 318
dudmuck 0:06cc2cd9f340 319 int16_t SX1232::read_reg_s16(uint8_t addr)
dudmuck 0:06cc2cd9f340 320 {
dudmuck 0:06cc2cd9f340 321 int16_t ret;
dudmuck 0:06cc2cd9f340 322 // Select the device by seting chip select low
dudmuck 0:06cc2cd9f340 323 m_cs = 0;
dudmuck 0:06cc2cd9f340 324
dudmuck 0:06cc2cd9f340 325 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:06cc2cd9f340 326
dudmuck 0:06cc2cd9f340 327 // Send a dummy byte to receive the contents of the WHOAMI register
dudmuck 0:06cc2cd9f340 328 ret = m_spi.write(0x00);
dudmuck 0:06cc2cd9f340 329 ret <<= 8;
dudmuck 0:06cc2cd9f340 330 ret += m_spi.write(0x00);
dudmuck 0:06cc2cd9f340 331
dudmuck 0:06cc2cd9f340 332 // Deselect the device
dudmuck 0:06cc2cd9f340 333 m_cs = 1;
dudmuck 0:06cc2cd9f340 334
dudmuck 0:06cc2cd9f340 335 return ret;
dudmuck 0:06cc2cd9f340 336 }
dudmuck 0:06cc2cd9f340 337
dudmuck 0:06cc2cd9f340 338 uint8_t SX1232::read_reg(uint8_t addr)
dudmuck 0:06cc2cd9f340 339 {
dudmuck 0:06cc2cd9f340 340 uint8_t ret;
dudmuck 0:06cc2cd9f340 341 // Select the device by seting chip select low
dudmuck 0:06cc2cd9f340 342 m_cs = 0;
dudmuck 0:06cc2cd9f340 343
dudmuck 0:06cc2cd9f340 344 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:06cc2cd9f340 345
dudmuck 0:06cc2cd9f340 346 // Send a dummy byte to receive the contents of the WHOAMI register
dudmuck 0:06cc2cd9f340 347 ret = m_spi.write(0x00);
dudmuck 0:06cc2cd9f340 348
dudmuck 0:06cc2cd9f340 349 // Deselect the device
dudmuck 0:06cc2cd9f340 350 m_cs = 1;
dudmuck 0:06cc2cd9f340 351
dudmuck 0:06cc2cd9f340 352 return ret;
dudmuck 0:06cc2cd9f340 353 }
dudmuck 0:06cc2cd9f340 354
dudmuck 0:06cc2cd9f340 355 void SX1232::write_reg(uint8_t addr, uint8_t data)
dudmuck 0:06cc2cd9f340 356 {
dudmuck 0:06cc2cd9f340 357 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:06cc2cd9f340 358
dudmuck 0:06cc2cd9f340 359 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:06cc2cd9f340 360
dudmuck 0:06cc2cd9f340 361 // Send a dummy byte to receive the contents of the WHOAMI register
dudmuck 0:06cc2cd9f340 362 m_spi.write(data);
dudmuck 0:06cc2cd9f340 363
dudmuck 0:06cc2cd9f340 364 m_cs = 1; // Deselect the device
dudmuck 0:06cc2cd9f340 365 }
dudmuck 0:06cc2cd9f340 366
dudmuck 0:06cc2cd9f340 367 // variable-length pkt is only 255byte max
dudmuck 0:06cc2cd9f340 368 void SX1232::write_fifo__varlen(uint8_t len)
dudmuck 0:06cc2cd9f340 369 {
dudmuck 0:06cc2cd9f340 370 int i;
dudmuck 0:06cc2cd9f340 371
dudmuck 0:06cc2cd9f340 372 m_cs = 0;
dudmuck 0:06cc2cd9f340 373 m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 0:06cc2cd9f340 374 m_spi.write(len);
dudmuck 0:06cc2cd9f340 375 for (i = 0; i < len; i++) {
dudmuck 0:06cc2cd9f340 376 // todo: flow control for pkt bigger than fifo
dudmuck 0:06cc2cd9f340 377 m_spi.write(tx_buf[i]);
dudmuck 0:06cc2cd9f340 378 }
dudmuck 0:06cc2cd9f340 379 m_cs = 1;
dudmuck 0:06cc2cd9f340 380 }
dudmuck 0:06cc2cd9f340 381
dudmuck 0:06cc2cd9f340 382 // fixed-length packet could be larger than 255 bytes
dudmuck 0:06cc2cd9f340 383 void SX1232::write_fifo__fixedlen(void)
dudmuck 0:06cc2cd9f340 384 {
dudmuck 0:06cc2cd9f340 385 int i, len = get_PayloadLength();
dudmuck 0:06cc2cd9f340 386 m_cs = 0;
dudmuck 0:06cc2cd9f340 387 m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 0:06cc2cd9f340 388 for (i = 0; i < len; i++) {
dudmuck 0:06cc2cd9f340 389 // todo: flow control for pkt bigger than fifo
dudmuck 0:06cc2cd9f340 390 m_spi.write(tx_buf[i]);
dudmuck 0:06cc2cd9f340 391 }
dudmuck 0:06cc2cd9f340 392 m_cs = 1;
dudmuck 0:06cc2cd9f340 393 }
dudmuck 0:06cc2cd9f340 394
dudmuck 0:06cc2cd9f340 395 // arg only for variable-length
dudmuck 0:06cc2cd9f340 396 void SX1232::start_tx(uint8_t len)
dudmuck 0:06cc2cd9f340 397 {
dudmuck 0:06cc2cd9f340 398 if (RegOpMode.bits.Mode > RF_OPMODE_STANDBY) {
dudmuck 0:06cc2cd9f340 399 RegIrqFlags1_t RegIrqFlags1;
dudmuck 0:06cc2cd9f340 400 set_opmode(RF_OPMODE_STANDBY); // unwise fill fifo in RX
dudmuck 0:06cc2cd9f340 401 wait(0.01);
dudmuck 0:06cc2cd9f340 402 RegIrqFlags1.octet = read_reg(REG_IRQFLAGS1);
dudmuck 0:06cc2cd9f340 403 while (!RegIrqFlags1.bits.ModeReady) {
dudmuck 0:06cc2cd9f340 404 //printf("to stby:%02x\r\n", RegIrqFlags1.octet);
dudmuck 0:06cc2cd9f340 405 wait(0.01);
dudmuck 0:06cc2cd9f340 406 RegIrqFlags1.octet = read_reg(REG_IRQFLAGS1);
dudmuck 0:06cc2cd9f340 407 }
dudmuck 0:06cc2cd9f340 408 }
dudmuck 0:06cc2cd9f340 409
dudmuck 0:06cc2cd9f340 410 // DIO0 to PacketSent
dudmuck 0:06cc2cd9f340 411 if (RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 0:06cc2cd9f340 412 RegDioMapping1.bits.Dio0Mapping = 0;
dudmuck 0:06cc2cd9f340 413 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:06cc2cd9f340 414 }
dudmuck 0:06cc2cd9f340 415
dudmuck 0:06cc2cd9f340 416 if (RegPktConfig1.bits.PacketFormatVariable)
dudmuck 0:06cc2cd9f340 417 write_fifo__varlen(len);
dudmuck 0:06cc2cd9f340 418 else
dudmuck 0:06cc2cd9f340 419 write_fifo__fixedlen();
dudmuck 0:06cc2cd9f340 420
dudmuck 0:06cc2cd9f340 421 set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 0:06cc2cd9f340 422 }
dudmuck 0:06cc2cd9f340 423
dudmuck 0:06cc2cd9f340 424 void SX1232::start_rx()
dudmuck 0:06cc2cd9f340 425 {
dudmuck 0:06cc2cd9f340 426 if (RegPktConfig1.bits.CrcOn) { // DIO0 to CrcOk
dudmuck 0:06cc2cd9f340 427 if (RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 0:06cc2cd9f340 428 RegDioMapping1.bits.Dio0Mapping = 1;
dudmuck 0:06cc2cd9f340 429 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:06cc2cd9f340 430 }
dudmuck 0:06cc2cd9f340 431 } else { // DIO0 to PayloadReady
dudmuck 0:06cc2cd9f340 432 if (RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 0:06cc2cd9f340 433 RegDioMapping1.bits.Dio0Mapping = 0;
dudmuck 0:06cc2cd9f340 434 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:06cc2cd9f340 435 }
dudmuck 0:06cc2cd9f340 436 }
dudmuck 0:06cc2cd9f340 437
dudmuck 0:06cc2cd9f340 438 set_opmode(RF_OPMODE_RECEIVER);
dudmuck 0:06cc2cd9f340 439 }