1.6 PRIME Service Dual Modem
The PRIME Service Dual Modem application implements the interface between the PRIME Library and an external device. This interface allows accessing the PRIME API through serial interface.
Serial messages are sent and received using the USI service. The modem can be managed by an external device such as an MCU, MPU or PC, which must implement the USI protocol and the protocol used to serialize the PRIME API. Microchip offers the PRIME Serialized Python library, which allows to develop customized Python scripts to perform different operations. To obtain Python libraries and example scripts contact to the Microchip Smart Energy support team.
Name | Path | Boards |
---|---|---|
Service Dual Modem | \smartenergy_prime_apps\apps\prime_apps\prime_service_dual_modem\pic32cxmtg_pl460_rf215.X | PIC32CXMTG-EK + PL460-EK + REB215-XPRO |
Application Example
The PRIME Service Dual Modem application implements the interface between the PRIME Library and an external device. This interface allows accessing the PRIME API through serial interface.
- Baud-rate depending on the platform (see Hardware Configuration)
- 8 data bits
- no parity
- 1 stop bit
- Firmware upgrade handling:
- Swapping of the PRIME Stack version between v1.3.6 and v1.4
depending on the network
traffic.
static void lAPP_PrimeVersionSwapRequest(SRV_FU_TRAFFIC_VERSION traffic) { /* Compare current PRIME pointer with detected traffic */ if (traffic == SRV_FU_TRAFFIC_VER_PRIME_1_4) { newPrimeApi = (PRIME_API *)PRIME_SN_FWSTACK14_ADDRESS; versionSwapEn = APP_VERSION_ENABLE_SWAP; } else if (traffic == SRV_FU_TRAFFIC_VER_PRIME_1_3) { newPrimeApi = (PRIME_API *)PRIME_SN_FWSTACK13_ADDRESS; versionSwapEn = APP_VERSION_ENABLE_SWAP; } else { // Do nothing } } static void lAPP_SwapStackVersion(void) { /* Initialize PRIME stack with the new pointer */ if (newPrimeApi == (PRIME_API *)PRIME_SN_FWSTACK14_ADDRESS) { PRIME_Restart((uint32_t *)newPrimeApi, PRIME_VERSION_1_4); } else { PRIME_Restart((uint32_t *)newPrimeApi, PRIME_VERSION_1_3); } /* Initialize Modem application */ APP_Modem_Initialize(); /* Needed to set up callbacks */ }
- Swapping of the firmware received in a firmware upgrade
process.
static void lAPP_PrimeFuResultHandler(SRV_FU_RESULT fuResult) { switch (fuResult) { case SRV_FU_RESULT_SUCCESS: /* Update FU pointer */ fuSwapEn = APP_FU_ENABLE_SWAP; break; case SRV_FU_RESULT_CRC_ERROR: /* Nothing to do - FU will restart automatically */ break; case SRV_FU_RESULT_CANCEL: /* Nothing to do */ break; case SRV_FU_RESULT_FW_CONFIRM: /* Nothing to do */ break; case SRV_FU_RESULT_FW_REVERT: /* Revert FU pointer */ fuSwapEn = APP_FU_ENABLE_SWAP; break; case SRV_FU_RESULT_ERROR: /* Nothing to do */ break; case SRV_FU_RESULT_SIGNATURE_ERROR: /* Nothing to do */ break; case SRV_FU_RESULT_IMAGE_ERROR: /* Nothing to do */ break; default: break; } } static void lAPP_SwapFirmware(void) { /* Swap firmware */ if (SRV_FU_SwapFirmware() == true) { /* Trigger reset to launch bootloader */ SRV_RESET_HANDLER_RestartSystem(RESET_HANDLER_FU_RESET); } }
- Swapping of the PRIME Stack version between v1.3.6 and v1.4
depending on the network
traffic.
Application Functionality
The PRIME Service Dual Modem application functionality is very simple as it just redirects requests and callbacks between the PRIME Stack and the USI.
void APP_Modem_Initialize(void)
{
SRV_STORAGE_PRIME_MODE_INFO_CONFIG boardInfo;
/* Initialize the reception queue */
inputMsgRecvIndex = 0;
outputMsgRecvIndex = 0;
(void) memset(sAppModemMsgRecv, 0, sizeof(sAppModemMsgRecv));
/* Initialize TxRx data indicators */
sRxdataIndication = false;
sTxdataIndication = false;
/* Reset node state */
sAppNodeState = APP_MODEM_NODE_UNREGISTERED;
(void) memset(&boardInfo, 0, sizeof(boardInfo));
/* Get the PRIME version */
SRV_STORAGE_GetConfigInfo(SRV_STORAGE_TYPE_MODE_PRIME, (uint8_t)sizeof(boardInfo),
(void *)&boardInfo);
/* Get PRIME API pointer */
switch (boardInfo.primeVersion)
{
case PRIME_VERSION_1_3:
PRIME_API_GetPrime13API(&gPrimeApi);
break;
case PRIME_VERSION_1_4:
default:
PRIME_API_GetPrime14API(&gPrimeApi);
break;
}
/* Set state */
modemState = APP_MODEM_STATE_CONFIGURE;
}
case APP_MODEM_STATE_CONFIGURE:
/* Check if PRIME stack is ready */
if (gPrimeApi->Status() == SYS_STATUS_READY)
{
/* Set callback functions */
APP_Modem_SetCallbacks();
/* Open USI */
gUsiHandle = SRV_USI_Open(SRV_USI_INDEX_0);
/* Configure USI protocol handler */
SRV_USI_CallbackRegister(gUsiHandle, SRV_USI_PROT_ID_PRIME_API,
APP_Modem_USI_PRIME_ApiHandler);
modemState = APP_MODEM_STATE_TASKS;
}
break;
static void APP_Modem_SetCallbacks(void)
{
MAC_CALLBACKS macCallbacks;
CL_432_CALLBACKS cl432_callbacks;
macCallbacks.mac_data_cfm = APP_Modem_DataConfirm;
macCallbacks.mac_data_ind = APP_Modem_DataIndication;
macCallbacks.mac_establish_cfm = APP_Modem_EstablishConfirm;
macCallbacks.mac_establish_ind = APP_Modem_EstablishIndication;
macCallbacks.mac_join_cfm = APP_Modem_JoinConfirm;
macCallbacks.mac_join_ind = APP_Modem_JoinIndication;
macCallbacks.mac_leave_cfm = APP_Modem_LeaveConfirm;
macCallbacks.mac_leave_ind = APP_Modem_LeaveIndication;
macCallbacks.mac_release_cfm = APP_Modem_ReleaseConfirm;
macCallbacks.mac_release_ind = APP_Modem_ReleaseIndication;
macCallbacks.mlme_demote_cfm = APP_Modem_MLME_DemoteConfirm;
macCallbacks.mlme_demote_ind = APP_Modem_MLME_DemoteIndication;
macCallbacks.mlme_mp_demote_cfm = APP_Modem_MLME_MP_DemoteConfirm;
macCallbacks.mlme_mp_demote_ind = APP_Modem_MLME_MP_DemoteIndication;
macCallbacks.mlme_get_cfm = APP_Modem_MLME_GetConfirm;
macCallbacks.mlme_list_get_cfm = APP_Modem_MLME_ListGetConfirm;
macCallbacks.mlme_promote_cfm = APP_Modem_MLME_PromoteConfirm;
macCallbacks.mlme_promote_ind = APP_Modem_MLME_PromoteIndication;
macCallbacks.mlme_mp_promote_cfm = APP_Modem_MLME_MP_PromoteConfirm;
macCallbacks.mlme_mp_promote_ind = APP_Modem_MLME_MP_PromoteIndication;
macCallbacks.mlme_register_cfm = APP_Modem_MLME_RegisterConfirm;
macCallbacks.mlme_register_ind = APP_Modem_MLME_RegisterIndication;
macCallbacks.mlme_reset_cfm = APP_Modem_MLME_ResetConfirm;
macCallbacks.mlme_set_cfm = APP_Modem_MLME_SetConfirm;
macCallbacks.mlme_unregister_cfm = APP_Modem_MLME_UnregisterConfirm;
macCallbacks.mlme_unregister_ind = APP_Modem_MLME_UnregisterIndication;
macCallbacks.plme_get_cfm = APP_Modem_PLME_GetConfirm;
macCallbacks.plme_reset_cfm = APP_Modem_PLME_ResetConfirm;
macCallbacks.plme_resume_cfm = APP_Modem_PLME_ResumeConfirm;
macCallbacks.plme_set_cfm = APP_Modem_PLME_SetConfirm;
macCallbacks.plme_sleep_cfm = APP_Modem_PLME_SleepConfirm;
macCallbacks.plme_testmode_cfm = NULL;
gPrimeApi->MacSetCallbacks(&macCallbacks);
cl432_callbacks.cl_432_dl_data_cfm = APP_Modem_CL432_DlDataConfirm;
cl432_callbacks.cl_432_dl_data_ind = APP_Modem_CL432_DlDataIndication;
cl432_callbacks.cl_432_establish_cfm = APP_Modem_CL432_EstablishConfirm;
cl432_callbacks.cl_432_release_cfm = APP_Modem_CL432_ReleaseConfirm;
gPrimeApi->Cl432SetCallbacks(&cl432_callbacks);
}
And finally the application just waits for callbacks from the PRIME Stack or request commands from the USI.