Europalab Devices produces a LoRaWAN transmitting client node, specialised for higher research of actuator and sensor assisted IoT networks. https://dev.europalab.com/nlnet/20200000/
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

415 Zeilen
15KB

  1. /**
  2. * \file task.c
  3. *
  4. * \brief Implementation of Tasks for LoRa Demo Application on MiWi P2P
  5. *
  6. * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries.
  7. *
  8. * \asf_license_start
  9. *
  10. * \page License
  11. *
  12. * Subject to your compliance with these terms, you may use Microchip
  13. * software and any derivatives exclusively with Microchip products.
  14. * It is your responsibility to comply with third party license terms applicable
  15. * to your use of third party software (including open source software) that
  16. * may accompany Microchip software.
  17. *
  18. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  19. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  20. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  21. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  22. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  23. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  24. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  25. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  26. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  27. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  28. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  29. *
  30. * \asf_license_stop
  31. *
  32. */
  33. /***********************Headers***************************************/
  34. #include "task.h"
  35. #include "miwi_api.h"
  36. #include "p2p_demo.h"
  37. #include "asf.h"
  38. #if defined(ENABLE_SLEEP_FEATURE)
  39. #include "sleep_mgr.h"
  40. #endif
  41. #include "sw_timer.h"
  42. #include "phy.h"
  43. /************************** VARIABLES ************************************/
  44. #define LIGHT 0x01
  45. #define SWITCH 0x02
  46. // Software Timer used for Tx timeout
  47. uint8_t TxTimerId = 0;
  48. #if defined(PERIODIC_TX)
  49. uint8_t PeriodicTxTimerId = 0xFF ;
  50. #endif
  51. /*************************************************************************/
  52. // AdditionalNodeID variable array defines the additional
  53. // information to identify a device on a PAN. This array
  54. // will be transmitted when initiate the connection between
  55. // the two devices. This variable array will be stored in
  56. // the Connection Entry structure of the partner device. The
  57. // size of this array is ADDITIONAL_NODE_ID_SIZE, defined in
  58. // miwi_config.h.
  59. // In this demo, this variable array is set to be empty.
  60. /*************************************************************************/
  61. #if ADDITIONAL_NODE_ID_SIZE > 0
  62. uint8_t AdditionalNodeID[ADDITIONAL_NODE_ID_SIZE] = {LIGHT};
  63. #endif
  64. /*************************************************************************/
  65. // The variable myChannel defines the channel that the device
  66. // is operate on. This variable will be only effective if energy scan
  67. // (ENABLE_ED_SCAN) is not turned on. Once the energy scan is turned
  68. // on, the operating channel will be one of the channels available with
  69. // least amount of energy (or noise).
  70. /*************************************************************************/
  71. uint8_t myChannel = 1;
  72. /* Range for default configuration: 1 to 10
  73. Note: TX Power and PHY Mode Setting needs to be modified as per the
  74. recommendation from Data Sheet for European band (ie.,Channel 0)*/
  75. static void Connection_Confirm(miwi_status_t status);
  76. #ifdef ENABLE_ACTIVE_SCAN
  77. void Scan_Confirm(uint8_t ActiveScanResultCount, void* PtrActiveScanResults);
  78. #endif // #ifdef ENABLE_ACTIVE_SCAN
  79. bool freezer_feature(void)
  80. {
  81. MIWI_TICK tick1, tick2;
  82. uint8_t switch_val;
  83. tick1.Val = MiWi_TickGet();
  84. while(1)
  85. {
  86. tick2.Val = MiWi_TickGet();
  87. if(MiWi_TickGetDiff(tick2, tick1) > (ONE_SECOND * 4))
  88. break;
  89. switch_val = ButtonPressed ();
  90. if(switch_val == 1)
  91. {
  92. #if defined (ENABLE_LCD)
  93. LCDDisplay((char *)"Restoring Network !!", 0, false);
  94. delay_ms(1000);
  95. #endif
  96. return true;
  97. }
  98. else
  99. {
  100. return false;
  101. }
  102. }
  103. return false;
  104. }
  105. #ifdef ENABLE_ACTIVE_SCAN
  106. void Scan_Confirm(uint8_t ActiveScanResultCount, void* PtrActiveScanResults)
  107. {
  108. ACTIVE_SCAN_RESULT* ActiveScanResult = (ACTIVE_SCAN_RESULT*) PtrActiveScanResults;
  109. #if defined (ENABLE_CONSOLE)
  110. for(uint8_t count =0; count <= ActiveScanResultCount-1; count++ )
  111. {
  112. printf("\nID\tDevice Address \t\tCapability \tPAN ID \tChannel \n");
  113. printf("%02x",count+1);
  114. printf("\t");
  115. for(uint8_t j = 0; j < 8; j++)
  116. {
  117. if( j < MY_ADDRESS_LENGTH )
  118. {
  119. printf("%02x",ActiveScanResult[count].Address[MY_ADDRESS_LENGTH-1-j] );
  120. }
  121. else
  122. {
  123. printf(" ");
  124. }
  125. }
  126. printf("\t");
  127. printf("%02x",(ActiveScanResult[count].Capability.Val));
  128. printf("\t\t");
  129. printf("%02x",(ActiveScanResult[count].PANID.Val));
  130. printf("\t");
  131. printf("%02x",ActiveScanResult[count].Channel);
  132. printf("\r\n");
  133. }
  134. printf("\r\n Scan Operation Status: %d device found",ActiveScanResultCount);
  135. #endif // #if defined (ENABLE_CONSOLE)
  136. }
  137. #endif // #ifdef ENABLE_ACTIVE_SCAN
  138. static void Connection_Confirm(miwi_status_t status)
  139. {
  140. #if defined (ENABLE_CONSOLE)
  141. printf("\r\nConnect Operation Status: %d\n", status) ;
  142. #endif // #if defined (ENABLE_CONSOLE)
  143. if ((SUCCESS == status) || (ALREADY_EXISTS == status))
  144. {
  145. #if defined (ENABLE_CONSOLE)
  146. printf("\r\nStarted Wireless Communication on Channel %u\r\n", currentChannel) ;
  147. //DumpConnection(0xFF) ;
  148. #endif // #if defined (ENABLE_CONSOLE)
  149. #if defined(PERIODIC_TX)
  150. SwTimerCreate(&PeriodicTxTimerId) ;
  151. SwTimerStart (PeriodicTxTimerId, MS_TO_US(1000), 0/*SW_TIMEOUT_RELATIVE*/, (void *)PeriodicTxCallback, NULL) ;
  152. #endif // #if defined(PERIODIC_TX)
  153. }
  154. }
  155. bool Initialize_Demo(bool freezer_enable)
  156. {
  157. uint8_t i;
  158. bool invalidIEEEAddrFlag = false;
  159. uint64_t invalidIEEEAddr;
  160. MiApp_SubscribeDataIndicationCallback(ReceivedDataIndication);
  161. #ifdef ENABLE_SLEEP_FEATURE
  162. sm_init();
  163. #endif
  164. if (freezer_enable)
  165. {
  166. MiApp_ProtocolInit(NULL, NULL);
  167. srand(PHY_RandomReq());
  168. /* Check if a valid IEEE address is available.
  169. 0x0000000000000000 and 0xFFFFFFFFFFFFFFFF is presumed to be invalid */
  170. /* Check if IEEE address is 0x0000000000000000 */
  171. memset((uint8_t *)&invalidIEEEAddr, 0x00, LONG_ADDR_LEN);
  172. if (0 == memcmp((uint8_t *)&invalidIEEEAddr, (uint8_t *)&myLongAddress, LONG_ADDR_LEN))
  173. {
  174. invalidIEEEAddrFlag = true;
  175. }
  176. /* Check if IEEE address is 0xFFFFFFFFFFFFFFFF */
  177. memset((uint8_t *)&invalidIEEEAddr, 0xFF, LONG_ADDR_LEN);
  178. if (0 == memcmp((uint8_t *)&invalidIEEEAddr, (uint8_t *)&myLongAddress, LONG_ADDR_LEN))
  179. {
  180. invalidIEEEAddrFlag = true;
  181. }
  182. if (invalidIEEEAddrFlag)
  183. {
  184. /*
  185. * In case no valid IEEE address is available, a random
  186. * IEEE address will be generated to be able to run the
  187. * applications for demonstration purposes.
  188. * In production code this can be omitted.
  189. */
  190. uint8_t* peui64 = (uint8_t *)&myLongAddress;
  191. for(i = 0; i<MY_ADDRESS_LENGTH; i++)
  192. {
  193. *peui64++ = (uint8_t)rand();
  194. }
  195. }
  196. PHY_SetIEEEAddr((uint8_t *)&myLongAddress);
  197. #if defined(PROTOCOL_P2P)
  198. DemoOutput_Instruction();
  199. #endif
  200. }
  201. else
  202. {
  203. LED_Off(LED0);
  204. MiApp_ProtocolInit(NULL, NULL);
  205. /*
  206. // -- For reference: set RF parameters just after protocol initialization
  207. // Set Tx Output Power
  208. uint8_t txPower = 0x1F ;
  209. PHY_SetTxPower(txPower) ;
  210. // Read back and print Tx output power
  211. txPower = 255 ;
  212. RADIO_GetAttr(OUTPUT_POWER, (void *)&txPower) ;
  213. printf("\nCurrent Tx output power: %d\r\n", txPower) ;
  214. // Read and print PA_BOOST status
  215. uint8_t paBoost = 255 ;
  216. RADIO_GetAttr(PABOOST, (void *)&paBoost) ;
  217. printf("PA BOOST status: %d\r\n", paBoost) ;
  218. // Read and print spreading factor
  219. RadioDataRate_t sf = 33 ;
  220. PHY_GetAttribute(SPREADING_FACTOR, (void *)&sf) ;
  221. printf("Current SF: SF%d\r\n", sf) ;
  222. // Read and print bandwidth
  223. RadioLoRaBandWidth_t bw ;
  224. PHY_GetAttribute(BANDWIDTH, (void *)&bw) ;
  225. printf("Current BW (125kHz=7, 250kHz=8, 500kHz=9): %d\r\n", bw) ;
  226. // Modify spreading factor
  227. sf = SF_12 ;
  228. printf("Setting SF%d\r\n", sf) ;
  229. RadioError_t ret = PHY_SetAttribute(SPREADING_FACTOR, (void *)&sf) ;
  230. if (ret == ERR_NONE)
  231. {
  232. printf("Successfully set attribute to SF%d\r\n", sf) ;
  233. }
  234. else
  235. {
  236. printf("Error to write SF (error %d)\r\n", ret) ;
  237. }
  238. // Read back spreading factor
  239. PHY_GetAttribute(SPREADING_FACTOR, (void *)&sf) ;
  240. printf("Current SF%d\r\n", sf) ;
  241. */
  242. srand(PHY_RandomReq());
  243. /* Check if a valid IEEE address is available.
  244. 0x0000000000000000 and 0xFFFFFFFFFFFFFFFF is presumed to be invalid */
  245. /* Check if IEEE address is 0x0000000000000000 */
  246. memset((uint8_t *)&invalidIEEEAddr, 0x00, LONG_ADDR_LEN);
  247. if (0 == memcmp((uint8_t *)&invalidIEEEAddr, (uint8_t *)&myLongAddress, LONG_ADDR_LEN))
  248. {
  249. invalidIEEEAddrFlag = true;
  250. }
  251. /* Check if IEEE address is 0xFFFFFFFFFFFFFFFF */
  252. memset((uint8_t *)&invalidIEEEAddr, 0xFF, LONG_ADDR_LEN);
  253. if (0 == memcmp((uint8_t *)&invalidIEEEAddr, (uint8_t *)&myLongAddress, LONG_ADDR_LEN))
  254. {
  255. invalidIEEEAddrFlag = true;
  256. }
  257. if (invalidIEEEAddrFlag)
  258. {
  259. /*
  260. * In case no valid IEEE address is available, a random
  261. * IEEE address will be generated to be able to run the
  262. * applications for demonstration purposes.
  263. * In production code this can be omitted.
  264. */
  265. uint8_t* peui64 = (uint8_t *)&myLongAddress;
  266. for(i = 0; i<MY_ADDRESS_LENGTH; i++)
  267. {
  268. *peui64++ = (uint8_t)rand();
  269. }
  270. }
  271. PHY_SetIEEEAddr((uint8_t *)&myLongAddress);
  272. // Set default channel
  273. /*******************************************************************/
  274. // Function MiApp_ConnectionMode defines the connection mode. The
  275. // possible connection modes are:
  276. // ENABLE_ALL_CONN: Enable all kinds of connection
  277. // ENABLE_PREV_CONN: Only allow connection already exists in
  278. // connection table
  279. // ENABL_ACTIVE_SCAN_RSP: Allow response to Active scan
  280. // DISABLE_ALL_CONN: Disable all connections.
  281. /*******************************************************************/
  282. MiApp_ConnectionMode(ENABLE_ALL_CONN);
  283. DemoOutput_Channel(myChannel, 0);
  284. #ifdef ENABLE_ED_SCAN
  285. uint8_t *NoiseLevel;
  286. MiApp_NoiseDetection(0xFFFFFFFF, 5, NOISE_DETECT_ENERGY, &NoiseLevel);
  287. #endif // #ifdef ENABLE_ED_SCAN
  288. #ifdef ENABLE_ACTIVE_SCAN
  289. MiApp_SearchConnection(5, 0xFFFFFFFF, Scan_Confirm);
  290. #endif // #ifdef ENABLE_ACTIVE_SCAN
  291. /*******************************************************************/
  292. // Function MiApp_EstablishConnection try to establish a new
  293. // connection with peer device.
  294. // The first parameter is the index to the active scan result,
  295. // which is acquired by discovery process (active scan). If
  296. // the value of the index is 0xFF, try to establish a
  297. // connection with any peer.
  298. // The second parameter is the mode to establish connection,
  299. // either direct or indirect. Direct mode means connection
  300. // within the radio range; indirect mode means connection
  301. // may or may not in the radio range.
  302. /*******************************************************************/
  303. // Set default channel
  304. if( MiApp_Set(CHANNEL, &myChannel) == false )
  305. {
  306. DemoOutput_ChannelError(myChannel);
  307. }
  308. uint16_t broadcastAddress = 0xFFFF;
  309. i = MiApp_EstablishConnection(myChannel, 0, (uint8_t*)&broadcastAddress, 0, Connection_Confirm);
  310. /*******************************************************************/
  311. // Display current operation on LCD of demo board, if applicable
  312. /*******************************************************************/
  313. if( i != 0xFF )
  314. {
  315. DemoOutput_Channel(myChannel, 1);
  316. }
  317. else
  318. {
  319. /*******************************************************************/
  320. // If no network can be found and join, we need to start a new
  321. // network by calling function MiApp_StartConnection
  322. //
  323. // The first parameter is the mode of start connection. There are
  324. // two valid connection modes:
  325. // - START_CONN_DIRECT start the connection on current
  326. // channel
  327. // - START_CONN_ENERGY_SCN perform an energy scan first,
  328. // before starting the connection on
  329. // the channel with least noise
  330. // - START_CONN_CS_SCN perform a carrier sense scan
  331. // first, before starting the
  332. // connection on the channel with
  333. // least carrier sense noise. Not
  334. // supported for current radios
  335. //
  336. // The second parameter is the scan duration, which has the same
  337. // definition in Energy Scan. 10 is roughly 1 second. 9 is a
  338. // half second and 11 is 2 seconds. Maximum scan duration is
  339. // 14, or roughly 16 seconds.
  340. //
  341. // The third parameter is the channel map. Bit 0 of the
  342. // double word parameter represents channel 0. For the 2.4GHz
  343. // frequency band, all possible channels are channel 11 to
  344. // channel 26. As the result, the bit map is 0x07FFF800. Stack
  345. // will filter out all invalid channels, so the application
  346. // only needs to pay attention to the channels that are not
  347. // preferred.
  348. /*******************************************************************/
  349. MiApp_StartConnection(START_CONN_DIRECT, 10, (1L << myChannel), Connection_Confirm);
  350. }
  351. /*******************************************************************/
  352. // Function DumpConnection is used to print out the content of the
  353. // Connection Entry on the hyper terminal. It may be useful in
  354. // the debugging phase.
  355. // The only parameter of this function is the index of the
  356. // Connection Entry. The value of 0xFF means to print out all
  357. // valid Connection Entry; otherwise, the Connection Entry
  358. // of the input index will be printed out.
  359. /*******************************************************************/
  360. #if defined(ENABLE_CONSOLE)
  361. DumpConnection(0xFF);
  362. #endif
  363. // Turn on LED 1 to indicate connection established
  364. LED_On(LED0);
  365. #if defined(PROTOCOL_P2P)
  366. DemoOutput_Instruction();
  367. #endif
  368. }
  369. /* Create SW timer for transmission timeout */
  370. SwTimerCreate(&TxTimerId) ;
  371. return true;
  372. }
  373. void Run_Demo(void)
  374. {
  375. P2PTasks();
  376. run_p2p_demo();
  377. }