wayne roberts / SX1232

Dependents:   chat_sx1232

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 }