File ns_rpc_generic_data.c
File List > neuralSPOT > neuralspot > ns-rpc > src > ns_rpc_generic_data.c
Go to the documentation of this file
#include "ns_rpc_generic_data.h"
#include "erpc_client_setup.h"
#include "erpc_server_setup.h"
#include "ns_usb.h"
// Common interface header files
#include "GenericDataOperations_EvbToPc.h"
#include "GenericDataOperations_PcToEvb.h"
#include "GenericDataOperations_PcToEvb_server.h"
#include "ns_ambiqsuite_harness.h"
#include "ns_core.h"
#include "ns_malloc.h"
#define NS_RPC_GENERIC_DATA
#ifdef NS_RPC_GENERIC_DATA
const ns_core_api_t ns_rpc_gdo_V0_0_1 = {.apiId = NS_RPC_GDO_API_ID, .version = NS_RPC_GDO_V0_0_1};
const ns_core_api_t ns_rpc_gdo_V1_0_0 = {.apiId = NS_RPC_GDO_API_ID, .version = NS_RPC_GDO_V1_0_0};
const ns_core_api_t ns_rpc_gdo_oldest_supported_version = {
.apiId = NS_RPC_GDO_API_ID, .version = NS_RPC_GDO_V0_0_1};
const ns_core_api_t ns_rpc_gdo_current_version = {
.apiId = NS_RPC_GDO_API_ID, .version = NS_RPC_GDO_V1_0_0};
ns_usb_config_t g_RpcGenericUSBHandle = {
.api = &ns_usb_V1_0_0,
.deviceType = NS_USB_CDC_DEVICE,
.rx_buffer = NULL,
.rx_bufferLength = 0,
.tx_buffer = NULL,
.tx_bufferLength = 0,
.rx_cb = NULL,
.tx_cb = NULL,
.service_cb = NULL};
ns_rpc_config_t g_RpcGenericDataConfig = {
.api = &ns_rpc_gdo_current_version,
.mode = NS_RPC_GENERICDATA_CLIENT,
.rx_buf = NULL,
.rx_bufLength = 0,
.tx_buf = NULL,
.tx_bufLength = 0,
.usbHandle = NULL,
.sendBlockToEVB_cb = NULL,
.fetchBlockFromEVB_cb = NULL,
.computeOnEVB_cb = NULL};
// GenericDataOperations implements 3 function calls that service
// remote calls from a PC. They must be instantiated to enable them.
// Datatypes, function prototypes, etc, are defined in the RPC's include files
status ns_rpc_data_sendBlockToEVB(const dataBlock *block) {
// ns_lp_printf("Received call to sendBlockToEVB\n");
if (g_RpcGenericDataConfig.sendBlockToEVB_cb != NULL) {
return g_RpcGenericDataConfig.sendBlockToEVB_cb(block);
} else {
return ns_rpc_data_success;
}
}
status ns_rpc_data_fetchBlockFromEVB(dataBlock *block) {
// ns_lp_printf("Received call to fetchBlockFromEVB\n");
if (g_RpcGenericDataConfig.fetchBlockFromEVB_cb != NULL) {
return g_RpcGenericDataConfig.fetchBlockFromEVB_cb(block);
} else {
return ns_rpc_data_success;
}
}
status ns_rpc_data_computeOnEVB(const dataBlock *in_block, dataBlock *result_block) {
// ns_lp_printf("Received call to computeOnEVB\n");
if (g_RpcGenericDataConfig.computeOnEVB_cb != NULL) {
return g_RpcGenericDataConfig.computeOnEVB_cb(in_block, result_block);
} else {
return ns_rpc_data_success;
}
}
// void ns_rpc_data_serverService(uint8_t haveUsbData) {
// if ((g_RpcGenericDataConfig.serviceServer == true) && (haveUsbData == 1)) {
// erpc_server_poll(); // service RPC server
// }
// }
uint16_t ns_rpc_genericDataOperations_init(ns_rpc_config_t *cfg) {
#ifndef NS_DISABLE_API_VALIDATION
if (cfg == NULL) {
return NS_STATUS_INVALID_HANDLE;
}
if (ns_core_check_api(
cfg->api, &ns_rpc_gdo_oldest_supported_version, &ns_rpc_gdo_current_version)) {
return NS_STATUS_INVALID_VERSION;
}
#endif
// usb_handle_t usb_handle = ns_usb_init(&g_RpcGenericUSBHandle);
usb_handle_t usb_handle = NULL;
// For server mode, add a service callback to USB
// if (cfg->mode == NS_RPC_GENERICDATA_SERVER) {
// g_RpcGenericUSBHandle.service_cb = &ns_rpc_data_serverService;
// }
g_RpcGenericUSBHandle.rx_buffer = cfg->rx_buf;
g_RpcGenericUSBHandle.rx_bufferLength = cfg->rx_bufLength;
g_RpcGenericUSBHandle.tx_buffer = cfg->tx_buf;
g_RpcGenericUSBHandle.tx_bufferLength = cfg->tx_bufLength;
NS_TRY(ns_usb_init(&g_RpcGenericUSBHandle, &usb_handle), "USB Init Failed\n");
g_RpcGenericDataConfig.mode = cfg->mode;
g_RpcGenericDataConfig.sendBlockToEVB_cb = cfg->sendBlockToEVB_cb;
g_RpcGenericDataConfig.fetchBlockFromEVB_cb = cfg->fetchBlockFromEVB_cb;
g_RpcGenericDataConfig.computeOnEVB_cb = cfg->computeOnEVB_cb;
// g_RpcGenericDataConfig.serviceServer = cfg->serviceServer;
g_RpcGenericDataConfig.rx_buf = cfg->rx_buf;
g_RpcGenericDataConfig.rx_bufLength = cfg->rx_bufLength;
g_RpcGenericDataConfig.tx_buf = cfg->tx_buf;
g_RpcGenericDataConfig.tx_bufLength = cfg->tx_bufLength;
g_RpcGenericDataConfig.usbHandle = usb_handle;
// Common ERPC init
/* USB transport layer initialization */
erpc_transport_t transport = erpc_transport_usb_cdc_init(usb_handle);
/* MessageBufferFactory initialization */
erpc_mbf_t message_buffer_factory = erpc_mbf_static_init();
if (cfg->mode == NS_RPC_GENERICDATA_CLIENT) {
/* Init eRPC client environment */
erpc_client_init(transport, message_buffer_factory);
} else {
// Initialize the server and service
erpc_server_init(transport, message_buffer_factory);
erpc_service_t service = create_pc_to_evb_service();
erpc_add_service_to_server(service);
}
return NS_STATUS_SUCCESS;
}
// void
// ns_rpc_genericDataOperations_enableServerPoll(ns_rpc_config_t *cfg) {
// g_RpcGenericDataConfig.serviceServer = true;
// }
// void
// ns_rpc_genericDataOperations_disableServerPoll(ns_rpc_config_t *cfg) {
// g_RpcGenericDataConfig.serviceServer = false;
// }
void ns_rpc_genericDataOperations_pollServer(ns_rpc_config_t *cfg) {
erpc_status_t stat;
if (ns_usb_data_available(cfg->usbHandle)) {
stat = erpc_server_poll(); // service RPC server
if (stat != kErpcStatus_Success) {
ns_lp_printf("erpc_server_poll failed with status %d\n", stat);
}
}
}
uint16_t ns_rpc_genericDataOperationsClient_reset(ns_rpc_config_t *cfg) {
erpc_client_deinit();
return ns_rpc_genericDataOperations_init(cfg);
}
void ns_rpc_genericDataOperations_printDatablock(const dataBlock *block) {
uint32_t i = 0;
ns_lp_printf("Descriptor: %s\n", block->description);
ns_lp_printf("Length: %d\n", block->length);
ns_lp_printf("buffer.dataLength: %d\n", block->buffer.dataLength);
ns_lp_printf("Contents:\n");
for (i = 0; i < block->buffer.dataLength; i++) {
ns_lp_printf("0x%x, ", block->buffer.data[i]);
}
ns_lp_printf("\n");
}
void ns_rpc_data_clientDoneWithBlockFromPC(const dataBlock *block) {
ns_free(block->description);
ns_free(block->buffer.data);
}
#else
uint16_t ns_rpc_genericDataOperations_init() { return 1; }
#endif