1.5 PRIME Base Modem

The PRIME Base Modem application implements the full PRIME Stack and 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.

The provided project for PRIME v1.3.6 is PLC. The provided project for PRIME v1.4 is PLC-RF hybrid, but it can be PLC-only or RF-only if only one expansion board is connected. These projects are without operative system (Bare-Metal). The following table shows the available PRIME Base Modem projects.
Table 1-1. PRIME Base Modem projects
NamePath Boards
Base 1.3 Modem\smartenergy_prime_apps\apps\prime_apps\prime_base_1_3_modem\pic32cxmtg_pl460.XPIC32CXMTG-EK + PL460-EK
Base 1.4 Modem\smartenergy_prime_apps\apps\prime_apps\prime_base_1_4_modem\pic32cxmtg_pl460_rf215.XPIC32CXMTG-EK + PL460-EK + REB215-XPRO

Application Example

The PRIME Base Modem application implements the full PRIME stack and allows accessing the PRIME API through serial interface.

The PRIME Base Modem Modem application interchanges data with the external device through a serial port, whose settings are:

Application Functionality

The PRIME Base Modem application functionality is very simple as it just redirects requests and callbacks between the PRIME Stack and the USI.

The APP_MODEM_Initialize function initializes the application’s State Machine and gets the PRIME API pointer:
void APP_Modem_Initialize(void)
{
     /* Initialize the reception queue */
     inputMsgRecvIndex = 0;
     outputMsgRecvIndex = 0;

     (void) memset(sAppModemMsgRecv, 0, sizeof(sAppModemMsgRecv));

     /* Initialize TxRx data indicators */
     sRxdataIndication = false;
     sTxdataIndication = false;

     /* Get PRIME API pointer */
     PRIME_API_GetPrimeAPI(&gPrimeApi);

     /* Set state */
     modemState = APP_MODEM_STATE_CONFIGURE;
}
After Initialization, the State Machine has to wait for the PRIME Stack to be ready before setting the corresponding callbacks:
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 cl432Callbacks;
    BMNG_CALLBACKS bmngCallbacks;

    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_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_mp_promote_cfm = APP_Modem_MLME_MP_PromoteConfirm;
    macCallbacks.mlme_reset_cfm = APP_Modem_MLME_ResetConfirm;
    macCallbacks.mlme_set_cfm = APP_Modem_MLME_SetConfirm;

    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);

    cl432Callbacks.cl_432_dl_data_cfm = APP_Modem_CL432_DlDataConfirm;
    cl432Callbacks.cl_432_dl_data_ind = APP_Modem_CL432_DlDataIndication;
    cl432Callbacks.cl_432_join_ind = APP_Modem_CL432_JoinIndication;
    cl432Callbacks.cl_432_leave_ind = APP_Modem_CL432_LeaveIndication;

    gPrimeApi->Cl432SetCallbacks(&cl432Callbacks);

    bmngCallbacks.fup_ack = APP_Modem_BMNG_FupAck;
    bmngCallbacks.fup_kill_ind = APP_Modem_BMNG_FupKillIndication;
    bmngCallbacks.fup_status_ind = APP_Modem_BMNG_FupStatusIndication;
    bmngCallbacks.fup_version_ind = APP_Modem_BMNG_FupVersionIndication;
    bmngCallbacks.network_event_ind = APP_Modem_BMNG_NetEventIndication;
    bmngCallbacks.pprof_ack = APP_Modem_BMNG_PprofAck;
    bmngCallbacks.pprof_get_response = APP_Modem_BMNG_PprofGetResponse;
    bmngCallbacks.pprof_get_enhanced_response =
                                     APP_Modem_BMNG_PprofGetEnhancedResponse;
    bmngCallbacks.pprof_get_zc_response = APP_Modem_BMNG_PprofGetZCResponse;
    bmngCallbacks.pprof_zc_diff_response = APP_Modem_BMNG_PprofDiffZCResponse;
    bmngCallbacks.whitelist_ack = APP_Modem_BMNG_WhitelistAck;

    gPrimeApi->BmngSetCallbacks(&bmngCallbacks);
}

And finally just wait for callbacks from the PRIME Stack or request commands from the USI.