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:
Thu May 02 00:39:38 2013 +0000
Revision:
2:8717baf6e00a
Parent:
1:67a841d57890
added SERVICE_TX_DONE

Who changed what in which revision?

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