
「ワイヤレスは簡単です!」 - 既存のロラワンアプリケーションにロラピアツーピア接続を追加する

これらの条件へのコンプライアンスの対象となると、MicroChipソフトウェアとMicroChip製品のみを使用してデリバティブを使用できます。マイクロチップソフトウェアに伴う可能性のあるサードパーティソフトウェア(オープンソースソフトウェアを含む)の使用に適用されるサードパーティのライセンス条件に従うことはあなたの責任です。
このソフトウェアは、「現状のまま」マイクロチップによって提供されます。明示的、黙示的であろうと法定であろうと、特定の目的に対する非侵害、商品性、適合性の暗黙の保証を含む、このソフトウェアに適用される保証はありません。
いかなる場合でも、マイクロチップは、マイクロチップが可能性や損害賠償が予測可能であっても、ソフトウェアに関連するあらゆる種類の間接的、特別、懲罰的、偶発的、または結果的な損失、損害、コスト、または費用に対して責任を負うことはありません。法律で許可されている最大限の範囲で、このソフトウェアに関連するあらゆる方法でのすべての請求に対するMicrochipの総責任は、このソフトウェアのMicrochipに直接支払った料金の額を超えません。
Lora Forumでこのソフトウェアについて仲間と対話します。
ASFV3から生成されたLorawan Moteアプリケーションに基づいて、このサンプルコードは、LORA変調を使用して2x ATSAMR34 Xplaine Proボード間のロラワンアプリケーションの共存と純粋な無線通信を示しています。
Microchip atsamr34 Lora SIPデバイスの詳細については、Microchip Webページにアクセスしてください。
https://www.microchip.com/design-centers/wireless-connectivity/low-power-wide-area-networks/lora-technology/sam-r34-r35

ATSAMR34 Xplained Pro評価キットは、ATSAMR34 LowPower®Sub-GHz SIPを評価するために使用されるハードウェアプラットフォームです。 Microchip Studio 7.0 IDEでサポートされており、3.44.0リリース以降、高度なソフトウェアフレームワーク(ASFV3)からサンプルコードのコレクションが入手できます。 Xplained Pro MCUシリーズ評価キットには、オンボード組み込みデバッガー(EDBG)が含まれており、ATSAMR34をプログラムまたはデバッグするために外部ツールは必要ありません。このキットは、ユーザーがATSAMR34 LowPower®Sub-GHz SIP周辺機器をすぐに開始できるようにし、デバイスを独自のデザインに統合する方法を理解できるようにする一連の機能を提供します。 ATSAMR34 Xplained Proキットには、次の項目が含まれています。

ピアツーピア通信を実証するには、少なくとも2倍のATSAMR34 Xplained Proボードが必要です。
このプロジェクトは、さまざまなソフトウェアモジュールにインターフェイスを提供するMicrochip Lorawan Stack(MLS)ソフトウェアAPIを統合します。
このアプリケーションでは、ロラワンMACレイヤー(MAC)を「一時停止」し、ピアツーピア通信にロラワン無線層(TAL)を使用し、ロラワンMACレイヤーを「再開」してロラワン操作を実行します。
ピアツーピア構成では、ロラワンMACレイヤーがバイパスされ、プロトコル、セキュリティ、デバイスの一意の識別子、明らかに相互運用性とエコシステム(ロラワンとは反対)で直接ラジオを直接駆動する機能を操作できます。これは、ロラワンアプリケーションでP2P通信を使用する機能を実証するのに役立ちます。
対応する周波数帯域のローカル規制に違反しないようにしてください。たとえば、ヨーロッパ内の868MHzバンドの25MWと1%のデューティサイクル。

MACレイヤーは、Lorawan仕様で定義された操作の機能を提供します。
TALレイヤーは無線ドライバーを使用し、SX1276トランシーバーへのアクセスを提供します。
ポイントツーポイント接続のためにデバイスをセットアップできるようにするには、コードが必要です。
void LORAWAN_Init(AppDataCb_t appdata, JoinResponseCb_t joindata);
StackRetStatus_t LORAWAN_Reset (IsmBand_t ismBand);
uint32_t LORAWAN_Pause (void);
RadioError_t RADIO_SetAttr(RadioAttribute_t attribute, void *value);
RADIO_SetAttr(WATCHDOG_TIMEOUT,(void *)&wdt) ;
RadioError_t RADIO_Receive(RadioReceiveParam_t *param);
この関数は、Radio_rxhandlerにタスク投稿を行うことにより、データを受信してバッファポインタースペースに保存するようにデバイスを受信モードに設定します。
RadioError_t RADIO_Transmit(RadioTransmitParam_t *param);
この関数は、Radio_txhandlerにタスク投稿を行うことにより、データを送信します。
ピアツーピア通信のために、サンプルコードは次のパラメーターでラジオを構成します。
typedef enum _AppTaskIds_t
{
DISPLAY_TASK_HANDLER,
PROCESS_TASK_HANDLER,
APP_TASKS_COUNT
}AppTaskIds_t;
typedef enum _AppTaskState_t
{
RESTORE_BAND_STATE,
DEMO_CERT_APP_STATE,
DEMO_APP_STATE,
JOIN_SEND_STATE
}AppTaskState_t;
static SYSTEM_TaskStatus_t (*appTaskHandlers[APP_TASKS_COUNT])(void) = {
/* In the order of descending priority */
displayTask,
processTask
};
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
/*********************************************************************//**
brief Calls appropriate functions based on state variables
*************************************************************************/
static SYSTEM_TaskStatus_t displayTask(void)
{
switch(appTaskState)
{
case RESTORE_BAND_STATE:
displayRunRestoreBand();
break;
case DEMO_CERT_APP_STATE:
displayRunDemoCertApp();
break;
case DEMO_APP_STATE:
displayRunDemoApp();
break;
case JOIN_SEND_STATE:
displayJoinAndSend();
break;
default:
printf("Error STATE Enteredrn");
break;
}
return SYSTEM_TASK_SUCCESS;
}
/*********************************************************************//**
brief Displays and activates LED's for joining to a network
and sending data to a network
*************************************************************************/
static void displayJoinAndSend(void)
{
printf("rn1. Send Join Requestrn");
printf("2. Send Datarn");
// new menu with p2p
printf("3. Main Menurn") ;
printf("4. MAC Pausern") ;
printf("5. MAC Resumern") ;
printf("6. Configure Radiorn") ;
printf("7. Send Radio Datarn") ;
printf("8. Enter Radio Receive modern") ;
printf("9. Exit Radio Receive modern") ;
#ifdef CONF_PMM_ENABLE
printf("0. Sleeprn") ;
#endif
printf("rnEnter your choice: ");
set_LED_data(LED_AMBER,&off);
set_LED_data(LED_GREEN,&off);
startReceiving = true;
}
/*********************************************************************//**
brief Pulls the data from UART when activated
*************************************************************************/
void serial_data_handler(void)
{
int rxChar;
char serialData;
/* verify if there was any character received*/
if (startReceiving == true)
{
if((-1) != (rxChar = sio2host_getchar_nowait()))
{
serialData = (char)rxChar;
if((serialData != 'r') && (serialData != 'n') && (serialData != 'b'))
{
startReceiving = false;
serialBuffer = rxChar;
appPostTask(PROCESS_TASK_HANDLER);
printf("rn");
}
}
}
}
/*********************************************************************//**
brief Calls appropriate functions based on state variables
*************************************************************************/
static SYSTEM_TaskStatus_t processTask(void)
{
switch(appTaskState)
{
case RESTORE_BAND_STATE:
processRunRestoreBand();
break;
case DEMO_CERT_APP_STATE:
processRunDemoCertApp();
break;
case DEMO_APP_STATE:
processRunDemoApp();
break;
case JOIN_SEND_STATE:
processJoinAndSend();
break;
default:
printf("Error STATE Enteredrn");
break;
}
return SYSTEM_TASK_SUCCESS;
}
/*********************************************************************//**
brief Sends Join request or Data to the network
*************************************************************************/
static void processJoinAndSend(void)
{
StackRetStatus_t status = LORAWAN_SUCCESS;
if(serialBuffer == '1')
{
status = LORAWAN_Join(DEMO_APP_ACTIVATION_TYPE);
if (LORAWAN_SUCCESS == (StackRetStatus_t)status)
{
set_LED_data(LED_GREEN,&on);
printf("nJoin Request Sentnr");
}
else
{
set_LED_data(LED_AMBER,&on);
print_stack_status(status);
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
}
else if(serialBuffer == '2' && joined == true)
{
sendData();
}
else if(serialBuffer == '2' && !joined)
{
set_LED_data(LED_AMBER,&on);
printf("Device not joined to the networkrn");
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
#ifdef CONF_PMM_ENABLE
else if(serialBuffer == '0')
{
static bool deviceResetsForWakeup = false;
PMM_SleepReq_t sleepReq;
/* Put the application to sleep */
sleepReq.sleepTimeMs = DEMO_CONF_DEFAULT_APP_SLEEP_TIME_MS;
sleepReq.pmmWakeupCallback = appWakeup;
sleepReq.sleep_mode = CONF_PMM_SLEEPMODE_WHEN_IDLE;
if (CONF_PMM_SLEEPMODE_WHEN_IDLE == SLEEP_MODE_STANDBY)
{
deviceResetsForWakeup = false;
}
if (true == LORAWAN_ReadyToSleep(deviceResetsForWakeup))
{
app_resources_uninit();
if (PMM_SLEEP_REQ_DENIED == PMM_Sleep(&sleepReq))
{
HAL_Radio_resources_init();
sio2host_init();
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
printf("rnsleep_not_okrn");
}
}
else
{
printf("rnsleep_not_okrn");
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
}
#endif
else if (serialBuffer == '3')
{
// main menu
appTaskState = DEMO_APP_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
else if (serialBuffer == '4')
{
// Pause the Microchip LoRaWAN Stack
uint32_t time_ms ;
time_ms = LORAWAN_Pause() ;
printf("rnMAC Pause %ldrn", time_ms) ;
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '5')
{
// Resume the Microchip LoRaWAN Stack
LORAWAN_Resume() ;
printf("rnMAC Resumern") ;
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '6')
{
// Configure Radio Parameters
// --------------------------
// Bandwidth = BW_125KHZ
// Channel frequency = FREQ_868100KHZ
// Channel frequency deviation = 25000
// CRC = enabled
// Error Coding Rate = 4/5
// IQ Inverted = disabled
// LoRa Sync Word = 0x34
// Modulation = LoRa
// PA Boost = disabled (disabled for EU , enabled for NA)
// Output Power = 1 (up to +14dBm for EU / up to +20dBm for NA)
// Spreading Factor = SF7
// Watchdog timeout = 60000
// Bandwidth
RadioLoRaBandWidth_t bw = BW_125KHZ ;
RADIO_SetAttr(BANDWIDTH, &bw) ;
printf("Configuring Radio Bandwidth: 125kHzrn") ;
// Channel Frequency
uint32_t freq = FREQ_868100KHZ ;
RADIO_SetAttr(CHANNEL_FREQUENCY, &freq) ;
printf("Configuring Channel Frequency %ldrn", freq) ;
// Channel Frequency Deviation
uint32_t fdev = 25000 ;
RADIO_SetAttr(CHANNEL_FREQUENCY_DEVIATION, &fdev) ;
printf("Configuring Channel Frequency Deviation %ldrn", fdev) ;
// CRC
uint8_t crc_state = 1 ;
RADIO_SetAttr(CRC, &crc_state) ;
printf("Configuring CRC state: %drn", crc_state) ;
// Error Coding Rate
RadioErrorCodingRate_t cr = CR_4_5 ;
RADIO_SetAttr(ERROR_CODING_RATE, &cr) ;
printf("Configuring Error Coding Rate 4/5rn") ;
// IQ Inverted
uint8_t iqi = 0 ;
RADIO_SetAttr(IQINVERTED, &iqi) ;
printf("Configuring IQ Inverted: %drn", iqi) ;
// LoRa Sync Word
uint8_t sync_word = 0x34 ;
RADIO_SetAttr(LORA_SYNC_WORD, &sync_word) ;
printf("Configuring LoRa sync word 0x%xrn", sync_word) ;
// Modulation
RadioModulation_t mod = MODULATION_LORA ;
RADIO_SetAttr(MODULATION, &mod) ;
printf("Configuring Modulation: LORArn") ;
// PA Boost
uint8_t pa_boost = 0 ;
RADIO_SetAttr(PABOOST, &pa_boost) ;
printf("Configuring PA Boost: %drn", pa_boost) ;
// Tx Output Power
int16_t outputPwr = 1 ;
RADIO_SetAttr(OUTPUT_POWER, (void *)&outputPwr) ;
printf("Configuring Radio Output Power %drn", outputPwr) ;
// Spreading Factor
int16_t sf = SF_7 ;
RADIO_SetAttr(SPREADING_FACTOR, (void *)&sf) ;
printf("Configuring Radio SF %drn", sf) ;
// Watchdog Timeout
uint32_t wdt = 60000 ;
RADIO_SetAttr(WATCHDOG_TIMEOUT, (void *)&wdt) ;
printf("Configuring Radio Watch Dog Timeout %ldrn", wdt) ;
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '7')
{
// Radio Transmit
// the counter value
counter++ ;
if (counter > 255) counter = 0 ;
tx_buffer[0] = counter ;
printf("Buffer transmitted: ") ;
print_array(tx_buffer, 1) ;
RadioError_t radioStatus ;
RadioTransmitParam_t radioTransmitParam ;
radioTransmitParam.bufferLen = 1 ;
radioTransmitParam.bufferPtr = (uint8_t *)&tx_buffer ;
radioStatus = RADIO_Transmit(&radioTransmitParam) ;
switch (radioStatus)
{
case ERR_NONE:
{
printf("Radio Transmit Successrn") ;
}
break ;
case ERR_DATA_SIZE:
{
// do nothing, status already set to invalid
}
break ;
default:
{
printf("Radio Busyrn") ;
}
}
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '8')
{
// Enter Radio Receive mode
RadioReceiveParam_t radioReceiveParam ;
uint32_t rxTimeout = 0 ; // forever
radioReceiveParam.action = RECEIVE_START ;
radioReceiveParam.rxWindowSize = rxTimeout ;
if (RADIO_Receive(&radioReceiveParam) == 0)
{
printf("Radio in Receive modern") ;
}
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '9')
{
// Stop Radio Receive mode
RadioReceiveParam_t radioReceiveParam ;
radioReceiveParam.action = RECEIVE_STOP ;
if (RADIO_Receive(&radioReceiveParam) == 0)
{
printf("Radio Exit Receive modern") ;
}
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else
{
set_LED_data(LED_AMBER,&on);
printf("Invalid choice enteredrn");
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
}
/* OTAA Join Parameters */
#define DEMO_DEVICE_EUI {0xde, 0xaf, 0xfa, 0xce, 0xde, 0xaf, 0xfa, 0xce}
#define DEMO_APPLICATION_EUI {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}
#define DEMO_APPLICATION_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}
conf_board.hファイル:
/* TODO: If Board is having EDBG with DEV_EUI flashed in
Userpage Enable this Macro otherwise make it as 0 */
#define EDBG_EUI_READ 1







