From 4977430ef31fb52994fed42b9cb180930ed943d0 Mon Sep 17 00:00:00 2001 From: Sylvain Miermont Date: Tue, 22 Oct 2013 18:23:52 +0200 Subject: Beta 8 - API: lgw_receive now return info on RX frequency and RF path for each packet (no need to keep track of RF/IF settings) - Unified some portion of the code with the 470 MHz variant of the HAL (use SX1255 radios instead of SX1257) - Improved AGC and ARB firmwares - Adding -Wall -Wextra for compilation, fixing all the new warnings for cleaner code - Fixed bugs in handling of FSK datarate - test_loragw_hal now dumps the content of all Lora registers after configuration in reg_dump.log --- libloragw/src/loragw_hal.c | 89 ++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 42 deletions(-) (limited to 'libloragw/src/loragw_hal.c') diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c index a57d9f1..930f13e 100644 --- a/libloragw/src/loragw_hal.c +++ b/libloragw/src/loragw_hal.c @@ -36,7 +36,7 @@ Description: #else #define DEBUG_MSG(str) #define DEBUG_PRINTF(fmt, args...) - #define DEBUG_ARRAY(a,b,c) + #define DEBUG_ARRAY(a,b,c) for(a=0;a!=0;){} #define CHECK_NULL(a) if(a==NULL){return LGW_HAL_ERROR;} #endif @@ -61,25 +61,25 @@ const uint32_t rf_tx_upfreq[LGW_RF_CHAIN_NB] = LGW_RF_TX_UPFREQ; #define MCU_AGC_FW_BYTE 8192 /* size of the firmware IN BYTES (= twice the number of 14b words) */ /* -SX1275 frequency setting : +SX1257 frequency setting : F_register(24bit) = F_rf (Hz) / F_step(Hz) = F_rf (Hz) * 2^19 / F_xtal(Hz) + = F_rf (Hz) * 2^19 / 32e6 = F_rf (Hz) * 256/15625 */ -#define SX1257_DENOM 15625 /* pll settings denominator when the numerator is 2^8 */ +#define SX125x_32MHz_FRAC 15625 /* irreductible fraction for PLL register caculation */ -#define SX1257_CLK_OUT 1 -#define SX1257_TX_DAC_CLK_SEL 1 /* 0:int, 1:ext */ -#define SX1257_TX_DAC_GAIN 2 /* 3:0, 2:-3, 1:-6, 0:-9 dBFS (default 2) */ -#define SX1257_TX_MIX_GAIN 14 /* -38 + 2*TxMixGain dB (default 14) */ -#define SX1257_TX_PLL_BW 3 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3) */ -#define SX1257_TX_ANA_BW 0 /* 17.5 / 2*(41-TxAnaBw) MHz (default 0) */ -#define SX1257_TX_DAC_BW 7 /* 24 + 8*TxDacBw Nb FIR taps (default 2) */ -#define SX1257_RX_LNA_GAIN 1 /* 1 to 6, 1 highest gain */ -#define SX1257_RX_BB_GAIN 12 /* 0 to 15 , 15 highest gain */ -#define SX1257_RX_ADC_BW 7 /* 0 to 7, 2:100 radio A, 1 -> radio B */ @@ -135,9 +135,9 @@ static uint32_t fsk_rx_dr = 0; /* FSK modem datarate in bauds */ int load_firmware(uint8_t target, uint8_t *firmware, uint16_t size); -void sx125x_write(uint8_t rf_chain, uint8_t addr, uint8_t data); +void sx125x_write(uint8_t channel, uint8_t addr, uint8_t data); -uint8_t sx125x_read(uint8_t rf_chain, uint8_t addr); +uint8_t sx125x_read(uint8_t channel, uint8_t addr); int setup_sx1257(uint8_t rf_chain, uint32_t freq_hz); @@ -148,7 +148,6 @@ void lgw_constant_adjust(void); /* size is the firmware size in bytes (not 14b words) */ int load_firmware(uint8_t target, uint8_t *firmware, uint16_t size) { - int32_t read_value; int reg_rst; int reg_sel; @@ -292,24 +291,28 @@ int setup_sx1257(uint8_t rf_chain, uint32_t freq_hz) { DEBUG_MSG("ERROR: INVALID RF_CHAIN\n"); return -1; } - - /* misc */ - sx125x_write(rf_chain, 0x10, SX1257_TX_DAC_CLK_SEL + SX1257_CLK_OUT*2); + + if (rf_chain == 0) { /* Enable 'clock out' for radio A only */ + sx125x_write(rf_chain, 0x10, SX125x_TX_DAC_CLK_SEL + 2); + } else { + sx125x_write(rf_chain, 0x10, SX125x_TX_DAC_CLK_SEL); + } + sx125x_write(rf_chain, 0x26, 0X2D); /* Disable gm of oscillator block */ /* Tx gain and trim */ - sx125x_write(rf_chain, 0x08, SX1257_TX_MIX_GAIN + SX1257_TX_DAC_GAIN*16); - sx125x_write(rf_chain, 0x0A, SX1257_TX_ANA_BW + SX1257_TX_PLL_BW*32); - sx125x_write(rf_chain, 0x0B, SX1257_TX_DAC_BW); + sx125x_write(rf_chain, 0x08, SX125x_TX_MIX_GAIN + SX125x_TX_DAC_GAIN*16); + sx125x_write(rf_chain, 0x0A, SX125x_TX_ANA_BW + SX125x_TX_PLL_BW*32); + sx125x_write(rf_chain, 0x0B, SX125x_TX_DAC_BW); /* Rx gain and trim */ - sx125x_write(rf_chain, 0x0C, 0 + SX1257_RX_BB_GAIN*2 + SX1257_RX_LNA_GAIN*32); - sx125x_write(rf_chain, 0x0D, SX1257_RXBB_BW + SX1257_RX_ADC_TRIM*4 + SX1257_RX_ADC_BW*32); + sx125x_write(rf_chain, 0x0C, 0 + SX125x_RX_BB_GAIN*2 + SX125x_RX_LNA_GAIN*32); + sx125x_write(rf_chain, 0x0D, SX125x_RXBB_BW + SX125x_RX_ADC_TRIM*4 + SX125x_RX_ADC_BW*32); /* set RX PLL frequency */ - part_int = freq_hz / SX1257_DENOM; /* integer part, gives the MSB and the middle byte */ - part_frac = ((freq_hz % SX1257_DENOM) << 8) / SX1257_DENOM; /* fractional part, gives LSB */ - sx125x_write(rf_chain, 0x01,0xFF & (part_int >> 8)); /* Most Significant Byte */ - sx125x_write(rf_chain, 0x02,0xFF & part_int); /* middle byte */ + part_int = freq_hz / (SX125x_32MHz_FRAC << 8); /* integer part, gives the MSB */ + part_frac = ((freq_hz % (SX125x_32MHz_FRAC << 8)) << 8) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */ + sx125x_write(rf_chain, 0x01,0xFF & part_int); /* Most Significant Byte */ + sx125x_write(rf_chain, 0x02,0xFF & (part_frac >> 8)); /* middle byte */ sx125x_write(rf_chain, 0x03,0xFF & part_frac); /* Least Significant Byte */ /* start and PLL lock */ @@ -321,9 +324,9 @@ int setup_sx1257(uint8_t rf_chain, uint32_t freq_hz) { sx125x_write(rf_chain, 0x00, 1); /* enable Xtal oscillator */ sx125x_write(rf_chain, 0x00, 3); /* Enable RX (PLL+FE) */ ++cpt_attempts; - DEBUG_PRINTF("Note: SX1257 #%d PLL start (attempt %d)\n", rf_chain, cpt_attempts); + DEBUG_PRINTF("Note: SX125x #%d PLL start (attempt %d)\n", rf_chain, cpt_attempts); wait_ms(1); - } while(sx125x_read(rf_chain, 0x11) & 0x02 == 0); + } while((sx125x_read(rf_chain, 0x11) & 0x02) == 0); return 0; } @@ -340,7 +343,7 @@ void lgw_constant_adjust(void) { // lgw_reg_w(LGW_MBWSSF_MODEM_INVERT_IQ,0); /* default 0 */ // lgw_reg_w(LGW_DC_NOTCH_EN,1); /* default 1 */ lgw_reg_w(LGW_RSSI_BB_FILTER_ALPHA,9); /* default 7 */ - lgw_reg_w(LGW_RSSI_DEC_FILTER_ALPHA,7); /* default 5 */ + lgw_reg_w(LGW_RSSI_DEC_FILTER_ALPHA,9); /* default 5 */ lgw_reg_w(LGW_RSSI_CHANN_FILTER_ALPHA,7); /* default 8 */ // lgw_reg_w(LGW_RSSI_BB_DEFAULT_VALUE,32); /* default 32 */ lgw_reg_w(LGW_RSSI_CHANN_DEFAULT_VALUE,90); /* default 100 */ @@ -608,7 +611,6 @@ int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s conf) { int lgw_start(void) { int i, j; int reg_stat; - int32_t read_value; if (lgw_is_started == true) { DEBUG_MSG("Note: Lora Gateway already started, restarting it now\n"); @@ -747,7 +749,6 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { int nb_pkt_fetch; /* loop variable and return value */ struct lgw_pkt_rx_s *p; /* pointer to the current structure in the struct array */ uint8_t buff[255+RX_METADATA_NB]; /* buffer to store the result of SPI read bursts */ - uint16_t data_addr; /* address read from the FIFO and programmed before the data buffer read operation */ int s; /* size of the payload, uses to address metadata */ int ifmod; /* type of if_chain/modem a packet was received by */ int stat_fifo; /* the packet status as indicated in the FIFO */ @@ -864,6 +865,10 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { p->count_us = (uint32_t)buff[s+6] + ((uint32_t)buff[s+7] << 8) + ((uint32_t)buff[s+8] << 16) + ((uint32_t)buff[s+9] << 24); p->crc = (uint16_t)buff[s+10] + ((uint16_t)buff[s+11] << 8); + /* get back info from configuration so that application doesn't have to keep track of it */ + p->rf_chain = (uint8_t)if_rf_chain[p->if_chain]; + p->freq_hz = (uint32_t)((int32_t)rf_rx_freq[p->rf_chain] + if_freq[p->if_chain]); + /* advance packet FIFO */ lgw_reg_w(LGW_RX_PACKET_DATA_FIFO_NUM_STORED, 0); } @@ -874,13 +879,13 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ int lgw_send(struct lgw_pkt_tx_s pkt_data) { + int i; uint8_t buff[256+TX_METADATA_NB]; /* buffer to prepare the packet to send + metadata before SPI write burst */ uint32_t part_int; /* integer part for PLL register value calculation */ uint32_t part_frac; /* fractional part for PLL register value calculation */ uint16_t fsk_dr_div; /* divider to configure for target datarate */ int transfer_size = 0; /* data to transfer from host to TX databuffer */ int payload_offset = 0; /* start of the payload content in the databuffer */ - int i; /* check if the gateway is running */ if (lgw_is_started == false) { @@ -953,10 +958,10 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) { payload_offset = TX_METADATA_NB; /* start the payload just after the metadata */ /* metadata 0 to 2, TX PLL frequency */ - part_int = pkt_data.freq_hz / SX1257_DENOM; /* integer part, gives the MSB and the middle byte */ - part_frac = ((pkt_data.freq_hz % SX1257_DENOM) << 8) / SX1257_DENOM; /* fractional part, gives LSB */ - buff[0] = 0xFF & (part_int >> 8); /* Most Significant Byte */ - buff[1] = 0xFF & part_int; /* middle byte */ + part_int = pkt_data.freq_hz / (SX125x_32MHz_FRAC << 8); /* integer part, gives the MSB */ + part_frac = ((pkt_data.freq_hz % (SX125x_32MHz_FRAC << 8)) << 8) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */ + buff[0] = 0xFF & part_int; /* Most Significant Byte */ + buff[1] = 0xFF & (part_frac >> 8); /* middle byte */ buff[2] = 0xFF & part_frac; /* Least Significant Byte */ /* metadata 3 to 6, timestamp trigger value */ @@ -1053,7 +1058,7 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) { buff[13] = 0xFF & pkt_data.preamble; /* metadata 14 & 15, FSK baudrate */ - fsk_dr_div = LGW_XTAL_FREQU / pkt_data.datarate; + fsk_dr_div = (uint16_t)((uint32_t)LGW_XTAL_FREQU / pkt_data.datarate); /* Ok for datarate between 500bps and 250kbps */ buff[14] = 0xFF & (fsk_dr_div >> 8); buff[15] = 0xFF & fsk_dr_div; -- cgit v1.2.3