Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /** 00002 * Copyright (c) 2017, Arm Limited and affiliates. 00003 * Copyright (c) 2019, Future Electronics. 00004 * SPDX-License-Identifier: Apache-2.0 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 #include <stdio.h> 00019 00020 #include "lorawan/LoRaWANInterface.h" 00021 #include "lorawan/system/lorawan_data_structures.h" 00022 #include "events/EventQueue.h" 00023 #include "psoc6_utils.h" 00024 #include "mbed.h" 00025 00026 // Application helpers 00027 #include "trace_helper.h" 00028 #include "lora_radio_helper.h" 00029 00030 #include "BD2808.h" 00031 00032 00033 using namespace events; 00034 using namespace mbed; 00035 00036 00037 // Max payload size can be LORAMAC_PHY_MAXPAYLOAD. 00038 // This example only communicates with much shorter messages (<30 bytes). 00039 // If longer messages are used, these buffers must be changed accordingly. 00040 uint8_t tx_buffer[30]; 00041 uint8_t rx_buffer[30]; 00042 00043 00044 /** 00045 * Maximum number of events for the event queue. 00046 * 10 is the safe number for the stack events, however, if application 00047 * also uses the queue for whatever purposes, this number should be increased. 00048 */ 00049 #define MAX_NUMBER_OF_EVENTS 20 00050 00051 /** 00052 * Maximum number of retries for CONFIRMED messages before giving up 00053 */ 00054 #define CONFIRMED_MSG_RETRY_COUNTER 3 00055 00056 /** 00057 * This event queue is the global event queue for both the 00058 * application and stack. To conserve memory, the stack is designed to run 00059 * in the same thread as the application and the application is responsible for 00060 * providing an event queue to the stack that will be used for ISR deferment as 00061 * well as application information event queuing. 00062 */ 00063 static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS *EVENTS_EVENT_SIZE); 00064 00065 /** 00066 * Event handler. 00067 * 00068 * This will be passed to the LoRaWAN stack to queue events for the 00069 * application which in turn drive the application. 00070 */ 00071 static void lora_event_handler(lorawan_event_t event); 00072 00073 /** 00074 * Constructing Mbed LoRaWANInterface and passing it the radio object from lora_radio_helper. 00075 */ 00076 static LoRaWANInterface lorawan(radio); 00077 00078 /** 00079 * Application specific callbacks 00080 */ 00081 static lorawan_app_callbacks_t callbacks; 00082 00083 00084 typedef enum { 00085 DUMMY_MESSAGE, 00086 SWITCH_MESSAGE 00087 } message_type_t; 00088 00089 /** 00090 * Button switch processing handler. 00091 */ 00092 static void button_handler(void); 00093 00094 static void send_message(message_type_t type); 00095 00096 00097 00098 Timer g_timer; 00099 DigitalOut led(LED1); 00100 DigitalIn button1(BUTTON1); 00101 BD2808 leds; 00102 00103 bool frame_send = false; 00104 bool is_connected = false; 00105 bool tx_in_progress = false; 00106 uint8_t power_on = 0; 00107 uint8_t msg_id = 0; 00108 uint32_t delay_counter = 0; 00109 00110 static uint32_t const INTER_FRAME_DELAY = 30; 00111 00112 //static const uint8_t target_device_eui[] = MBED_CONF_APP_TARGET_DEVICE_EUI; 00113 static const uint8_t target_device_eui[] = { 0x00, 0xa0, 0x50, 0xff, 0xfe, 0x81, 0x27, 0x95 }; 00114 00115 /** 00116 * Helper routine to set RGB LEDs to specific color. 00117 */ 00118 static void leds_set(uint8_t red, uint8_t green, uint8_t blue) 00119 { 00120 for (int i = 0; i < 8; ++i) { 00121 leds.set_color(i, BGR24_color_t(blue, green, red)); 00122 } 00123 leds.refresh(); 00124 } 00125 00126 00127 static void timer_one_sec(void) 00128 { 00129 if (is_connected) { 00130 if (!tx_in_progress) { 00131 led = 1; 00132 ThisThread::sleep_for(40); 00133 led = 0; 00134 --delay_counter; 00135 if (delay_counter == 0) { 00136 delay_counter = INTER_FRAME_DELAY; 00137 send_message(DUMMY_MESSAGE); 00138 } 00139 } 00140 } else { 00141 } 00142 } 00143 00144 00145 /** 00146 * Entry point for application 00147 */ 00148 int main(void) 00149 { 00150 static uint8_t mac_address[6]; 00151 static uint8_t device_eui[8] = {0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00}; 00152 static const uint8_t application_eui[] = MBED_CONF_LORA_APPLICATION_EUI; 00153 static const uint8_t application_key[] = MBED_CONF_LORA_APPLICATION_KEY; 00154 static lorawan_connect_t connect_params = { 00155 .connect_type = LORAWAN_CONNECTION_OTAA, 00156 }; 00157 00158 leds.set_dma_usage(DMA_USAGE_ALWAYS); 00159 00160 // setup tracing 00161 setup_trace(); 00162 00163 // stores the status of a call to LoRaWAN protocol 00164 lorawan_status_t retcode; 00165 00166 // Create unique, hardware-dependent EUI. 00167 cy_get_bd_mac_address(mac_address); 00168 // MAC address is in reverse sequence. 00169 for (int i = 0; i < 3; ++i) { 00170 device_eui[i] = mac_address[5 - i]; 00171 device_eui[i + 5] = mac_address[2 - i]; 00172 } 00173 printf("\r\nDevice EUI is %02X", device_eui[0]); 00174 for (int i = 1; i < 8; ++i) { 00175 printf(":%02X", device_eui[i]); 00176 } 00177 printf(" [ "); 00178 for (int i = 0; i < 8; ++i) { 00179 printf("%02x", device_eui[i]); 00180 } 00181 printf(" ]\r\n"); 00182 00183 // Initialize LoRaWAN stack 00184 if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) { 00185 printf("\r\n LoRa initialization failed! \r\n"); 00186 return -1; 00187 } 00188 00189 printf("\r\n Mbed LoRaWANStack initialized \r\n"); 00190 00191 // prepare application callbacks 00192 callbacks.events = mbed::callback(lora_event_handler); 00193 lorawan.add_app_callbacks(&callbacks); 00194 00195 // Set number of retries in case of CONFIRMED messages 00196 if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER) 00197 != LORAWAN_STATUS_OK) { 00198 printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n"); 00199 return -1; 00200 } 00201 00202 printf("\r\n CONFIRMED message retries : %d \r\n", 00203 CONFIRMED_MSG_RETRY_COUNTER); 00204 00205 // Enable adaptive data rate 00206 if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) { 00207 printf("\r\n enable_adaptive_datarate failed! \r\n"); 00208 return -1; 00209 } 00210 00211 printf("\r\n Adaptive data rate (ADR) - Enabled \r\n"); 00212 00213 // Specify class C 00214 if (lorawan.set_device_class(CLASS_C) != LORAWAN_STATUS_OK) { 00215 printf("\r\n setting class C failed! \r\n"); 00216 return -1; 00217 } 00218 00219 printf("\r\n Class C - Enabled \r\n"); 00220 00221 connect_params.connection_u.otaa.dev_eui = device_eui; 00222 connect_params.connection_u.otaa.app_eui = const_cast<uint8_t *>(application_eui); 00223 connect_params.connection_u.otaa.app_key = const_cast<uint8_t *>(application_key); 00224 connect_params.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS; 00225 00226 g_timer.start(); 00227 00228 retcode = lorawan.connect(connect_params); 00229 00230 if (retcode == LORAWAN_STATUS_OK || 00231 retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { 00232 } else { 00233 printf("\r\n Connection error, code = %d \r\n", retcode); 00234 return -1; 00235 } 00236 00237 printf("\r\n Connection - In Progress ...\r\n"); 00238 00239 // Start button handler; will check button switch every 100ms. 00240 ev_queue.call_every(100, button_handler); 00241 00242 ev_queue.call_every(1000, timer_one_sec); 00243 00244 // make your event queue dispatching events forever 00245 ev_queue.dispatch_forever(); 00246 00247 return 0; 00248 } 00249 00250 00251 /** 00252 * Sends a message to the Network Server 00253 */ 00254 static void send_message(message_type_t type) 00255 { 00256 uint16_t packet_len; 00257 int16_t retcode; 00258 uint8_t port = MBED_CONF_LORA_APP_PORT; 00259 00260 printf("\r\n[%8u] Sending message (%d) \r\n", g_timer.read_ms(), msg_id); 00261 00262 switch (type) { 00263 case SWITCH_MESSAGE: 00264 memcpy(tx_buffer, target_device_eui, 8); 00265 for (int i = 8; i < 11; ++i) { 00266 tx_buffer[8] = power_on? 0xf0 : 0x00; 00267 } 00268 packet_len = 11; 00269 break; 00270 00271 case DUMMY_MESSAGE: 00272 tx_buffer[1] = msg_id; 00273 packet_len = 1; 00274 port += 1; 00275 } 00276 00277 led = 1; 00278 tx_in_progress = true; 00279 00280 retcode = lorawan.send(port, tx_buffer, packet_len, MSG_UNCONFIRMED_FLAG); 00281 00282 if (retcode < 0) { 00283 retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n") 00284 : printf("\r\n send() - Error code %d \r\n", retcode); 00285 00286 if (retcode == LORAWAN_STATUS_WOULD_BLOCK) { 00287 lorawan.cancel_sending(); 00288 led = 0; 00289 //retry in 3 seconds 00290 if (MBED_CONF_LORA_DUTY_CYCLE_ON) { 00291 ev_queue.call_in(3000, send_message, type); 00292 } 00293 } 00294 return; 00295 } 00296 00297 frame_send = true; 00298 printf("\r\n[%8u] %d bytes scheduled for transmission \r\n", g_timer.read_ms(), retcode); 00299 memset(tx_buffer, 0, sizeof(tx_buffer)); 00300 } 00301 00302 /** 00303 * Receive a message from the Network Server 00304 */ 00305 static void receive_message() 00306 { 00307 uint8_t port; 00308 int flags; 00309 int16_t retcode = lorawan.receive(rx_buffer, sizeof(rx_buffer), port, flags); 00310 00311 if (retcode < 0) { 00312 printf("\r\n receive() - Error code %d \r\n", retcode); 00313 return; 00314 } 00315 00316 printf("[%8u] RX Data on port %u (%d bytes): ", g_timer.read_ms(), port, retcode); 00317 for (uint8_t i = 0; i < retcode; i++) { 00318 printf("%02x ", rx_buffer[i]); 00319 } 00320 // Expecting exactly 3 bytes: red, green + blue color value. 00321 // Other messages are ignored. 00322 if ((retcode == 3) && (port == MBED_CONF_LORA_APP_PORT)) { 00323 leds_set(rx_buffer[0], rx_buffer[1], rx_buffer[2]); 00324 } else { 00325 printf(" - ignored (%d)", MBED_CONF_LORA_APP_PORT); 00326 } 00327 printf("\r\n"); 00328 00329 memset(rx_buffer, 0, sizeof(rx_buffer)); 00330 } 00331 00332 /** 00333 * Detects and processes button events. 00334 */ 00335 static void button_handler(void) 00336 { 00337 static uint8_t prev_state = 1; 00338 static uint8_t stable_state = 1; 00339 static uint8_t count = 2; 00340 00341 uint8_t curr_state = button1; 00342 00343 if (curr_state != prev_state) { 00344 count = 2; 00345 } else { 00346 if (count > 0) { 00347 --count; 00348 } else { 00349 if ((stable_state == 0) && (curr_state != 0)) { 00350 // we react on release of the button 00351 if (is_connected) { 00352 power_on = power_on? 0 : 1; 00353 send_message(SWITCH_MESSAGE); 00354 } 00355 } 00356 stable_state = curr_state; 00357 } 00358 } 00359 prev_state = curr_state; 00360 } 00361 00362 00363 /** 00364 * Event handler 00365 */ 00366 static void lora_event_handler(lorawan_event_t event) 00367 { 00368 switch (event) { 00369 case CONNECTED: 00370 printf("\r\n[%8u] Connection - Successful \r\n", g_timer.read_ms()); 00371 is_connected = true; 00372 msg_id = 0; 00373 delay_counter = INTER_FRAME_DELAY; 00374 send_message(DUMMY_MESSAGE); 00375 break; 00376 case DISCONNECTED: 00377 led = 0; 00378 frame_send = false; 00379 ev_queue.break_dispatch(); 00380 printf("\r\n[%8u] Disconnected Successfully \r\n", g_timer.read_ms()); 00381 break; 00382 case TX_DONE: 00383 led = 0; 00384 tx_in_progress = false; 00385 if (frame_send) { 00386 frame_send = false; 00387 delay_counter = INTER_FRAME_DELAY; 00388 ++msg_id; 00389 printf("\r\n[%8u] Message Sent to Network Server \r\n", g_timer.read_ms()); 00390 } else { 00391 // printf("\r\n[%8u] Duplicate TX_DONE !!! \r\n", g_timer.read_ms()); 00392 } 00393 break; 00394 case TX_TIMEOUT: 00395 case TX_ERROR: 00396 case TX_CRYPTO_ERROR: 00397 case TX_SCHEDULING_ERROR: 00398 led = 0; 00399 frame_send = false; 00400 tx_in_progress = false; 00401 delay_counter = INTER_FRAME_DELAY; 00402 printf("\r\n[%8u] Transmission Error - EventCode = %d \r\n", g_timer.read_ms(), event); 00403 break; 00404 case RX_DONE: 00405 printf("\r\n[%8u] Received message from Network Server \r\n", g_timer.read_ms()); 00406 receive_message(); 00407 break; 00408 case RX_TIMEOUT: 00409 case RX_ERROR: 00410 printf("\r\n[%8u] Error in reception - Code = %d \r\n", g_timer.read_ms(), event); 00411 break; 00412 case JOIN_FAILURE: 00413 printf("\r\n OTAA Failed - Check Keys \r\n"); 00414 break; 00415 case UPLINK_REQUIRED: 00416 printf("\r\n[%8u] Uplink required by NS \r\n", g_timer.read_ms()); 00417 break; 00418 default: 00419 MBED_ASSERT("Unknown Event"); 00420 } 00421 } 00422 00423 // EOF
Generated on Thu Jul 14 2022 02:41:07 by
1.7.2