loragw_sx1302.c 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826
  1. /*
  2. / _____) _ | |
  3. ( (____ _____ ____ _| |_ _____ ____| |__
  4. \____ \| ___ | (_ _) ___ |/ ___) _ \
  5. _____) ) ____| | | || |_| ____( (___| | | |
  6. (______/|_____)_|_|_| \__)_____)\____)_| |_|
  7. (C)2019 Semtech
  8. Description:
  9. SX1302 Hardware Abstraction Layer entry functions.
  10. License: Revised BSD License, see LICENSE.TXT file include in the project
  11. */
  12. /* -------------------------------------------------------------------------- */
  13. /* --- DEPENDANCIES --------------------------------------------------------- */
  14. #include <stdint.h> /* C99 types */
  15. #include <stdio.h> /* printf fprintf */
  16. #include <string.h> /* memcmp */
  17. #include <math.h> /* pow, cell */
  18. #include <inttypes.h>
  19. #include <time.h>
  20. #include "loragw_reg.h"
  21. #include "loragw_aux.h"
  22. #include "loragw_hal.h"
  23. #include "loragw_sx1302.h"
  24. #include "loragw_sx1302_timestamp.h"
  25. #include "loragw_sx1302_rx.h"
  26. #include "loragw_sx1250.h"
  27. #include "loragw_agc_params.h"
  28. #include "loragw_cal.h"
  29. #include "loragw_debug.h"
  30. /* -------------------------------------------------------------------------- */
  31. /* --- PRIVATE MACROS ------------------------------------------------------- */
  32. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  33. #if DEBUG_SX1302 == 1
  34. #define DEBUG_MSG(str) fprintf(stdout, str)
  35. #define DEBUG_PRINTF(fmt, args...) fprintf(stdout, fmt, args)
  36. #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
  37. #else
  38. #define DEBUG_MSG(str)
  39. #define DEBUG_PRINTF(fmt, args...)
  40. #define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
  41. #endif
  42. #define CHECK_ERR(a) if(a==-1){return LGW_REG_ERROR;}
  43. #define IF_HZ_TO_REG(f) ((f * 32) / 15625)
  44. #define SX1302_FREQ_TO_REG(f) (uint32_t)((uint64_t)f * (1 << 18) / 32000000U)
  45. /* -------------------------------------------------------------------------- */
  46. /* --- PRIVATE TYPES -------------------------------------------------------- */
  47. /* -------------------------------------------------------------------------- */
  48. /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
  49. #define AGC_RADIO_A_INIT_DONE 0x80
  50. #define AGC_RADIO_B_INIT_DONE 0x20
  51. #define MCU_AGC 0x01
  52. #define MCU_ARB 0x02
  53. #define AGC_MEM_ADDR 0x0000
  54. #define ARB_MEM_ADDR 0x2000
  55. #define MCU_FW_SIZE 8192 /* size of the firmware IN BYTES (= twice the number of 14b words) */
  56. #define FW_VERSION_CAL 1 /* Expected version of calibration firmware */
  57. #define RSSI_FSK_POLY_0 90.636423 /* polynomiam coefficients to linearize FSK RSSI */
  58. #define RSSI_FSK_POLY_1 0.420835
  59. #define RSSI_FSK_POLY_2 0.007129
  60. #define RSSI_FSK_POLY_3 -0.000026
  61. #define FREQ_OFFSET_LSB_125KHZ 0.11920929f /* 125000 * 32 / 2^6 / 2^19 */
  62. #define FREQ_OFFSET_LSB_250KHZ 0.238418579f /* 250000 * 32 / 2^6 / 2^19 */
  63. #define FREQ_OFFSET_LSB_500KHZ 0.476837158f /* 500000 * 32 / 2^6 / 2^19 */
  64. /* sx1302 hardware modem capabilities */
  65. #define LGW_IFMODEM_CONFIG {\
  66. IF_LORA_MULTI, \
  67. IF_LORA_MULTI, \
  68. IF_LORA_MULTI, \
  69. IF_LORA_MULTI, \
  70. IF_LORA_MULTI, \
  71. IF_LORA_MULTI, \
  72. IF_LORA_MULTI, \
  73. IF_LORA_MULTI, \
  74. IF_LORA_STD, \
  75. IF_FSK_STD } /* configuration of available IF chains and modems on the hardware */
  76. /* constant arrays defining hardware capability */
  77. const uint8_t ifmod_config[LGW_IF_CHAIN_NB] = LGW_IFMODEM_CONFIG;
  78. #define MIN_LORA_PREAMBLE 6
  79. #define STD_LORA_PREAMBLE 8
  80. #define MIN_FSK_PREAMBLE 3
  81. #define STD_FSK_PREAMBLE 5
  82. #define GPIO_CFG_REGISTER 0x00
  83. #define GPIO_CFG_AGC 0x01
  84. #define GPIO_CFG_ARB 0x02
  85. #define GPIO_CFG_SPI_EXP_1 0x03
  86. #define GPIO_CFG_CSN_SPI_EXP 0x04
  87. #define GPIO_CFG_SPI_EXP_2 0x05
  88. #define GPIO_CFG_UART 0x06
  89. #define GPIO_CFG_SX1255_IQ 0x07
  90. #define GPIO_CFG_SX1261_IQ 0x08
  91. #define GPIO_CFG_STATUS 0x09
  92. #define GPIO_CFG_MBIST 0x0A
  93. #define GPIO_CFG_OTP 0x0B
  94. /* -------------------------------------------------------------------------- */
  95. /* --- PRIVATE VARIABLES ---------------------------------------------------- */
  96. /* Radio calibration firmware */
  97. #include "cal_fw.var" /* text_cal_sx1257_16_Nov_1 */
  98. /* Buffer to hold RX data */
  99. rx_buffer_t rx_buffer;
  100. /* Internal timestamp counter */
  101. timestamp_counter_t counter_us;
  102. /* -------------------------------------------------------------------------- */
  103. /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
  104. /**
  105. @brief TODO
  106. @param TODO
  107. @return TODO
  108. */
  109. extern int32_t lgw_sf_getval(int x);
  110. /**
  111. @brief TODO
  112. @param TODO
  113. @return TODO
  114. */
  115. extern int32_t lgw_bw_getval(int x);
  116. /**
  117. @brief TODO
  118. @param TODO
  119. @return TODO
  120. */
  121. void lora_crc16(const char data, int *crc);
  122. /* -------------------------------------------------------------------------- */
  123. /* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
  124. /* Log file */
  125. extern FILE * log_file;
  126. /* -------------------------------------------------------------------------- */
  127. /* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
  128. int calculate_freq_to_time_drift(uint32_t freq_hz, uint8_t bw, uint16_t * mant, uint8_t * exp) {
  129. uint64_t mantissa_u64;
  130. uint8_t exponent = 0;
  131. int32_t bw_hz;
  132. /* check input variables */
  133. CHECK_NULL(mant);
  134. CHECK_NULL(exp);
  135. bw_hz = lgw_bw_getval(bw);
  136. if (bw_hz < 0) {
  137. printf("ERROR: Unsupported bandwidth for frequency to time drift calculation\n");
  138. return LGW_REG_ERROR;
  139. }
  140. mantissa_u64 = (uint64_t)bw_hz * (2 << (20-1)) / freq_hz;
  141. while (mantissa_u64 < 2048) {
  142. exponent += 1;
  143. mantissa_u64 <<= 1;
  144. }
  145. *mant = (uint16_t)mantissa_u64;
  146. *exp = exponent;
  147. return LGW_REG_SUCCESS;
  148. }
  149. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  150. void lora_crc16(const char data, int *crc) {
  151. int next = 0;
  152. next = (((data>>0)&1) ^ ((*crc>>12)&1) ^ ((*crc>> 8)&1) ) ;
  153. next += ((((data>>1)&1) ^ ((*crc>>13)&1) ^ ((*crc>> 9)&1) )<<1 ) ;
  154. next += ((((data>>2)&1) ^ ((*crc>>14)&1) ^ ((*crc>>10)&1) )<<2 ) ;
  155. next += ((((data>>3)&1) ^ ((*crc>>15)&1) ^ ((*crc>>11)&1) )<<3 ) ;
  156. next += ((((data>>4)&1) ^ ((*crc>>12)&1) )<<4 ) ;
  157. next += ((((data>>5)&1) ^ ((*crc>>13)&1) ^ ((*crc>>12)&1) ^ ((*crc>> 8)&1))<<5 ) ;
  158. next += ((((data>>6)&1) ^ ((*crc>>14)&1) ^ ((*crc>>13)&1) ^ ((*crc>> 9)&1))<<6 ) ;
  159. next += ((((data>>7)&1) ^ ((*crc>>15)&1) ^ ((*crc>>14)&1) ^ ((*crc>>10)&1))<<7 ) ;
  160. next += ((((*crc>>0)&1) ^ ((*crc>>15)&1) ^ ((*crc>>11)&1) )<<8 ) ;
  161. next += ((((*crc>>1)&1) ^ ((*crc>>12)&1) )<<9 ) ;
  162. next += ((((*crc>>2)&1) ^ ((*crc>>13)&1) )<<10) ;
  163. next += ((((*crc>>3)&1) ^ ((*crc>>14)&1) )<<11) ;
  164. next += ((((*crc>>4)&1) ^ ((*crc>>15)&1) ^ ((*crc>>12)&1) ^ ((*crc>> 8)&1))<<12) ;
  165. next += ((((*crc>>5)&1) ^ ((*crc>>13)&1) ^ ((*crc>> 9)&1) )<<13) ;
  166. next += ((((*crc>>6)&1) ^ ((*crc>>14)&1) ^ ((*crc>>10)&1) )<<14) ;
  167. next += ((((*crc>>7)&1) ^ ((*crc>>15)&1) ^ ((*crc>>11)&1) )<<15) ;
  168. (*crc) = next;
  169. }
  170. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  171. int sx1302_config_gpio(void) {
  172. int err;
  173. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_0_SELECTION, GPIO_CFG_REGISTER); /* GPIO_0 => CONFIG_DONE */
  174. CHECK_ERR(err);
  175. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_1_SELECTION, GPIO_CFG_REGISTER); /* GPIO_1 => UNUSED */
  176. CHECK_ERR(err);
  177. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_2_SELECTION, GPIO_CFG_STATUS); /* GPIO_2 => Tx ON */
  178. CHECK_ERR(err);
  179. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_3_SELECTION, GPIO_CFG_REGISTER); /* GPIO_3 => UNUSED */
  180. CHECK_ERR(err);
  181. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_4_SELECTION, GPIO_CFG_STATUS); /* GPIO_4 => RX ON (PKT_RECEIVE_TOGGLE_OUT) */
  182. CHECK_ERR(err);
  183. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_5_SELECTION, GPIO_CFG_REGISTER); /* GPIO_5 => UNUSED */
  184. CHECK_ERR(err);
  185. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_6_SELECTION, GPIO_CFG_REGISTER); /* GPIO_6 => UNUSED */
  186. CHECK_ERR(err);
  187. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_7_SELECTION, GPIO_CFG_AGC); /* GPIO_7 => USED FOR LBT (MUST BE INPUT) */
  188. CHECK_ERR(err);
  189. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_DIR_L_DIRECTION, 0x7F); /* GPIO output direction (0 for input and 1 for output) */
  190. CHECK_ERR(err);
  191. return LGW_REG_SUCCESS;
  192. }
  193. /* -------------------------------------------------------------------------- */
  194. /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
  195. int sx1302_init(const struct lgw_conf_ftime_s * ftime_context) {
  196. sx1302_model_id_t model_id;
  197. int x;
  198. /* Check input parameters */
  199. CHECK_NULL(ftime_context);
  200. /* Initialize internal counter */
  201. timestamp_counter_new(&counter_us);
  202. /* Initialize RX buffer */
  203. rx_buffer_new(&rx_buffer);
  204. /* Configure timestamping mode */
  205. if (ftime_context->enable == true) {
  206. x = sx1302_get_model_id(&model_id);
  207. if (x != LGW_REG_SUCCESS) {
  208. printf("ERROR: failed to get Chip Model ID\n");
  209. return LGW_REG_ERROR;
  210. }
  211. if (model_id != CHIP_MODEL_ID_SX1303) {
  212. printf("ERROR: Fine Timestamping is not supported on this Chip Model ID 0x%02X\n", model_id);
  213. return LGW_REG_ERROR;
  214. }
  215. }
  216. x = timestamp_counter_mode(ftime_context->enable);
  217. if (x != LGW_REG_SUCCESS) {
  218. printf("ERROR: failed to configure timestamp counter mode\n");
  219. return LGW_REG_ERROR;
  220. }
  221. x = sx1302_config_gpio();
  222. if (x != LGW_REG_SUCCESS) {
  223. printf("ERROR: failed to configure sx1302 GPIOs\n");
  224. return LGW_REG_ERROR;
  225. }
  226. return LGW_REG_SUCCESS;
  227. }
  228. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  229. int sx1302_get_eui(uint64_t * eui) {
  230. int i, err;
  231. int32_t val;
  232. *eui = 0;
  233. for (i = 0; i < 8; i++) {
  234. err = lgw_reg_w(SX1302_REG_OTP_BYTE_ADDR_ADDR, i);
  235. if (err != LGW_REG_SUCCESS) {
  236. return LGW_REG_ERROR;
  237. }
  238. err = lgw_reg_r(SX1302_REG_OTP_RD_DATA_RD_DATA, &val);
  239. if (err != LGW_REG_SUCCESS) {
  240. return LGW_REG_ERROR;
  241. }
  242. *eui |= (uint64_t)((uint8_t)val) << (56 - (i * 8));
  243. }
  244. return LGW_REG_SUCCESS;
  245. }
  246. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  247. int sx1302_get_model_id(sx1302_model_id_t * model_id) {
  248. int err;
  249. int32_t val;
  250. /* Select ChipModelID */
  251. err = lgw_reg_w(SX1302_REG_OTP_BYTE_ADDR_ADDR, 0xD0);
  252. if (err != LGW_REG_SUCCESS) {
  253. return LGW_REG_ERROR;
  254. }
  255. /* Read Modem ID */
  256. err = lgw_reg_r(SX1302_REG_OTP_RD_DATA_RD_DATA, &val);
  257. if (err != LGW_REG_SUCCESS) {
  258. return LGW_REG_ERROR;
  259. }
  260. *model_id = (sx1302_model_id_t)val;
  261. return LGW_REG_SUCCESS;
  262. }
  263. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  264. int sx1302_update(void) {
  265. uint32_t inst, pps;
  266. /* performances variables */
  267. struct timeval tm;
  268. /* Record function start time */
  269. _meas_time_start(&tm);
  270. #if 0 /* Disabled because it brings latency on USB, for low value. TODO: do this less frequently ? */
  271. int32_t val;
  272. /* Check MCUs parity errors */
  273. lgw_reg_r(SX1302_REG_AGC_MCU_CTRL_PARITY_ERROR, &val);
  274. if (val != 0) {
  275. printf("ERROR: Parity error check failed on AGC firmware\n");
  276. return LGW_REG_ERROR;
  277. }
  278. lgw_reg_r(SX1302_REG_ARB_MCU_CTRL_PARITY_ERROR, &val);
  279. if (val != 0) {
  280. printf("ERROR: Parity error check failed on ARB firmware\n");
  281. return LGW_REG_ERROR;
  282. }
  283. #endif
  284. /* Update internal timestamp counter wrapping status */
  285. timestamp_counter_get(&counter_us, &inst, &pps);
  286. _meas_time_stop(2, tm, __FUNCTION__);
  287. return LGW_REG_SUCCESS;
  288. }
  289. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  290. int sx1302_radio_clock_select(uint8_t rf_chain) {
  291. int err = LGW_REG_SUCCESS;
  292. /* Check input parameters */
  293. if (rf_chain >= LGW_RF_CHAIN_NB)
  294. {
  295. DEBUG_MSG("ERROR: invalid RF chain\n");
  296. return LGW_REG_ERROR;
  297. }
  298. /* Switch SX1302 clock from SPI clock to radio clock of the selected RF chain */
  299. switch (rf_chain) {
  300. case 0:
  301. DEBUG_MSG("Select Radio A clock\n");
  302. err |= lgw_reg_w(SX1302_REG_CLK_CTRL_CLK_SEL_CLK_RADIO_A_SEL, 0x01);
  303. err |= lgw_reg_w(SX1302_REG_CLK_CTRL_CLK_SEL_CLK_RADIO_B_SEL, 0x00);
  304. break;
  305. case 1:
  306. DEBUG_MSG("Select Radio B clock\n");
  307. err |= lgw_reg_w(SX1302_REG_CLK_CTRL_CLK_SEL_CLK_RADIO_A_SEL, 0x00);
  308. err |= lgw_reg_w(SX1302_REG_CLK_CTRL_CLK_SEL_CLK_RADIO_B_SEL, 0x01);
  309. break;
  310. default:
  311. return LGW_REG_ERROR;
  312. }
  313. /* Enable clock dividers */
  314. err |= lgw_reg_w(SX1302_REG_CLK_CTRL_CLK_SEL_CLKDIV_EN, 0x01);
  315. /* Set the RIF clock to the 32MHz clock of the radio */
  316. err |= lgw_reg_w(SX1302_REG_COMMON_CTRL0_CLK32_RIF_CTRL, 0x01);
  317. /* Check if something went wrong */
  318. if (err != LGW_REG_SUCCESS) {
  319. printf("ERROR: failed to select radio clock for radio_%u\n", rf_chain);
  320. return LGW_REG_ERROR;
  321. }
  322. return LGW_REG_SUCCESS;
  323. }
  324. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  325. int sx1302_radio_reset(uint8_t rf_chain, lgw_radio_type_t type) {
  326. uint16_t reg_radio_en;
  327. uint16_t reg_radio_rst;
  328. int err = LGW_REG_SUCCESS;
  329. /* Check input parameters */
  330. if (rf_chain >= LGW_RF_CHAIN_NB)
  331. {
  332. DEBUG_MSG("ERROR: invalid RF chain\n");
  333. return LGW_REG_ERROR;
  334. }
  335. if ((type != LGW_RADIO_TYPE_SX1255) && (type != LGW_RADIO_TYPE_SX1257) && (type != LGW_RADIO_TYPE_SX1250)) {
  336. DEBUG_MSG("ERROR: invalid radio type\n");
  337. return LGW_REG_ERROR;
  338. }
  339. /* Switch to SPI clock before reseting the radio */
  340. err |= lgw_reg_w(SX1302_REG_COMMON_CTRL0_CLK32_RIF_CTRL, 0x00);
  341. /* Enable the radio */
  342. reg_radio_en = REG_SELECT(rf_chain, SX1302_REG_AGC_MCU_RF_EN_A_RADIO_EN, SX1302_REG_AGC_MCU_RF_EN_B_RADIO_EN);
  343. err |= lgw_reg_w(reg_radio_en, 0x01);
  344. /* Select the proper reset sequence depending on the radio type */
  345. reg_radio_rst = REG_SELECT(rf_chain, SX1302_REG_AGC_MCU_RF_EN_A_RADIO_RST, SX1302_REG_AGC_MCU_RF_EN_B_RADIO_RST);
  346. err |= lgw_reg_w(reg_radio_rst, 0x01);
  347. wait_ms(500);
  348. err |= lgw_reg_w(reg_radio_rst, 0x00);
  349. wait_ms(10);
  350. switch (type) {
  351. case LGW_RADIO_TYPE_SX1255:
  352. case LGW_RADIO_TYPE_SX1257:
  353. /* Do nothing */
  354. DEBUG_PRINTF("INFO: reset sx125x (RADIO_%s) done\n", REG_SELECT(rf_chain, "A", "B"));
  355. break;
  356. case LGW_RADIO_TYPE_SX1250:
  357. err |= lgw_reg_w(reg_radio_rst, 0x01);
  358. wait_ms(10); /* wait for auto calibration to complete */
  359. DEBUG_PRINTF("INFO: reset sx1250 (RADIO_%s) done\n", REG_SELECT(rf_chain, "A", "B"));
  360. break;
  361. default:
  362. return LGW_REG_ERROR;
  363. }
  364. /* Check if something went wrong */
  365. if (err != LGW_REG_SUCCESS) {
  366. printf("ERROR: failed to reset the radios\n");
  367. return LGW_REG_ERROR;
  368. }
  369. return LGW_REG_SUCCESS;
  370. }
  371. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  372. int sx1302_radio_set_mode(uint8_t rf_chain, lgw_radio_type_t type) {
  373. uint16_t reg;
  374. int err;
  375. /* Check input parameters */
  376. if (rf_chain >= LGW_RF_CHAIN_NB) {
  377. DEBUG_MSG("ERROR: invalid RF chain\n");
  378. return LGW_REG_ERROR;
  379. }
  380. if ((type != LGW_RADIO_TYPE_SX1255) && (type != LGW_RADIO_TYPE_SX1257) && (type != LGW_RADIO_TYPE_SX1250)) {
  381. DEBUG_MSG("ERROR: invalid radio type\n");
  382. return LGW_REG_ERROR;
  383. }
  384. /* Set the radio mode */
  385. reg = REG_SELECT(rf_chain, SX1302_REG_COMMON_CTRL0_SX1261_MODE_RADIO_A,
  386. SX1302_REG_COMMON_CTRL0_SX1261_MODE_RADIO_B);
  387. switch (type) {
  388. case LGW_RADIO_TYPE_SX1250:
  389. DEBUG_PRINTF("Setting rf_chain_%u in sx1250 mode\n", rf_chain);
  390. err = lgw_reg_w(reg, 0x01);
  391. break;
  392. default:
  393. DEBUG_PRINTF("Setting rf_chain_%u in sx125x mode\n", rf_chain);
  394. err = lgw_reg_w(reg, 0x00);
  395. break;
  396. }
  397. if (err != LGW_REG_SUCCESS) {
  398. printf("ERROR: failed to set mode for radio %u\n", rf_chain);
  399. return LGW_REG_ERROR;
  400. }
  401. return LGW_REG_SUCCESS;
  402. }
  403. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  404. int sx1302_radio_host_ctrl(bool host_ctrl) {
  405. return lgw_reg_w(SX1302_REG_COMMON_CTRL0_HOST_RADIO_CTRL, (host_ctrl == false) ? 0x00 : 0x01);
  406. }
  407. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  408. int sx1302_radio_calibrate(struct lgw_conf_rxrf_s * context_rf_chain, uint8_t clksrc, struct lgw_tx_gain_lut_s * txgain_lut) {
  409. int i;
  410. int err = LGW_REG_SUCCESS;
  411. /* -- Reset radios */
  412. for (i = 0; i < LGW_RF_CHAIN_NB; i++) {
  413. if (context_rf_chain[i].enable == true) {
  414. err = sx1302_radio_reset(i, context_rf_chain[i].type);
  415. if (err != LGW_REG_SUCCESS) {
  416. printf("ERROR: failed to reset radio %d\n", i);
  417. return LGW_REG_ERROR;
  418. }
  419. err = sx1302_radio_set_mode(i, context_rf_chain[i].type);
  420. if (err != LGW_REG_SUCCESS) {
  421. printf("ERROR: failed to set radio %d mode\n", i);
  422. return LGW_REG_ERROR;
  423. }
  424. }
  425. }
  426. /* -- Select the radio which provides the clock to the sx1302 */
  427. err = sx1302_radio_clock_select(clksrc);
  428. if (err != LGW_REG_SUCCESS) {
  429. printf("ERROR: failed to get select clock from radio %u\n", clksrc);
  430. return LGW_REG_ERROR;
  431. }
  432. /* -- Ensure PA/LNA are disabled */
  433. err |= lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_FORCE_HOST_FE_CTRL, 1);
  434. err |= lgw_reg_w(SX1302_REG_AGC_MCU_RF_EN_A_PA_EN, 0);
  435. err |= lgw_reg_w(SX1302_REG_AGC_MCU_RF_EN_A_LNA_EN, 0);
  436. /* -- Start calibration */
  437. if ((context_rf_chain[clksrc].type == LGW_RADIO_TYPE_SX1257) ||
  438. (context_rf_chain[clksrc].type == LGW_RADIO_TYPE_SX1255)) {
  439. DEBUG_MSG("Loading CAL fw for sx125x\n");
  440. err = sx1302_agc_load_firmware(cal_firmware_sx125x);
  441. if (err != LGW_REG_SUCCESS) {
  442. printf("ERROR: Failed to load calibration fw\n");
  443. return LGW_REG_ERROR;
  444. }
  445. err = sx1302_cal_start(FW_VERSION_CAL, context_rf_chain, txgain_lut);
  446. if (err != LGW_REG_SUCCESS) {
  447. printf("ERROR: radio calibration failed\n");
  448. sx1302_radio_reset(0, context_rf_chain[0].type);
  449. sx1302_radio_reset(1, context_rf_chain[1].type);
  450. return LGW_REG_ERROR;
  451. }
  452. } else {
  453. DEBUG_MSG("Calibrating sx1250 radios\n");
  454. for (i = 0; i < LGW_RF_CHAIN_NB; i++) {
  455. if (context_rf_chain[i].enable == true) {
  456. err = sx1250_calibrate(i, context_rf_chain[i].freq_hz);
  457. if (err != LGW_REG_SUCCESS) {
  458. printf("ERROR: radio calibration failed\n");
  459. return LGW_REG_ERROR;
  460. }
  461. }
  462. }
  463. }
  464. /* -- Release control over FE */
  465. err |= lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_FORCE_HOST_FE_CTRL, 0);
  466. return err;
  467. }
  468. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  469. int sx1302_pa_lna_lut_configure(struct lgw_conf_board_s * context_board) {
  470. int err = LGW_REG_SUCCESS;
  471. /* Configure LUT Table A */
  472. if (context_board->full_duplex == true) {
  473. err |= lgw_reg_w(SX1302_REG_AGC_MCU_LUT_TABLE_A_PA_LUT, 0x0C); /* Enable PA: RADIO_CTRL[2] is high when PA_EN=1 */
  474. err |= lgw_reg_w(SX1302_REG_AGC_MCU_LUT_TABLE_A_LNA_LUT, 0x0F); /* Enable LNA: RADIO_CTRL[1] is always high */
  475. } else {
  476. err |= lgw_reg_w(SX1302_REG_AGC_MCU_LUT_TABLE_A_PA_LUT, 0x04); /* Enable PA: RADIO_CTRL[2] is high when PA_EN=1 */
  477. err |= lgw_reg_w(SX1302_REG_AGC_MCU_LUT_TABLE_A_LNA_LUT, 0x02); /* Enable LNA: RADIO_CTRL[1] is high when PA_EN=0 & LNA_EN=1 */
  478. }
  479. /* Configure LUT Table B */
  480. err |= lgw_reg_w(SX1302_REG_AGC_MCU_LUT_TABLE_B_PA_LUT, 0x04); /* Enable PA: RADIO_CTRL[8] is high when PA_EN=1 & LNA_EN=0 */
  481. err |= lgw_reg_w(SX1302_REG_AGC_MCU_LUT_TABLE_B_LNA_LUT, 0x02); /* Enable LNA: RADIO_CTRL[7] is high when PA_EN=0 & LNA_EN=1 */
  482. return err;
  483. }
  484. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  485. int sx1302_radio_fe_configure(void) {
  486. int err = LGW_REG_SUCCESS;
  487. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_BB_FILTER_ALPHA_RADIO_A_RSSI_BB_FILTER_ALPHA, 0x03);
  488. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_DEC_FILTER_ALPHA_RADIO_A_RSSI_DEC_FILTER_ALPHA, 0x07);
  489. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_BB_FILTER_ALPHA_RADIO_B_RSSI_BB_FILTER_ALPHA, 0x03);
  490. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_DEC_FILTER_ALPHA_RADIO_B_RSSI_DEC_FILTER_ALPHA, 0x07);
  491. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_DB_DEF_RADIO_A_RSSI_DB_DEFAULT_VALUE, 23);
  492. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_DEC_DEF_RADIO_A_RSSI_DEC_DEFAULT_VALUE, 66);
  493. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_DB_DEF_RADIO_B_RSSI_DB_DEFAULT_VALUE, 23);
  494. err |= lgw_reg_w(SX1302_REG_RADIO_FE_RSSI_DEC_DEF_RADIO_B_RSSI_DEC_DEFAULT_VALUE, 66);
  495. err |= lgw_reg_w(SX1302_REG_RADIO_FE_CTRL0_RADIO_A_DC_NOTCH_EN, 1);
  496. err |= lgw_reg_w(SX1302_REG_RADIO_FE_CTRL0_RADIO_A_HOST_FILTER_GAIN, 0x0b);
  497. err |= lgw_reg_w(SX1302_REG_RADIO_FE_CTRL0_RADIO_B_DC_NOTCH_EN, 1);
  498. err |= lgw_reg_w(SX1302_REG_RADIO_FE_CTRL0_RADIO_B_HOST_FILTER_GAIN, 0x0b);
  499. return err;
  500. }
  501. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  502. uint8_t sx1302_get_ifmod_config(uint8_t if_chain) {
  503. return ifmod_config[if_chain];
  504. }
  505. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  506. int sx1302_channelizer_configure(struct lgw_conf_rxif_s * if_cfg, bool fix_gain) {
  507. int32_t if_freq;
  508. uint8_t channels_mask = 0x00;
  509. int i;
  510. int err = LGW_REG_SUCCESS;
  511. /* Check input parameters */
  512. CHECK_NULL(if_cfg);
  513. /* Select which radio is connected to each multi-SF channel */
  514. for (i = 0; i < LGW_MULTI_NB; i++) {
  515. channels_mask |= (if_cfg[i].rf_chain << i);
  516. }
  517. DEBUG_PRINTF("LoRa multi-SF radio select: 0x%02X\n", channels_mask);
  518. err |= lgw_reg_w(SX1302_REG_RX_TOP_RADIO_SELECT_RADIO_SELECT, channels_mask);
  519. /* Select which radio is connected to the LoRa service channel */
  520. DEBUG_PRINTF("LoRa service radio select: 0x%02X\n", if_cfg[8].rf_chain);
  521. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_RADIO_SEL_RADIO_SELECT, if_cfg[8].rf_chain);
  522. /* Select which radio is connected to the FSK channel */
  523. DEBUG_PRINTF("FSK radio select %u\n", if_cfg[9].rf_chain);
  524. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_RADIO_SELECT, if_cfg[9].rf_chain);
  525. /* Configure multi-SF channels IF frequencies */
  526. if_freq = IF_HZ_TO_REG(if_cfg[0].freq_hz);
  527. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_0_MSB_IF_FREQ_0, (if_freq >> 8) & 0x0000001F);
  528. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_0_LSB_IF_FREQ_0, (if_freq >> 0) & 0x000000FF);
  529. if_freq = IF_HZ_TO_REG(if_cfg[1].freq_hz);
  530. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_1_MSB_IF_FREQ_1, (if_freq >> 8) & 0x0000001F);
  531. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_1_LSB_IF_FREQ_1, (if_freq >> 0) & 0x000000FF);
  532. if_freq = IF_HZ_TO_REG(if_cfg[2].freq_hz);
  533. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_2_MSB_IF_FREQ_2, (if_freq >> 8) & 0x0000001F);
  534. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_2_LSB_IF_FREQ_2, (if_freq >> 0) & 0x000000FF);
  535. if_freq = IF_HZ_TO_REG(if_cfg[3].freq_hz);
  536. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_3_MSB_IF_FREQ_3, (if_freq >> 8) & 0x0000001F);
  537. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_3_LSB_IF_FREQ_3, (if_freq >> 0) & 0x000000FF);
  538. if_freq = IF_HZ_TO_REG(if_cfg[4].freq_hz);
  539. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_4_MSB_IF_FREQ_4, (if_freq >> 8) & 0x0000001F);
  540. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_4_LSB_IF_FREQ_4, (if_freq >> 0) & 0x000000FF);
  541. if_freq = IF_HZ_TO_REG(if_cfg[5].freq_hz);
  542. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_5_MSB_IF_FREQ_5, (if_freq >> 8) & 0x0000001F);
  543. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_5_LSB_IF_FREQ_5, (if_freq >> 0) & 0x000000FF);
  544. if_freq = IF_HZ_TO_REG(if_cfg[6].freq_hz);
  545. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_6_MSB_IF_FREQ_6, (if_freq >> 8) & 0x0000001F);
  546. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_6_LSB_IF_FREQ_6, (if_freq >> 0) & 0x000000FF);
  547. if_freq = IF_HZ_TO_REG(if_cfg[7].freq_hz);
  548. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_7_MSB_IF_FREQ_7, (if_freq >> 8) & 0x0000001F);
  549. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_7_LSB_IF_FREQ_7, (if_freq >> 0) & 0x000000FF);
  550. /* Configure LoRa service channel IF frequency */
  551. if_freq = IF_HZ_TO_REG(if_cfg[8].freq_hz);
  552. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_FREQ_MSB_IF_FREQ_0, (if_freq >> 8) & 0x0000001F);
  553. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_FREQ_LSB_IF_FREQ_0, (if_freq >> 0) & 0x000000FF);
  554. /* Configure FSK channel IF frequency */
  555. if_freq = IF_HZ_TO_REG(if_cfg[9].freq_hz);
  556. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_FREQ_MSB_IF_FREQ_0, (if_freq >> 8) & 0x0000001F);
  557. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_FREQ_LSB_IF_FREQ_0, (if_freq >> 0) & 0x000000FF);
  558. /* Set the low pass filtering corner frequency for RSSI indicator */
  559. err |= lgw_reg_w(SX1302_REG_RX_TOP_RSSI_CONTROL_RSSI_FILTER_ALPHA, 0x05);
  560. /* Set the channelizer RSSI reset value */
  561. err |= lgw_reg_w(SX1302_REG_RX_TOP_RSSI_DEF_VALUE_CHAN_RSSI_DEF_VALUE, 85);
  562. /* Force channelizer in fix gain, or let it be controlled by AGC */
  563. if (fix_gain == true) {
  564. err |= lgw_reg_w(SX1302_REG_RX_TOP_CHANN_DAGC_CFG5_CHAN_DAGC_MODE, 0x00);
  565. err |= lgw_reg_w(SX1302_REG_RX_TOP_GAIN_CONTROL_CHAN_GAIN, 5);
  566. } else {
  567. /* Allow the AGC to control gains */
  568. err |= lgw_reg_w(SX1302_REG_RX_TOP_CHANN_DAGC_CFG5_CHAN_DAGC_MODE, 0x01);
  569. /* Disable the internal DAGC */
  570. err |= lgw_reg_w(SX1302_REG_RX_TOP_CHANN_DAGC_CFG1_CHAN_DAGC_THRESHOLD_HIGH, 255 );
  571. err |= lgw_reg_w(SX1302_REG_RX_TOP_CHANN_DAGC_CFG2_CHAN_DAGC_THRESHOLD_LOW, 0 );
  572. err |= lgw_reg_w(SX1302_REG_RX_TOP_CHANN_DAGC_CFG3_CHAN_DAGC_MAX_ATTEN, 15 );
  573. err |= lgw_reg_w(SX1302_REG_RX_TOP_CHANN_DAGC_CFG3_CHAN_DAGC_MIN_ATTEN, 0 );
  574. }
  575. return err;
  576. }
  577. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  578. int sx1302_fsk_configure(struct lgw_conf_rxif_s * cfg) {
  579. uint64_t fsk_sync_word_reg;
  580. uint32_t fsk_br_reg;
  581. int err = LGW_REG_SUCCESS;
  582. DEBUG_PRINTF("FSK: syncword:0x%" PRIx64 ", syncword_size:%u\n", cfg->sync_word, cfg->sync_word_size);
  583. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_PSIZE, cfg->sync_word_size - 1);
  584. fsk_sync_word_reg = cfg->sync_word << (8 * (8 - cfg->sync_word_size));
  585. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 0));
  586. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 8));
  587. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 16));
  588. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 24));
  589. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 32));
  590. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 40));
  591. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 48));
  592. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN, (uint8_t)(fsk_sync_word_reg >> 56));
  593. fsk_br_reg = 32000000 / cfg->datarate;
  594. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BIT_RATE_MSB_BIT_RATE, (uint8_t)(fsk_br_reg >> 8));
  595. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BIT_RATE_LSB_BIT_RATE, (uint8_t)(fsk_br_reg >> 0));
  596. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_CH_BW_EXPO, 0x03); /* 125KHz */
  597. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_RX_INVERT, 0);
  598. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_MODEM_INVERT_IQ, 0);
  599. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_4_RSSI_LENGTH, 4);
  600. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_PKT_MODE, 1); /* variable length */
  601. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_CRC_EN, 1);
  602. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_DCFREE_ENC, 2);
  603. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_CRC_IBM, 0);
  604. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_4_ERROR_OSR_TOL, 10);
  605. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_PKT_LENGTH_PKT_LENGTH, 255);
  606. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_NODE_ADRS_NODE_ADRS, 0);
  607. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_BROADCAST_BROADCAST, 0);
  608. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_AUTO_AFC, 1); /* ?? */
  609. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_TIMEOUT_MSB_TIMEOUT, 0);
  610. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_TIMEOUT_LSB_TIMEOUT, 128);
  611. return err;
  612. }
  613. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  614. int sx1302_lora_correlator_configure(struct lgw_conf_rxif_s * if_cfg, struct lgw_conf_demod_s * demod_cfg) {
  615. int i, err = LGW_REG_SUCCESS;
  616. uint8_t channels_mask = 0x00;
  617. /* Check input parameters */
  618. CHECK_NULL(if_cfg);
  619. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF5_CFG2_ACC_PNR, 52);
  620. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF5_CFG4_MSP_PNR, 24);
  621. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF5_CFG6_MSP_PEAK_NB, 7);
  622. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF5_CFG7_MSP2_PEAK_NB, 5);
  623. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF6_CFG2_ACC_PNR, 52);
  624. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF6_CFG4_MSP_PNR, 24);
  625. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF6_CFG6_MSP_PEAK_NB, 7);
  626. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF6_CFG7_MSP2_PEAK_NB, 5);
  627. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF7_CFG2_ACC_PNR, 52);
  628. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF7_CFG4_MSP_PNR, 24);
  629. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF7_CFG6_MSP_PEAK_NB, 7);
  630. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF7_CFG7_MSP2_PEAK_NB, 5);
  631. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF8_CFG2_ACC_PNR, 52);
  632. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF8_CFG4_MSP_PNR, 24);
  633. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF8_CFG6_MSP_PEAK_NB, 7);
  634. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF8_CFG7_MSP2_PEAK_NB, 5);
  635. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF9_CFG2_ACC_PNR, 52);
  636. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF9_CFG4_MSP_PNR, 24);
  637. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF9_CFG6_MSP_PEAK_NB, 7);
  638. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF9_CFG7_MSP2_PEAK_NB, 5);
  639. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF10_CFG2_ACC_PNR, 52);
  640. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF10_CFG4_MSP_PNR, 24);
  641. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF10_CFG6_MSP_PEAK_NB, 7);
  642. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF10_CFG7_MSP2_PEAK_NB, 5);
  643. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF11_CFG2_ACC_PNR, 52);
  644. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF11_CFG4_MSP_PNR, 24);
  645. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF11_CFG6_MSP_PEAK_NB, 7);
  646. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF11_CFG7_MSP2_PEAK_NB, 5);
  647. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF12_CFG2_ACC_PNR, 52);
  648. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF12_CFG4_MSP_PNR, 24);
  649. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF12_CFG6_MSP_PEAK_NB, 7);
  650. err |= lgw_reg_w(SX1302_REG_RX_TOP_SF12_CFG7_MSP2_PEAK_NB, 5);
  651. err |= lgw_reg_w(SX1302_REG_RX_TOP_CORRELATOR_ENABLE_ONLY_FIRST_DET_EDGE_ENABLE_ONLY_FIRST_DET_EDGE, 0xFF);
  652. err |= lgw_reg_w(SX1302_REG_RX_TOP_CORRELATOR_ENABLE_ACC_CLEAR_ENABLE_CORR_ACC_CLEAR, 0xFF);
  653. /* Enabled selected spreading factors */
  654. err |= lgw_reg_w(SX1302_REG_RX_TOP_CORRELATOR_SF_EN_CORR_SF_EN, demod_cfg->multisf_datarate);
  655. DEBUG_PRINTF("INFO: LoRa multi-SF correlator SF enable mask: 0x%02X\n", demod_cfg->multisf_datarate);
  656. /* Enable correlator if channel is enabled (1 correlator per channel) */
  657. for (i = 0; i < LGW_MULTI_NB; i++) {
  658. channels_mask |= (if_cfg[i].enable << i);
  659. }
  660. DEBUG_PRINTF("INFO: LoRa multi-SF channel enable mask: 0x%02X\n", channels_mask);
  661. err |= lgw_reg_w(SX1302_REG_RX_TOP_CORR_CLOCK_ENABLE_CLK_EN, channels_mask);
  662. err |= lgw_reg_w(SX1302_REG_RX_TOP_CORRELATOR_EN_CORR_EN, channels_mask);
  663. /* For debug: get packets with sync_error and header_error in FIFO */
  664. #if 0
  665. err |= lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_STORE_SYNC_FAIL_META, 0x01);
  666. err |= lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_STORE_HEADER_ERR_META, 0x01);
  667. #endif
  668. return err;
  669. }
  670. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  671. int sx1302_lora_service_correlator_configure(struct lgw_conf_rxif_s * cfg) {
  672. int err = LGW_REG_SUCCESS;
  673. /* Common config for all SF */
  674. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP2_MSP_PEAK_NB, 7);
  675. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP2_MSP2_PEAK_NB, 5);
  676. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_USE_GAIN_SYMB, 1);
  677. switch (cfg->datarate) {
  678. case 5:
  679. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 1);
  680. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  681. break;
  682. case 6:
  683. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 1);
  684. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  685. break;
  686. case 7:
  687. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 0);
  688. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  689. break;
  690. case 8:
  691. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 0);
  692. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  693. break;
  694. case 9:
  695. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 0);
  696. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  697. break;
  698. case 10:
  699. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 0);
  700. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  701. break;
  702. case 11:
  703. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 0);
  704. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  705. break;
  706. case 12:
  707. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN, 0);
  708. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR, 52);
  709. break;
  710. default:
  711. printf("ERROR: Failed to configure LoRa service modem correlators\n");
  712. return LGW_REG_ERROR;
  713. }
  714. return err;
  715. }
  716. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  717. int sx1302_lora_modem_configure(uint32_t radio_freq_hz) {
  718. uint16_t mantissa = 0;
  719. uint8_t exponent = 0;
  720. int err = LGW_REG_SUCCESS;
  721. err |= lgw_reg_w(SX1302_REG_RX_TOP_DC_NOTCH_CFG1_ENABLE, 0x00);
  722. err |= lgw_reg_w(SX1302_REG_RX_TOP_RX_DFE_AGC1_FORCE_DEFAULT_FIR, 0x01);
  723. err |= lgw_reg_w(SX1302_REG_RX_TOP_DAGC_CFG_GAIN_DROP_COMP, 0x01);
  724. err |= lgw_reg_w(SX1302_REG_RX_TOP_DAGC_CFG_TARGET_LVL, 0x01);
  725. /* Enable full modems */
  726. DEBUG_MSG("Configuring 8 full-SF modems\n");
  727. err |= lgw_reg_w(SX1302_REG_OTP_MODEM_EN_0_MODEM_EN, 0xFF);
  728. /* Enable limited modems */
  729. DEBUG_MSG("Configuring 8 limited-SF modems\n");
  730. err |= lgw_reg_w(SX1302_REG_OTP_MODEM_EN_1_MODEM_EN, 0xFF);
  731. /* Configure coarse sync between correlators and modems */
  732. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_MSB_MODEM_SYNC_DELTA, 0);
  733. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_LSB_MODEM_SYNC_DELTA, 126);
  734. /* Configure fine sync offset for each channel */
  735. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_01_CHANNEL_0_OFFSET, 1);
  736. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_01_CHANNEL_1_OFFSET, 5);
  737. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_23_CHANNEL_2_OFFSET, 9);
  738. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_23_CHANNEL_3_OFFSET, 13);
  739. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_45_CHANNEL_4_OFFSET, 1);
  740. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_45_CHANNEL_5_OFFSET, 5);
  741. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_67_CHANNEL_6_OFFSET, 9);
  742. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_67_CHANNEL_7_OFFSET, 13);
  743. /* Configure PPM offset */
  744. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF5, 0x00);
  745. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF6, 0x00);
  746. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF7, 0x00);
  747. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF8, 0x00);
  748. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF9, 0x00);
  749. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF10, 0x00);
  750. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF11, 0x01);
  751. err |= lgw_reg_w(SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF12, 0x01);
  752. /* Improve SF5 and SF6 performances */
  753. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_A_1_GAIN_P_AUTO, 3); // Default is 1
  754. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_A_1_GAIN_P_PAYLOAD, 3); // Default is 2
  755. /* Improve SF11/SF12 performances */
  756. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF11, 1);
  757. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF12, 1);
  758. /* Set threshold for 1bin correction (CAN-314) */
  759. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK4_FREQ_SYNCH_THR, 15);
  760. /* Configure modems for best tracking (best demodulation) */
  761. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF5, RX_FREQ_TRACK_AUTO);
  762. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF6, RX_FREQ_TRACK_AUTO);
  763. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF7, RX_FREQ_TRACK_AUTO);
  764. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF8, RX_FREQ_TRACK_AUTO);
  765. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF9, RX_FREQ_TRACK_AUTO);
  766. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF10, RX_FREQ_TRACK_AUTO);
  767. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF11, RX_FREQ_TRACK_AUTO);
  768. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF12, RX_FREQ_TRACK_AUTO);
  769. /* Configure modems for best timestamping (only valid when double demodulation is enabled) */
  770. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF5, RX_FREQ_TRACK_OFF);
  771. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF6, RX_FREQ_TRACK_OFF);
  772. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF7, RX_FREQ_TRACK_OFF);
  773. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF8, RX_FREQ_TRACK_OFF);
  774. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF9, RX_FREQ_TRACK_OFF);
  775. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF10, RX_FREQ_TRACK_OFF);
  776. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF11, RX_FREQ_TRACK_OFF);
  777. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF12, RX_FREQ_TRACK_OFF);
  778. /* -- */
  779. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF11, 0);
  780. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF12, 0);
  781. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_0_ROUNDING, 1);
  782. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_0_MODE, RX_FINE_TIMING_MODE_LINEAR);
  783. /* -- */
  784. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_1_GAIN_P_AUTO, 0);
  785. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_1_GAIN_P_PREAMB, 6);
  786. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_1_GAIN_P_PAYLOAD, 2);
  787. /* -- */
  788. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_2_GAIN_I_AUTO, 0);
  789. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_2_GAIN_I_PREAMB, 1);
  790. err |= lgw_reg_w(SX1302_REG_RX_TOP_FINE_TIMING_B_2_GAIN_I_PAYLOAD, 0);
  791. /* Set preamble size to 10 (to handle 12 for SF5/SF6 and 8 for SF7->SF12) */
  792. err |= lgw_reg_w(SX1302_REG_RX_TOP_TXRX_CFG7_PREAMBLE_SYMB_NB, 0); /* MSB */
  793. err |= lgw_reg_w(SX1302_REG_RX_TOP_TXRX_CFG6_PREAMBLE_SYMB_NB, 10); /* LSB */
  794. /* Freq2TimeDrift computation */
  795. if (calculate_freq_to_time_drift(radio_freq_hz, BW_125KHZ, &mantissa, &exponent) != 0) {
  796. printf("ERROR: failed to calculate frequency to time drift for LoRa modem\n");
  797. return LGW_REG_ERROR;
  798. }
  799. DEBUG_PRINTF("Freq2TimeDrift MultiSF: Mantissa = %d (0x%02X, 0x%02X), Exponent = %d (0x%02X)\n", mantissa, (mantissa >> 8) & 0x00FF, (mantissa) & 0x00FF, exponent, exponent);
  800. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TO_TIME0_FREQ_TO_TIME_DRIFT_MANT, (mantissa >> 8) & 0x00FF);
  801. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TO_TIME1_FREQ_TO_TIME_DRIFT_MANT, (mantissa) & 0x00FF);
  802. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TO_TIME2_FREQ_TO_TIME_DRIFT_EXP, exponent);
  803. /* Time drift compensation */
  804. err |= lgw_reg_w(SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_SYMB, 1);
  805. /* DFT peak mode : set to AUTO, check timestamp_counter_correction() if changed */
  806. err |= lgw_reg_w(SX1302_REG_RX_TOP_RX_CFG0_DFT_PEAK_EN, RX_DFT_PEAK_MODE_AUTO);
  807. return err;
  808. }
  809. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  810. int sx1302_lora_service_modem_configure(struct lgw_conf_rxif_s * cfg, uint32_t radio_freq_hz) {
  811. uint16_t mantissa = 0;
  812. uint8_t exponent = 0;
  813. uint8_t preamble_nb_symb;
  814. int err = LGW_REG_SUCCESS;
  815. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_ENABLE, 0x00);
  816. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_FORCE_DEFAULT_FIR, 0x01);
  817. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_GAIN_DROP_COMP, 0x01);
  818. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_TARGET_LVL, 0x01);
  819. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_AUTO, 0x03);
  820. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_PAYLOAD, 0x03);
  821. switch (cfg->datarate) {
  822. case DR_LORA_SF5:
  823. case DR_LORA_SF6:
  824. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PREAMB, 0x04); // Default value
  825. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN, 0x00); // Default value
  826. break;
  827. case DR_LORA_SF7:
  828. case DR_LORA_SF8:
  829. case DR_LORA_SF9:
  830. case DR_LORA_SF10:
  831. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PREAMB, 0x06);
  832. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN, 0x00);
  833. break;
  834. case DR_LORA_SF11:
  835. case DR_LORA_SF12:
  836. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PREAMB, 0x07);
  837. switch (cfg->bandwidth) {
  838. case BW_125KHZ:
  839. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN, 0x01);
  840. break;
  841. case BW_250KHZ:
  842. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN, 0x02);
  843. break;
  844. case BW_500KHZ:
  845. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN, 0x03);
  846. break;
  847. default:
  848. printf("ERROR: unsupported bandwidth %u for LoRa Service modem\n", cfg->bandwidth);
  849. break;
  850. }
  851. break;
  852. default:
  853. printf("ERROR: unsupported datarate %u for LoRa Service modem\n", cfg->datarate);
  854. break;
  855. }
  856. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_IMPLICIT_HEADER, (cfg->implicit_hdr == true) ? 1 : 0);
  857. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_CRC_EN, (cfg->implicit_crc_en == true) ? 1 : 0);
  858. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_CODING_RATE, cfg->implicit_coderate);
  859. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG3_PAYLOAD_LENGTH, cfg->implicit_payload_length);
  860. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG0_MODEM_SF, cfg->datarate);
  861. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG0_MODEM_BW, cfg->bandwidth);
  862. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_PPM_OFFSET, SET_PPM_ON(cfg->bandwidth, cfg->datarate));
  863. /* Set preamble size to 8 for SF7->SF12 and to 12 for SF5->SF6 (aligned with end-device drivers) */
  864. if ((cfg->datarate == DR_LORA_SF5) || (cfg->datarate == DR_LORA_SF6)) {
  865. preamble_nb_symb = 12;
  866. } else {
  867. preamble_nb_symb = 8;
  868. }
  869. printf("INFO: LoRa Service modem: configuring preamble size to %u symbols\n", preamble_nb_symb);
  870. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG7_PREAMBLE_SYMB_NB, (preamble_nb_symb >> 8) & 0xFF); /* MSB */
  871. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG6_PREAMBLE_SYMB_NB, (preamble_nb_symb >> 0) & 0xFF); /* LSB */
  872. /* Freq2TimeDrift computation */
  873. if (calculate_freq_to_time_drift(radio_freq_hz, cfg->bandwidth, &mantissa, &exponent) != 0) {
  874. printf("ERROR: failed to calculate frequency to time drift for LoRa service modem\n");
  875. return LGW_REG_ERROR;
  876. }
  877. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME0_FREQ_TO_TIME_DRIFT_MANT, (mantissa >> 8) & 0x00FF);
  878. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME1_FREQ_TO_TIME_DRIFT_MANT, (mantissa) & 0x00FF);
  879. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME2_FREQ_TO_TIME_DRIFT_EXP, exponent);
  880. DEBUG_PRINTF("Freq2TimeDrift SingleSF: Mantissa = %d (0x%02X, 0x%02X), Exponent = %d (0x%02X)\n", mantissa, (mantissa >> 8) & 0x00FF, (mantissa) & 0x00FF, exponent, exponent);
  881. /* Time drift compensation */
  882. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_SYMB, 1);
  883. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_DAGC_IN_COMP, 1);
  884. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_MODEM_EN, 1);
  885. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_CADRXTX, 1);
  886. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_MODEM_START, 1);
  887. /* DFT peak mode : set to AUTO, check timestamp_counter_correction() if changed */
  888. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG0_DFT_PEAK_EN, RX_DFT_PEAK_MODE_AUTO);
  889. return err;
  890. }
  891. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  892. int sx1302_modem_enable(void) {
  893. int err = LGW_REG_SUCCESS;
  894. /* Enable LoRa multi-SF modems */
  895. err |= lgw_reg_w(SX1302_REG_COMMON_GEN_CONCENTRATOR_MODEM_ENABLE, 0x01);
  896. /* Enable LoRa service modem */
  897. err |= lgw_reg_w(SX1302_REG_COMMON_GEN_MBWSSF_MODEM_ENABLE, 0x01);
  898. /* Enable FSK modem */
  899. err |= lgw_reg_w(SX1302_REG_COMMON_GEN_FSK_MODEM_ENABLE, 0x01);
  900. /* Enable RX */
  901. err |= lgw_reg_w(SX1302_REG_COMMON_GEN_GLOBAL_EN, 0x01);
  902. return err;
  903. }
  904. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  905. int sx1302_lora_syncword(bool public, uint8_t lora_service_sf) {
  906. int err = LGW_REG_SUCCESS;
  907. /* Multi-SF modem configuration */
  908. DEBUG_MSG("INFO: configuring LoRa (Multi-SF) SF5->SF6 with syncword PRIVATE (0x12)\n");
  909. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH0_SF5_PEAK1_POS_SF5, 2);
  910. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH1_SF5_PEAK2_POS_SF5, 4);
  911. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH0_SF6_PEAK1_POS_SF6, 2);
  912. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH1_SF6_PEAK2_POS_SF6, 4);
  913. if (public == true) {
  914. DEBUG_MSG("INFO: configuring LoRa (Multi-SF) SF7->SF12 with syncword PUBLIC (0x34)\n");
  915. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH0_SF7TO12_PEAK1_POS_SF7TO12, 6);
  916. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH1_SF7TO12_PEAK2_POS_SF7TO12, 8);
  917. } else {
  918. DEBUG_MSG("INFO: configuring LoRa (Multi-SF) SF7->SF12 with syncword PRIVATE (0x12)\n");
  919. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH0_SF7TO12_PEAK1_POS_SF7TO12, 2);
  920. err |= lgw_reg_w(SX1302_REG_RX_TOP_FRAME_SYNCH1_SF7TO12_PEAK2_POS_SF7TO12, 4);
  921. }
  922. /* LoRa Service modem configuration */
  923. if ((public == false) || (lora_service_sf == DR_LORA_SF5) || (lora_service_sf == DR_LORA_SF6)) {
  924. DEBUG_PRINTF("INFO: configuring LoRa (Service) SF%u with syncword PRIVATE (0x12)\n", lora_service_sf);
  925. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH0_PEAK1_POS, 2);
  926. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH1_PEAK2_POS, 4);
  927. } else {
  928. DEBUG_PRINTF("INFO: configuring LoRa (Service) SF%u with syncword PUBLIC (0x34)\n", lora_service_sf);
  929. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH0_PEAK1_POS, 6);
  930. err |= lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH1_PEAK2_POS, 8);
  931. }
  932. return err;
  933. }
  934. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  935. uint32_t sx1302_timestamp_counter(bool pps) {
  936. uint32_t inst_cnt, pps_cnt;
  937. timestamp_counter_get(&counter_us, &inst_cnt, &pps_cnt);
  938. return ((pps == true) ? pps_cnt : inst_cnt);
  939. }
  940. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  941. int sx1302_gps_enable(bool enable) {
  942. int err = LGW_REG_SUCCESS;
  943. if (enable == true) {
  944. err |= lgw_reg_w(SX1302_REG_TIMESTAMP_GPS_CTRL_GPS_EN, 1);
  945. err |= lgw_reg_w(SX1302_REG_TIMESTAMP_GPS_CTRL_GPS_POL, 1); /* invert polarity for PPS */
  946. } else {
  947. err |= lgw_reg_w(SX1302_REG_TIMESTAMP_GPS_CTRL_GPS_EN, 0);
  948. }
  949. return err;
  950. }
  951. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  952. int sx1302_agc_load_firmware(const uint8_t *firmware) {
  953. int32_t val;
  954. uint8_t fw_check[MCU_FW_SIZE];
  955. int err = LGW_REG_SUCCESS;
  956. /* Take control over AGC MCU */
  957. err |= lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_MCU_CLEAR, 0x01);
  958. err |= lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_HOST_PROG, 0x01);
  959. err |= lgw_reg_w(SX1302_REG_COMMON_PAGE_PAGE, 0x00);
  960. /* Write AGC fw in AGC MEM */
  961. err |= lgw_mem_wb(AGC_MEM_ADDR, firmware, MCU_FW_SIZE);
  962. /* Read back and check */
  963. err |= lgw_mem_rb(AGC_MEM_ADDR, fw_check, MCU_FW_SIZE, false);
  964. if (memcmp(firmware, fw_check, sizeof fw_check) != 0) {
  965. printf("ERROR: AGC fw read/write check failed\n");
  966. return LGW_REG_ERROR;
  967. }
  968. /* Release control over AGC MCU */
  969. err |= lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_HOST_PROG, 0x00);
  970. err |= lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_MCU_CLEAR, 0x00);
  971. err |= lgw_reg_r(SX1302_REG_AGC_MCU_CTRL_PARITY_ERROR, &val);
  972. if (val != 0) {
  973. printf("ERROR: Failed to load AGC fw: parity error check failed\n");
  974. return LGW_REG_ERROR;
  975. }
  976. DEBUG_MSG("AGC fw loaded\n");
  977. return err;
  978. }
  979. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  980. int sx1302_agc_status(uint8_t* status) {
  981. int32_t val;
  982. int err = LGW_REG_SUCCESS;
  983. err = lgw_reg_r(SX1302_REG_AGC_MCU_MCU_AGC_STATUS_MCU_AGC_STATUS, &val);
  984. if (err != LGW_REG_SUCCESS) {
  985. printf("ERROR: Failed to get AGC status\n");
  986. return LGW_REG_ERROR;
  987. }
  988. *status = (uint8_t)val;
  989. return err;
  990. }
  991. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  992. int sx1302_agc_wait_status(uint8_t status) {
  993. uint8_t val;
  994. do {
  995. if (sx1302_agc_status(&val) != LGW_REG_SUCCESS) {
  996. return LGW_REG_ERROR;
  997. }
  998. /* TODO: add timeout */
  999. } while (val != status);
  1000. return LGW_REG_SUCCESS;
  1001. }
  1002. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1003. int sx1302_agc_mailbox_read(uint8_t mailbox, uint8_t* value) {
  1004. uint16_t reg;
  1005. int32_t val;
  1006. /* Check parameters */
  1007. if (mailbox > 3) {
  1008. printf("ERROR: invalid AGC mailbox ID\n");
  1009. return LGW_REG_ERROR;
  1010. }
  1011. reg = SX1302_REG_AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE0_MCU_MAIL_BOX_RD_DATA - mailbox;
  1012. if (lgw_reg_r(reg, &val) != LGW_REG_SUCCESS) {
  1013. printf("ERROR: failed to read AGC mailbox\n");
  1014. return LGW_REG_ERROR;
  1015. }
  1016. *value = (uint8_t)val;
  1017. return LGW_REG_SUCCESS;
  1018. }
  1019. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1020. int sx1302_agc_mailbox_write(uint8_t mailbox, uint8_t value) {
  1021. uint16_t reg;
  1022. /* Check parameters */
  1023. if (mailbox > 3) {
  1024. printf("ERROR: invalid AGC mailbox ID\n");
  1025. return LGW_REG_ERROR;
  1026. }
  1027. reg = SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE0_MCU_MAIL_BOX_WR_DATA - mailbox;
  1028. if (lgw_reg_w(reg, (int32_t)value) != LGW_REG_SUCCESS) {
  1029. printf("ERROR: failed to write AGC mailbox\n");
  1030. return LGW_REG_ERROR;
  1031. }
  1032. return LGW_REG_SUCCESS;
  1033. }
  1034. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1035. int sx1302_agc_start(uint8_t version, lgw_radio_type_t radio_type, uint8_t ana_gain, uint8_t dec_gain, bool full_duplex, bool lbt_enable) {
  1036. uint8_t val;
  1037. struct agc_gain_params_s agc_params;
  1038. uint8_t pa_start_delay;
  1039. uint8_t fdd_mode = ((full_duplex == true) ? 1 : 0);
  1040. /* Check parameters */
  1041. if ((radio_type != LGW_RADIO_TYPE_SX1255) && (radio_type != LGW_RADIO_TYPE_SX1257) && (radio_type != LGW_RADIO_TYPE_SX1250)) {
  1042. DEBUG_MSG("ERROR: invalid radio type\n");
  1043. return LGW_REG_ERROR;
  1044. }
  1045. /* Wait for AGC fw to be started, and VERSION available in mailbox */
  1046. sx1302_agc_wait_status(0x01); /* fw has started, VERSION is ready in mailbox */
  1047. sx1302_agc_mailbox_read(0, &val);
  1048. if (val != version) {
  1049. printf("ERROR: wrong AGC fw version (%d)\n", val);
  1050. return LGW_REG_ERROR;
  1051. }
  1052. DEBUG_PRINTF("AGC FW VERSION: %d\n", val);
  1053. /* -----------------------------------------------------------------------*/
  1054. /* Configure Radio A gains */
  1055. sx1302_agc_mailbox_write(0, ana_gain); /* 0:auto agc*/
  1056. sx1302_agc_mailbox_write(1, dec_gain);
  1057. if (radio_type != LGW_RADIO_TYPE_SX1250) {
  1058. printf("AGC: setting fdd_mode to %u\n", fdd_mode);
  1059. sx1302_agc_mailbox_write(2, fdd_mode);
  1060. }
  1061. /* notify AGC that gains has been set to mailbox for Radio A */
  1062. sx1302_agc_mailbox_write(3, AGC_RADIO_A_INIT_DONE);
  1063. /* Wait for AGC to acknoledge it has received gain settings for Radio A */
  1064. sx1302_agc_wait_status(0x02);
  1065. /* Check ana_gain setting */
  1066. sx1302_agc_mailbox_read(0, &val);
  1067. if (val != ana_gain) {
  1068. printf("ERROR: Analog gain of Radio A has not been set properly\n");
  1069. return LGW_REG_ERROR;
  1070. }
  1071. /* Check dec_gain setting */
  1072. sx1302_agc_mailbox_read(1, &val);
  1073. if (val != dec_gain) {
  1074. printf("ERROR: Decimator gain of Radio A has not been set properly\n");
  1075. return LGW_REG_ERROR;
  1076. }
  1077. /* Check FDD mode setting */
  1078. sx1302_agc_mailbox_read(2, &val);
  1079. if (val != fdd_mode) {
  1080. printf("ERROR: FDD mode of Radio A has not been set properly\n");
  1081. return LGW_REG_ERROR;
  1082. }
  1083. DEBUG_MSG("AGC: Radio A config done\n");
  1084. /* -----------------------------------------------------------------------*/
  1085. /* Configure Radio B gains */
  1086. sx1302_agc_mailbox_write(0, ana_gain); /* 0:auto agc*/
  1087. sx1302_agc_mailbox_write(1, dec_gain);
  1088. if (radio_type != LGW_RADIO_TYPE_SX1250) {
  1089. sx1302_agc_mailbox_write(2, fdd_mode);
  1090. }
  1091. /* notify AGC that gains has been set to mailbox for Radio B */
  1092. sx1302_agc_mailbox_write(3, AGC_RADIO_B_INIT_DONE);
  1093. /* Wait for AGC to acknoledge it has received gain settings for Radio B */
  1094. sx1302_agc_wait_status(0x03);
  1095. /* Check ana_gain setting */
  1096. sx1302_agc_mailbox_read(0, &val);
  1097. if (val != ana_gain) {
  1098. printf("ERROR: Analog gain of Radio B has not been set properly\n");
  1099. return LGW_REG_ERROR;
  1100. }
  1101. /* Check dec_gain setting */
  1102. sx1302_agc_mailbox_read(1, &val);
  1103. if (val != dec_gain) {
  1104. printf("ERROR: Decimator gain of Radio B has not been set properly\n");
  1105. return LGW_REG_ERROR;
  1106. }
  1107. /* Check FDD mode setting */
  1108. sx1302_agc_mailbox_read(2, &val);
  1109. if (val != fdd_mode) {
  1110. printf("ERROR: FDD mode of Radio B has not been set properly\n");
  1111. return LGW_REG_ERROR;
  1112. }
  1113. DEBUG_MSG("AGC: Radio B config done\n");
  1114. /* -----------------------------------------------------------------------*/
  1115. /* Configure AGC gains */
  1116. agc_params = (radio_type == LGW_RADIO_TYPE_SX1250) ? agc_params_sx1250 : agc_params_sx125x;
  1117. /* Configure analog gain min/max */
  1118. sx1302_agc_mailbox_write(0, agc_params.ana_min);
  1119. sx1302_agc_mailbox_write(1, agc_params.ana_max);
  1120. /* notify AGC that params have been set to mailbox */
  1121. sx1302_agc_mailbox_write(3, 0x03);
  1122. /* Wait for AGC to acknoledge it has received params */
  1123. sx1302_agc_wait_status(0x04);
  1124. /* Check params */
  1125. sx1302_agc_mailbox_read(0, &val);
  1126. if (val != agc_params.ana_min) {
  1127. printf("ERROR: wrong ana_min (w:%u r:%u)\n", agc_params.ana_min, val);
  1128. return LGW_REG_ERROR;
  1129. }
  1130. sx1302_agc_mailbox_read(1, &val);
  1131. if (val != agc_params.ana_max) {
  1132. printf("ERROR: ana_max (w:%u r:%u)\n", agc_params.ana_max, val);
  1133. return LGW_REG_ERROR;
  1134. }
  1135. DEBUG_MSG("AGC: config of analog gain min/max done\n");
  1136. /* -----------------------------------------------------------------------*/
  1137. /* Configure analog thresholds */
  1138. sx1302_agc_mailbox_write(0, agc_params.ana_thresh_l);
  1139. sx1302_agc_mailbox_write(1, agc_params.ana_thresh_h);
  1140. /* notify AGC that params have been set to mailbox */
  1141. sx1302_agc_mailbox_write(3, 0x04);
  1142. /* Wait for AGC to acknoledge it has received params */
  1143. sx1302_agc_wait_status(0x05);
  1144. /* Check params */
  1145. sx1302_agc_mailbox_read(0, &val);
  1146. if (val != agc_params.ana_thresh_l) {
  1147. printf("ERROR: wrong ana_thresh_l (w:%u r:%u)\n", agc_params.ana_thresh_l, val);
  1148. return LGW_REG_ERROR;
  1149. }
  1150. sx1302_agc_mailbox_read(1, &val);
  1151. if (val != agc_params.ana_thresh_h) {
  1152. printf("ERROR: wrong ana_thresh_h (w:%u r:%u)\n", agc_params.ana_thresh_h, val);
  1153. return LGW_REG_ERROR;
  1154. }
  1155. DEBUG_MSG("AGC: config of analog threshold done\n");
  1156. /* -----------------------------------------------------------------------*/
  1157. /* Configure decimator attenuation min/max */
  1158. sx1302_agc_mailbox_write(0, agc_params.dec_attn_min);
  1159. sx1302_agc_mailbox_write(1, agc_params.dec_attn_max);
  1160. /* notify AGC that params have been set to mailbox */
  1161. sx1302_agc_mailbox_write(3, 0x05);
  1162. /* Wait for AGC to acknoledge it has received params */
  1163. sx1302_agc_wait_status(0x06);
  1164. /* Check params */
  1165. sx1302_agc_mailbox_read(0, &val);
  1166. if (val != agc_params.dec_attn_min) {
  1167. printf("ERROR: wrong dec_attn_min (w:%u r:%u)\n", agc_params.dec_attn_min, val);
  1168. return LGW_REG_ERROR;
  1169. }
  1170. sx1302_agc_mailbox_read(1, &val);
  1171. if (val != agc_params.dec_attn_max) {
  1172. printf("ERROR: wrong dec_attn_max (w:%u r:%u)\n", agc_params.dec_attn_max, val);
  1173. return LGW_REG_ERROR;
  1174. }
  1175. DEBUG_MSG("AGC: config of decimator atten min/max done\n");
  1176. /* -----------------------------------------------------------------------*/
  1177. /* Configure decimator attenuation thresholds */
  1178. sx1302_agc_mailbox_write(0, agc_params.dec_thresh_l);
  1179. sx1302_agc_mailbox_write(1, agc_params.dec_thresh_h1);
  1180. sx1302_agc_mailbox_write(2, agc_params.dec_thresh_h2);
  1181. /* notify AGC that params have been set to mailbox */
  1182. sx1302_agc_mailbox_write(3, 0x06);
  1183. /* Wait for AGC to acknoledge it has received params */
  1184. sx1302_agc_wait_status(0x07);
  1185. /* Check params */
  1186. sx1302_agc_mailbox_read(0, &val);
  1187. if (val != agc_params.dec_thresh_l) {
  1188. printf("ERROR: wrong dec_thresh_l (w:%u r:%u)\n", agc_params.dec_thresh_l, val);
  1189. return LGW_REG_ERROR;
  1190. }
  1191. sx1302_agc_mailbox_read(1, &val);
  1192. if (val != agc_params.dec_thresh_h1) {
  1193. printf("ERROR: wrong dec_thresh_h1 (w:%u r:%u)\n", agc_params.dec_thresh_h1, val);
  1194. return LGW_REG_ERROR;
  1195. }
  1196. sx1302_agc_mailbox_read(2, &val);
  1197. if (val != agc_params.dec_thresh_h2) {
  1198. printf("ERROR: wrong dec_thresh_h2 (w:%u r:%u)\n", agc_params.dec_thresh_h2, val);
  1199. return LGW_REG_ERROR;
  1200. }
  1201. DEBUG_MSG("AGC: config of decimator threshold done\n");
  1202. /* -----------------------------------------------------------------------*/
  1203. /* Configure channel attenuation min/max */
  1204. sx1302_agc_mailbox_write(0, agc_params.chan_attn_min);
  1205. sx1302_agc_mailbox_write(1, agc_params.chan_attn_max);
  1206. /* notify AGC that params have been set to mailbox */
  1207. sx1302_agc_mailbox_write(3, 0x07);
  1208. /* Wait for AGC to acknoledge it has received params */
  1209. sx1302_agc_wait_status(0x08);
  1210. /* Check params */
  1211. sx1302_agc_mailbox_read(0, &val);
  1212. if (val != agc_params.chan_attn_min) {
  1213. printf("ERROR: wrong chan_attn_min (w:%u r:%u)\n", agc_params.chan_attn_min, val);
  1214. return LGW_REG_ERROR;
  1215. }
  1216. sx1302_agc_mailbox_read(1, &val);
  1217. if (val != agc_params.chan_attn_max) {
  1218. printf("ERROR: wrong chan_attn_max (w:%u r:%u)\n", agc_params.chan_attn_max, val);
  1219. return LGW_REG_ERROR;
  1220. }
  1221. DEBUG_MSG("AGC: config of channel atten min/max done\n");
  1222. /* -----------------------------------------------------------------------*/
  1223. /* Configure channel attenuation threshold */
  1224. sx1302_agc_mailbox_write(0, agc_params.chan_thresh_l);
  1225. sx1302_agc_mailbox_write(1, agc_params.chan_thresh_h);
  1226. /* notify AGC that params have been set to mailbox */
  1227. sx1302_agc_mailbox_write(3, 0x08);
  1228. /* Wait for AGC to acknoledge it has received params */
  1229. sx1302_agc_wait_status(0x09);
  1230. /* Check params */
  1231. sx1302_agc_mailbox_read(0, &val);
  1232. if (val != agc_params.chan_thresh_l) {
  1233. printf("ERROR: wrong chan_thresh_l (w:%u r:%u)\n", agc_params.chan_thresh_l, val);
  1234. return LGW_REG_ERROR;
  1235. }
  1236. sx1302_agc_mailbox_read(1, &val);
  1237. if (val != agc_params.chan_thresh_h) {
  1238. printf("ERROR: wrong chan_thresh_h (w:%u r:%u)\n", agc_params.chan_thresh_h, val);
  1239. return LGW_REG_ERROR;
  1240. }
  1241. DEBUG_MSG("AGC: config of channel atten threshold done\n");
  1242. /* -----------------------------------------------------------------------*/
  1243. /* Configure sx1250 SetPAConfig */
  1244. if (radio_type == LGW_RADIO_TYPE_SX1250) {
  1245. sx1302_agc_mailbox_write(0, agc_params.deviceSel);
  1246. sx1302_agc_mailbox_write(1, agc_params.hpMax);
  1247. sx1302_agc_mailbox_write(2, agc_params.paDutyCycle);
  1248. /* notify AGC that params have been set to mailbox */
  1249. sx1302_agc_mailbox_write(3, 0x09);
  1250. /* Wait for AGC to acknoledge it has received params */
  1251. sx1302_agc_wait_status(0x0A);
  1252. /* Check params */
  1253. sx1302_agc_mailbox_read(0, &val);
  1254. if (val != agc_params.deviceSel) {
  1255. printf("ERROR: wrong deviceSel (w:%u r:%u)\n", agc_params.deviceSel, val);
  1256. return LGW_REG_ERROR;
  1257. }
  1258. sx1302_agc_mailbox_read(1, &val);
  1259. if (val != agc_params.hpMax) {
  1260. printf("ERROR: wrong hpMax (w:%u r:%u)\n", agc_params.hpMax, val);
  1261. return LGW_REG_ERROR;
  1262. }
  1263. sx1302_agc_mailbox_read(2, &val);
  1264. if (val != agc_params.paDutyCycle) {
  1265. printf("ERROR: wrong paDutyCycle (w:%u r:%u)\n", agc_params.paDutyCycle, val);
  1266. return LGW_REG_ERROR;
  1267. }
  1268. DEBUG_MSG("AGC: config of sx1250 PA optimal settings done\n");
  1269. }
  1270. /* -----------------------------------------------------------------------*/
  1271. /* Set PA start delay */
  1272. pa_start_delay = 8;
  1273. sx1302_agc_mailbox_write(0, pa_start_delay); /* 1 LSB = 100 µs*/
  1274. /* notify AGC that params have been set to mailbox */
  1275. sx1302_agc_mailbox_write(3, 0x0A);
  1276. /* Wait for AGC to acknoledge it has received params */
  1277. sx1302_agc_wait_status(0x0B);
  1278. /* Check params */
  1279. sx1302_agc_mailbox_read(0, &val);
  1280. if (val != pa_start_delay) {
  1281. printf("ERROR: wrong PA start delay (w:%u r:%u)\n", pa_start_delay, val);
  1282. return LGW_REG_ERROR;
  1283. }
  1284. DEBUG_MSG("AGC: config of PA start delay done\n");
  1285. /* -----------------------------------------------------------------------*/
  1286. /* Enable LBT if required */
  1287. sx1302_agc_mailbox_write(0, (lbt_enable == true) ? 1 : 0);
  1288. /* notify AGC that params have been set to mailbox */
  1289. sx1302_agc_mailbox_write(3, 0x0B);
  1290. /* Wait for AGC to acknoledge it has received params */
  1291. sx1302_agc_wait_status(0x0F);
  1292. /* Check params */
  1293. sx1302_agc_mailbox_read(0, &val);
  1294. if ((bool)val != lbt_enable) {
  1295. printf("ERROR: wrong LBT configuration (w:%u r:%u)\n", lbt_enable, val);
  1296. return LGW_REG_ERROR;
  1297. }
  1298. DEBUG_PRINTF("AGC: LBT is %s\n", (lbt_enable == true) ? "enabled" : "disabled");
  1299. /* -----------------------------------------------------------------------*/
  1300. /* notify AGC that configuration is finished */
  1301. sx1302_agc_mailbox_write(3, 0x0F);
  1302. DEBUG_MSG("AGC: started\n");
  1303. return LGW_REG_SUCCESS;
  1304. }
  1305. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1306. int sx1302_arb_load_firmware(const uint8_t *firmware) {
  1307. uint8_t fw_check[MCU_FW_SIZE];
  1308. int32_t val;
  1309. int err = LGW_REG_SUCCESS;
  1310. /* Take control over ARB MCU */
  1311. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CTRL_MCU_CLEAR, 0x01);
  1312. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CTRL_HOST_PROG, 0x01);
  1313. err |= lgw_reg_w(SX1302_REG_COMMON_PAGE_PAGE, 0x00);
  1314. /* Write ARB fw in ARB MEM */
  1315. err |= lgw_mem_wb(ARB_MEM_ADDR, &firmware[0], MCU_FW_SIZE);
  1316. /* Read back and check */
  1317. err |= lgw_mem_rb(ARB_MEM_ADDR, fw_check, MCU_FW_SIZE, false);
  1318. if (memcmp(firmware, fw_check, sizeof fw_check) != 0) {
  1319. printf("ERROR: ARB fw read/write check failed\n");
  1320. return LGW_REG_ERROR;
  1321. }
  1322. /* Release control over ARB MCU */
  1323. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CTRL_HOST_PROG, 0x00);
  1324. err |= lgw_reg_w(SX1302_REG_ARB_MCU_CTRL_MCU_CLEAR, 0x00);
  1325. err |= lgw_reg_r(SX1302_REG_ARB_MCU_CTRL_PARITY_ERROR, &val);
  1326. if (val != 0) {
  1327. printf("ERROR: Failed to load ARB fw: parity error check failed\n");
  1328. return LGW_REG_ERROR;
  1329. }
  1330. DEBUG_MSG("ARB fw loaded\n");
  1331. return err;
  1332. }
  1333. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1334. int sx1302_arb_status(uint8_t* status) {
  1335. int32_t val;
  1336. int err = LGW_REG_SUCCESS;
  1337. err = lgw_reg_r(SX1302_REG_ARB_MCU_MCU_ARB_STATUS_MCU_ARB_STATUS, &val);
  1338. if (err != LGW_REG_SUCCESS) {
  1339. printf("ERROR: Failed to get ARB status\n");
  1340. return LGW_REG_ERROR;
  1341. }
  1342. *status = (uint8_t)val;
  1343. return err;
  1344. }
  1345. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1346. int sx1302_arb_wait_status(uint8_t status) {
  1347. uint8_t val;
  1348. do {
  1349. if (sx1302_arb_status(&val) != LGW_REG_SUCCESS) {
  1350. return LGW_REG_ERROR;
  1351. }
  1352. /* TODO: add timeout */
  1353. } while (val != status);
  1354. return LGW_REG_SUCCESS;
  1355. }
  1356. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1357. int sx1302_arb_debug_read(uint8_t reg_id, uint8_t* value) {
  1358. uint16_t reg;
  1359. int32_t val;
  1360. /* Check parameters */
  1361. if (reg_id > 15) {
  1362. printf("ERROR: invalid ARB debug register ID\n");
  1363. return LGW_REG_ERROR;
  1364. }
  1365. reg = SX1302_REG_ARB_MCU_ARB_DEBUG_STS_0_ARB_DEBUG_STS_0 + reg_id;
  1366. if (lgw_reg_r(reg, &val) != LGW_REG_SUCCESS) {
  1367. printf("ERROR: failed to read ARB debug register\n");
  1368. return LGW_REG_ERROR;
  1369. }
  1370. *value = (uint8_t)val;
  1371. return LGW_REG_SUCCESS;
  1372. }
  1373. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1374. int sx1302_arb_debug_write(uint8_t reg_id, uint8_t value) {
  1375. uint16_t reg;
  1376. /* Check parameters */
  1377. if (reg_id > 3) {
  1378. printf("ERROR: invalid ARB debug register ID\n");
  1379. return LGW_REG_ERROR;
  1380. }
  1381. reg = SX1302_REG_ARB_MCU_ARB_DEBUG_CFG_0_ARB_DEBUG_CFG_0 + reg_id;
  1382. if (lgw_reg_w(reg, (int32_t)value) != LGW_REG_SUCCESS) {
  1383. printf("ERROR: failed to write ARB debug register ID\n");
  1384. return LGW_REG_ERROR;
  1385. }
  1386. return LGW_REG_SUCCESS;
  1387. }
  1388. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1389. void sx1302_arb_set_debug_stats(bool enable, uint8_t sf) {
  1390. if (enable == true) {
  1391. DEBUG_PRINTF("ARB: Debug stats enabled for SF%u\n", sf);
  1392. lgw_reg_w(SX1302_REG_ARB_MCU_ARB_DEBUG_CFG_0_ARB_DEBUG_CFG_0, sf);
  1393. } else {
  1394. DEBUG_MSG("ARB: Debug stats disabled\n");
  1395. }
  1396. }
  1397. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1398. uint8_t sx1302_arb_get_debug_stats_detect(uint8_t channel) {
  1399. int32_t dbg_val;
  1400. if (channel >= 8) {
  1401. printf("ERROR: wrong configuration, channel num must be < 8");
  1402. return 0;
  1403. }
  1404. lgw_reg_r(SX1302_REG_ARB_MCU_ARB_DEBUG_STS_0_ARB_DEBUG_STS_0 + channel, &dbg_val);
  1405. return (uint8_t)dbg_val;
  1406. }
  1407. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1408. uint8_t sx1302_arb_get_debug_stats_alloc(uint8_t channel) {
  1409. int32_t dbg_val;
  1410. if (channel >= 8) {
  1411. printf("ERROR: wrong configuration, channel num must be < 8");
  1412. return 0;
  1413. }
  1414. lgw_reg_r(SX1302_REG_ARB_MCU_ARB_DEBUG_STS_8_ARB_DEBUG_STS_8 + channel, &dbg_val);
  1415. return (uint8_t)dbg_val;
  1416. }
  1417. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1418. void sx1302_arb_print_debug_stats(void) {
  1419. int i;
  1420. uint8_t nb_detect;
  1421. uint8_t nb_alloc;
  1422. int nb_detect_total = 0;
  1423. int nb_alloc_total = 0;
  1424. /* Get number of detects for all channels */
  1425. nb_detect_total = 0;
  1426. DEBUG_MSG("ARB: nb_detect: [");
  1427. for (i = 0; i < 8; i++) {
  1428. nb_detect = sx1302_arb_get_debug_stats_detect(i);
  1429. DEBUG_PRINTF("%u ", nb_detect);
  1430. nb_detect_total += nb_detect;
  1431. }
  1432. DEBUG_MSG("]\n");
  1433. /* Get number of modem allocation for all channels */
  1434. nb_alloc_total = 0;
  1435. DEBUG_MSG("ARB: nb_alloc: [");
  1436. for (i = 0; i < 8; i++) {
  1437. nb_alloc = sx1302_arb_get_debug_stats_alloc(i);
  1438. DEBUG_PRINTF("%u ", nb_alloc);
  1439. nb_alloc_total += nb_alloc;
  1440. }
  1441. DEBUG_MSG("]\n");
  1442. }
  1443. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1444. int sx1302_arb_start(uint8_t version, const struct lgw_conf_ftime_s * ftime_context) {
  1445. uint8_t val;
  1446. /* Wait for ARB fw to be started, and VERSION available in debug registers */
  1447. sx1302_arb_wait_status(0x01);
  1448. /* Get firmware VERSION */
  1449. sx1302_arb_debug_read(0, &val);
  1450. if (val != version) {
  1451. printf("ERROR: wrong ARB fw version (%d)\n", val);
  1452. return LGW_REG_ERROR;
  1453. }
  1454. DEBUG_PRINTF("ARB FW VERSION: %d\n", val);
  1455. /* Enable/disable ARB detect/modem alloc stats for the specified SF */
  1456. sx1302_arb_set_debug_stats(true, DR_LORA_SF7);
  1457. /* Enable/Disable double demod for different timing set (best timestamp / best demodulation) - 1 bit per SF (LSB=SF5, MSB=SF12) => 0:Disable 1:Enable */
  1458. if (ftime_context->enable == false) {
  1459. printf("ARB: dual demodulation disabled for all SF\n");
  1460. sx1302_arb_debug_write(3, 0x00); /* double demod disabled for all SF */
  1461. } else {
  1462. if (ftime_context->mode == LGW_FTIME_MODE_ALL_SF) {
  1463. printf("ARB: dual demodulation enabled for all SF\n");
  1464. sx1302_arb_debug_write(3, 0xFF); /* double demod enabled for all SF */
  1465. } else if (ftime_context->mode == LGW_FTIME_MODE_HIGH_CAPACITY) {
  1466. printf("ARB: dual demodulation enabled for SF5 -> SF10\n");
  1467. sx1302_arb_debug_write(3, 0x3F); /* double demod enabled for SF10 <- SF5 */
  1468. } else {
  1469. printf("ERROR: fine timestamp mode is not supported (%d)\n", ftime_context->mode);
  1470. return LGW_REG_ERROR;
  1471. }
  1472. }
  1473. /* Set double detect packet filtering threshold [0..3] */
  1474. sx1302_arb_debug_write(2, 3);
  1475. /* Notify ARB that it can resume */
  1476. sx1302_arb_debug_write(1, 1);
  1477. /* Wait for ARB to acknoledge */
  1478. sx1302_arb_wait_status(0x00);
  1479. DEBUG_MSG("ARB: started\n");
  1480. return LGW_REG_SUCCESS;
  1481. }
  1482. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1483. int sx1302_fetch(uint8_t * nb_pkt) {
  1484. int err;
  1485. struct timeval tm;
  1486. /* Record function start time */
  1487. _meas_time_start(&tm);
  1488. /* Fetch packets from sx1302 if no more left in RX buffer */
  1489. if (rx_buffer.buffer_pkt_nb == 0) {
  1490. /* Initialize RX buffer */
  1491. err = rx_buffer_new(&rx_buffer);
  1492. if (err != LGW_REG_SUCCESS) {
  1493. printf("ERROR: Failed to initialize RX buffer\n");
  1494. return LGW_REG_ERROR;
  1495. }
  1496. /* Fetch RX buffer if any data available */
  1497. err = rx_buffer_fetch(&rx_buffer);
  1498. if (err != LGW_REG_SUCCESS) {
  1499. printf("ERROR: Failed to fetch RX buffer\n");
  1500. return LGW_REG_ERROR;
  1501. }
  1502. } else {
  1503. printf("Note: remaining %u packets in RX buffer, do not fetch sx1302 yet...\n", rx_buffer.buffer_pkt_nb);
  1504. }
  1505. /* Return the number of packet fetched */
  1506. *nb_pkt = rx_buffer.buffer_pkt_nb;
  1507. _meas_time_stop(2, tm, __FUNCTION__);
  1508. return LGW_REG_SUCCESS;
  1509. }
  1510. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1511. int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p) {
  1512. int err;
  1513. int ifmod; /* type of if_chain/modem a packet was received by */
  1514. int32_t if_freq_hz;
  1515. int32_t if_freq_error;
  1516. double pkt_freq_error;
  1517. uint16_t payload_crc16_calc;
  1518. uint8_t cr;
  1519. int32_t timestamp_correction;
  1520. rx_packet_t pkt;
  1521. struct timeval tm;
  1522. /* Record function start time */
  1523. _meas_time_start(&tm);
  1524. /* Check input params */
  1525. CHECK_NULL(context);
  1526. CHECK_NULL(p);
  1527. #if 0
  1528. /* For DEBUG: WARNING: it is quite time consuming in USB mode, due to SPI over USB latency
  1529. Print statistics of number of detects and modem allocations from ARB for configured SF (see sx1302_arb_start())
  1530. */
  1531. sx1302_arb_print_debug_stats();
  1532. #endif
  1533. /* get packet from RX buffer */
  1534. err = rx_buffer_pop(&rx_buffer, &pkt);
  1535. if (err == LGW_REG_WARNING) {
  1536. rx_buffer_del(&rx_buffer); /* clear the buffer */
  1537. return err;
  1538. } else if (err == LGW_REG_ERROR) {
  1539. return err;
  1540. }
  1541. /* copy payload to result struct */
  1542. memcpy((void *)p->payload, (void *)(&(pkt.payload)), pkt.rxbytenb_modem);
  1543. p->size = pkt.rxbytenb_modem;
  1544. /* process metadata */
  1545. p->modem_id = pkt.modem_id;
  1546. p->if_chain = pkt.rx_channel_in;
  1547. if (p->if_chain >= LGW_IF_CHAIN_NB) {
  1548. DEBUG_PRINTF("WARNING: %u NOT A VALID IF_CHAIN NUMBER, ABORTING\n", p->if_chain);
  1549. return LGW_REG_ERROR;
  1550. }
  1551. ifmod = ifmod_config[p->if_chain];
  1552. DEBUG_PRINTF("[%d 0x%02X]\n", p->if_chain, ifmod);
  1553. p->rf_chain = (uint8_t)context->if_chain_cfg[p->if_chain].rf_chain;
  1554. /* Get the frequency for the channel configuration */
  1555. p->freq_hz = (uint32_t)((int32_t)context->rf_chain_cfg[p->rf_chain].freq_hz + context->if_chain_cfg[p->if_chain].freq_hz);
  1556. /* Get signal strength : offset and temperature compensation will be applied later */
  1557. p->rssic = (float)(pkt.rssi_chan_avg);
  1558. p->rssis = (float)(pkt.rssi_signal_avg);
  1559. /* Get modulation metadata */
  1560. if ((ifmod == IF_LORA_MULTI) || (ifmod == IF_LORA_STD)) {
  1561. DEBUG_PRINTF("Note: LoRa packet (modem %u chan %u)\n", p->modem_id, p->if_chain);
  1562. p->modulation = MOD_LORA;
  1563. /* Get CRC status */
  1564. if (pkt.crc_en || ((ifmod == IF_LORA_STD) && (context->lora_service_cfg.implicit_crc_en == true))) {
  1565. /* CRC enabled */
  1566. if (pkt.payload_crc_error) {
  1567. p->status = STAT_CRC_BAD;
  1568. } else {
  1569. p->status = STAT_CRC_OK;
  1570. /* Sanity check of the payload CRC */
  1571. if (p->size > 0) {
  1572. payload_crc16_calc = sx1302_lora_payload_crc(p->payload, p->size);
  1573. if (payload_crc16_calc != pkt.rx_crc16_value) {
  1574. printf("ERROR: Payload CRC16 check failed (got:0x%04X calc:0x%04X)\n", pkt.rx_crc16_value, payload_crc16_calc);
  1575. if (log_file != NULL) {
  1576. fprintf(log_file, "ERROR: Payload CRC16 check failed (got:0x%04X calc:0x%04X)\n", pkt.rx_crc16_value, payload_crc16_calc);
  1577. dbg_log_buffer_to_file(log_file, rx_buffer.buffer, rx_buffer.buffer_size);
  1578. }
  1579. return LGW_REG_ERROR;
  1580. } else {
  1581. DEBUG_PRINTF("Payload CRC check OK (0x%04X)\n", pkt.rx_crc16_value);
  1582. }
  1583. }
  1584. }
  1585. } else {
  1586. /* CRC disabled */
  1587. p->status = STAT_NO_CRC;
  1588. }
  1589. #if 0
  1590. int i;
  1591. /* FOR DEBUG: Check data integrity for known devices (debug context) */
  1592. if (p->status == STAT_CRC_OK || p->status == STAT_NO_CRC) {
  1593. /* We compare the received payload with predefined ones to ensure that the payload content is what we expect.
  1594. 4 bytes: ID to identify the payload
  1595. 4 bytes: packet counter used to initialize the seed for pseudo-random generation
  1596. x bytes: pseudo-random payload
  1597. */
  1598. int res;
  1599. for (i = 0; i < context->debug_cfg.nb_ref_payload; i++) {
  1600. res = dbg_check_payload(&(context->debug_cfg), log_file, p->payload, p->size, i, pkt.rx_rate_sf);
  1601. if (res == -1) {
  1602. printf("ERROR: 0x%08X payload error\n", context->debug_cfg.ref_payload[i].id);
  1603. if (log_file != NULL) {
  1604. fprintf(log_file, "ERROR: 0x%08X payload error\n", context->debug_cfg.ref_payload[i].id);
  1605. dbg_log_buffer_to_file(log_file, rx_buffer.buffer, rx_buffer.buffer_size);
  1606. dbg_log_payload_diff_to_file(log_file, p->payload, context->debug_cfg.ref_payload[i].payload, p->size);
  1607. }
  1608. return LGW_REG_ERROR;
  1609. } else if (res == 1) {
  1610. DEBUG_PRINTF("0x%08X payload matches\n", context->debug_cfg.ref_payload[i].id);
  1611. } else {
  1612. /* Do nothing */
  1613. }
  1614. }
  1615. }
  1616. #endif
  1617. /* Get SNR - converted from 0.25dB step to dB */
  1618. p->snr = (float)(pkt.snr_average) / 4;
  1619. /* Get bandwidth */
  1620. if (ifmod == IF_LORA_MULTI) {
  1621. p->bandwidth = BW_125KHZ; /* fixed in hardware */
  1622. } else {
  1623. p->bandwidth = context->lora_service_cfg.bandwidth; /* get the parameter from the config variable */
  1624. }
  1625. /* Get datarate */
  1626. switch (pkt.rx_rate_sf) {
  1627. case 5: p->datarate = DR_LORA_SF5; break;
  1628. case 6: p->datarate = DR_LORA_SF6; break;
  1629. case 7: p->datarate = DR_LORA_SF7; break;
  1630. case 8: p->datarate = DR_LORA_SF8; break;
  1631. case 9: p->datarate = DR_LORA_SF9; break;
  1632. case 10: p->datarate = DR_LORA_SF10; break;
  1633. case 11: p->datarate = DR_LORA_SF11; break;
  1634. case 12: p->datarate = DR_LORA_SF12; break;
  1635. default: p->datarate = DR_UNDEFINED;
  1636. }
  1637. /* Get coding rate */
  1638. if ((ifmod == IF_LORA_MULTI) || (context->lora_service_cfg.implicit_hdr == false)) {
  1639. cr = pkt.coding_rate;
  1640. } else {
  1641. cr = context->lora_service_cfg.implicit_coderate;
  1642. }
  1643. switch (cr) {
  1644. case 1: p->coderate = CR_LORA_4_5; break;
  1645. case 2: p->coderate = CR_LORA_4_6; break;
  1646. case 3: p->coderate = CR_LORA_4_7; break;
  1647. case 4: p->coderate = CR_LORA_4_8; break;
  1648. default: p->coderate = CR_UNDEFINED;
  1649. }
  1650. /* Get frequency offset in Hz depending on bandwidth */
  1651. switch (p->bandwidth) {
  1652. case BW_125KHZ:
  1653. p->freq_offset = (int32_t)((float)(pkt.frequency_offset_error) * FREQ_OFFSET_LSB_125KHZ);
  1654. break;
  1655. case BW_250KHZ:
  1656. p->freq_offset = (int32_t)((float)(pkt.frequency_offset_error) * FREQ_OFFSET_LSB_250KHZ);
  1657. break;
  1658. case BW_500KHZ:
  1659. p->freq_offset = (int32_t)((float)(pkt.frequency_offset_error) * FREQ_OFFSET_LSB_500KHZ);
  1660. break;
  1661. default:
  1662. p->freq_offset = 0;
  1663. printf("Invalid frequency offset\n");
  1664. break;
  1665. }
  1666. /* Adjust the frequency offset with channel IF frequency error:
  1667. When the channel IF frequency has been configured, a precision error may have been introduced
  1668. due to the register precision. We calculate this error here, and adjust the returned frequency error
  1669. accordingly. */
  1670. if_freq_hz = context->if_chain_cfg[p->if_chain].freq_hz; /* The IF frequency set in the registers, is the offset from the zero IF. */
  1671. if_freq_error = if_freq_hz - (IF_HZ_TO_REG(if_freq_hz) * 15625 / 32); /* The error corresponds to how many Hz are missing to get to actual 0 IF. */
  1672. /* Example to better understand what we get here:
  1673. - For a channel set to IF 400000Hz
  1674. - The IF frequency register will actually be set to 399902Hz due to its resolution
  1675. - This means that the modem, to shift to 0 IF, will apply -399902, instead of -400000.
  1676. - This means that the modem will be centered +98hz above the real 0 IF
  1677. - As the freq_offset given is supposed to be relative to the 0 IF, we add this resolution error to it */
  1678. p->freq_offset += if_freq_error;
  1679. /* Get timestamp correction to be applied to count_us */
  1680. timestamp_correction = timestamp_counter_correction(context, p->bandwidth, p->datarate, p->coderate, pkt.crc_en, pkt.rxbytenb_modem, RX_DFT_PEAK_MODE_AUTO);
  1681. /* Compute fine timestamp for packets coming from the modem optimized for fine timestamping, if CRC is OK */
  1682. p->ftime_received = false;
  1683. p->ftime = 0;
  1684. if ((pkt.num_ts_metrics_stored > 0) && (pkt.timing_set == true) && (p->status == STAT_CRC_OK)) {
  1685. /* The actual packet frequency error compared to the channel frequency, need to compute the ftime */
  1686. pkt_freq_error = ((double)(p->freq_hz + p->freq_offset) / (double)(p->freq_hz)) - 1.0;
  1687. /* Compute the fine timestamp */
  1688. err = precise_timestamp_calculate(pkt.num_ts_metrics_stored, &pkt.timestamp_avg[0], pkt.timestamp_cnt, pkt.rx_rate_sf, context->if_chain_cfg[p->if_chain].freq_hz, pkt_freq_error, &(p->ftime));
  1689. if (err == 0) {
  1690. p->ftime_received = true;
  1691. }
  1692. }
  1693. } else if (ifmod == IF_FSK_STD) {
  1694. DEBUG_PRINTF("Note: FSK packet (modem %u chan %u)\n", pkt.modem_id, p->if_chain);
  1695. p->modulation = MOD_FSK;
  1696. /* Get CRC status */
  1697. if (pkt.crc_en) {
  1698. /* CRC enabled */
  1699. if (pkt.payload_crc_error) {
  1700. printf("FSK: CRC ERR\n");
  1701. p->status = STAT_CRC_BAD;
  1702. } else {
  1703. printf("FSK: CRC OK\n");
  1704. p->status = STAT_CRC_OK;
  1705. }
  1706. } else {
  1707. /* CRC disabled */
  1708. p->status = STAT_NO_CRC;
  1709. }
  1710. /* Get modulation params */
  1711. p->bandwidth = context->fsk_cfg.bandwidth;
  1712. p->datarate = context->fsk_cfg.datarate;
  1713. /* Compute timestamp correction to be applied */
  1714. timestamp_correction = ((uint32_t)680000 / context->fsk_cfg.datarate) - 20;
  1715. /* RSSI correction */
  1716. p->rssic = RSSI_FSK_POLY_0 + RSSI_FSK_POLY_1 * p->rssic + RSSI_FSK_POLY_2 * pow(p->rssic, 2) + RSSI_FSK_POLY_3 * pow(p->rssic, 3);
  1717. /* Undefined for FSK */
  1718. p->coderate = CR_UNDEFINED;
  1719. p->snr = -128.0;
  1720. p->rssis = -128.0;
  1721. } else {
  1722. DEBUG_MSG("ERROR: UNEXPECTED PACKET ORIGIN\n");
  1723. p->status = STAT_UNDEFINED;
  1724. p->modulation = MOD_UNDEFINED;
  1725. p->rssic = -128.0;
  1726. p->rssis = -128.0;
  1727. p->snr = -128.0;
  1728. p->snr_min = -128.0;
  1729. p->snr_max = -128.0;
  1730. p->bandwidth = BW_UNDEFINED;
  1731. p->datarate = DR_UNDEFINED;
  1732. p->coderate = CR_UNDEFINED;
  1733. timestamp_correction = 0;
  1734. }
  1735. /* Scale 32 MHz packet timestamp to 1 MHz (microseconds) */
  1736. p->count_us = pkt.timestamp_cnt / 32;
  1737. /* Expand 27-bits counter to 32-bits counter, based on current wrapping status (updated after fetch) */
  1738. p->count_us = timestamp_pkt_expand(&counter_us, p->count_us);
  1739. #if 0 // debug code to check for failed submicros/micros handling
  1740. {
  1741. static uint32_t last_valid = 0;
  1742. static uint32_t last_us32 = 0;
  1743. static uint32_t last_pkt_num;
  1744. int32_t diff = p->count_us - last_us32;
  1745. uint32_t pkt_num = (p->payload[4] << 24) | (p->payload[5] << 16) | (p->payload[6] << 8) | (p->payload[7] << 0);
  1746. printf("XXXXXXXXXXXXXXXX inst - ref=%u wrap=%u\n", counter_us.inst.counter_us_27bits_ref, counter_us.inst.counter_us_27bits_wrap);
  1747. printf("XXXXXXXXXXXXXXXX pps - ref=%u wrap=%u\n", counter_us.pps.counter_us_27bits_ref, counter_us.pps.counter_us_27bits_wrap);
  1748. printf("XXXXXXXXXXXXXXXX pkt=%u (%u) last=%u diff=%d\n", p->count_us, pkt.timestamp_cnt / 32, last_us32, diff);
  1749. printf("XXXXXXXXXXXXXXXX pkt num=%u\n", pkt_num);
  1750. if (last_valid && (diff > 30000000) && (pkt_num == (last_pkt_num + 1))) {
  1751. printf("XXXXXXXXXXXXXXXX ERROR jump ahead count_us\n");
  1752. exit(1);
  1753. }
  1754. last_us32 = p->count_us;
  1755. last_pkt_num = pkt_num;
  1756. last_valid = 1;
  1757. }
  1758. #endif
  1759. /* Packet timestamp corrected */
  1760. p->count_us = p->count_us + timestamp_correction;
  1761. /* Packet CRC status */
  1762. p->crc = pkt.rx_crc16_value;
  1763. _meas_time_stop(2, tm, __FUNCTION__);
  1764. return LGW_REG_SUCCESS;
  1765. }
  1766. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1767. uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size) {
  1768. int i;
  1769. int crc = 0;
  1770. for (i = 0; i < size; i++) {
  1771. lora_crc16(data[i], &crc);
  1772. }
  1773. //printf("CRC16: 0x%02X 0x%02X (%X)\n", (uint8_t)(crc >> 8), (uint8_t)crc, crc);
  1774. return (uint16_t)crc;
  1775. }
  1776. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1777. int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth, uint8_t chirp_lowpass, uint16_t * delay) {
  1778. int err;
  1779. uint16_t tx_start_delay = TX_START_DELAY_DEFAULT * 32;
  1780. uint16_t radio_bw_delay = 0;
  1781. uint16_t filter_delay = 0;
  1782. uint16_t modem_delay = 0;
  1783. int32_t bw_hz = lgw_bw_getval(bandwidth);
  1784. uint8_t buff[2]; /* for 16 bits register write operation */
  1785. CHECK_NULL(delay);
  1786. /* tx start delay only necessary for beaconing (LoRa) */
  1787. if (modulation != MOD_LORA) {
  1788. *delay = 0;
  1789. return LGW_REG_SUCCESS;
  1790. }
  1791. /* Adjust with radio type and bandwidth */
  1792. switch (radio_type) {
  1793. case LGW_RADIO_TYPE_SX1250:
  1794. if (bandwidth == BW_125KHZ) {
  1795. radio_bw_delay = 19;
  1796. } else if (bandwidth == BW_250KHZ) {
  1797. radio_bw_delay = 24;
  1798. } else if (bandwidth == BW_500KHZ) {
  1799. radio_bw_delay = 21;
  1800. } else {
  1801. DEBUG_MSG("ERROR: bandwidth not supported\n");
  1802. return LGW_REG_ERROR;
  1803. }
  1804. break;
  1805. case LGW_RADIO_TYPE_SX1255:
  1806. case LGW_RADIO_TYPE_SX1257:
  1807. radio_bw_delay = 3*32 + 4;
  1808. if (bandwidth == BW_125KHZ) {
  1809. radio_bw_delay += 0;
  1810. } else if (bandwidth == BW_250KHZ) {
  1811. radio_bw_delay += 6;
  1812. } else if (bandwidth == BW_500KHZ) {
  1813. radio_bw_delay += 0;
  1814. } else {
  1815. DEBUG_MSG("ERROR: bandwidth not supported\n");
  1816. return LGW_REG_ERROR;
  1817. }
  1818. break;
  1819. default:
  1820. DEBUG_MSG("ERROR: radio type not supported\n");
  1821. return LGW_REG_ERROR;
  1822. }
  1823. /* Adjust with modulation */
  1824. filter_delay = ((1 << chirp_lowpass) - 1) * 1e6 / bw_hz;
  1825. modem_delay = 8 * (32e6 / (32 * bw_hz)); /* if bw=125k then modem freq=4MHz */
  1826. /* Compute total delay */
  1827. tx_start_delay -= (radio_bw_delay + filter_delay + modem_delay);
  1828. DEBUG_PRINTF("INFO: tx_start_delay=%u (%u, radio_bw_delay=%u, filter_delay=%u, modem_delay=%u)\n", (uint16_t)tx_start_delay, TX_START_DELAY_DEFAULT*32, radio_bw_delay, filter_delay, modem_delay);
  1829. buff[0] = (uint8_t)(tx_start_delay >> 8);
  1830. buff[1] = (uint8_t)(tx_start_delay >> 0);
  1831. err = lgw_reg_wb(SX1302_REG_TX_TOP_TX_START_DELAY_MSB_TX_START_DELAY(rf_chain), buff, 2);
  1832. CHECK_ERR(err);
  1833. /* return tx_start_delay */
  1834. *delay = tx_start_delay;
  1835. return LGW_REG_SUCCESS;
  1836. }
  1837. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1838. float sx1302_rssi_get_temperature_offset(struct lgw_rssi_tcomp_s * context, float temperature) {
  1839. /* Chekc params */
  1840. CHECK_NULL(context);
  1841. DEBUG_MSG ("INFO: RSSI temperature compensation:\n");
  1842. DEBUG_PRINTF(" coeff_a: %.3f\n", context->coeff_a);
  1843. DEBUG_PRINTF(" coeff_b: %.3f\n", context->coeff_b);
  1844. DEBUG_PRINTF(" coeff_c: %.3f\n", context->coeff_c);
  1845. DEBUG_PRINTF(" coeff_d: %.3f\n", context->coeff_d);
  1846. DEBUG_PRINTF(" coeff_e: %.3f\n", context->coeff_e);
  1847. /* Compute the offset to be applied to RSSI for given temperature */
  1848. return ((context->coeff_a * pow(temperature, 4)) +
  1849. (context->coeff_b * pow(temperature, 3)) +
  1850. (context->coeff_c * pow(temperature, 2)) +
  1851. (context->coeff_d * temperature) + context->coeff_e) / pow(2, 16);
  1852. }
  1853. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1854. uint8_t sx1302_tx_status(uint8_t rf_chain) {
  1855. int err;
  1856. int32_t read_value;
  1857. err = lgw_reg_r(SX1302_REG_TX_TOP_TX_FSM_STATUS_TX_STATUS(rf_chain), &read_value);
  1858. if (err != LGW_REG_SUCCESS) {
  1859. printf("ERROR: Failed to read TX STATUS\n");
  1860. return TX_STATUS_UNKNOWN;
  1861. }
  1862. if (read_value == 0x80) {
  1863. return TX_FREE;
  1864. } else if ((read_value == 0x30) || (read_value == 0x50) || (read_value == 0x60) || (read_value == 0x70)) {
  1865. return TX_EMITTING;
  1866. } else if ((read_value == 0x91) || (read_value == 0x92)) {
  1867. return TX_SCHEDULED;
  1868. } else {
  1869. printf("ERROR: UNKNOWN TX STATUS 0x%02X\n", read_value);
  1870. return TX_STATUS_UNKNOWN;
  1871. }
  1872. }
  1873. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1874. uint8_t sx1302_rx_status(uint8_t rf_chain) {
  1875. if (rf_chain) {}; /* dummy for compilation */
  1876. /* Not implemented */
  1877. return RX_STATUS_UNKNOWN;
  1878. }
  1879. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1880. int sx1302_tx_abort(uint8_t rf_chain) {
  1881. int err;
  1882. uint8_t tx_status = TX_STATUS_UNKNOWN;
  1883. struct timeval tm_start;
  1884. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(rf_chain), 0x00);
  1885. err |= lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_DELAYED(rf_chain), 0x00);
  1886. err |= lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_GPS(rf_chain), 0x00);
  1887. if (err != LGW_REG_SUCCESS) {
  1888. printf("ERROR: Failed to stop TX trigger\n");
  1889. return err;
  1890. }
  1891. timeout_start(&tm_start);
  1892. do {
  1893. /* handle timeout */
  1894. if (timeout_check(tm_start, 1000) != 0) {
  1895. printf("ERROR: %s: TIMEOUT on TX abort\n", __FUNCTION__);
  1896. return LGW_REG_ERROR;
  1897. }
  1898. /* get tx status */
  1899. tx_status = sx1302_tx_status(rf_chain);
  1900. wait_ms(1);
  1901. } while (tx_status != TX_FREE);
  1902. return LGW_REG_SUCCESS;
  1903. }
  1904. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1905. int sx1302_tx_configure(lgw_radio_type_t radio_type) {
  1906. int err = LGW_REG_SUCCESS;
  1907. /* Select the TX destination interface */
  1908. switch (radio_type) {
  1909. case LGW_RADIO_TYPE_SX1250:
  1910. /* Let AGC control PLL DIV (sx1250 only) */
  1911. err |= lgw_reg_w(SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC, 1);
  1912. err |= lgw_reg_w(SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC, 1);
  1913. /* SX126x Tx RFFE */
  1914. err |= lgw_reg_w(SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_DST, 0x01);
  1915. err |= lgw_reg_w(SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_DST, 0x01);
  1916. break;
  1917. case LGW_RADIO_TYPE_SX1255:
  1918. case LGW_RADIO_TYPE_SX1257:
  1919. /* SX1255/57 Tx RFFE */
  1920. err |= lgw_reg_w(SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_DST, 0x00);
  1921. err |= lgw_reg_w(SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_DST, 0x00);
  1922. break;
  1923. default:
  1924. DEBUG_MSG("ERROR: radio type not supported\n");
  1925. return LGW_REG_ERROR;
  1926. }
  1927. /* Configure the TX mode of operation */
  1928. err |= lgw_reg_w(SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_MODE, 0x01); /* Modulation */
  1929. err |= lgw_reg_w(SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_MODE, 0x01); /* Modulation */
  1930. /* Configure the output data clock edge */
  1931. err |= lgw_reg_w(SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_CLK_EDGE, 0x00); /* Data on rising edge */
  1932. err |= lgw_reg_w(SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_CLK_EDGE, 0x00); /* Data on rising edge */
  1933. return err;
  1934. }
  1935. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  1936. int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, bool lwan_public, struct lgw_conf_rxif_s * context_fsk, struct lgw_pkt_tx_s * pkt_data) {
  1937. int err;
  1938. uint32_t freq_reg, fdev_reg;
  1939. uint32_t freq_dev;
  1940. uint32_t fsk_br_reg;
  1941. uint64_t fsk_sync_word_reg;
  1942. uint16_t mem_addr;
  1943. uint32_t count_us;
  1944. uint8_t power;
  1945. uint8_t pow_index;
  1946. uint8_t mod_bw;
  1947. uint8_t pa_en;
  1948. uint16_t tx_start_delay;
  1949. uint8_t chirp_lowpass = 0;
  1950. uint8_t buff[2]; /* for 16-bits register write operation */
  1951. /* performances variables */
  1952. struct timeval tm;
  1953. /* Record function start time */
  1954. _meas_time_start(&tm);
  1955. /* Check input parameters */
  1956. CHECK_NULL(tx_lut);
  1957. CHECK_NULL(pkt_data);
  1958. /* Setting BULK write mode (to speed up configuration on USB) */
  1959. err = lgw_com_set_write_mode(LGW_COM_WRITE_MODE_BULK);
  1960. CHECK_ERR(err);
  1961. /* Select the proper modem */
  1962. switch (pkt_data->modulation) {
  1963. case MOD_CW:
  1964. err = lgw_reg_w(SX1302_REG_TX_TOP_GEN_CFG_0_MODULATION_TYPE(pkt_data->rf_chain), 0x00);
  1965. CHECK_ERR(err);
  1966. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_IF_SRC(pkt_data->rf_chain), 0x00);
  1967. CHECK_ERR(err);
  1968. break;
  1969. case MOD_LORA:
  1970. err = lgw_reg_w(SX1302_REG_TX_TOP_GEN_CFG_0_MODULATION_TYPE(pkt_data->rf_chain), 0x00);
  1971. CHECK_ERR(err);
  1972. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_IF_SRC(pkt_data->rf_chain), 0x01);
  1973. CHECK_ERR(err);
  1974. break;
  1975. case MOD_FSK:
  1976. err = lgw_reg_w(SX1302_REG_TX_TOP_GEN_CFG_0_MODULATION_TYPE(pkt_data->rf_chain), 0x01);
  1977. CHECK_ERR(err);
  1978. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_IF_SRC(pkt_data->rf_chain), 0x02);
  1979. CHECK_ERR(err);
  1980. break;
  1981. default:
  1982. DEBUG_MSG("ERROR: modulation type not supported\n");
  1983. return LGW_REG_ERROR;
  1984. }
  1985. /* Find the proper index in the TX gain LUT according to requested rf_power */
  1986. for (pow_index = tx_lut->size-1; pow_index > 0; pow_index--) {
  1987. if (tx_lut->lut[pow_index].rf_power <= pkt_data->rf_power) {
  1988. break;
  1989. }
  1990. }
  1991. DEBUG_PRINTF("INFO: selecting TX Gain LUT index %u\n", pow_index);
  1992. /* loading calibrated Tx DC offsets */
  1993. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_I_OFFSET_I_OFFSET(pkt_data->rf_chain), tx_lut->lut[pow_index].offset_i);
  1994. CHECK_ERR(err);
  1995. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_Q_OFFSET_Q_OFFSET(pkt_data->rf_chain), tx_lut->lut[pow_index].offset_q);
  1996. CHECK_ERR(err);
  1997. DEBUG_PRINTF("INFO: Applying IQ offset (i:%d, q:%d)\n", tx_lut->lut[pow_index].offset_i, tx_lut->lut[pow_index].offset_q);
  1998. /* Set the power parameters to be used for TX */
  1999. switch (radio_type) {
  2000. case LGW_RADIO_TYPE_SX1250:
  2001. pa_en = (tx_lut->lut[pow_index].pa_gain > 0) ? 1 : 0; /* only 1 bit used to control the external PA */
  2002. power = (pa_en << 6) | tx_lut->lut[pow_index].pwr_idx;
  2003. break;
  2004. case LGW_RADIO_TYPE_SX1255:
  2005. case LGW_RADIO_TYPE_SX1257:
  2006. power = (tx_lut->lut[pow_index].pa_gain << 6) | (tx_lut->lut[pow_index].dac_gain << 4) | tx_lut->lut[pow_index].mix_gain;
  2007. break;
  2008. default:
  2009. DEBUG_MSG("ERROR: radio type not supported\n");
  2010. return LGW_REG_ERROR;
  2011. }
  2012. err = lgw_reg_w(SX1302_REG_TX_TOP_AGC_TX_PWR_AGC_TX_PWR(pkt_data->rf_chain), power);
  2013. CHECK_ERR(err);
  2014. /* Set digital gain */
  2015. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_IQ_GAIN_IQ_GAIN(pkt_data->rf_chain), tx_lut->lut[pow_index].dig_gain);
  2016. CHECK_ERR(err);
  2017. /* Set Tx frequency */
  2018. if (radio_type == LGW_RADIO_TYPE_SX1255) {
  2019. freq_reg = SX1302_FREQ_TO_REG(pkt_data->freq_hz * 2);
  2020. } else {
  2021. freq_reg = SX1302_FREQ_TO_REG(pkt_data->freq_hz);
  2022. }
  2023. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_RF_H_FREQ_RF(pkt_data->rf_chain), (freq_reg >> 16) & 0xFF);
  2024. CHECK_ERR(err);
  2025. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_RF_M_FREQ_RF(pkt_data->rf_chain), (freq_reg >> 8) & 0xFF);
  2026. CHECK_ERR(err);
  2027. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_RF_L_FREQ_RF(pkt_data->rf_chain), (freq_reg >> 0) & 0xFF);
  2028. CHECK_ERR(err);
  2029. /* Set AGC bandwidth and modulation type*/
  2030. switch (pkt_data->modulation) {
  2031. case MOD_LORA:
  2032. mod_bw = pkt_data->bandwidth;
  2033. break;
  2034. case MOD_CW:
  2035. case MOD_FSK:
  2036. mod_bw = (0x01 << 7) | pkt_data->bandwidth;
  2037. break;
  2038. default:
  2039. printf("ERROR: Modulation not supported\n");
  2040. return LGW_REG_ERROR;
  2041. }
  2042. err = lgw_reg_w(SX1302_REG_TX_TOP_AGC_TX_BW_AGC_TX_BW(pkt_data->rf_chain), mod_bw);
  2043. CHECK_ERR(err);
  2044. /* Configure modem */
  2045. switch (pkt_data->modulation) {
  2046. case MOD_CW:
  2047. /* Set frequency deviation */
  2048. freq_dev = ceil(fabs( (float)pkt_data->freq_offset / 10) ) * 10e3;
  2049. printf("CW: f_dev %d Hz\n", (int)(freq_dev));
  2050. fdev_reg = SX1302_FREQ_TO_REG(freq_dev);
  2051. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV(pkt_data->rf_chain), (fdev_reg >> 8) & 0xFF);
  2052. CHECK_ERR(err);
  2053. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV(pkt_data->rf_chain), (fdev_reg >> 0) & 0xFF);
  2054. CHECK_ERR(err);
  2055. /* Send frequency deviation to AGC fw for radio config */
  2056. fdev_reg = SX1250_FREQ_TO_REG(freq_dev);
  2057. err = lgw_reg_w(SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE2_MCU_MAIL_BOX_WR_DATA, (fdev_reg >> 16) & 0xFF); /* Needed by AGC to configure the sx1250 */
  2058. CHECK_ERR(err);
  2059. err = lgw_reg_w(SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE1_MCU_MAIL_BOX_WR_DATA, (fdev_reg >> 8) & 0xFF); /* Needed by AGC to configure the sx1250 */
  2060. CHECK_ERR(err);
  2061. err = lgw_reg_w(SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE0_MCU_MAIL_BOX_WR_DATA, (fdev_reg >> 0) & 0xFF); /* Needed by AGC to configure the sx1250 */
  2062. CHECK_ERR(err);
  2063. /* Set the frequency offset (ratio of the frequency deviation)*/
  2064. printf("CW: IF test mod freq %d\n", (int)(((float)pkt_data->freq_offset*1e3*64/(float)freq_dev)));
  2065. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_TEST_MOD_FREQ(pkt_data->rf_chain), (int)(((float)pkt_data->freq_offset*1e3*64/(float)freq_dev)));
  2066. CHECK_ERR(err);
  2067. break;
  2068. case MOD_LORA:
  2069. /* Set bandwidth */
  2070. freq_dev = lgw_bw_getval(pkt_data->bandwidth) / 2;
  2071. fdev_reg = SX1302_FREQ_TO_REG(freq_dev);
  2072. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV(pkt_data->rf_chain), (fdev_reg >> 8) & 0xFF);
  2073. CHECK_ERR(err);
  2074. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV(pkt_data->rf_chain), (fdev_reg >> 0) & 0xFF);
  2075. CHECK_ERR(err);
  2076. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_0_MODEM_BW(pkt_data->rf_chain), pkt_data->bandwidth);
  2077. CHECK_ERR(err);
  2078. /* Preamble length */
  2079. if (pkt_data->preamble == 0) { /* if not explicit, use recommended LoRa preamble size */
  2080. pkt_data->preamble = STD_LORA_PREAMBLE;
  2081. } else if (pkt_data->preamble < MIN_LORA_PREAMBLE) { /* enforce minimum preamble size */
  2082. pkt_data->preamble = MIN_LORA_PREAMBLE;
  2083. DEBUG_MSG("Note: preamble length adjusted to respect minimum LoRa preamble size\n");
  2084. }
  2085. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG1_3_PREAMBLE_SYMB_NB(pkt_data->rf_chain), (pkt_data->preamble >> 8) & 0xFF); /* MSB */
  2086. CHECK_ERR(err);
  2087. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG1_2_PREAMBLE_SYMB_NB(pkt_data->rf_chain), (pkt_data->preamble >> 0) & 0xFF); /* LSB */
  2088. CHECK_ERR(err);
  2089. /* LoRa datarate */
  2090. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_0_MODEM_SF(pkt_data->rf_chain), pkt_data->datarate);
  2091. CHECK_ERR(err);
  2092. /* Chirp filtering */
  2093. chirp_lowpass = (pkt_data->datarate < 10) ? 6 : 7;
  2094. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_CFG0_0_CHIRP_LOWPASS(pkt_data->rf_chain), (int32_t)chirp_lowpass);
  2095. CHECK_ERR(err);
  2096. /* Coding Rate */
  2097. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_1_CODING_RATE(pkt_data->rf_chain), pkt_data->coderate);
  2098. CHECK_ERR(err);
  2099. /* Start LoRa modem */
  2100. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_2_MODEM_EN(pkt_data->rf_chain), 1);
  2101. CHECK_ERR(err);
  2102. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_2_CADRXTX(pkt_data->rf_chain), 2);
  2103. CHECK_ERR(err);
  2104. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG1_1_MODEM_START(pkt_data->rf_chain), 1);
  2105. CHECK_ERR(err);
  2106. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_CFG0_0_CONTINUOUS(pkt_data->rf_chain), 0);
  2107. CHECK_ERR(err);
  2108. /* Modulation options */
  2109. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_CFG0_0_CHIRP_INVERT(pkt_data->rf_chain), (pkt_data->invert_pol) ? 1 : 0);
  2110. CHECK_ERR(err);
  2111. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_2_IMPLICIT_HEADER(pkt_data->rf_chain), (pkt_data->no_header) ? 1 : 0);
  2112. CHECK_ERR(err);
  2113. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_2_CRC_EN(pkt_data->rf_chain), (pkt_data->no_crc) ? 0 : 1);
  2114. CHECK_ERR(err);
  2115. /* Syncword */
  2116. if ((lwan_public == false) || (pkt_data->datarate == DR_LORA_SF5) || (pkt_data->datarate == DR_LORA_SF6)) {
  2117. DEBUG_MSG("Setting LoRa syncword 0x12\n");
  2118. err = lgw_reg_w(SX1302_REG_TX_TOP_FRAME_SYNCH_0_PEAK1_POS(pkt_data->rf_chain), 2);
  2119. CHECK_ERR(err);
  2120. err = lgw_reg_w(SX1302_REG_TX_TOP_FRAME_SYNCH_1_PEAK2_POS(pkt_data->rf_chain), 4);
  2121. CHECK_ERR(err);
  2122. } else {
  2123. DEBUG_MSG("Setting LoRa syncword 0x34\n");
  2124. err = lgw_reg_w(SX1302_REG_TX_TOP_FRAME_SYNCH_0_PEAK1_POS(pkt_data->rf_chain), 6);
  2125. CHECK_ERR(err);
  2126. err = lgw_reg_w(SX1302_REG_TX_TOP_FRAME_SYNCH_1_PEAK2_POS(pkt_data->rf_chain), 8);
  2127. CHECK_ERR(err);
  2128. }
  2129. /* Set Fine Sync for SF5/SF6 */
  2130. if ((pkt_data->datarate == DR_LORA_SF5) || (pkt_data->datarate == DR_LORA_SF6)) {
  2131. DEBUG_MSG("Enable Fine Sync\n");
  2132. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_2_FINE_SYNCH_EN(pkt_data->rf_chain), 1);
  2133. CHECK_ERR(err);
  2134. } else {
  2135. DEBUG_MSG("Disable Fine Sync\n");
  2136. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_2_FINE_SYNCH_EN(pkt_data->rf_chain), 0);
  2137. CHECK_ERR(err);
  2138. }
  2139. /* Set Payload length */
  2140. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_3_PAYLOAD_LENGTH(pkt_data->rf_chain), pkt_data->size);
  2141. CHECK_ERR(err);
  2142. /* Set PPM offset (low datarate optimization) */
  2143. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL(pkt_data->rf_chain), 0);
  2144. CHECK_ERR(err);
  2145. if (SET_PPM_ON(pkt_data->bandwidth, pkt_data->datarate)) {
  2146. DEBUG_MSG("Low datarate optimization ENABLED\n");
  2147. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_1_PPM_OFFSET(pkt_data->rf_chain), 1);
  2148. CHECK_ERR(err);
  2149. } else {
  2150. DEBUG_MSG("Low datarate optimization DISABLED\n");
  2151. err = lgw_reg_w(SX1302_REG_TX_TOP_TXRX_CFG0_1_PPM_OFFSET(pkt_data->rf_chain), 0);
  2152. CHECK_ERR(err);
  2153. }
  2154. break;
  2155. case MOD_FSK:
  2156. CHECK_NULL(context_fsk);
  2157. /* Set frequency deviation */
  2158. freq_dev = pkt_data->f_dev * 1e3;
  2159. fdev_reg = SX1302_FREQ_TO_REG(freq_dev);
  2160. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV(pkt_data->rf_chain), (fdev_reg >> 8) & 0xFF);
  2161. CHECK_ERR(err);
  2162. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV(pkt_data->rf_chain), (fdev_reg >> 0) & 0xFF);
  2163. CHECK_ERR(err);
  2164. /* Send frequency deviation to AGC fw for radio config */
  2165. fdev_reg = SX1250_FREQ_TO_REG(freq_dev);
  2166. err = lgw_reg_w(SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE2_MCU_MAIL_BOX_WR_DATA, (fdev_reg >> 16) & 0xFF); /* Needed by AGC to configure the sx1250 */
  2167. CHECK_ERR(err);
  2168. err = lgw_reg_w(SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE1_MCU_MAIL_BOX_WR_DATA, (fdev_reg >> 8) & 0xFF); /* Needed by AGC to configure the sx1250 */
  2169. CHECK_ERR(err);
  2170. err = lgw_reg_w(SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE0_MCU_MAIL_BOX_WR_DATA, (fdev_reg >> 0) & 0xFF); /* Needed by AGC to configure the sx1250 */
  2171. CHECK_ERR(err);
  2172. /* Modulation parameters */
  2173. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_CFG_0_PKT_MODE(pkt_data->rf_chain), 1); /* Variable length */
  2174. CHECK_ERR(err);
  2175. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_CFG_0_CRC_EN(pkt_data->rf_chain), (pkt_data->no_crc) ? 0 : 1);
  2176. CHECK_ERR(err);
  2177. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_CFG_0_CRC_IBM(pkt_data->rf_chain), 0); /* CCITT CRC */
  2178. CHECK_ERR(err);
  2179. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_CFG_0_DCFREE_ENC(pkt_data->rf_chain), 2); /* Whitening Encoding */
  2180. CHECK_ERR(err);
  2181. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_MOD_FSK_GAUSSIAN_EN(pkt_data->rf_chain), 1);
  2182. CHECK_ERR(err);
  2183. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_MOD_FSK_GAUSSIAN_SELECT_BT(pkt_data->rf_chain), 2);
  2184. CHECK_ERR(err);
  2185. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_MOD_FSK_REF_PATTERN_EN(pkt_data->rf_chain), 1);
  2186. CHECK_ERR(err);
  2187. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_MOD_FSK_REF_PATTERN_SIZE(pkt_data->rf_chain), context_fsk->sync_word_size - 1);
  2188. CHECK_ERR(err);
  2189. /* Syncword */
  2190. fsk_sync_word_reg = context_fsk->sync_word << (8 * (8 - context_fsk->sync_word_size));
  2191. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 0));
  2192. CHECK_ERR(err);
  2193. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 8));
  2194. CHECK_ERR(err);
  2195. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 16));
  2196. CHECK_ERR(err);
  2197. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 24));
  2198. CHECK_ERR(err);
  2199. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 32));
  2200. CHECK_ERR(err);
  2201. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 40));
  2202. CHECK_ERR(err);
  2203. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 48));
  2204. CHECK_ERR(err);
  2205. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN(pkt_data->rf_chain), (uint8_t)(fsk_sync_word_reg >> 56));
  2206. CHECK_ERR(err);
  2207. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_MOD_FSK_PREAMBLE_SEQ(pkt_data->rf_chain), 0);
  2208. CHECK_ERR(err);
  2209. /* Set datarate */
  2210. fsk_br_reg = 32000000 / pkt_data->datarate;
  2211. buff[0] = (uint8_t)(fsk_br_reg >> 8);
  2212. buff[1] = (uint8_t)(fsk_br_reg >> 0);
  2213. err = lgw_reg_wb(SX1302_REG_TX_TOP_FSK_BIT_RATE_MSB_BIT_RATE(pkt_data->rf_chain), buff, 2);
  2214. CHECK_ERR(err);
  2215. /* Preamble length */
  2216. if (pkt_data->preamble == 0) { /* if not explicit, use LoRaWAN preamble size */
  2217. pkt_data->preamble = STD_FSK_PREAMBLE;
  2218. } else if (pkt_data->preamble < MIN_FSK_PREAMBLE) { /* enforce minimum preamble size */
  2219. pkt_data->preamble = MIN_FSK_PREAMBLE;
  2220. DEBUG_MSG("Note: preamble length adjusted to respect minimum FSK preamble size\n");
  2221. }
  2222. buff[0] = (uint8_t)(pkt_data->preamble >> 8);
  2223. buff[1] = (uint8_t)(pkt_data->preamble >> 0);
  2224. err = lgw_reg_wb(SX1302_REG_TX_TOP_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE(pkt_data->rf_chain), buff, 2);
  2225. CHECK_ERR(err);
  2226. /* Set Payload length */
  2227. err = lgw_reg_w(SX1302_REG_TX_TOP_FSK_PKT_LEN_PKT_LENGTH(pkt_data->rf_chain), pkt_data->size);
  2228. CHECK_ERR(err);
  2229. break;
  2230. default:
  2231. printf("ERROR: Modulation not supported\n");
  2232. return LGW_REG_ERROR;
  2233. }
  2234. /* Set TX start delay */
  2235. err = sx1302_tx_set_start_delay(pkt_data->rf_chain, radio_type, pkt_data->modulation, pkt_data->bandwidth, chirp_lowpass, &tx_start_delay);
  2236. CHECK_ERR(err);
  2237. /* Write payload in transmit buffer */
  2238. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_CTRL_WRITE_BUFFER(pkt_data->rf_chain), 0x01);
  2239. CHECK_ERR(err);
  2240. mem_addr = REG_SELECT(pkt_data->rf_chain, 0x5300, 0x5500);
  2241. if (pkt_data->modulation == MOD_FSK) {
  2242. err = lgw_mem_wb(mem_addr, (uint8_t *)(&(pkt_data->size)), 1); /* insert payload size in the packet for FSK variable mode (1 byte) */
  2243. CHECK_ERR(err);
  2244. err = lgw_mem_wb(mem_addr+1, &(pkt_data->payload[0]), pkt_data->size);
  2245. CHECK_ERR(err);
  2246. } else {
  2247. err = lgw_mem_wb(mem_addr, &(pkt_data->payload[0]), pkt_data->size);
  2248. CHECK_ERR(err);
  2249. }
  2250. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_CTRL_WRITE_BUFFER(pkt_data->rf_chain), 0x00);
  2251. CHECK_ERR(err);
  2252. /* Trigger transmit */
  2253. DEBUG_PRINTF("Start Tx: Freq:%u %s%u size:%u preamb:%u\n", pkt_data->freq_hz, (pkt_data->modulation == MOD_LORA) ? "SF" : "DR:", pkt_data->datarate, pkt_data->size, pkt_data->preamble);
  2254. switch (pkt_data->tx_mode) {
  2255. case IMMEDIATE:
  2256. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(pkt_data->rf_chain), 0x00); /* reset state machine */
  2257. CHECK_ERR(err);
  2258. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(pkt_data->rf_chain), 0x01);
  2259. CHECK_ERR(err);
  2260. break;
  2261. case TIMESTAMPED:
  2262. count_us = pkt_data->count_us * 32 - tx_start_delay;
  2263. DEBUG_PRINTF("--> programming trig delay at %u (%u)\n", pkt_data->count_us - (tx_start_delay / 32), count_us);
  2264. err = lgw_reg_w(SX1302_REG_TX_TOP_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG(pkt_data->rf_chain), (uint8_t)((count_us >> 0) & 0x000000FF));
  2265. CHECK_ERR(err);
  2266. err = lgw_reg_w(SX1302_REG_TX_TOP_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG(pkt_data->rf_chain), (uint8_t)((count_us >> 8) & 0x000000FF));
  2267. CHECK_ERR(err);
  2268. err = lgw_reg_w(SX1302_REG_TX_TOP_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG(pkt_data->rf_chain), (uint8_t)((count_us >> 16) & 0x000000FF));
  2269. CHECK_ERR(err);
  2270. err = lgw_reg_w(SX1302_REG_TX_TOP_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG(pkt_data->rf_chain), (uint8_t)((count_us >> 24) & 0x000000FF));
  2271. CHECK_ERR(err);
  2272. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_DELAYED(pkt_data->rf_chain), 0x00); /* reset state machine */
  2273. CHECK_ERR(err);
  2274. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_DELAYED(pkt_data->rf_chain), 0x01);
  2275. CHECK_ERR(err);
  2276. break;
  2277. case ON_GPS:
  2278. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_GPS(pkt_data->rf_chain), 0x00); /* reset state machine */
  2279. CHECK_ERR(err);
  2280. err = lgw_reg_w(SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_GPS(pkt_data->rf_chain), 0x01);
  2281. CHECK_ERR(err);
  2282. break;
  2283. default:
  2284. printf("ERROR: TX mode not supported\n");
  2285. return LGW_REG_ERROR;
  2286. }
  2287. /* Flush write (USB BULK mode) */
  2288. err = lgw_com_flush();
  2289. CHECK_ERR(err);
  2290. /* Setting back to SINGLE BULK write mode */
  2291. err = lgw_com_set_write_mode(LGW_COM_WRITE_MODE_SINGLE);
  2292. CHECK_ERR(err);
  2293. /* Compute time spent in this function */
  2294. _meas_time_stop(2, tm, __FUNCTION__);
  2295. return LGW_REG_SUCCESS;
  2296. }
  2297. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  2298. int sx1302_set_gpio(uint8_t gpio_reg_val) {
  2299. int err;
  2300. err = lgw_reg_w(SX1302_REG_GPIO_GPIO_OUT_L_OUT_VALUE, gpio_reg_val); /* set all GPIOs at once, 1 bit per GPIO */
  2301. CHECK_ERR(err);
  2302. return LGW_REG_SUCCESS;
  2303. }
  2304. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  2305. double sx1302_dc_notch_delay(double if_freq_khz) {
  2306. double delay;
  2307. if ((if_freq_khz < -75.0) || (if_freq_khz > 75.0)) {
  2308. delay = 0.0;
  2309. } else {
  2310. delay = 1.7e-6 * pow(if_freq_khz, 4) + 2.4e-6 * pow(if_freq_khz, 3) - 0.0101 * pow(if_freq_khz, 2) - 0.01275 * if_freq_khz + 10.2922;
  2311. }
  2312. /* Number of 32MHz clock cycles */
  2313. return delay;
  2314. }
  2315. /* --- EOF ------------------------------------------------------------------ */