Hi,
thank you for your replay.
Unfortunately for the used LPC54605 there is no demo code. My starting point was the LED example from GitHub: https://github.com/EmbeddedRPC/erpc
I try to describe more exactly what I'm doing here:
- principal environment
*---------------* *-----------------*
| erpc Client | ----> | erpc Server |
*---------------* *-----------------*
- Xilinx UltraScale+ - NXP LPC54605
- petalinux - FreeRTOS
- SPI Master - SPI Slave
- IDL code
// Define a data type.
const int32 BUFFER_SIZE_1k = 1024;
type TestBuffer1k_t = int8[BUFFER_SIZE_1k];
// Grouping name for test module
@group("Test")
// An interface is a logical grouping of functions.
interface testFunctions {
writeData1k(in TestBuffer1k_t buffer) -> void
readData1k(out TestBuffer1k_t buffer) -> void
}
- eRPC Server task
erpc_transport_t tTransport;
erpc_mbf_t tBuffer;
erpc_status_t tStatus;
/* MU transport layer initialization */
tTransport = erpc_transport_spi_slave_init(BOARD_SPI0_BM_BASEADDR, 1e6, CLOCK_GetFlexCommClkFreq(kFRO12M_to_FLEXCOMM5));
/* MessageBufferFactory initialization */
tBuffer = erpc_mbf_dynamic_init();
/* eRPC server side initialization */
erpc_server_init(tTransport, tBuffer);
// Add the IO service.
erpc_add_service_to_server(create_testFunctions_service());
/* set SPI client IRQ priority above SYSCALL_INTERRUPT_PIORITY as requested in FreeRTOS */
NVIC_SetPriority(FLEXCOMM5_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
while (true) {
// Run the server.
tStatus = erpc_server_run();
// print error message
PRINTF("eRPC Server Run quit: %d\n", tStatus);
// NOT WORKING but solution for erpc client hook because of erpc server exit on e.g. CRC error
// after error erpc client hook into receiving ERPC_BOARD_SPI_SLAVE_READY_MARKER1 = 0xAB and ERPC_BOARD_SPI_SLAVE_READY_MARKER2 = 0xCD
//SendSlaveReadyMarker();
} // endless loop
- eRPC server function implementation
static TestBuffer1k_t TestBuffer;
void writeData1k(const TestBuffer1k_t buf) {
memcpy(&TestBuffer[0], &buf[0], sizeof(TestBuffer));
}
void readData1k(TestBuffer1k_t buf) {
memcpy(&buf[0], &TestBuffer[0], sizeof(TestBuffer));
}
- eRPC client code
TestBuffer1k_t txBuf;
TestBuffer1k_t rxBuf;
/* Init eRPC client environment */
/* spiDev transport layer initialization */
erpc_transport_t transport = erpc_transport_spidev_master_init("/dev/spidev0.0", 1e6);
/* MessageBufferFactory initialization */
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
/* eRPC client side initialization */
erpc_client_init(transport, message_buffer_factory);
erpc_client_set_error_handler(error_handler);
/* eRPC test loop */
while (true) {
/* fill buffer with random data */
for (i = 0; i < BUFFER_SIZE_1k; i++) {
txBuf[i] = (int8_t) random();
}
/* send data to erpc Server */
writeData1k(&txBuf[0]);
/* receive previosly send data again */
readData1k(&rxBuf[0]);
/* check for data consistency */
for (i = 0; i < BUFFER_SIZE_1k; i++) {
if (txBuf[i] != rxBuf[i]) {
m_print.out(DL_None, "Failed_1k 0x%08X != 0x%08X\n", txBuf[i], rxBuf[i]);
}
}
}
- eRPC client error handler
void error_handler(erpc_status_t err, uint32_t functionID) {
if (err != 0) {
// error accured sleep 1s to allow MCU to restart eRPC server
printf("err_%d - fucId: %d\n", err, functionID);
sleep(1);
} else {
// sleep after RPC was sucessfull to avoid MCU SPI overload
usleep(4);
}
}
Hopefully this is understandable, feel free to ask if there are any questions or you need more information.
This code works fine for a certain time but in a disturbed environment a CRC could accure. For this CRC error I dont know how to handle correctly.
After CRC error accures the eRPC client stuck into the endless loop waiting for the ERPC_BOARD_SPI_SLAVE_READY_MARKER1 and ERPC_BOARD_SPI_SLAVE_READY_MARKER2 as defined in "erpc_spi_master_transport.cpp". To release the loop the eRPC server has to send this two markers. If I do this manually the SPI erpc server initialisation interferes with the manual way so this couldn't be the solution.
Thank you and best regards
Sebastian