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:42:35 2013 +0000
Revision:
1:67a841d57890
Parent:
0:06cc2cd9f340
Child:
2:8717baf6e00a
apache license

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 0:06cc2cd9f340 119 }
dudmuck 0:06cc2cd9f340 120 break;
dudmuck 0:06cc2cd9f340 121 case 1:
dudmuck 0:06cc2cd9f340 122 service_action = SERVICE_READ_FIFO;
dudmuck 0:06cc2cd9f340 123 break;
dudmuck 0:06cc2cd9f340 124 default:
dudmuck 0:06cc2cd9f340 125 service_action = SERVICE_ERROR;
dudmuck 0:06cc2cd9f340 126 break;
dudmuck 0:06cc2cd9f340 127 }
dudmuck 0:06cc2cd9f340 128
dudmuck 0:06cc2cd9f340 129 }
dudmuck 0:06cc2cd9f340 130
dudmuck 0:06cc2cd9f340 131 void SX1232::set_opmode(chip_mode_e mode)
dudmuck 0:06cc2cd9f340 132 {
dudmuck 0:06cc2cd9f340 133 RegOpMode.bits.Mode = mode;
dudmuck 0:06cc2cd9f340 134 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:06cc2cd9f340 135 }
dudmuck 0:06cc2cd9f340 136
dudmuck 0:06cc2cd9f340 137 float SX1232::get_frf_MHz(void)
dudmuck 0:06cc2cd9f340 138 {
dudmuck 0:06cc2cd9f340 139 uint32_t frf;
dudmuck 0:06cc2cd9f340 140 uint8_t lsb, mid, msb;
dudmuck 0:06cc2cd9f340 141 msb = read_reg(REG_FRFMSB);
dudmuck 0:06cc2cd9f340 142 mid = read_reg(REG_FRFMID);
dudmuck 0:06cc2cd9f340 143 lsb = read_reg(REG_FRFLSB);
dudmuck 0:06cc2cd9f340 144 frf = msb;
dudmuck 0:06cc2cd9f340 145 frf <<= 8;
dudmuck 0:06cc2cd9f340 146 frf += mid;
dudmuck 0:06cc2cd9f340 147 frf <<= 8;
dudmuck 0:06cc2cd9f340 148 frf += lsb;
dudmuck 0:06cc2cd9f340 149 return frf * FREQ_STEP_MHZ;
dudmuck 0:06cc2cd9f340 150 }
dudmuck 0:06cc2cd9f340 151
dudmuck 0:06cc2cd9f340 152 void SX1232::set_bitrate(uint32_t bps)
dudmuck 0:06cc2cd9f340 153 {
dudmuck 0:06cc2cd9f340 154 uint8_t lsb, msb;
dudmuck 0:06cc2cd9f340 155 uint16_t br = XTAL_FREQ / bps;
dudmuck 0:06cc2cd9f340 156 msb = br >> 8;
dudmuck 0:06cc2cd9f340 157 lsb = br & 0xff;
dudmuck 0:06cc2cd9f340 158 write_reg(REG_BITRATEMSB, msb);
dudmuck 0:06cc2cd9f340 159 write_reg(REG_BITRATELSB, lsb);
dudmuck 0:06cc2cd9f340 160 }
dudmuck 0:06cc2cd9f340 161
dudmuck 0:06cc2cd9f340 162 uint32_t SX1232::get_bitrate()
dudmuck 0:06cc2cd9f340 163 {
dudmuck 0:06cc2cd9f340 164 uint16_t br;
dudmuck 0:06cc2cd9f340 165
dudmuck 0:06cc2cd9f340 166 br = read_reg(REG_BITRATEMSB);
dudmuck 0:06cc2cd9f340 167 br <<= 8;
dudmuck 0:06cc2cd9f340 168 br += read_reg(REG_BITRATELSB);
dudmuck 0:06cc2cd9f340 169
dudmuck 0:06cc2cd9f340 170 return XTAL_FREQ / br;
dudmuck 0:06cc2cd9f340 171 }
dudmuck 0:06cc2cd9f340 172
dudmuck 0:06cc2cd9f340 173 void SX1232::set_tx_fdev_hz(uint32_t hz)
dudmuck 0:06cc2cd9f340 174 {
dudmuck 0:06cc2cd9f340 175 uint16_t fdev = hz / FREQ_STEP_HZ;
dudmuck 0:06cc2cd9f340 176 uint8_t lsb, msb;
dudmuck 0:06cc2cd9f340 177 msb = fdev >> 8;
dudmuck 0:06cc2cd9f340 178 lsb = fdev & 0xff;
dudmuck 0:06cc2cd9f340 179 write_reg(REG_FDEVMSB, msb);
dudmuck 0:06cc2cd9f340 180 write_reg(REG_FDEVLSB, lsb);
dudmuck 0:06cc2cd9f340 181 }
dudmuck 0:06cc2cd9f340 182
dudmuck 0:06cc2cd9f340 183 uint32_t SX1232::get_tx_fdev_hz(void)
dudmuck 0:06cc2cd9f340 184 {
dudmuck 0:06cc2cd9f340 185 uint16_t fdev;
dudmuck 0:06cc2cd9f340 186
dudmuck 0:06cc2cd9f340 187 fdev = read_reg(REG_FDEVMSB);
dudmuck 0:06cc2cd9f340 188 fdev <<= 8;
dudmuck 0:06cc2cd9f340 189 fdev += read_reg(REG_FDEVLSB);
dudmuck 0:06cc2cd9f340 190
dudmuck 0:06cc2cd9f340 191 return fdev * FREQ_STEP_HZ;
dudmuck 0:06cc2cd9f340 192 }
dudmuck 0:06cc2cd9f340 193
dudmuck 0:06cc2cd9f340 194 void SX1232::set_frf_MHz( float MHz )
dudmuck 0:06cc2cd9f340 195 {
dudmuck 0:06cc2cd9f340 196 uint32_t frf;
dudmuck 0:06cc2cd9f340 197 uint8_t lsb, mid, msb;
dudmuck 0:06cc2cd9f340 198
dudmuck 0:06cc2cd9f340 199 frf = MHz / FREQ_STEP_MHZ;
dudmuck 0:06cc2cd9f340 200 msb = frf >> 16;
dudmuck 0:06cc2cd9f340 201 mid = (frf >> 8) & 0xff;
dudmuck 0:06cc2cd9f340 202 lsb = frf & 0xff;
dudmuck 0:06cc2cd9f340 203 write_reg(REG_FRFMSB, msb);
dudmuck 0:06cc2cd9f340 204 write_reg(REG_FRFMID, mid);
dudmuck 0:06cc2cd9f340 205 write_reg(REG_FRFLSB, lsb);
dudmuck 0:06cc2cd9f340 206 }
dudmuck 0:06cc2cd9f340 207
dudmuck 0:06cc2cd9f340 208 void SX1232::ComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
dudmuck 0:06cc2cd9f340 209 {
dudmuck 0:06cc2cd9f340 210 uint8_t tmpExp, tmpMant;
dudmuck 0:06cc2cd9f340 211 double tmpRxBw;
dudmuck 0:06cc2cd9f340 212 double rxBwMin = 10e6;
dudmuck 0:06cc2cd9f340 213
dudmuck 0:06cc2cd9f340 214 for( tmpExp = 0; tmpExp < 8; tmpExp++ ) {
dudmuck 0:06cc2cd9f340 215 for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) {
dudmuck 0:06cc2cd9f340 216 tmpRxBw = ComputeRxBw(tmpMant, tmpExp);
dudmuck 0:06cc2cd9f340 217 if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) {
dudmuck 0:06cc2cd9f340 218 rxBwMin = fabs( tmpRxBw - rxBwValue );
dudmuck 0:06cc2cd9f340 219 *mantisse = tmpMant;
dudmuck 0:06cc2cd9f340 220 *exponent = tmpExp;
dudmuck 0:06cc2cd9f340 221 }
dudmuck 0:06cc2cd9f340 222 }
dudmuck 0:06cc2cd9f340 223 }
dudmuck 0:06cc2cd9f340 224 }
dudmuck 0:06cc2cd9f340 225
dudmuck 0:06cc2cd9f340 226 uint32_t SX1232::ComputeRxBw( uint8_t mantisse, uint8_t exponent ) {
dudmuck 0:06cc2cd9f340 227 // rxBw
dudmuck 0:06cc2cd9f340 228 if (RegOpMode.bits.ModulationType == 0)
dudmuck 0:06cc2cd9f340 229 return XTAL_FREQ / (mantisse * (1 << exponent+2));
dudmuck 0:06cc2cd9f340 230 else
dudmuck 0:06cc2cd9f340 231 return XTAL_FREQ / (mantisse * (1 << exponent+3));
dudmuck 0:06cc2cd9f340 232 }
dudmuck 0:06cc2cd9f340 233
dudmuck 0:06cc2cd9f340 234 void SX1232::set_rx_dcc_bw_hz(uint32_t dccValue, uint32_t bw_hz )
dudmuck 0:06cc2cd9f340 235 {
dudmuck 0:06cc2cd9f340 236 uint8_t mantisse = 0;
dudmuck 0:06cc2cd9f340 237 uint8_t exponent = 0;
dudmuck 0:06cc2cd9f340 238 uint8_t reg;
dudmuck 0:06cc2cd9f340 239
dudmuck 0:06cc2cd9f340 240 reg = ( uint8_t )dccValue & 0x60;
dudmuck 0:06cc2cd9f340 241 ComputeRxBwMantExp( bw_hz, &mantisse, &exponent );
dudmuck 0:06cc2cd9f340 242 switch( mantisse ) {
dudmuck 0:06cc2cd9f340 243 case 16:
dudmuck 0:06cc2cd9f340 244 reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) );
dudmuck 0:06cc2cd9f340 245 break;
dudmuck 0:06cc2cd9f340 246 case 20:
dudmuck 0:06cc2cd9f340 247 reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) );
dudmuck 0:06cc2cd9f340 248 break;
dudmuck 0:06cc2cd9f340 249 case 24:
dudmuck 0:06cc2cd9f340 250 reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) );
dudmuck 0:06cc2cd9f340 251 break;
dudmuck 0:06cc2cd9f340 252 default:
dudmuck 0:06cc2cd9f340 253 // Something went terribely wrong
dudmuck 0:06cc2cd9f340 254 printf("maintisse:%d\r\n", mantisse);
dudmuck 0:06cc2cd9f340 255 break;
dudmuck 0:06cc2cd9f340 256 }
dudmuck 0:06cc2cd9f340 257
dudmuck 0:06cc2cd9f340 258 write_reg(REG_RXBW, reg);
dudmuck 0:06cc2cd9f340 259 }
dudmuck 0:06cc2cd9f340 260
dudmuck 0:06cc2cd9f340 261 uint32_t SX1232::get_rx_bw_hz(uint8_t addr)
dudmuck 0:06cc2cd9f340 262 {
dudmuck 0:06cc2cd9f340 263 uint8_t mantisse = 0;
dudmuck 0:06cc2cd9f340 264 uint8_t reg = read_reg(REG_RXBW);
dudmuck 0:06cc2cd9f340 265 switch( ( reg & 0x18 ) >> 3 )
dudmuck 0:06cc2cd9f340 266 {
dudmuck 0:06cc2cd9f340 267 case 0:
dudmuck 0:06cc2cd9f340 268 mantisse = 16;
dudmuck 0:06cc2cd9f340 269 break;
dudmuck 0:06cc2cd9f340 270 case 1:
dudmuck 0:06cc2cd9f340 271 mantisse = 20;
dudmuck 0:06cc2cd9f340 272 break;
dudmuck 0:06cc2cd9f340 273 case 2:
dudmuck 0:06cc2cd9f340 274 mantisse = 24;
dudmuck 0:06cc2cd9f340 275 break;
dudmuck 0:06cc2cd9f340 276 default:
dudmuck 0:06cc2cd9f340 277 break;
dudmuck 0:06cc2cd9f340 278 }
dudmuck 0:06cc2cd9f340 279 return ComputeRxBw( mantisse, ( uint8_t )reg & 0x07 );
dudmuck 0:06cc2cd9f340 280 }
dudmuck 0:06cc2cd9f340 281
dudmuck 0:06cc2cd9f340 282 uint16_t SX1232::get_PayloadLength()
dudmuck 0:06cc2cd9f340 283 {
dudmuck 0:06cc2cd9f340 284 uint16_t ret;
dudmuck 0:06cc2cd9f340 285
dudmuck 0:06cc2cd9f340 286 RegPktConfig2.octet = read_reg(REG_PACKETCONFIG2);
dudmuck 0:06cc2cd9f340 287 RegPayloadLength = read_reg(REG_PAYLOADLENGTH);
dudmuck 0:06cc2cd9f340 288
dudmuck 0:06cc2cd9f340 289 ret = RegPktConfig2.bits.PayloadLengthHi;
dudmuck 0:06cc2cd9f340 290 ret <<= 8;
dudmuck 0:06cc2cd9f340 291 ret += RegPayloadLength;
dudmuck 0:06cc2cd9f340 292
dudmuck 0:06cc2cd9f340 293 return ret;
dudmuck 0:06cc2cd9f340 294 }
dudmuck 0:06cc2cd9f340 295
dudmuck 0:06cc2cd9f340 296 void SX1232::set_RegPayloadLength(uint16_t len)
dudmuck 0:06cc2cd9f340 297 {
dudmuck 0:06cc2cd9f340 298 RegPktConfig2.bits.PayloadLengthHi = len >> 8;
dudmuck 0:06cc2cd9f340 299 write_reg(REG_PACKETCONFIG2, RegPktConfig2.octet);
dudmuck 0:06cc2cd9f340 300 RegPayloadLength = len & 0xff;
dudmuck 0:06cc2cd9f340 301 write_reg(REG_PAYLOADLENGTH, RegPayloadLength);
dudmuck 0:06cc2cd9f340 302 }
dudmuck 0:06cc2cd9f340 303
dudmuck 0:06cc2cd9f340 304 void SX1232::enable_afc(char en)
dudmuck 0:06cc2cd9f340 305 {
dudmuck 0:06cc2cd9f340 306 if (en) {
dudmuck 0:06cc2cd9f340 307 RegRxConfig.bits.AfcAutoOn = 1;
dudmuck 0:06cc2cd9f340 308 RegRxConfig.bits.RxTrigger = 6; // 6: trigger on preamble detect
dudmuck 0:06cc2cd9f340 309
dudmuck 0:06cc2cd9f340 310 if (RegSyncConfig.bits.AutoRestartRxMode != 1) {
dudmuck 0:06cc2cd9f340 311 // 2 is for frequency hopping application
dudmuck 0:06cc2cd9f340 312 // if 0 then manual RestartRx in RxConfig required
dudmuck 0:06cc2cd9f340 313 RegSyncConfig.bits.AutoRestartRxMode = 1;
dudmuck 0:06cc2cd9f340 314 }
dudmuck 0:06cc2cd9f340 315 // preamble detector triggers AFC
dudmuck 0:06cc2cd9f340 316 if (!RegPreambleDetect.bits.PreambleDetectorOn) {
dudmuck 0:06cc2cd9f340 317 RegPreambleDetect.bits.PreambleDetectorOn = 1;
dudmuck 0:06cc2cd9f340 318 RegPreambleDetect.bits.PreambleDetectorTol = 10; // chips
dudmuck 0:06cc2cd9f340 319 RegPreambleDetect.bits.PreambleDetectorSize = 1; // bytes
dudmuck 0:06cc2cd9f340 320 write_reg(REG_PREAMBLEDETECT, RegPreambleDetect.octet);
dudmuck 0:06cc2cd9f340 321 }
dudmuck 0:06cc2cd9f340 322 // set DIO4 output. not required, only for monitoring
dudmuck 0:06cc2cd9f340 323 if ((RegDioMapping2.bits.Dio4Mapping != 3) || !RegDioMapping2.bits.MapPreambleDetect) {
dudmuck 0:06cc2cd9f340 324 RegDioMapping2.bits.Dio4Mapping = 3;
dudmuck 0:06cc2cd9f340 325 RegDioMapping2.bits.MapPreambleDetect = 1;
dudmuck 0:06cc2cd9f340 326 write_reg(REG_DIOMAPPING2, RegDioMapping2.octet);
dudmuck 0:06cc2cd9f340 327 }
dudmuck 0:06cc2cd9f340 328 } else {
dudmuck 0:06cc2cd9f340 329 RegRxConfig.bits.AfcAutoOn = 0;
dudmuck 0:06cc2cd9f340 330 RegRxConfig.bits.RxTrigger = 0;
dudmuck 0:06cc2cd9f340 331 }
dudmuck 0:06cc2cd9f340 332 write_reg(REG_RXCONFIG, RegRxConfig.octet);
dudmuck 0:06cc2cd9f340 333 }
dudmuck 0:06cc2cd9f340 334
dudmuck 0:06cc2cd9f340 335 int16_t SX1232::read_reg_s16(uint8_t addr)
dudmuck 0:06cc2cd9f340 336 {
dudmuck 0:06cc2cd9f340 337 int16_t ret;
dudmuck 0:06cc2cd9f340 338 // Select the device by seting chip select low
dudmuck 0:06cc2cd9f340 339 m_cs = 0;
dudmuck 0:06cc2cd9f340 340
dudmuck 0:06cc2cd9f340 341 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:06cc2cd9f340 342
dudmuck 0:06cc2cd9f340 343 // Send a dummy byte to receive the contents of the WHOAMI register
dudmuck 0:06cc2cd9f340 344 ret = m_spi.write(0x00);
dudmuck 0:06cc2cd9f340 345 ret <<= 8;
dudmuck 0:06cc2cd9f340 346 ret += m_spi.write(0x00);
dudmuck 0:06cc2cd9f340 347
dudmuck 0:06cc2cd9f340 348 // Deselect the device
dudmuck 0:06cc2cd9f340 349 m_cs = 1;
dudmuck 0:06cc2cd9f340 350
dudmuck 0:06cc2cd9f340 351 return ret;
dudmuck 0:06cc2cd9f340 352 }
dudmuck 0:06cc2cd9f340 353
dudmuck 0:06cc2cd9f340 354 uint8_t SX1232::read_reg(uint8_t addr)
dudmuck 0:06cc2cd9f340 355 {
dudmuck 0:06cc2cd9f340 356 uint8_t ret;
dudmuck 0:06cc2cd9f340 357 // Select the device by seting chip select low
dudmuck 0:06cc2cd9f340 358 m_cs = 0;
dudmuck 0:06cc2cd9f340 359
dudmuck 0:06cc2cd9f340 360 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:06cc2cd9f340 361
dudmuck 0:06cc2cd9f340 362 // Send a dummy byte to receive the contents of the WHOAMI register
dudmuck 0:06cc2cd9f340 363 ret = m_spi.write(0x00);
dudmuck 0:06cc2cd9f340 364
dudmuck 0:06cc2cd9f340 365 // Deselect the device
dudmuck 0:06cc2cd9f340 366 m_cs = 1;
dudmuck 0:06cc2cd9f340 367
dudmuck 0:06cc2cd9f340 368 return ret;
dudmuck 0:06cc2cd9f340 369 }
dudmuck 0:06cc2cd9f340 370
dudmuck 0:06cc2cd9f340 371 void SX1232::write_reg(uint8_t addr, uint8_t data)
dudmuck 0:06cc2cd9f340 372 {
dudmuck 0:06cc2cd9f340 373 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:06cc2cd9f340 374
dudmuck 0:06cc2cd9f340 375 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:06cc2cd9f340 376
dudmuck 0:06cc2cd9f340 377 // Send a dummy byte to receive the contents of the WHOAMI register
dudmuck 0:06cc2cd9f340 378 m_spi.write(data);
dudmuck 0:06cc2cd9f340 379
dudmuck 0:06cc2cd9f340 380 m_cs = 1; // Deselect the device
dudmuck 0:06cc2cd9f340 381 }
dudmuck 0:06cc2cd9f340 382
dudmuck 0:06cc2cd9f340 383 // variable-length pkt is only 255byte max
dudmuck 0:06cc2cd9f340 384 void SX1232::write_fifo__varlen(uint8_t len)
dudmuck 0:06cc2cd9f340 385 {
dudmuck 0:06cc2cd9f340 386 int i;
dudmuck 0:06cc2cd9f340 387
dudmuck 0:06cc2cd9f340 388 m_cs = 0;
dudmuck 0:06cc2cd9f340 389 m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 0:06cc2cd9f340 390 m_spi.write(len);
dudmuck 0:06cc2cd9f340 391 for (i = 0; i < len; i++) {
dudmuck 0:06cc2cd9f340 392 // todo: flow control for pkt bigger than fifo
dudmuck 0:06cc2cd9f340 393 m_spi.write(tx_buf[i]);
dudmuck 0:06cc2cd9f340 394 }
dudmuck 0:06cc2cd9f340 395 m_cs = 1;
dudmuck 0:06cc2cd9f340 396 }
dudmuck 0:06cc2cd9f340 397
dudmuck 0:06cc2cd9f340 398 // fixed-length packet could be larger than 255 bytes
dudmuck 0:06cc2cd9f340 399 void SX1232::write_fifo__fixedlen(void)
dudmuck 0:06cc2cd9f340 400 {
dudmuck 0:06cc2cd9f340 401 int i, len = get_PayloadLength();
dudmuck 0:06cc2cd9f340 402 m_cs = 0;
dudmuck 0:06cc2cd9f340 403 m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 0:06cc2cd9f340 404 for (i = 0; i < len; i++) {
dudmuck 0:06cc2cd9f340 405 // todo: flow control for pkt bigger than fifo
dudmuck 0:06cc2cd9f340 406 m_spi.write(tx_buf[i]);
dudmuck 0:06cc2cd9f340 407 }
dudmuck 0:06cc2cd9f340 408 m_cs = 1;
dudmuck 0:06cc2cd9f340 409 }
dudmuck 0:06cc2cd9f340 410
dudmuck 0:06cc2cd9f340 411 // arg only for variable-length
dudmuck 0:06cc2cd9f340 412 void SX1232::start_tx(uint8_t len)
dudmuck 0:06cc2cd9f340 413 {
dudmuck 0:06cc2cd9f340 414 if (RegOpMode.bits.Mode > RF_OPMODE_STANDBY) {
dudmuck 0:06cc2cd9f340 415 RegIrqFlags1_t RegIrqFlags1;
dudmuck 0:06cc2cd9f340 416 set_opmode(RF_OPMODE_STANDBY); // unwise fill fifo in RX
dudmuck 0:06cc2cd9f340 417 wait(0.01);
dudmuck 0:06cc2cd9f340 418 RegIrqFlags1.octet = read_reg(REG_IRQFLAGS1);
dudmuck 0:06cc2cd9f340 419 while (!RegIrqFlags1.bits.ModeReady) {
dudmuck 0:06cc2cd9f340 420 //printf("to stby:%02x\r\n", RegIrqFlags1.octet);
dudmuck 0:06cc2cd9f340 421 wait(0.01);
dudmuck 0:06cc2cd9f340 422 RegIrqFlags1.octet = read_reg(REG_IRQFLAGS1);
dudmuck 0:06cc2cd9f340 423 }
dudmuck 0:06cc2cd9f340 424 }
dudmuck 0:06cc2cd9f340 425
dudmuck 0:06cc2cd9f340 426 // DIO0 to PacketSent
dudmuck 0:06cc2cd9f340 427 if (RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 0:06cc2cd9f340 428 RegDioMapping1.bits.Dio0Mapping = 0;
dudmuck 0:06cc2cd9f340 429 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:06cc2cd9f340 430 }
dudmuck 0:06cc2cd9f340 431
dudmuck 0:06cc2cd9f340 432 if (RegPktConfig1.bits.PacketFormatVariable)
dudmuck 0:06cc2cd9f340 433 write_fifo__varlen(len);
dudmuck 0:06cc2cd9f340 434 else
dudmuck 0:06cc2cd9f340 435 write_fifo__fixedlen();
dudmuck 0:06cc2cd9f340 436
dudmuck 0:06cc2cd9f340 437 set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 0:06cc2cd9f340 438 }
dudmuck 0:06cc2cd9f340 439
dudmuck 0:06cc2cd9f340 440 void SX1232::start_rx()
dudmuck 0:06cc2cd9f340 441 {
dudmuck 0:06cc2cd9f340 442 if (RegPktConfig1.bits.CrcOn) { // DIO0 to CrcOk
dudmuck 0:06cc2cd9f340 443 if (RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 0:06cc2cd9f340 444 RegDioMapping1.bits.Dio0Mapping = 1;
dudmuck 0:06cc2cd9f340 445 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:06cc2cd9f340 446 }
dudmuck 0:06cc2cd9f340 447 } else { // DIO0 to PayloadReady
dudmuck 0:06cc2cd9f340 448 if (RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 0:06cc2cd9f340 449 RegDioMapping1.bits.Dio0Mapping = 0;
dudmuck 0:06cc2cd9f340 450 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:06cc2cd9f340 451 }
dudmuck 0:06cc2cd9f340 452 }
dudmuck 0:06cc2cd9f340 453
dudmuck 0:06cc2cd9f340 454 set_opmode(RF_OPMODE_RECEIVER);
dudmuck 0:06cc2cd9f340 455 }