123
Diff: sx127x_fsk.cpp
- Revision:
- 2:fdae76e1215e
- Child:
- 3:3bf2515b1eed
diff -r 7dc60eb4c7ec -r fdae76e1215e sx127x_fsk.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sx127x_fsk.cpp Wed Apr 30 22:49:43 2014 +0000 @@ -0,0 +1,251 @@ +#include "sx127x_fsk.h" + +/* SX127x driver + * Copyright (c) 2013 Semtech + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//SX127x_fsk::SX127x_fsk(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1, PinName fem_ctx, PinName fem_cps) : SX127x(mosi, miso, sclk, cs, rst, dio_0, dio_1, fem_ctx, fem_cps) +SX127x_fsk::SX127x_fsk(SX127x r) : m_xcvr(r) +{ +} + +SX127x_fsk::~SX127x_fsk() +{ +} + +void SX127x_fsk::write_fifo(uint8_t len) +{ + int i; + + m_xcvr.m_cs = 0; + m_xcvr.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio + + if (!m_xcvr.RegOpMode.bits.LongRangeMode && RegPktConfig1.bits.PacketFormatVariable) + m_xcvr.m_spi.write(len); + + for (i = 0; i < len; i++) { + m_xcvr.m_spi.write(m_xcvr.tx_buf[i]); + } + m_xcvr.m_cs = 1; +} + +void SX127x_fsk::enable() +{ + m_xcvr.set_opmode(RF_OPMODE_SLEEP); + + m_xcvr.RegOpMode.bits.LongRangeMode = 0; + m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet); + wait(0.01); + + /*RegOpMode.octet = read_reg(REG_OPMODE); + printf("setloraoff:%02x\r\n", RegOpMode.octet);*/ + + // todo: read FSK regsiters + //SX1272ReadBuffer( REG_OPMODE, SX1272Regs + 1, 0x70 - 1 ); + RegPktConfig1.octet = m_xcvr.read_reg(REG_FSK_PACKETCONFIG1); + RegPktConfig2.word = m_xcvr.read_u16(REG_FSK_PACKETCONFIG2); + + m_xcvr.set_opmode(RF_OPMODE_STANDBY); +} + +uint32_t SX127x_fsk::ComputeRxBw( uint8_t mantisse, uint8_t exponent ) +{ + // rxBw + if (m_xcvr.RegOpMode.bits.ModulationType == 0) + return XTAL_FREQ / (mantisse * (1 << (exponent+2))); + else + return XTAL_FREQ / (mantisse * (1 << (exponent+3))); +} + + +void SX127x_fsk::ComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent ) +{ + uint8_t tmpExp, tmpMant; + double tmpRxBw; + double rxBwMin = 10e6; + + for( tmpExp = 0; tmpExp < 8; tmpExp++ ) { + for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) { + tmpRxBw = ComputeRxBw(tmpMant, tmpExp); + if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) { + rxBwMin = fabs( tmpRxBw - rxBwValue ); + *mantisse = tmpMant; + *exponent = tmpExp; + } + } + } +} + + +uint32_t SX127x_fsk::get_rx_bw_hz(uint8_t addr) +{ + FSKRegRxBw_t reg_bw; + uint8_t mantissa; + + if (m_xcvr.RegOpMode.bits.LongRangeMode) + return 0; + + reg_bw.octet = m_xcvr.read_reg(addr); + switch (reg_bw.bits.Mantissa) { + case 0: mantissa = 16; break; + case 1: mantissa = 20; break; + case 2: mantissa = 24; break; + default: mantissa = 0; break; + } + + if (addr == REG_FSK_RXBW) + RegRxBw.octet = reg_bw.octet; + else if (addr == REG_FSK_AFCBW) + RegAfcBw.octet = reg_bw.octet; + + return ComputeRxBw(mantissa, reg_bw.bits.Exponent); +} + + +void SX127x_fsk::set_rx_dcc_bw_hz(uint32_t bw_hz, char afc) +{ + uint8_t mantisse = 0; + uint8_t exponent = 0; + + if (m_xcvr.RegOpMode.bits.LongRangeMode) + return; + + ComputeRxBwMantExp( bw_hz, &mantisse, &exponent ); + //printf("bw_hz:%d, mantisse:%d, exponent:%d\n", bw_hz, mantisse, exponent ); + switch( mantisse ) { + case 16: + RegRxBw.bits.Mantissa = 0; + break; + case 20: + RegRxBw.bits.Mantissa = 1; + break; + case 24: + RegRxBw.bits.Mantissa = 2; + break; + default: + // Something went terribely wrong + printf("maintisse:%d\n", mantisse); + break; + } + RegRxBw.bits.Exponent = exponent; + + if (afc) + m_xcvr.write_reg(REG_FSK_AFCBW, RegRxBw.octet); + else + m_xcvr.write_reg(REG_FSK_RXBW, RegRxBw.octet); +} + + +void SX127x_fsk::start_tx(uint16_t arg_len) +{ + uint16_t pkt_buf_len; + FSKRegIrqFlags2_t RegIrqFlags2; + int maxlen = FSK_FIFO_SIZE-1; + + if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) { + m_xcvr.set_opmode(RF_OPMODE_STANDBY); + } + + if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) { + m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; + m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet); + } + + if (RegPktConfig1.bits.PacketFormatVariable) { + printf("variable-fmt %d\r\n", arg_len); + pkt_buf_len = arg_len; + } else { + pkt_buf_len = RegPktConfig2.bits.PayloadLength; + printf("fixed-fmt %d\r\n", pkt_buf_len); + } + + RegIrqFlags2.octet = m_xcvr.read_reg(REG_FSK_IRQFLAGS2); + if (RegIrqFlags2.bits.FifoEmpty) { + if (RegPktConfig1.bits.PacketFormatVariable) { + --maxlen; // space for length byte + if (pkt_buf_len > maxlen) { + /*setup_FifoLevel(FALLING_EDGE); + radio_write_fifo_(pkt_buf, maxlen, pkt_buf_len); + remaining_ = pkt_buf_len - maxlen; + printf("var-oversized %d R=%d\r\n", pkt_buf_len, remaining_);*/ + printf("var-oversized %d\r\n", pkt_buf_len); + } else { + //setup_FifoLevel(NO_EDGE); // disable + printf("var-write-fifo %d\r\n", pkt_buf_len); + write_fifo(pkt_buf_len); + //remaining_ = 0; // all was sent + } + } else { // fixed-length pkt format... + pkt_buf_len = RegPktConfig2.bits.PayloadLength; + if (RegPktConfig2.bits.PayloadLength > maxlen) { + /*setup_FifoLevel(FALLING_EDGE); + radio_write_fifo_(pkt_buf, maxlen, -1); + remaining_ = SX1272FSK->RegPktConfig2.bits.PayloadLength - maxlen;*/ + printf("todo: fsk large packet\r\n"); + } else { + //setup_FifoLevel(NO_EDGE); // disable + printf("fixed-write-fifo %d\r\n", RegPktConfig2.bits.PayloadLength); + write_fifo(RegPktConfig2.bits.PayloadLength); + } + } + } else + printf("fifo not empty %02x\r\n", RegIrqFlags2.octet); + + m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER); + +} + + +void SX127x_fsk::start_rx() +{ + if (m_xcvr.RegOpMode.bits.LongRangeMode) + return; + + if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) { + // was already receiving, restart it + m_xcvr.set_opmode(RF_OPMODE_STANDBY); + wait(0.01); + } + m_xcvr.set_opmode(RF_OPMODE_RECEIVER); +} + +service_action_e SX127x_fsk::service() +{ + int i; + + if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) { + if (m_xcvr.dio0) { + m_xcvr.set_opmode(RF_OPMODE_STANDBY); + return SERVICE_TX_DONE; + } + } else if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) { + uint8_t len; + if (RegPktConfig1.bits.PacketFormatVariable) { + len = m_xcvr.read_reg(REG_FIFO); + } else { + len = RegPktConfig2.bits.PayloadLength; + } + + m_xcvr.m_cs = 0; + m_xcvr.m_spi.write(REG_FIFO); // bit7 is low for reading from radio + for (i = 0; i < len; i++) { + m_xcvr.rx_buf[i] = m_xcvr.m_spi.write(0); + } + m_xcvr.m_cs = 1; + return SERVICE_READ_FIFO; + } + + return SERVICE_NONE; +}