#include #include /* Include to get access to the VectorNav SPI functions. */ #include "vn/protocol/spi.h" #include "vn/protocol/common.h" #include "vn/xplat/thread.h" int display_error(const char* msg); void mockspi_initialize(void); void mockspi_writeread(const char* dataOut, size_t dataOutSize, char* dataIn); int main(void) { /* This example walks through using the VectorNav C Library to connect to * and interact with a mock VectorNav sensor through the Serial Peripheral * Interaface (SPI). Once you work through and understand the example, you * may want to try replacing the mock functions with ones that interface * with your SPI subsystem. */ char txbuf[0x100]; char rxbuf[0x100]; size_t bufcmdsize; size_t responseSize; vec3f ypr; char strConversions[50]; size_t i; mockspi_initialize(); /* With SPI 'initialize', let's work through reading the current yaw, pitch, * roll values from the sensor. */ /* First we must generate the command to query the sensor. */ bufcmdsize = sizeof(txbuf); /* First set this variable to the size of the buffer. */ if (VnSpi_genReadYawPitchRoll( txbuf, &bufcmdsize, /* Pass in the pointer since the function will set this with the length of the command generate. */ 0, &responseSize) != E_NONE) return display_error("Error generating read yaw, pitch, roll command.\n"); /* Send out the command over SPI. */ mockspi_writeread( txbuf, responseSize, rxbuf); /* Now the sensor will have responded with data on this transaction but * since the sensor only responds on following transaction, we will * disregard this data. These double transactions can be mitigated by only * requesting the same data each time or by staggering the the requested * data in an appropriate order. */ /* Make sure enough time has passed for the sensor to format the previous response. */ VnThread_sleepMs(1); /* Actual sensor requirement is only 50 us. */ /* Retransmit so the sensor responds with the previous request. */ mockspi_writeread( txbuf, responseSize, rxbuf); /* Now parse the received response. */ if (VnSpi_parseYawPitchRoll( rxbuf, &ypr) != E_NONE) return display_error("Error parsing yaw, pitch, roll.\n"); str_vec3f(strConversions, ypr); printf("Current YPR: %s\n", strConversions); /* We have now shown how to process one full command transaction which * requires two SPI transactions because the VectorNav sensor requires a * short amount of time to ready the response. Now we can optimize this * transaction squence to utilize this behavior when we are only requesting * the same data each time. This is illustrated in the for loop below. */ for (i = 0; i < 25; i++) { /* For this loop, we want to display data at ~10 Hz. */ VnThread_sleepMs(100); /* Perform a transaction for the same sensor register. */ mockspi_writeread( txbuf, responseSize, rxbuf); /* Now since the previous command was for the same register, we will * have valid data and can print/use the results. */ if (VnSpi_parseYawPitchRoll( rxbuf, &ypr) != E_NONE) return display_error("Error parsing yaw, pitch, roll.\n"); str_vec3f(strConversions, ypr); printf("Current YPR: %s\n", strConversions); } /* We illustrate how to write settings to the sensor by changing the * asynchronous data output type. Note that this setting only affects the * output on the UART ports and has no effect on the SPI ports. It is only * used for illustration purposes. */ /* Remember to reset the bufcmdsize variable to let the function know how * large the provided buffer is. */ bufcmdsize = sizeof(txbuf); if (VnSpi_genWriteAsyncDataOutputType( txbuf, &bufcmdsize, 0, &responseSize, VNYPR) != E_NONE) return display_error("Error generating write async data output type command.\n"); mockspi_writeread( txbuf, responseSize, rxbuf); return 0; } int display_error(const char* msg) { printf("%s\n", msg); return -1; } void mockspi_initialize(void) { /* Do nothing since we are faking the SPI interface. */ } void mockspi_writeread(const char* dataOut, size_t dataOutSize, char* dataIn) { /* This function fakes a SPI subsystem for this example. */ char yprResponse[] = { 0x00, 0x01, 0x08, 0x00, 0xd8, 0x9c, 0xd4, 0x42, 0x44, 0xba, 0x9e, 0x40, 0x4e, 0xe4, 0x8b, 0x40 }; /* Silence 'unreferenced formal parameters' warning in Visual Studio. */ (dataOut); (dataOutSize); memcpy(dataIn, yprResponse, sizeof(yprResponse)); }