bool sx127x_get_crc(const sx127x_t *dev) { #if defined(MODULE_SX1272) return (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1) & SX1272_RF_LORA_MODEMCONFIG1_RXPAYLOADCRC_MASK); #else /* MODULE_SX1276 */ return (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2) & SX1276_RF_LORA_MODEMCONFIG2_RXPAYLOADCRC_MASK); #endif }
void sx127x_set_tx(sx127x_t *dev) { switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: { if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* RFLR_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | /* RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | */ SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=TxDone, DIO2=FhssChangeChannel */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1 ) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK & SX127X_RF_LORA_DIOMAPPING1_DIO2_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01 | SX127X_RF_LORA_DIOMAPPING1_DIO2_00); } else { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* RFLR_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=TxDone */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01); } } break; } sx127x_set_state(dev, SX127X_RF_RX_RUNNING); if (dev->settings.lora.tx_timeout != 0) { xtimer_set(&(dev->_internal.tx_timeout_timer), dev->settings.lora.tx_timeout); } sx127x_set_op_mode(dev, SX127X_RF_OPMODE_TRANSMITTER ); }
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) { sx127x_t *dev = (sx127x_t*) netdev; volatile uint8_t irq_flags = 0; uint8_t size = 0; switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: /* Clear IRQ */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_RXDONE); irq_flags = sx127x_reg_read(dev, SX127X_REG_LR_IRQFLAGS); if ( (irq_flags & SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR_MASK) == SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR) { /* Clear IRQ */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR); if (!(dev->settings.lora.flags & SX127X_RX_CONTINUOUS_FLAG)) { sx127x_set_state(dev, SX127X_RF_IDLE); } xtimer_remove(&dev->_internal.rx_timeout_timer); netdev->event_callback(netdev, NETDEV_EVENT_CRC_ERROR); return -EBADMSG; } netdev_sx127x_lora_packet_info_t *packet_info = info; if (packet_info) { /* there is no LQI for LoRa */ packet_info->lqi = 0; uint8_t snr_value = sx127x_reg_read(dev, SX127X_REG_LR_PKTSNRVALUE); if (snr_value & 0x80) { /* The SNR is negative */ /* Invert and divide by 4 */ packet_info->snr = -1 * ((~snr_value + 1) & 0xFF) >> 2; } else { /* Divide by 4 */ packet_info->snr = (snr_value & 0xFF) >> 2; } int16_t rssi = sx127x_reg_read(dev, SX127X_REG_LR_PKTRSSIVALUE); if (packet_info->snr < 0) { #if defined(MODULE_SX1272) packet_info->rssi = SX127X_RSSI_OFFSET + rssi + (rssi >> 4) + packet_info->snr; #else /* MODULE_SX1276 */ if (dev->settings.channel > SX127X_RF_MID_BAND_THRESH) { packet_info->rssi = SX127X_RSSI_OFFSET_HF + rssi + (rssi >> 4) + packet_info->snr; }
uint8_t sx127x_get_max_payload_len(const sx127x_t *dev) { switch (dev->settings.modem) { case SX127X_MODEM_FSK: return sx127x_reg_read(dev, SX127X_REG_PAYLOADLENGTH); case SX127X_MODEM_LORA: return sx127x_reg_read(dev, SX127X_REG_LR_PAYLOADMAXLENGTH); } /* should never be reached */ return 0; }
void sx127x_set_op_mode(const sx127x_t *dev, uint8_t op_mode) { #if ENABLE_DEBUG switch(op_mode) { case SX127X_RF_OPMODE_SLEEP: DEBUG("[sx127x] Set op mode: SLEEP\n"); break; case SX127X_RF_OPMODE_STANDBY: DEBUG("[sx127x] Set op mode: STANDBY\n"); break; case SX127X_RF_OPMODE_RECEIVER_SINGLE: DEBUG("[sx127x] Set op mode: RECEIVER SINGLE\n"); break; case SX127X_RF_OPMODE_RECEIVER: DEBUG("[sx127x] Set op mode: RECEIVER\n"); break; case SX127X_RF_OPMODE_TRANSMITTER: DEBUG("[sx127x] Set op mode: TRANSMITTER\n"); break; default: DEBUG("[sx127x] Set op mode: UNKNOWN (%d)\n", op_mode); break; } #endif /* Replace previous mode value and setup new mode value */ sx127x_reg_write(dev, SX127X_REG_OPMODE, (sx127x_reg_read(dev, SX127X_REG_OPMODE) & SX127X_RF_OPMODE_MASK) | op_mode); }
void sx127x_set_crc(sx127x_t *dev, bool crc) { DEBUG("[sx127x] Set CRC: %d\n", crc); _set_flag(dev, SX127X_ENABLE_CRC_FLAG, crc); #if defined(MODULE_SX1272) uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1); config2_reg &= SX1272_RF_LORA_MODEMCONFIG1_RXPAYLOADCRC_MASK; config2_reg |= crc << 1; sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config2_reg); #else /* MODULE_SX1276 */ uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2); config2_reg &= SX1276_RF_LORA_MODEMCONFIG2_RXPAYLOADCRC_MASK; config2_reg |= crc << 2; sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG2, config2_reg); #endif }
void sx127x_set_symbol_timeout(sx127x_t *dev, uint16_t timeout) { DEBUG("[sx127x] Set symbol timeout: %d\n", timeout); uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2); config2_reg &= SX127X_RF_LORA_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK; config2_reg |= (timeout >> 8) & ~SX127X_RF_LORA_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK; sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG2, config2_reg); sx127x_reg_write(dev, SX127X_REG_LR_SYMBTIMEOUTLSB, timeout & 0xFF); }
void sx127x_set_hop_period(sx127x_t *dev, uint8_t hop_period) { DEBUG("[sx127x] Set Hop period: %d\n", hop_period); dev->settings.lora.freq_hop_period = hop_period; uint8_t tmp = sx127x_reg_read(dev, SX127X_REG_LR_PLLHOP); if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { tmp |= SX127X_RF_LORA_PLLHOP_FASTHOP_ON; sx127x_reg_write(dev, SX127X_REG_LR_PLLHOP, tmp); sx127x_reg_write(dev, SX127X_REG_LR_HOPPERIOD, hop_period); } }
void sx127x_set_modem(sx127x_t *dev, uint8_t modem) { DEBUG("[sx127x] set modem: %d\n", modem); if ((sx127x_reg_read(dev, SX127X_REG_OPMODE) & SX127X_RF_LORA_OPMODE_LONGRANGEMODE_ON) != 0) { dev->settings.modem = SX127X_MODEM_LORA; } else { dev->settings.modem = SX127X_MODEM_FSK; } /* Skip if unchanged to avoid resetting the transceiver below (may end up * in crashes) */ if (dev->settings.modem == modem) { DEBUG("[sx127x] already using modem: %d\n", modem); return; } dev->settings.modem = modem; switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* Todo */ break; case SX127X_MODEM_LORA: sx127x_set_op_mode(dev, SX127X_RF_OPMODE_SLEEP); sx127x_reg_write(dev, SX127X_REG_OPMODE, (sx127x_reg_read(dev, SX127X_REG_OPMODE) & SX127X_RF_LORA_OPMODE_LONGRANGEMODE_MASK) | SX127X_RF_LORA_OPMODE_LONGRANGEMODE_ON); sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, 0x00); sx127x_reg_write(dev, SX127X_REG_DIOMAPPING2, 0x00); break; default: break; } }
static void _low_datarate_optimize(sx127x_t *dev) { if ( ((dev->settings.lora.bandwidth == LORA_BW_125_KHZ) && ((dev->settings.lora.datarate == LORA_SF11) || (dev->settings.lora.datarate == LORA_SF12))) || ((dev->settings.lora.bandwidth == LORA_BW_250_KHZ) && (dev->settings.lora.datarate == LORA_SF12))) { dev->settings.lora.flags |= SX127X_LOW_DATARATE_OPTIMIZE_FLAG; } else { dev->settings.lora.flags &= ~SX127X_LOW_DATARATE_OPTIMIZE_FLAG; } #if defined(MODULE_SX1272) sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1) & SX127X_RF_LORA_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) | ((dev->settings.lora.flags & SX127X_LOW_DATARATE_OPTIMIZE_FLAG))); #else /* MODULE_SX1276 */ sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG3, (sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG3) & SX127X_RF_LORA_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) | ((dev->settings.lora.flags & SX127X_LOW_DATARATE_OPTIMIZE_FLAG) << 3)); #endif }
void sx127x_set_fixed_header_len_mode(sx127x_t *dev, bool fixed_len) { DEBUG("[sx127x] Set fixed header length: %d\n", fixed_len); _set_flag(dev, SX127X_ENABLE_FIXED_HEADER_LENGTH_FLAG, fixed_len); uint8_t config1_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1); #if defined(MODULE_SX1272) config1_reg &= SX1272_RF_LORA_MODEMCONFIG1_IMPLICITHEADER_MASK; config1_reg |= fixed_len << 2; #else /* MODULE_SX1276 */ config1_reg &= SX1276_RF_LORA_MODEMCONFIG1_IMPLICITHEADER_MASK; config1_reg |= fixed_len; #endif sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config1_reg); }
void sx127x_set_iq_invert(sx127x_t *dev, bool iq_invert) { DEBUG("[sx127x] Set IQ invert: %d\n", iq_invert); _set_flag(dev, SX127X_IQ_INVERTED_FLAG, iq_invert); sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ, (sx127x_reg_read(dev, SX127X_REG_LR_INVERTIQ) & SX127X_RF_LORA_INVERTIQ_RX_MASK & SX127X_RF_LORA_INVERTIQ_TX_MASK) | SX127X_RF_LORA_INVERTIQ_RX_OFF | (iq_invert ? SX127X_RF_LORA_INVERTIQ_TX_ON : SX127X_RF_LORA_INVERTIQ_TX_OFF)); sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ2, (iq_invert ? SX127X_RF_LORA_INVERTIQ2_ON : SX127X_RF_LORA_INVERTIQ2_OFF)); }
void sx127x_set_coding_rate(sx127x_t *dev, uint8_t coderate) { DEBUG("[sx127x] Set coding rate: %d\n", coderate); dev->settings.lora.coderate = coderate; uint8_t config1_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1); #if defined(MODULE_SX1272) config1_reg &= SX1272_RF_LORA_MODEMCONFIG1_CODINGRATE_MASK; config1_reg |= coderate << 3; #else /* MODULE_SX1276 */ config1_reg &= SX1276_RF_LORA_MODEMCONFIG1_CODINGRATE_MASK; config1_reg |= coderate << 1; #endif sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config1_reg); }
static void _update_bandwidth(const sx127x_t *dev) { uint8_t config1_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG1); #if defined(MODULE_SX1272) config1_reg &= SX1272_RF_LORA_MODEMCONFIG1_BW_MASK; switch (dev->settings.lora.bandwidth) { case LORA_BW_125_KHZ: config1_reg |= SX1272_RF_LORA_MODEMCONFIG1_BW_125_KHZ; break; case LORA_BW_250_KHZ: config1_reg |= SX1272_RF_LORA_MODEMCONFIG1_BW_250_KHZ; break; case LORA_BW_500_KHZ: config1_reg |= SX1272_RF_LORA_MODEMCONFIG1_BW_500_KHZ; break; default: DEBUG("Unsupported bandwidth, %d", dev->settings.lora.bandwidth); break; } #else /* MODULE_SX1276 */ config1_reg &= SX1276_RF_LORA_MODEMCONFIG1_BW_MASK; switch (dev->settings.lora.bandwidth) { case LORA_BW_125_KHZ: config1_reg |= SX1276_RF_LORA_MODEMCONFIG1_BW_125_KHZ; break; case LORA_BW_250_KHZ: config1_reg |= SX1276_RF_LORA_MODEMCONFIG1_BW_250_KHZ; break; case LORA_BW_500_KHZ: config1_reg |= SX1276_RF_LORA_MODEMCONFIG1_BW_500_KHZ; break; default: DEBUG("[sx127x] Unsupported bandwidth, %d\n", dev->settings.lora.bandwidth); break; } #endif sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG1, config1_reg); }
void sx127x_set_spreading_factor(sx127x_t *dev, uint8_t datarate) { DEBUG("[sx127x] Set spreading factor: %d\n", datarate); if (datarate == LORA_SF6 && !(dev->settings.lora.flags & SX127X_ENABLE_FIXED_HEADER_LENGTH_FLAG)) { /* SF 6 is only valid when using explicit header mode */ DEBUG("Spreading Factor 6 can only be used when explicit header " "mode is set, this mode is not supported by this driver." "Ignoring.\n"); return; } dev->settings.lora.datarate = datarate; uint8_t config2_reg = sx127x_reg_read(dev, SX127X_REG_LR_MODEMCONFIG2); config2_reg &= SX127X_RF_LORA_MODEMCONFIG2_SF_MASK; config2_reg |= datarate << 4; sx127x_reg_write(dev, SX127X_REG_LR_MODEMCONFIG2, config2_reg); _low_datarate_optimize(dev); switch(dev->settings.lora.datarate) { case LORA_SF6: sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE, SX127X_RF_LORA_DETECTIONOPTIMIZE_SF6); sx127x_reg_write(dev, SX127X_REG_LR_DETECTIONTHRESHOLD, SX127X_RF_LORA_DETECTIONTHRESH_SF6); break; default: sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE, SX127X_RF_LORA_DETECTIONOPTIMIZE_SF7_TO_SF12); sx127x_reg_write(dev, SX127X_REG_LR_DETECTIONTHRESHOLD, SX127X_RF_LORA_DETECTIONTHRESH_SF7_TO_SF12); break; } }
int register_cmd(int argc, char **argv) { if (argc < 2) { puts("usage: register <get | set>"); return -1; } if (strstr(argv[1], "get") != NULL) { if (argc < 3) { puts("usage: register get <all | allinline | regnum>"); return -1; } if (strcmp(argv[2], "all") == 0) { puts("- listing all registers -"); uint8_t reg = 0, data = 0; /* Listing registers map */ puts("Reg 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for (unsigned i = 0; i <= 7; i++) { printf("0x%02X ", i << 4); for (unsigned j = 0; j <= 15; j++, reg++) { data = sx127x_reg_read(&sx127x, reg); printf("%02X ", data); } puts(""); } puts("-done-"); return 0; } else if (strcmp(argv[2], "allinline") == 0) { puts("- listing all registers in one line -"); /* Listing registers map */ for (uint16_t reg = 0; reg < 256; reg++) { printf("%02X ", sx127x_reg_read(&sx127x, (uint8_t) reg)); } puts("- done -"); return 0; } else { long int num = 0; /* Register number in hex */ if (strstr(argv[2], "0x") != NULL) { num = strtol(argv[2], NULL, 16); } else { num = atoi(argv[2]); } if (num >= 0 && num <= 255) { printf("[regs] 0x%02X = 0x%02X\n", (uint8_t) num, sx127x_reg_read(&sx127x, (uint8_t) num)); } else { puts("regs: invalid register number specified"); return -1; } } } else if (strstr(argv[1], "set") != NULL) { if (argc < 4) { puts("usage: register set <regnum> <value>"); return -1; } long num, val; /* Register number in hex */ if (strstr(argv[2], "0x") != NULL) { num = strtol(argv[2], NULL, 16); } else { num = atoi(argv[2]); } /* Register value in hex */ if (strstr(argv[3], "0x") != NULL) { val = strtol(argv[3], NULL, 16); } else { val = atoi(argv[3]); } sx127x_reg_write(&sx127x, (uint8_t) num, (uint8_t) val); } else { puts("usage: register get <all | allinline | regnum>"); return -1; } return 0; }
uint32_t sx127x_get_channel(const sx127x_t *dev) { return (((uint32_t)sx127x_reg_read(dev, SX127X_REG_FRFMSB) << 16) | (sx127x_reg_read(dev, SX127X_REG_FRFMID) << 8) | (sx127x_reg_read(dev, SX127X_REG_FRFLSB))) * LORA_FREQUENCY_RESOLUTION_DEFAULT; }
void sx127x_set_rx(sx127x_t *dev) { DEBUG("[sx127x] Set RX\n"); switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: { sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ, ((sx127x_reg_read(dev, SX127X_REG_LR_INVERTIQ) & SX127X_RF_LORA_INVERTIQ_TX_MASK & SX127X_RF_LORA_INVERTIQ_RX_MASK) | ((dev->settings.lora.flags & SX127X_IQ_INVERTED_FLAG) ? SX127X_RF_LORA_INVERTIQ_RX_ON :SX127X_RF_LORA_INVERTIQ_RX_OFF) | SX127X_RF_LORA_INVERTIQ_TX_OFF)); sx127x_reg_write(dev, SX127X_REG_LR_INVERTIQ2, ((dev->settings.lora.flags & SX127X_IQ_INVERTED_FLAG) ? SX127X_RF_LORA_INVERTIQ2_ON : SX127X_RF_LORA_INVERTIQ2_OFF)); #if defined(MODULE_SX1276) /* ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal */ if (dev->settings.lora.bandwidth < 9) { sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE, sx127x_reg_read(dev, SX127X_REG_LR_DETECTOPTIMIZE) & 0x7F); sx127x_reg_write(dev, SX127X_REG_LR_TEST30, 0x00); switch (dev->settings.lora.bandwidth) { case LORA_BW_125_KHZ: /* 125 kHz */ sx127x_reg_write(dev, SX127X_REG_LR_TEST2F, 0x40); break; case LORA_BW_250_KHZ: /* 250 kHz */ sx127x_reg_write(dev, SX127X_REG_LR_TEST2F, 0x40); break; default: break; } } else { sx127x_reg_write(dev, SX127X_REG_LR_DETECTOPTIMIZE, sx127x_reg_read(dev, SX127X_REG_LR_DETECTOPTIMIZE) | 0x80); } #endif /* Setup interrupts */ if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, /* SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | */ SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | SX127X_RF_LORA_IRQFLAGS_TXDONE | SX127X_RF_LORA_IRQFLAGS_CADDONE | /* SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | */ SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=RxDone, DIO2=FhssChangeChannel */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK & SX127X_RF_LORA_DIOMAPPING1_DIO2_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_00 | SX127X_RF_LORA_DIOMAPPING1_DIO2_00); } else { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, /* SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | */ SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | SX127X_RF_LORA_IRQFLAGS_TXDONE | SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=RxDone */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_00); } sx127x_reg_write(dev, SX127X_REG_LR_FIFORXBASEADDR, 0); sx127x_reg_write(dev, SX127X_REG_LR_FIFOADDRPTR, 0); } break; } sx127x_set_state(dev, SX127X_RF_RX_RUNNING); if (dev->settings.lora.rx_timeout != 0) { xtimer_set(&(dev->_internal.rx_timeout_timer), dev->settings.lora.rx_timeout); } if (dev->settings.lora.flags & SX127X_RX_CONTINUOUS_FLAG) { sx127x_set_op_mode(dev, SX127X_RF_LORA_OPMODE_RECEIVER); } else { sx127x_set_op_mode(dev, SX127X_RF_LORA_OPMODE_RECEIVER_SINGLE); } }
void sx127x_set_tx_power(sx127x_t *dev, int8_t power) { DEBUG("[sx127x] Set power: %d\n", power); dev->settings.lora.power = power; uint8_t pa_config = sx127x_reg_read(dev, SX127X_REG_PACONFIG); #if defined(MODULE_SX1272) uint8_t pa_dac = sx127x_reg_read(dev, SX1272_REG_PADAC); #else /* MODULE_SX1276 */ uint8_t pa_dac = sx127x_reg_read(dev, SX1276_REG_PADAC); #endif pa_config = ((pa_config & SX127X_RF_PACONFIG_PASELECT_MASK) | sx127x_get_pa_select(dev)); #if defined(MODULE_SX1276) /* max power is 14dBm */ pa_config = (pa_config & SX127X_RF_PACONFIG_MAX_POWER_MASK) | 0x70; #endif sx127x_reg_write(dev, SX127X_REG_PARAMP, SX127X_RF_PARAMP_0050_US); if ((pa_config & SX127X_RF_PACONFIG_PASELECT_PABOOST) == SX127X_RF_PACONFIG_PASELECT_PABOOST) { if (power > 17) { pa_dac = ((pa_dac & SX127X_RF_PADAC_20DBM_MASK) | SX127X_RF_PADAC_20DBM_ON); } else { pa_dac = ((pa_dac & SX127X_RF_PADAC_20DBM_MASK) | SX127X_RF_PADAC_20DBM_OFF); } if ((pa_dac & SX127X_RF_PADAC_20DBM_ON) == SX127X_RF_PADAC_20DBM_ON) { if (power < 5) { power = 5; } if (power > 20) { power = 20; } pa_config = ((pa_config & SX127X_RF_PACONFIG_OUTPUTPOWER_MASK) | (uint8_t)((uint16_t)(power - 5) & 0x0F)); } else { if (power < 2) { power = 2; } if (power > 17) { power = 17; } pa_config = ((pa_config & SX127X_RF_PACONFIG_OUTPUTPOWER_MASK) | (uint8_t)((uint16_t)(power - 2) & 0x0F)); } } else { if (power < -1) { power = -1; } if (power > 14) { power = 14; } pa_config = ((pa_config & SX127X_RF_PACONFIG_OUTPUTPOWER_MASK) | (uint8_t)((uint16_t)(power + 1) & 0x0F)); } sx127x_reg_write(dev, SX127X_REG_PACONFIG, pa_config); #if defined(MODULE_SX1272) sx127x_reg_write(dev, SX1272_REG_PADAC, pa_dac); #else /* MODULE_SX1276 */ sx127x_reg_write(dev, SX1276_REG_PADAC, pa_dac); #endif }
uint8_t sx127x_get_payload_length(const sx127x_t *dev) { return sx127x_reg_read(dev, SX127X_REG_LR_PAYLOADLENGTH);; }
uint8_t sx127x_get_op_mode(const sx127x_t *dev) { return sx127x_reg_read(dev, SX127X_REG_OPMODE) & ~SX127X_RF_OPMODE_MASK; }
uint8_t sx127x_get_hop_period(const sx127x_t *dev) { return sx127x_reg_read(dev, SX127X_REG_LR_HOPPERIOD); }
uint8_t sx127x_get_syncword(const sx127x_t *dev) { return sx127x_reg_read(dev, SX127X_REG_LR_SYNCWORD); }
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) { sx127x_t *dev = (sx127x_t*) netdev; if (sx127x_get_state(dev) == SX127X_RF_TX_RUNNING) { DEBUG("[WARNING] Cannot send packet: radio already in transmitting " "state.\n"); return -ENOTSUP; } uint8_t size; size = _get_tx_len(vector, count); switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: /* Initializes the payload size */ sx127x_set_payload_length(dev, size); /* Full buffer used for Tx */ sx127x_reg_write(dev, SX127X_REG_LR_FIFOTXBASEADDR, 0x00); sx127x_reg_write(dev, SX127X_REG_LR_FIFOADDRPTR, 0x00); /* FIFO operations can not take place in Sleep mode * So wake up the chip */ if (sx127x_get_op_mode(dev) == SX127X_RF_OPMODE_SLEEP) { sx127x_set_standby(dev); xtimer_usleep(SX127X_RADIO_WAKEUP_TIME); /* wait for chip wake up */ } /* Write payload buffer */ for (size_t i = 0; i < count; i++) { sx127x_write_fifo(dev, vector[i].iov_base, vector[i].iov_len); } break; default: puts("sx127x_netdev, Unsupported modem"); break; } /* Enable TXDONE interrupt */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* SX127X_RF_LORA_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* Set TXDONE interrupt to the DIO0 line */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01); /* Start TX timeout timer */ xtimer_set(&dev->_internal.tx_timeout_timer, dev->settings.lora.tx_timeout); /* Put chip into transfer mode */ sx127x_set_state(dev, SX127X_RF_TX_RUNNING); sx127x_set_op_mode(dev, SX127X_RF_OPMODE_TRANSMITTER); return 0; }
void sx127x_set_tx(sx127x_t *dev) { #ifdef SX127X_USE_RX_SWITCH gpio_clear(dev->params.rx_switch_pin); #endif #ifdef SX127X_USE_TX_SWITCH gpio_set(dev->params.tx_switch_pin); #endif switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ break; case SX127X_MODEM_LORA: { if (dev->settings.lora.flags & SX127X_CHANNEL_HOPPING_FLAG) { sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* RFLR_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | /* RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | */ SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* DIO0=TxDone, DIO2=FhssChangeChannel */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1 ) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK & SX127X_RF_LORA_DIOMAPPING1_DIO2_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01 | SX127X_RF_LORA_DIOMAPPING1_DIO2_00); } else { /* Enable TXDONE interrupt */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGSMASK, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT | SX127X_RF_LORA_IRQFLAGS_RXDONE | SX127X_RF_LORA_IRQFLAGS_PAYLOADCRCERROR | SX127X_RF_LORA_IRQFLAGS_VALIDHEADER | /* SX127X_RF_LORA_IRQFLAGS_TXDONE | */ SX127X_RF_LORA_IRQFLAGS_CADDONE | SX127X_RF_LORA_IRQFLAGS_FHSSCHANGEDCHANNEL | SX127X_RF_LORA_IRQFLAGS_CADDETECTED); /* Set TXDONE interrupt to the DIO0 line */ sx127x_reg_write(dev, SX127X_REG_DIOMAPPING1, (sx127x_reg_read(dev, SX127X_REG_DIOMAPPING1) & SX127X_RF_LORA_DIOMAPPING1_DIO0_MASK) | SX127X_RF_LORA_DIOMAPPING1_DIO0_01); } } break; } sx127x_set_state(dev, SX127X_RF_TX_RUNNING); /* Start TX timeout timer */ if (dev->settings.lora.tx_timeout != 0) { xtimer_set(&(dev->_internal.tx_timeout_timer), dev->settings.lora.tx_timeout); } /* Put chip into transfer mode */ sx127x_set_op_mode(dev, SX127X_RF_OPMODE_TRANSMITTER ); }