diff --git a/examples/OpenIMU300RI/IMU/platformio.ini b/examples/OpenIMU300RI/IMU/platformio.ini index cc4f0c1..6a502f0 100644 --- a/examples/OpenIMU300RI/IMU/platformio.ini +++ b/examples/OpenIMU300RI/IMU/platformio.ini @@ -15,7 +15,7 @@ platform = aceinna_imu lib_archive = false board = OpenIMU300 ;lib_deps = ../../openIMU300-lib/openIMU300-lib -lib_deps = OpenIMU300-base-library@1.1.6 +lib_deps = OpenIMU300-base-library@~1.1.8 build_flags = ; -D CLI -D SAE_J1939 diff --git a/examples/OpenIMU300RI/IMU/src/appVersion.h b/examples/OpenIMU300RI/IMU/src/appVersion.h index e5eb59d..8f23782 100644 --- a/examples/OpenIMU300RI/IMU/src/appVersion.h +++ b/examples/OpenIMU300RI/IMU/src/appVersion.h @@ -26,7 +26,7 @@ limitations under the License. #ifndef _IMU_APP_VERSION_H #define _IMU_APP_VERSION_H -#define APP_VERSION_STRING "IMU_J1939 1.1.3" +#define APP_VERSION_STRING "IMU_J1939 1.1.4" #endif diff --git a/examples/OpenIMU300RI/IMU/src/user/UserMessagingCAN.c b/examples/OpenIMU300RI/IMU/src/user/UserMessagingCAN.c index ee69f53..38ad19c 100644 --- a/examples/OpenIMU300RI/IMU/src/user/UserMessagingCAN.c +++ b/examples/OpenIMU300RI/IMU/src/user/UserMessagingCAN.c @@ -149,14 +149,14 @@ void ProcessRequest(void *dsc) } // pasket type request else if ((req_ps_val == gEcuConfigPtr->packet_type_ps)) { - aceinna_j1939_send_packet_rate(gEcuConfigPtr->packet_type); + aceinna_j1939_send_packet_type(gEcuConfigPtr->packet_type); } // filter settings request else if ((req_ps_val == gEcuConfigPtr->digital_filter_ps)) { aceinna_j1939_send_digital_filter(gEcuConfigPtr->accel_cut_off, gEcuConfigPtr->rate_cut_off); } // orientation settings request - else if ((req_ps_val == gEcuConfigPtr->orien_bits)) { + else if ((req_ps_val == gEcuConfigPtr->orientation_ps)) { uint8_t bytes[2]; bytes[0] = (gEcuConfigPtr->orien_bits >> 8) & 0xff; bytes[1] = (gEcuConfigPtr->orien_bits) & 0xff; diff --git a/examples/OpenIMU300RI/INS/platformio.ini b/examples/OpenIMU300RI/INS/platformio.ini index 9e3284a..b9878a9 100644 --- a/examples/OpenIMU300RI/INS/platformio.ini +++ b/examples/OpenIMU300RI/INS/platformio.ini @@ -14,8 +14,8 @@ description = A Kalman filter based algorithm that uses rate-sensors to propagat platform = aceinna_imu lib_archive = false board = OpenIMU300 -;lib_deps = ../../openIMU300-lib\openIMU300-lib -lib_deps = OpenIMU300-base-library@1.1.6 +;lib_deps = ../../../../../openIMU300-lib/openIMU300-lib +lib_deps = OpenIMU300-base-library@~1.1.8 build_flags = -D GPS -D GPS_OVER_CAN diff --git a/examples/OpenIMU300RI/INS/src/appVersion.h b/examples/OpenIMU300RI/INS/src/appVersion.h index 94fac93..e70c371 100644 --- a/examples/OpenIMU300RI/INS/src/appVersion.h +++ b/examples/OpenIMU300RI/INS/src/appVersion.h @@ -26,7 +26,7 @@ limitations under the License. #ifndef _IMU_APP_VERSION_H #define _IMU_APP_VERSION_H -#define APP_VERSION_STRING "INS_J1939 1.0.3" +#define APP_VERSION_STRING "INS_J1939 1.0.4" #endif diff --git a/examples/OpenIMU300RI/INS/src/user/UserMessagingCAN.c b/examples/OpenIMU300RI/INS/src/user/UserMessagingCAN.c index 82183dd..602da8a 100644 --- a/examples/OpenIMU300RI/INS/src/user/UserMessagingCAN.c +++ b/examples/OpenIMU300RI/INS/src/user/UserMessagingCAN.c @@ -161,7 +161,7 @@ void ProcessRequest(void *dsc) aceinna_j1939_send_digital_filter(gEcuConfigPtr->accel_cut_off, gEcuConfigPtr->rate_cut_off); } // orientation settings request - else if ((req_ps_val == gEcuConfigPtr->orien_bits)) { + else if ((req_ps_val == gEcuConfigPtr->orientation_ps)) { uint8_t bytes[2]; bytes[0] = (gEcuConfigPtr->orien_bits >> 8) & 0xff; bytes[1] = (gEcuConfigPtr->orien_bits) & 0xff; @@ -183,11 +183,11 @@ void ProcessRequest(void *dsc) void ProcessVehiclePosition(struct sae_j1939_rx_desc *desc) { GPS_DATA *posData = (GPS_DATA*)desc->rx_buffer.Data; - canInputNavParams.latitude = (double)posData->latitude*0.000001 - 210; // degrees - canInputNavParams.longitude = (double)posData->longitude*0.000001 - 210; // degrees + canInputNavParams.latitude = (double)posData->latitude*0.0000001 - 210; // degrees + canInputNavParams.longitude = (double)posData->longitude*0.0000001 - 210; // degrees canInputNavParams.status |= J1939_GPS_POSITION_DATA_UPDATED; - gCanGps.latitude = (double)posData->latitude*0.000001 - 210; // degrees - gCanGps.longitude = (double)posData->longitude*0.000001 - 210; // degrees + gCanGps.latitude = (double)posData->latitude*0.0000001 - 210; // degrees + gCanGps.longitude = (double)posData->longitude*0.0000001 - 210; // degrees } void ProcessWheelSpeed(struct sae_j1939_rx_desc *desc) @@ -360,6 +360,7 @@ void EnqeuePeriodicDataPackets(int latency, int sendPeriodicPackets) } // ss2 packets supported by 9DOF +#ifndef GPS_OVER_CAN if (packets_to_send & ACEINNA_SAE_J1939_PACKET_LATLONG) { GPS_DATA gpsData; @@ -375,7 +376,7 @@ void EnqeuePeriodicDataPackets(int latency, int sendPeriodicPackets) aceinna_j1939_send_GPS(&gpsData); } - +#endif // acceleration packets if (packets_to_send & ACEINNA_SAE_J1939_PACKET_ACCELERATION) { diff --git a/examples/OpenIMU300RI/VG_AHRS/platformio.ini b/examples/OpenIMU300RI/VG_AHRS/platformio.ini index cceb861..ecff942 100644 --- a/examples/OpenIMU300RI/VG_AHRS/platformio.ini +++ b/examples/OpenIMU300RI/VG_AHRS/platformio.ini @@ -15,7 +15,7 @@ platform = aceinna_imu lib_archive = false board = OpenIMU300 ;lib_deps = ../../openIMU300-lib/openIMU300-lib -lib_deps = OpenIMU300-base-library@1.1.6 +lib_deps = OpenIMU300-base-library@~1.1.8 build_flags = ; -D CLI ; Comment next line for VG algorithm diff --git a/examples/OpenIMU300RI/VG_AHRS/src/user/UserMessagingCAN.c b/examples/OpenIMU300RI/VG_AHRS/src/user/UserMessagingCAN.c index 4a33a00..25f8c60 100644 --- a/examples/OpenIMU300RI/VG_AHRS/src/user/UserMessagingCAN.c +++ b/examples/OpenIMU300RI/VG_AHRS/src/user/UserMessagingCAN.c @@ -149,14 +149,14 @@ void ProcessRequest(void *dsc) } // pasket type request else if ((req_ps_val == gEcuConfigPtr->packet_type_ps)) { - aceinna_j1939_send_packet_rate(gEcuConfigPtr->packet_type); + aceinna_j1939_send_packet_type(gEcuConfigPtr->packet_type); } // filter settings request else if ((req_ps_val == gEcuConfigPtr->digital_filter_ps)) { aceinna_j1939_send_digital_filter(gEcuConfigPtr->accel_cut_off, gEcuConfigPtr->rate_cut_off); } // orientation settings request - else if ((req_ps_val == gEcuConfigPtr->orien_bits)) { + else if ((req_ps_val == gEcuConfigPtr->orientation_ps)) { uint8_t bytes[2]; bytes[0] = (gEcuConfigPtr->orien_bits >> 8) & 0xff; bytes[1] = (gEcuConfigPtr->orien_bits) & 0xff; diff --git a/examples/OpenRTK330LI/RAWDATA/include/app_version.h b/examples/OpenRTK330LI/RAWDATA/include/app_version.h index 771e946..db74825 100644 --- a/examples/OpenRTK330LI/RAWDATA/include/app_version.h +++ b/examples/OpenRTK330LI/RAWDATA/include/app_version.h @@ -26,7 +26,7 @@ limitations under the License. #ifndef _APP_VERSION_H #define _APP_VERSION_H -#define APP_VERSION_STRING "OpenRTK330L RAWDATA App 0.1.1" +#define APP_VERSION_STRING "OpenRTK330L RAWDATA App 1.1.1" #define PRODUCT_NAME_STRING "OpenRTK330L" diff --git a/examples/OpenRTK330LI/RAWDATA/platformio.ini b/examples/OpenRTK330LI/RAWDATA/platformio.ini index 3085ccb..cdee294 100644 --- a/examples/OpenRTK330LI/RAWDATA/platformio.ini +++ b/examples/OpenRTK330LI/RAWDATA/platformio.ini @@ -18,7 +18,9 @@ description = platform = aceinna_imu board = OpenRTK lib_archive = false -lib_deps = OpenRTK-base-library@1.0.3 + +lib_deps = OpenRTK-base-library@1.0.6 + build_flags = -D STM32F469xx diff --git a/examples/OpenRTK330LI/RAWDATA/src/gnss_data_acq_task.c b/examples/OpenRTK330LI/RAWDATA/src/gnss_data_acq_task.c index d6fc3fa..c73940e 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/gnss_data_acq_task.c +++ b/examples/OpenRTK330LI/RAWDATA/src/gnss_data_acq_task.c @@ -26,6 +26,7 @@ limitations under the License. #include "gnss_data_api.h" #include "uart.h" +#include "bt_packet.h" #include "ntrip_client.h" #include "led.h" @@ -63,8 +64,10 @@ static void _handleGpsMessages(uint8_t *RtcmBuff, int length) base_cnt ++; if(base_cnt > 200) { - LED_RTCM_OFF; //No base station signal, led2 off + /* If no base station signal, RED LED is off */ + LED_RTCM_OFF; } + while (length) { length--; @@ -106,10 +109,10 @@ static void _handleGpsMessages(uint8_t *RtcmBuff, int length) uint8_t res = osSemaphoreWait(g_sem_rtk_finish, 0); if (res == osOK && gnss_signal_flag) { - g_ptr_gnss_data->rov = *obs; - g_ptr_gnss_data->ref = *(rtcm->obs + BASE); - g_ptr_gnss_data->nav = rtcm->nav; - osSemaphoreRelease(g_sem_rtk_start); + g_ptr_gnss_data->rov = *obs; + g_ptr_gnss_data->ref = *(rtcm->obs + BASE); + g_ptr_gnss_data->nav = rtcm->nav; + osSemaphoreRelease(g_sem_rtk_start); } } } @@ -139,12 +142,11 @@ void GnssDataAcqTask(void const *argument) { int BtLen = 0; BtLen = uart_read_bytes(UART_BT, bt_buff, GPS_BUFF_SIZE, 0); - if (BtLen) { if(uart_sem_wait(UART_BT,0) == RTK_SEM_OK) { - //ret = bt_uart_parse(bt_buff); + ret = bt_uart_parse(bt_buff); } if (ret != RTK_JSON) { diff --git a/examples/OpenRTK330LI/RAWDATA/src/imu_data_acq_task.c b/examples/OpenRTK330LI/RAWDATA/src/imu_data_acq_task.c index dab53e4..2b3007c 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/imu_data_acq_task.c +++ b/examples/OpenRTK330LI/RAWDATA/src/imu_data_acq_task.c @@ -50,8 +50,6 @@ void TaskDataAcquisition(void const *argument) res = InitSensors(); InitSensorsData(); - configSetPacketRate(100, TRUE); - while (1) { //UBaseType_t uxHighWaterMark; diff --git a/examples/OpenRTK330LI/RAWDATA/src/main.c b/examples/OpenRTK330LI/RAWDATA/src/main.c index 503db79..9035dcd 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/main.c +++ b/examples/OpenRTK330LI/RAWDATA/src/main.c @@ -123,6 +123,8 @@ int main(void) uart_driver_install(UART_GPS,&uart_gps_rx_fifo,&huart_gps,460800); uart_driver_install(UART_BT,&uart_bt_rx_fifo,&huart_bt,460800); + delay_ms(10000); //Delay, in case the usb driver is not installed on computer + ResetForEnterBootMode(); // normal or iap mode InitFactoryCalibration(); diff --git a/examples/OpenRTK330LI/RAWDATA/src/rtk_task.c b/examples/OpenRTK330LI/RAWDATA/src/rtk_task.c index 4b3d73e..9ef705c 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/rtk_task.c +++ b/examples/OpenRTK330LI/RAWDATA/src/rtk_task.c @@ -28,14 +28,69 @@ limitations under the License.*/ #include "led.h" #include "ntrip_client.h" #include "utils.h" +#include "nav_math.h" extern gnss_raw_data_t *g_ptr_gnss_data; - -static void RTKAlgorithm(void); +gnss_solution_t g_gnss_sol = {0}; char gga_buff[200] = "$GPGGA,,,N,,E,,,,,M,,M,,*\r\n"; + +/** *************************************************************************** + * @name copy_pvt_result() + * @brief store PVT result to the global PVT struct + * @param in: rover PVT [ST internal; RTK algorithm output; INS algorithm output] + * out: gnss solution + * @retval N/A + ******************************************************************************/ +static void copy_pvt_result(const st_pvt_type999_t* rov, gnss_solution_t* gnss_sol) +{ + double blh[3] = {0}; + + if (gnss_sol != NULL) + { + ecef2pos(rov->pos_xyz, blh); + gnss_sol->gps_week = rov->ext_gps_week_number; + gnss_sol->gps_tow = (uint32_t)(rov->gnss_epoch_time); + gnss_sol->latitude = blh[0]; + gnss_sol->longitude = blh[1]; + gnss_sol->height = blh[2]; + + memcpy(gnss_sol->pos_ecef, rov->pos_xyz, 3*sizeof(double)); + + double C_en[3][3] = { {0.0} }, vel[3]; + blh2C_en(blh, C_en); + for (int i = 0; i < 3; ++i) { + gnss_sol->vel_ned[i] = 0.0f; + for (int j = 0; j < 3; ++j) { + gnss_sol->vel_ned[i] += C_en[i][j]*rov->vel_xyz[j]; + } + } + + gnss_sol->sol_age = 0.0; + + gnss_sol->num_sats = rov->num_sat_in_use; + gnss_sol->gnss_fix_type = 1; + gnss_sol->dops[2] = rov->hdop; + gnss_sol->gnss_update = 1; + } +} + +/** *************************************************************************** + * @name rtk_algorithm() + * @brief GNSS RTK algorithm entry + * Rover and base data are stored in g_ptr_gnss_data + * nav_t *nav = &g_ptr_gnss_data->nav; +* obs_t *rov = &g_ptr_gnss_data->rov; + * @param N/A + * @retval N/A + ******************************************************************************/ +static void rtk_algorithm(void) +{ + +} + /** *************************************************************************** * @name RTKTask() * @brief RTK Algorithm task @@ -46,7 +101,6 @@ void RTKTask(void const *argument) { // UBaseType_t uxHighWaterMark; // uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); - obs_t* ptr_rover_obs = &g_ptr_gnss_data->rtcm.obs[0]; uint8_t res = osSemaphoreWait(g_sem_rtk_start, 0); while (1) @@ -61,34 +115,33 @@ void RTKTask(void const *argument) } LED1_Toggle(); - RTKAlgorithm(); + rtk_algorithm(); - // use rover obs to make gga and pull base rtcm data - print_pos_gga_util(ptr_rover_obs->time, ptr_rover_obs->pos, ptr_rover_obs->n, 1, 1.0, 0.0, gga_buff); + /* use ST internal SPP solution as an example for GNSS PVT solution + * For User reference, copy your RTK PVT to g_gnss_sol struct + */ + st_pvt_type999_t* st_pvt = &g_ptr_gnss_data->rtcm.rcv[ROVER].st_pvt; + if (st_pvt->flag_gnss_update) { + copy_pvt_result(st_pvt, &g_gnss_sol); - //uart_write_bytes(UART_DEBUG, gga_buff, strlen(gga_buff), 1); - //send gga from Bluetooth - uart_write_bytes(UART_BT, gga_buff, strlen(gga_buff), 1); - //send gga from Internet - ntrip_push_tx_data((uint8_t*)gga_buff, strlen(gga_buff)); + /* use rover position to make NMEA GGA message and pull base rtcm data */ + gtime_t time = gpst2time(g_gnss_sol.gps_week, g_gnss_sol.gps_tow*0.001); + print_pos_gga(time, g_gnss_sol.pos_ecef, g_gnss_sol.num_sats, g_gnss_sol.gnss_fix_type, g_gnss_sol.dops[2], g_gnss_sol.sol_age, gga_buff); + + /* send NMEA GGA position to NTRIP server using Bluetooth */ + uart_write_bytes(UART_BT, gga_buff, strlen(gga_buff), 1); + /* send NMEA GGA position to NTRIP server using Ethernet */ + ntrip_push_tx_data((uint8_t*)gga_buff, strlen(gga_buff)); + + st_pvt->flag_gnss_update = 0; + } + else { + g_gnss_sol.gnss_update = 0; + } osSemaphoreRelease(g_sem_rtk_finish); // uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); // printf("uxhigh=%d\r\n",TASKRTD_STACK-uxHighWaterMark); } -} - -/** *************************************************************************** - * @name RTKAlgorithm() - * @brief RTK Algorithm - * Rover and base data are stored in g_ptr_gnss_data - * nav_t *nav = &g_ptr_gnss_data->nav; -* obs_t *rov = &g_ptr_gnss_data->rov; - * @param N/A - * @retval N/A - ******************************************************************************/ -static void RTKAlgorithm(void) -{ - } \ No newline at end of file diff --git a/examples/OpenRTK330LI/RAWDATA/src/user/user_config.c b/examples/OpenRTK330LI/RAWDATA/src/user/user_config.c index a6941a0..2f4b4d5 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/user/user_config.c +++ b/examples/OpenRTK330LI/RAWDATA/src/user/user_config.c @@ -24,7 +24,7 @@ limitations under the License. *******************************************************************************/ #include "stm32f4xx_hal.h" #include "string.h" - +#include "app_version.h" #include "platformAPI.h" #include "eepromAPI.h" #include "ntrip_client.h" @@ -33,14 +33,15 @@ limitations under the License. #include "configurationAPI.h" #include "osapi.h" #include "crc16.h" -#include "uart.h" + // Default user configuration structure // Do Not remove - just add extra parameters if needed // Change default settings if desired const UserConfigurationStruct gDefaultUserConfig = { .dataCRC = 0, .dataSize = sizeof(UserConfigurationStruct), - + .userPacketType = "s1", + .userPacketRate = 200, // add default parameter values here, if desired .leverArmBx = 0.0, .leverArmBy = 0.0, @@ -71,6 +72,16 @@ CCMRAM UserConfigurationStruct gUserConfiguration; const uint8_t *pUserConfigInFlash = (uint8_t *)APP_USER_CONFIG_ADDR; BOOL configValid = FALSE; +uint8_t* get_user_packet_type(void) +{ + return gUserConfiguration.userPacketType; +} + +uint16_t get_user_packet_rate(void) +{ + return gUserConfiguration.userPacketRate; +} + float* get_user_ins_para() { return &(gUserConfiguration.leverArmBx); @@ -87,17 +98,17 @@ float* get_user_ins_para() * size of user configuration structure * @retval error (0), no error (1) ******************************************************************************/ -BOOL EEPROM_ValidateUserConfig(int *userConfigSize) +BOOL EEPROM_ValidateUserConfig(uint16_t *userConfigSize) { - uint64_t crc, configCrc, size; - uint64_t *dataPtr = (uint64_t*)pUserConfigInFlash; + uint16_t crc, configCrc, size; + uint16_t *dataPtr = (uint16_t*)pUserConfigInFlash; configCrc = dataPtr[0]; // CRC size = dataPtr[1]; // Total Number of bytes in user config structure in eeprom if(size != *userConfigSize){ // check if image fits into user storage in RAM return FALSE; } - crc = CalculateCRC((uint8_t*)pUserConfigInFlash + 8, size - 8); + crc = CalculateCRC((uint8_t*)pUserConfigInFlash + 2, size - 2); if(crc == configCrc){ return TRUE; } @@ -113,9 +124,9 @@ BOOL EEPROM_ValidateUserConfig(int *userConfigSize) * @param [in] N/A * @retval error (0), no error (1) ******************************************************************************/ -BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, int *userConfigSize) +BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, uint16_t *ptrUserConfigSize) { - memcpy(ptrToUserConfigInRam, pUserConfigInFlash, *userConfigSize); + memcpy(ptrToUserConfigInRam, pUserConfigInFlash, *ptrUserConfigSize); return TRUE; } @@ -128,19 +139,19 @@ BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, int *userConfigSize) * @param [in] N/A * @retval error (0), no error (1) ******************************************************************************/ -BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, int userConfigStructLen) +BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, uint16_t userConfigSize) { HAL_StatusTypeDef status = HAL_OK; FLASH_EraseInitTypeDef pEraseInit; uint32_t PageError; uint16_t offset = 0; - uint16_t num = userConfigStructLen; + uint16_t num = userConfigSize; uint32_t start = (uint32_t)pUserConfigInFlash; uint32_t *dataPtr = (uint32_t*)ptrToUserConfigStruct; - uint64_t *paramPtr = (uint64_t*)ptrToUserConfigStruct; + uint16_t *paramPtr = (uint16_t*)ptrToUserConfigStruct; paramPtr[1] = num; // Total size of user config structure, including Crc and data size - paramPtr[0] = CalculateCRC((uint8_t*)ptrToUserConfigStruct + 8, num - 8); + paramPtr[0] = CalculateCRC((uint8_t*)ptrToUserConfigStruct + 2, num - 2); // calculate CRC over user configuration structure ENTER_CRITICAL(); @@ -181,34 +192,28 @@ BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, int userConfigStructL } + void userInitConfigureUnit(void) { - uint8_t *ptrUser = (uint8_t*)&gUserConfiguration.leverArmBx; - uint8_t offset = 0; - int size = sizeof(gUserConfiguration); + uint16_t size = sizeof(gUserConfiguration); // Validate checksum of user configuration structure configValid = EEPROM_ValidateUserConfig(&size); #ifdef DEVICE_DEBUG printf("configValid = %d\r\n", configValid); #endif - - //printf("sizeof(gUserConfiguration) = %d\r\n", size); if (configValid == TRUE) { // Here we have validated User configuration image. // Load it from eeprom into ram on top of the default configuration - EEPROM_LoadUserConfig((void*)&gUserConfiguration, &size); - } else{ + EEPROM_LoadUserConfig((uint8_t*)&gUserConfiguration, &size); + } else { RestoreDefaultUserConfig(); } + update_system_para(); - for (int i = USER_LAST_SYSTEM_PARAM+1; i < USER_MAX_PARAM; i++) - { - ptrUser = ptrUser + offset; - offset = UpdateUserParameter(i, ptrUser); - } + update_user_para(); /* printf("gUserConfiguration.leverArmBx = %f\r\n",gUserConfiguration.leverArmBx); printf("gUserConfiguration.leverArmBy = %f\r\n",gUserConfiguration.leverArmBy); @@ -222,6 +227,138 @@ void userInitConfigureUnit(void) */ } +void update_system_para(void) +{ + uint8_t *ptrSys = (uint8_t*)gUserConfiguration.userPacketType; + uint8_t offset = 0; + uint32_t i; + + for (i = USER_UART_PACKET_TYPE; i <= USER_LAST_SYSTEM_PARAM; i++) { + ptrSys = ptrSys + offset; + offset = UpdateSystemParameter(i, ptrSys); + } +} + +void update_user_para(void) +{ + uint8_t *ptrUser = (uint8_t*)&gUserConfiguration.leverArmBx; + uint8_t offset = 0; + uint32_t i; + + for (i = USER_LAST_SYSTEM_PARAM + 1; i < USER_MAX_PARAM; i++) { + ptrUser = ptrUser + offset; + offset = UpdateUserParameter(i, ptrUser); + } +} + +BOOL valid_user_config_parameter(uint8_t number, uint8_t *data) +{ + uint16_t userPacketRate; + // judge of APP VERSION + if (strstr(APP_VERSION_STRING, "RAWDATA")){ + // RAWDATA app always out 's1' with 50, 100, 200Hz + switch (number) + { + case USER_UART_PACKET_TYPE: + if (setUserPacketType(data, FALSE)) { + return TRUE; + } + break; + case USER_UART_PACKET_RATE: + userPacketRate = *(uint16_t*)data; + if (userPacketRate == 200 || userPacketRate == 100 || userPacketRate == 50){ + return TRUE; + } + break; + default: + break; + } + } else if (strstr(APP_VERSION_STRING, "RTK")){ + + } else if (strstr(APP_VERSION_STRING, "INS")){ + + } + + return FALSE; +} + +/** *************************************************************************** + * @name UpdateSystemParameter - updating of system configuration parameter based of user preferences + * @brief + * @param [in] number - parameter number in user configuration structure + * @param [in] data - value of the parameter in little endian format + * @retval len + ******************************************************************************/ +uint8_t UpdateSystemParameter(uint32_t number, uint8_t *data) +{ + uint8_t dataLen = 0; + BOOL fApply = TRUE; + + switch (number) + { + case USER_UART_PACKET_TYPE: + setUserPacketType(data, fApply); + dataLen = sizeof(gUserConfiguration.userPacketType); + break; + case USER_UART_PACKET_RATE: + configSetPacketRate(*(uint16_t*)data, fApply); + dataLen = 2; + break; + default: + break; + } + + return dataLen; +} + +/** *************************************************************************** + * @name UpdateSystemParameterValid + * @brief + * @param [in] number - parameter number in user configuration structure + * @param [in] data - value of the parameter in little endian format + * @retval error (1), no error (0) + ******************************************************************************/ +BOOL UpdateSystemParameterValid(uint32_t number, uint8_t *data, BOOL fApply) +{ + BOOL result = TRUE; + + if (number < USER_CRC || number > USER_LAST_SYSTEM_PARAM) { + return FALSE; + } + + switch (number) + { + case USER_UART_PACKET_TYPE: + result = setUserPacketType(data, fApply); + break; + case USER_UART_PACKET_RATE: + result = configSetPacketRate(*(uint16_t*)data, fApply); + break; + case USER_CRC: + case USER_DATA_SIZE: + return TRUE; + default: + result = FALSE; + break; + } + + if (result == TRUE){ + switch (number) + { + case USER_UART_PACKET_TYPE: + memcpy(gUserConfiguration.userPacketType, data, sizeof(gUserConfiguration.userPacketType)); + break; + case USER_UART_PACKET_RATE: + gUserConfiguration.userPacketRate = *(uint16_t*)data; + break; + default: + break; + } + } + + return result; +} + /** *************************************************************************** * @name UpdateUserParameter - updating of user configuration parameter based of user preferences * @brief @@ -354,29 +491,32 @@ BOOL UpdateEthNtripConfig(uint32_t number) * @name UpdateUserParam * @brief writes user data into user configuration structure, validates data if * required, updates system parameters - * * @param [in] pointer to userData payload in the packet * @retval N/A ******************************************************************************/ BOOL UpdateUserParam(userParamPayload *pld, uint8_t *payloadLen) { - uint8_t ret; + uint8_t ret = 0; int32_t result = 0; - - if (pld->paramNum < USER_MAX_PARAM) - { - ret = UpdateUserParameter(pld->paramNum, pld->parameter); - if (ret > 0) - { - UpdateEthNtripConfig(pld->paramNum); + + if (pld->paramNum < USER_MAX_PARAM) { + if (pld->paramNum <= USER_LAST_SYSTEM_PARAM) { + ret = UpdateSystemParameterValid(pld->paramNum, pld->parameter, FALSE); + if (ret) { + ret = UpdateSystemParameterValid(pld->paramNum, pld->parameter, TRUE); + } + } else { + ret = UpdateUserParameter(pld->paramNum, pld->parameter); + if (ret > 0) { + UpdateEthNtripConfig(pld->paramNum); + } } - else - { + + if (!ret){ result = INVALID_VALUE; } } - else - { + else { result = INVALID_PARAM; } @@ -395,19 +535,13 @@ BOOL UpdateUserParam(userParamPayload *pld, uint8_t *payloadLen) * @param [in] pointer to userData payload in the packet * @retval N/A ******************************************************************************/ -BOOL GetAllUserParams(allUserParamsPayload* pld, uint8_t *payloadLen) +BOOL GetAllUserParams(uint8_t *payload, uint8_t *payloadLen) { - uint32_t offset, i, numParams; - uint64_t *ptr = (uint64_t *)&gUserConfiguration; + uint16_t size = sizeof(UserConfigurationStruct); - numParams = sizeof(UserConfigurationStruct)/8; - - offset = 0; - for (i = 0; i < numParams; i++, offset++){ - pld->parameters[i] = ptr[offset]; - } + memcpy(payload, &gUserConfiguration, size); - *payloadLen = numParams* 8; + *payloadLen = size; return TRUE; } @@ -423,7 +557,7 @@ BOOL GetAllUserParams(allUserParamsPayload* pld, uint8_t *payloadLen) ******************************************************************************/ BOOL SaveUserConfig(void) { - int size; + uint16_t size; BOOL status; size = sizeof(UserConfigurationStruct); diff --git a/examples/OpenRTK330LI/RAWDATA/src/user/user_config.h b/examples/OpenRTK330LI/RAWDATA/src/user/user_config.h index 0271ec7..b3135d0 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/user/user_config.h +++ b/examples/OpenRTK330LI/RAWDATA/src/user/user_config.h @@ -36,9 +36,16 @@ limitations under the License. #pragma pack(4) typedef struct { - uint64_t dataCRC; /// CRC of user configuration structure CRC-16 - uint64_t dataSize; /// Size of the user configuration structure - + uint16_t dataCRC; /// CRC of user configuration structure CRC-16 + uint16_t dataSize; /// Size of the user configuration structure + + uint8_t userPacketType[2]; /// User packet to be continiously sent by unit + /// Packet types defined in structure UserOutPacketType + /// in file UserMessaging.h + + uint16_t userPacketRate; /// Packet rate for continiously output packet, Hz. + /// Valid settings are: 0 ,2, 5, 10, 20, 25, 50, 100, 200 + // place new arbitrary configuration parameters here // parameter size should even to 4 bytes // Add parameter offset in UserConfigParamOffset structure if validation or @@ -78,8 +85,9 @@ typedef enum { // add system parameters here and reassign USER_LAST_SYSTEM_PARAM (DO NOT CHANGE THIS!!!) USER_CRC = 0, USER_DATA_SIZE , // 1 - - USER_LAST_SYSTEM_PARAM = USER_DATA_SIZE, + USER_UART_PACKET_TYPE , + USER_UART_PACKET_RATE , + USER_LAST_SYSTEM_PARAM = USER_UART_PACKET_RATE, //***************************************************************************************** // add parameter enumerator here while adding new parameter in user UserConfigurationStruct USER_LEVER_ARM_BX , @@ -122,18 +130,23 @@ typedef enum { extern UserConfigurationStruct gUserConfiguration; -extern void userInitConfigureUnit(void); -extern BOOL UpdateUserParam(userParamPayload* pld, uint8_t *payloadLen); -extern BOOL SaveUserConfig(void); -extern BOOL RestoreDefaultUserConfig(void); -extern BOOL GetAllUserParams(allUserParamsPayload* pld, uint8_t *payloadLen); -extern uint8_t UpdateUserParameter(uint32_t number, uint8_t* data); - - -BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, int userConfigStructLen); -BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, int *userConfigSize); - -void initinsconfigfm(UserConfigurationStruct* p_gUserConfiguration); +void userInitConfigureUnit(void); +BOOL UpdateUserParam(userParamPayload* pld, uint8_t *payloadLen); +BOOL SaveUserConfig(void); +BOOL RestoreDefaultUserConfig(void); +BOOL GetAllUserParams(uint8_t *payload, uint8_t *payloadLen); +BOOL valid_user_config_parameter(uint8_t number, uint8_t *data); +void update_system_para(void); +void update_user_para(void); +BOOL UpdateSystemParameter(uint32_t number, uint8_t* data); +BOOL UpdateSystemParameterValid(uint32_t number, uint8_t *data, BOOL fApply); +uint8_t UpdateUserParameter(uint32_t number, uint8_t* data); + +BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, uint16_t userConfigSize); +BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, uint16_t *ptrUserConfigSize); + +uint8_t* get_user_packet_type(void); +uint16_t get_user_packet_rate(void); float* get_user_ins_para(); #endif /* _USER_CONFIG_H */ diff --git a/examples/OpenRTK330LI/RAWDATA/src/user/user_message.c b/examples/OpenRTK330LI/RAWDATA/src/user/user_message.c index 52ed508..243e52c 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/user/user_message.c +++ b/examples/OpenRTK330LI/RAWDATA/src/user/user_message.c @@ -38,6 +38,9 @@ limitations under the License. #include "timer.h" #include "rtklib_core.h" #include "rtcm.h" +#include "gnss_data_api.h" +#include "configuration.h" + /// List of allowed packet codes usr_packet_t userInputPackets[] = { @@ -136,6 +139,47 @@ void userPacketTypeToBytes(uint8_t bytes[]) } +/** *************************************************************************** + * @name setUserPacketType - set user output packet type + * @brief + * @param [in] packet type + * @retval - TRUE if success, FALSE otherwise + ******************************************************************************/ +BOOL setUserPacketType(uint8_t *data, BOOL fApply) +{ + int type = -1; + uint16_t *code = (uint16_t*)data; + uint16_t tmp; + BOOL result = TRUE; + + usr_packet_t *packet = &userOutputPackets[1]; + for(int i = 0; i < USR_OUT_MAX; i++, packet++){ + if(*code == *((uint16_t*)packet->packetCode)){ + type = packet->packetType; + break; + } + } + + switch(type){ + case USR_OUT_SCALED1: // packet with arbitrary data + _outputPacketType = type; + break; + default: + result = FALSE; + break; + } + + if (result == FALSE){ + return FALSE; + } + + tmp = (data[0] << 8) | data[1]; + + result = configSetOutputPacketCode(tmp, fApply); + + return result; +} + /****************************************************************************** * @name FillPingPacketPayload - API call ro prepare user output packet * @brief general handler @@ -209,7 +253,29 @@ static BOOL Fill_s1PacketPayload(uint8_t *payload, uint8_t *payloadLen) ******************************************************************************/ static BOOL Fill_posPacketPayload(uint8_t *payload, uint8_t *payloadLen) { - // pos_payload_t *pld = (pos_payload_t *)payload; + // need to be filled your own data + pos_payload_t *pld = (pos_payload_t *)payload; + + pld->week = g_gnss_sol.gps_week; + pld->timeOfWeek = (double) g_gnss_sol.gps_tow / 1000; + + pld->positionMode = g_gnss_sol.gnss_fix_type; + pld->latitude = g_gnss_sol.latitude * RAD_TO_DEG; + pld->longitude = g_gnss_sol.longitude * RAD_TO_DEG; + pld->height = g_gnss_sol.height; + pld->numberOfSVs = g_gnss_sol.num_sats; + pld->hdop = g_gnss_sol.dops[2]; + + pld->velocityMode = g_gnss_sol.vel_mode; + pld->velocityNorth = g_gnss_sol.vel_ned[0]; + pld->velocityEast = g_gnss_sol.vel_ned[1]; + pld->velocityDown = g_gnss_sol.vel_ned[2]; + + pld->insStatus = 0; + pld->insPositionType = 0; + pld->roll = 0; + pld->pitch = 0; + pld->heading = 0; *payloadLen = sizeof(pos_payload_t); return TRUE; @@ -224,9 +290,80 @@ static BOOL Fill_posPacketPayload(uint8_t *payload, uint8_t *payloadLen) ******************************************************************************/ static BOOL Fill_skyviewPacketPayload(uint8_t *payload, uint8_t *payloadLen) { - // skyview_payload_t *pld = (skyview_payload_t *)payload; + // need to be filled your own data + skyview_payload_t *pld = (skyview_payload_t *)payload; + obs_t* ptr_rover_obs = &g_ptr_gnss_data->rov; + uint8_t sys = 0; + uint8_t maxn = ptr_rover_obs->n; + static uint8_t index = 0; + uint8_t n = 0; + + if (maxn - index*10 <= 0) + { + index = 0; + *payloadLen = 0; + } + else if (maxn - index*10 > 10) + { + n = (index+1)*10; + *payloadLen = sizeof(skyview_payload_t) * 10; + } + else + { + n = maxn; + *payloadLen = sizeof(skyview_payload_t) * (maxn-index*10); + } + + for (uint8_t i = index*10; i < n; i++) + { + pld->timeOfWeek = (double) g_gnss_sol.gps_tow / 1000; + + pld->satelliteId = ptr_rover_obs->data[i].sat; + sys = satsys(ptr_rover_obs->data[i].sat, NULL); + if (sys == _SYS_GPS_) + { + pld->systemId = 0; + } + else if (sys == _SYS_GLO_) + { + pld->systemId = 1; + } + else if (sys == _SYS_GAL_) + { + pld->systemId = 2; + } + else if (sys == _SYS_QZS_) + { + pld->systemId = 3; + } + else if (sys == _SYS_BDS_) + { + pld->systemId = 4; + } + else if (sys == _SYS_SBS_) + { + pld->systemId = 5; + } + else + { + pld->systemId = 111; + } + pld->antennaId = 0; // 0,1... + pld->l1cn0 = ptr_rover_obs->data[i].SNR[0] / 4; + pld->l2cn0 = ptr_rover_obs->data[i].SNR[1] / 4; + + pld->azimuth = 0; + pld->elevation = 0; + + pld++; + } + + index++; + if (n == maxn) + { + index = 0; + } - *payloadLen = sizeof(skyview_payload_t) * 10; return true; } @@ -268,7 +405,7 @@ int HandleUserInputPacket(UcbPacketStruct *ptrUcbPacket) } break; case USR_IN_GET_ALL: - if(!GetAllUserParams((allUserParamsPayload*)ptrUcbPacket->payload, &ptrUcbPacket->payloadLength)){ + if(!GetAllUserParams(ptrUcbPacket->payload, &ptrUcbPacket->payloadLength)){ valid = FALSE; } break; diff --git a/examples/OpenRTK330LI/RAWDATA/src/user/user_message.h b/examples/OpenRTK330LI/RAWDATA/src/user/user_message.h index e339ec3..4c076d8 100644 --- a/examples/OpenRTK330LI/RAWDATA/src/user/user_message.h +++ b/examples/OpenRTK330LI/RAWDATA/src/user/user_message.h @@ -32,42 +32,17 @@ limitations under the License. #include "ucb_packet.h" - -#define MAX_NUMBER_OF_USER_PARAMS_IN_THE_PACKET 30 - // total size of user packet structure should not exceed 255 bytes #pragma pack(1) -typedef struct -{ - uint8_t packetPayload[252]; // maximum 252 bytes -} userPacket; - -// example of user payload structure -typedef struct -{ - uint32_t numParams; // number of consecutive parameters to update (little endian) - uint32_t paramOffset; // parameter number in parameters structure (little endian) - uint64_t parameters[MAX_NUMBER_OF_USER_PARAMS_IN_THE_PACKET]; // up to 30 64-bit parameters (little endian) -} userConfigPayload; - // example of user payload structure typedef struct { uint32_t paramNum; // parameter number in parameters structure (little endian) uint8_t parameter[64]; // up to 30 64-bit parameters (little endian) } userParamPayload; -// example of user payload structure -typedef struct { - uint64_t parameters[MAX_NUMBER_OF_USER_PARAMS_IN_THE_PACKET]; // up to 30 64-bit parameters (little endian) -} allUserParamsPayload; - #pragma pack() -#define USER_OK 0x00 -#define USER_NAK 0x80 -#define USER_INVALID 0x81 - typedef enum { USR_IN_NONE = 0, @@ -93,7 +68,7 @@ typedef enum { // payload structure of alternative IMU data message typedef struct { - int32_t week; + uint32_t week; double timeOfWeek; float accel_g[3]; float rate_dps[3]; @@ -102,27 +77,23 @@ typedef struct { // payload structure of standard pos data message typedef struct { - uint32_t systemTime; + uint32_t week; double timeOfWeek; uint32_t positionMode; double latitude; double longitude; - double ellipsoidalHeight; - double mslHeight; - double positionRMS; + double height; + uint32_t numberOfSVs; + float hdop; uint32_t velocityMode; float velocityNorth; float velocityEast; float velocityDown; - float velocityRMS; uint32_t insStatus; uint32_t insPositionType; float roll; float pitch; float heading; - float rollRMS; - float pitchRMS; - float headingRMS; } pos_payload_t; // payload structure of standard skyview data message @@ -140,11 +111,13 @@ typedef struct { #pragma pack() -extern int checkUserPacketType(uint16_t receivedCode); -extern int checkUserOutPacketType(uint16_t receivedCode); -extern void userPacketTypeToBytes(uint8_t bytes[]); +int checkUserPacketType(uint16_t receivedCode); +int checkUserOutPacketType(uint16_t receivedCode); +void userPacketTypeToBytes(uint8_t bytes[]); + +BOOL setUserPacketType(uint8_t *data, BOOL fApply); -extern int HandleUserInputPacket (UcbPacketStruct *ptrUcbPacket); -extern BOOL HandleUserOutputPacket(uint8_t *payload, uint8_t *payloadLen); +int HandleUserInputPacket (UcbPacketStruct *ptrUcbPacket); +BOOL HandleUserOutputPacket(uint8_t *payload, uint8_t *payloadLen); #endif /* _USER_MESSAGE_H */ diff --git a/examples/OpenRTK330LI/RTK/.gitignore b/examples/OpenRTK330LI/RTK/.gitignore new file mode 100644 index 0000000..163190d --- /dev/null +++ b/examples/OpenRTK330LI/RTK/.gitignore @@ -0,0 +1,27 @@ + +.pio/** +.pio/libdeps/** +.vscode/** +.pioenvs/** +.piolibdeps/** +*.map +.settings +.cproject +.project + + +.pioenvs +.vscode/ +.vscode/*.json +.vscode/.*.DB +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +msvc/*.rtcm3 +openrtk_offline/*.csv +openrtk_offline/*.gga +openrtk_offline/*.kml +openrtk_offline/*.dat +openrtk_offline/*.ini +openrtk_offline/*/ +results/ \ No newline at end of file diff --git a/examples/OpenRTK330LI/RTK/.travis.yml b/examples/OpenRTK330LI/RTK/.travis.yml new file mode 100644 index 0000000..7c486f1 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/examples/OpenRTK330LI/RTK/include/FreeRTOSConfig.h b/examples/OpenRTK330LI/RTK/include/FreeRTOSConfig.h new file mode 100644 index 0000000..a9a362a --- /dev/null +++ b/examples/OpenRTK330LI/RTK/include/FreeRTOSConfig.h @@ -0,0 +1,193 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +/* Ensure stdint is only used by the compiler, and not the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + #include + extern uint32_t SystemCoreClock; +#endif + + +#define TASK_GNSS_RTK_STACK (20*1024) +#define TASK_GNSS_DATA_ACQ_STACK (6*1024) +#define TASK_IMU_DATA_ACQ_STACK (5*1024) +#define TASK_ETHERNET_STACK (2*1024) + +#define TOTAL_STACK (TASK_GNSS_RTK_STACK + TASK_GNSS_DATA_ACQ_STACK + TASK_IMU_DATA_ACQ_STACK + TASK_ETHERNET_STACK)*4 +#define MIN_FREERTOS_HEAP_SIZE (15*1024) + + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES (7) +#define configMINIMAL_STACK_SIZE ((uint16_t)512) +#define configTOTAL_HEAP_SIZE ((size_t)(TOTAL_STACK + MIN_FREERTOS_HEAP_SIZE)) +#define configMAX_TASK_NAME_LEN (30) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configGENERATE_RUN_TIME_STATS 0 +#define configAPPLICATION_ALLOCATED_HEAP 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES (4) + +/* Software timer definitions. */ +#define configUSE_TIMERS 0 +#define configTIMER_TASK_PRIORITY (2) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 0 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 + +#define INCLUDE_eTaskGetState 1 // info +#define INCLUDE_xTaskGetHandle 1 // info + + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 4 /* 15 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 + + +//#define configKERNEL_INTERRUPT_PRIORITY ( 0x01 << 4 ) /* Priority 15, or 255 as only the top four bits are implemented. This is the lowest priority. */ +//#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 0x01 << 4 ) /* Priority 5, or 80 as only the top four bits are implemented. */ + + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS + standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler + +/* IMPORTANT: This define MUST be commented when used with STM32Cube firmware, + to prevent overwriting SysTick_Handler defined within STM32Cube HAL */ +//#define xPortSysTickHandler SysTick_Handler +#define osSystickHandler SysTick_Handler + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/examples/OpenRTK330LI/RTK/include/app_version.h b/examples/OpenRTK330LI/RTK/include/app_version.h new file mode 100644 index 0000000..771e946 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/include/app_version.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * @file app_version.h + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + * @brief Version definition based on UCB serial protocol. + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ +#ifndef _APP_VERSION_H +#define _APP_VERSION_H + +#define APP_VERSION_STRING "OpenRTK330L RAWDATA App 0.1.1" + +#define PRODUCT_NAME_STRING "OpenRTK330L" + +#endif diff --git a/examples/OpenRTK330LI/RTK/include/main.h b/examples/OpenRTK330LI/RTK/include/main.h new file mode 100644 index 0000000..a3c53b2 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/include/main.h @@ -0,0 +1,81 @@ +/***************************************************************************** + * @file main.h + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + * + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef _MAIN_H +#define _MAIN_H + +/* Includes ------------------------------------------------------------------*/ + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private define ------------------------------------------------------------*/ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#include +#include + +#include "cmsis_os.h" +#include "portmacro.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + +void _Error_Handler(char *, int); +#define Error_Handler() _Error_Handler(__FILE__, __LINE__) + +void TaskDataAcquisition(void const *argument); +void GnssDataAcqTask(void const *argument); +void EthTask(void const *argument); +void RTKTask(void const *argument); + +extern osSemaphoreId g_sem_imu_data_acq; +extern osSemaphoreId g_sem_rtk_start; +extern osSemaphoreId g_sem_rtk_finish; + + +#ifdef __cplusplus +} +#endif + +#define CCMRAM __attribute__((section(".ccmram"))) + +#endif /* _MAIN_H */ + diff --git a/examples/OpenRTK330LI/RTK/platformio.ini b/examples/OpenRTK330LI/RTK/platformio.ini new file mode 100644 index 0000000..3090f97 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/platformio.ini @@ -0,0 +1,45 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + +[platformio] +description = + Open source firmware for OpenRTK330 module that features a multi-frequency and multi-constellation Global Navigation Satellite System (GNSS) chipset + and a triple-redundant high performance 6-axis MEMS Inertial Measurement Unit (IMU). This RTK App includes a proprietary GNSS RTK positioning engine for high precision positioning applications, in addition to raw GNSS data in RTCMv3 format and + raw factory calibrated IMU data outputs. +[env:OpenRTK] +platform = aceinna_imu +board = OpenRTK +lib_archive = false + +lib_deps = OpenRTK-base-library@1.0.5 + +build_flags = + + -D STM32F469xx + -D ARM_MATH_CM4 + -D __FPU_PRESENT + -D USE_HAL_DRIVER + + -I src + -I src/user + -I include + + -I I1587 + -O1 + -Wno-comment + -Wl,-Map,OpenRTK.map + +; -Wl,-Tstm32f43x.ld + -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 + +; upload_protocol = jlink +; debug_tool = jlink + + diff --git a/examples/OpenRTK330LI/RTK/src/eth_task.c b/examples/OpenRTK330LI/RTK/src/eth_task.c new file mode 100644 index 0000000..64f0f3f --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/eth_task.c @@ -0,0 +1,49 @@ +/***************************************************************************** + * @file eth_task.c + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ +#include + +#include "FreeRTOS.h" +#include "lwip_comm.h" +#include "ntrip_client.h" + + +/** *************************************************************************** + * @name EthTask() + * @brief Embedded server,sending and receiving data from Internet + * @param N/A + * @retval N/A + ******************************************************************************/ +void EthTask(void const *argument) +{ + fifo_init(&ntrip_tx_fifo, ntripTxBuf, NTRIP_TX_BUFSIZE); + fifo_init(&ntrip_rx_fifo, ntripRxBuf, NTRIP_RX_BUFSIZE); + + ethernet_init(); // init ethnernet + + while (1) + { + NTRIP_interface(); + } +} diff --git a/examples/OpenRTK330LI/RTK/src/gnss_data_acq_task.c b/examples/OpenRTK330LI/RTK/src/gnss_data_acq_task.c new file mode 100644 index 0000000..c73940e --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/gnss_data_acq_task.c @@ -0,0 +1,206 @@ +/** *************************************************************************** + * @file gnss_data_acq_task.c handle GPS data, make sure the GPS handling function gets + * called on a regular basis + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + *****************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +************************************************************************/ +#include + +#include "gnss_data_api.h" +#include "uart.h" +#include "bt_packet.h" +#include "ntrip_client.h" +#include "led.h" + +#define CCMRAM __attribute__((section(".ccmram"))) + +extern volatile mcu_time_base_t g_MCU_time; +static uint16_t GpsRxLen; + +extern uint8_t g_pps_flag; + +CCMRAM gnss_raw_data_t g_gnss_data = {0}; +gnss_raw_data_t *g_ptr_gnss_data = &g_gnss_data; +uint8_t gnss_signal_flag = 0; //1:Satellite signal availability + +uint8_t stnID = 0; +volatile mcu_time_base_t g_obs_rcv_time; + +/** *************************************************************************** + * @name _handleGpsMessages() + * @brief Decode RTCM data and store it in g_gnss_data + * @param uint8_t *RtcmBuff:RTCM data flow + * int length:RTCM data lenth + * @retval N/A + ******************************************************************************/ +static void _handleGpsMessages(uint8_t *RtcmBuff, int length) +{ + int pos = 0; + gnss_rtcm_t *rtcm = &g_gnss_data.rtcm; + obs_t *obs = rtcm->obs + stnID; + rtcm_t *rcv = rtcm->rcv + stnID; + + int8_t ret_val = 0; + static uint8_t base_cnt = 0; + + base_cnt ++; + if(base_cnt > 200) + { + /* If no base station signal, RED LED is off */ + LED_RTCM_OFF; + } + + while (length) + { + length--; + ret_val = input_rtcm3(RtcmBuff[pos++], stnID, rtcm); + /* relocated from rtcm.c */ + if (stnID == BASE && ret_val == 1) //Base station data reception completed + { + clear_ntrip_stream_count(); + LED_RTCM_TOOGLE(); + base_cnt = 0; + } + + if (ret_val == 1) + { + if (g_pps_flag == 0) + { + g_MCU_time.time = obs->time.time; + g_MCU_time.msec = (obs->time.sec * 1000); + } + + if (obs->pos[0] == 0.0 || obs->pos[1] == 0.0 || obs->pos[2] == 0.0) + { + /* do not output */ + } + else if (stnID == ROVER) + { + g_obs_rcv_time = g_MCU_time; + static gtime_t timeCpy; + if ((timeCpy.sec == obs->time.sec && timeCpy.time == obs->time.time) || obs->n < 4) + { + gnss_signal_flag = 0; + } + else + { + timeCpy = obs->time; + if (obs->n > 10) + gnss_signal_flag = 1; + } + uint8_t res = osSemaphoreWait(g_sem_rtk_finish, 0); + if (res == osOK && gnss_signal_flag) + { + g_ptr_gnss_data->rov = *obs; + g_ptr_gnss_data->ref = *(rtcm->obs + BASE); + g_ptr_gnss_data->nav = rtcm->nav; + osSemaphoreRelease(g_sem_rtk_start); + } + } + } + } +} +/** *************************************************************************** + * @name GnssDataAcqTask() + * @brief Satellite data acquisition task,include base and rover + * Get the base data from UART_GPS,and get the base data from UART_BT or + * ntrip_rx_fifo. + * @param N/A + * @retval N/A + ******************************************************************************/ +void GnssDataAcqTask(void const *argument) +{ + int ret = 0; + uint8_t Gpsbuf[GPS_BUFF_SIZE]; + uint8_t bt_buff[GPS_BUFF_SIZE]; + + memset(g_ptr_gnss_data, 0, sizeof(gnss_raw_data_t)); + + while (1) + { + // UBaseType_t uxHighWaterMark; + // uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + if (!is_ntrip_interactive()) + { + int BtLen = 0; + BtLen = uart_read_bytes(UART_BT, bt_buff, GPS_BUFF_SIZE, 0); + if (BtLen) + { + if(uart_sem_wait(UART_BT,0) == RTK_SEM_OK) + { + ret = bt_uart_parse(bt_buff); + } + if (ret != RTK_JSON) + { + stnID = BASE; + _handleGpsMessages(bt_buff, BtLen); + //send base from DEBUG port + uart_write_bytes(UART_DEBUG, (char*)bt_buff, BtLen, 1); + } + } + } + else + { + int ethRxLen = 0; + ethRxLen = fifo_get(&ntrip_rx_fifo, bt_buff, GPS_BUFF_SIZE); + if (ethRxLen) + { + stnID = BASE; + _handleGpsMessages(bt_buff, ethRxLen); + //send base from DEBUG port + uart_write_bytes(UART_DEBUG, (char*)bt_buff, ethRxLen, 1); + } + } + + update_fifo_in(UART_GPS); + GpsRxLen = uart_read_bytes(UART_GPS, Gpsbuf, GPS_BUFF_SIZE, 0); + if (GpsRxLen) + { + stnID = ROVER; + _handleGpsMessages(Gpsbuf, GpsRxLen); + } + // uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + // printf("uxhigh=%d\r\n",TASK_GNSS_DATA_STACK-uxHighWaterMark); + OS_Delay(10); + } +} + +/** *************************************************************************** + * @name get_obs_time() + * @brief Acquisition of satellite time + * @param N/A + * @retval N/A + ******************************************************************************/ +time_t get_obs_time() +{ + return g_ptr_gnss_data->rtcm.obs[0].time.time; +} + +/** *************************************************************************** + * @name get_gnss_signal_flag() + * @brief obtain get_gnss_signal_flag + * @param N/A + * @retval N/A + ******************************************************************************/ +uint8_t get_gnss_signal_flag() +{ + return gnss_signal_flag; +} diff --git a/examples/OpenRTK330LI/RTK/src/imu_data_acq_task.c b/examples/OpenRTK330LI/RTK/src/imu_data_acq_task.c new file mode 100644 index 0000000..2b3007c --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/imu_data_acq_task.c @@ -0,0 +1,90 @@ +/***************************************************************************** + * @file imu_data_acq_task.c + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + * sensor data acquisition task runs at 50Hz, gets the data for each sensor + * and applies available calibration + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ + +#include "sensorsAPI.h" +#include "calibrationAPI.h" +#include "configurationAPI.h" +#include "commAPI.h" +#include "uart.h" +#include "bsp.h" +#include "timer.h" + +mcu_time_base_t imu_time; + +/** *************************************************************************** + * @name TaskDataAcquisition() + * @brief Get the sensor data at the specified frequency (based on the + * configuration of the accelerometer rate-sensor). Process and provide + * information to the user via the UART. + * @param N/A + * @retval N/A + ******************************************************************************/ +void TaskDataAcquisition(void const *argument) +{ + int res; + + res = InitSensors(); + InitSensorsData(); + + while (1) + { + //UBaseType_t uxHighWaterMark; + //uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + + res = osSemaphoreWait(g_sem_imu_data_acq, 1000); + if (res != osOK) + { + continue; + // Wait timeout expired. Something wrong wit the data acq system + // Process timeout here + } + imu_time = g_MCU_time; + + NSS_Toggle(); + SampleSensorsData(); + ApplyFactoryCalibration(); + + /* + Add the INS algorithm here + double accels[3]; + GetAccelData_g_AsDouble(accels); + double rates[3]; + GetRateData_radPerSec_AsDouble(rates); + imu_time:imu time + + INS_Algorithm(); + */ + + ProcessUserCommands(); + + SendContinuousPacket(); + + //uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + //printf("uxhigh=%d\r\n",TASK_IMU_DATA_ACQ_STACK-uxHighWaterMark); + } +} + diff --git a/examples/OpenRTK330LI/RTK/src/main.c b/examples/OpenRTK330LI/RTK/src/main.c new file mode 100644 index 0000000..9035dcd --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/main.c @@ -0,0 +1,178 @@ + +/** *************************************************************************** + * @file main.c + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + * main is the center of the system universe, it all starts here. And never ends. + * entry point for system (pins, clocks, interrupts), data and task initialization. + * contains the main processing loop. - this is a standard implementation + * which has mainly os functionality in the main loop + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ + +#define __MAIN +#include "main.h" +#include "configureGPIO.h" +#include "bsp.h" +#include "uart.h" +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "calibrationAPI.h" +#include "configurationAPI.h" +#include "user_config.h" +#include "timer.h" + + +osThreadId IMU_DATA_ACQ_TASK; +osThreadId GNSS_RTK_TASK; +osThreadId GNSS_DATA_ACQ_TASK; +osThreadId ETHERNET_TASK; + +osSemaphoreDef(IMU_DATA_ACQ_SEM); +osSemaphoreDef(RTK_START_SEM); +osSemaphoreDef(RTK_FINISH_SEM); + + +osSemaphoreId g_sem_imu_data_acq; +osSemaphoreId g_sem_rtk_start; +osSemaphoreId g_sem_rtk_finish; + +/** *************************************************************************** + * @name CreateTasks() + * @brief CreateTasks + * @param N/A + * @retval N/A + ******************************************************************************/ +void CreateTasks(void) +{ + osThreadId iD; + + /// Create RTOS tasks: + // dacq task + g_sem_imu_data_acq = osSemaphoreCreate(osSemaphore(IMU_DATA_ACQ_SEM), 1); + g_sem_rtk_start = osSemaphoreCreate(osSemaphore(RTK_START_SEM), 1); + g_sem_rtk_finish = osSemaphoreCreate(osSemaphore(RTK_FINISH_SEM), 1); + + osThreadDef(IMU_DATA_ACQ_TASK, TaskDataAcquisition, osPriorityRealtime, 0, TASK_IMU_DATA_ACQ_STACK); + iD = osThreadCreate(osThread(IMU_DATA_ACQ_TASK), NULL); + if (iD == NULL) + { + while (1) + ; + } + + osThreadDef(GNSS_DATA_ACQ_TASK, GnssDataAcqTask, osPriorityBelowNormal, 0, TASK_GNSS_DATA_ACQ_STACK); + iD = osThreadCreate(osThread(GNSS_DATA_ACQ_TASK), NULL); + if (iD == NULL) + { + while (1) + ; + } + + osThreadDef(GNSS_RTK_TASK, RTKTask, osPriorityLow, 0, TASK_GNSS_RTK_STACK); + iD = osThreadCreate(osThread(GNSS_RTK_TASK), NULL); + if (iD == NULL) + { + while (1) + ; + } + + osThreadDef(ETHERNET_TASK, EthTask, osPriorityNormal, 0, TASK_ETHERNET_STACK); + iD = osThreadCreate(osThread(ETHERNET_TASK), NULL); + if (iD == NULL) + { + while (1) + ; + } + +} + + +/** *************************************************************************** + * @name main() + * @brief mian + * @param N/A + * @retval N/A + ******************************************************************************/ +int main(void) +{ + // Initialize processor and board-related signals + BoardInit(); + MX_DMA_Init(); + + uart_driver_install(UART_DEBUG,&uart_debug_rx_fifo,&huart_debug,460800); + uart_driver_install(UART_USER,&uart_user_rx_fifo,&huart_user,460800); + uart_driver_install(UART_GPS,&uart_gps_rx_fifo,&huart_gps,460800); + uart_driver_install(UART_BT,&uart_bt_rx_fifo,&huart_bt,460800); + + delay_ms(10000); //Delay, in case the usb driver is not installed on computer + + ResetForEnterBootMode(); // normal or iap mode + + InitFactoryCalibration(); + ApplyFactoryConfiguration(); + userInitConfigureUnit(); + + CreateTasks(); + MX_TIM_SENSOR_Init(); + + /* Infinite loop */ + while ( 1 ) + { + + osKernelStart(); + + // We should never get here as control is now taken by the scheduler + for (;;) + ; + + } +} + + + +/** + * @brief This function is executed in case of error occurrence. + * @param file: The file name as string. + * @param line: The line in file as a number. + * @retval None + */ +void _Error_Handler(char *file, int line) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ) +{ + while(1); +} + +void vApplicationMallocFailedHook( void ) +{ + while(1); +} + + diff --git a/examples/OpenRTK330LI/RTK/src/rtk_task.c b/examples/OpenRTK330LI/RTK/src/rtk_task.c new file mode 100644 index 0000000..fd2a100 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/rtk_task.c @@ -0,0 +1,82 @@ +/** *************************************************************************** + * @file rtk_task.c + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + *****************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.*/ + +#include + +#include "gnss_data_api.h" +#include "uart.h" +#include "led.h" +#include "ntrip_client.h" +#include "utils.h" +#include "rtk_api.h" + +gnss_solution_t g_gnss_sol = {0}; +gnss_solution_t *g_ptr_gnss_sol = &g_gnss_sol; + +extern gnss_raw_data_t *g_ptr_gnss_data; + + + +/** *************************************************************************** + * @name RTKTask() + * @brief RTK Algorithm task + * @param N/A + * @retval N/A + ******************************************************************************/ +void RTKTask(void const *argument) +{ + // UBaseType_t uxHighWaterMark; + // uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + obs_t* ptr_rover_obs = &g_ptr_gnss_data->rtcm.obs[0]; + + uint8_t res = osSemaphoreWait(g_sem_rtk_start, 0); + while (1) + { + uint8_t res = osSemaphoreWait(g_sem_rtk_start, 10); + if (res != osOK) + { + osSemaphoreRelease(g_sem_rtk_finish); + continue; + /* Wait timeout expired. Something wrong wit the dacq system + Process timeout here */ + } + LED1_Toggle(); + + rtk_algorithm(); + + // use rover obs to make gga and pull base rtcm data + // print_pos_gga_util(ptr_rover_obs->time, ptr_rover_obs->pos, ptr_rover_obs->n, 1, 1.0, 0.0, gga_buff); + + //uart_write_bytes(UART_DEBUG, gga_buff, strlen(gga_buff), 1); + //send gga from Bluetooth + // uart_write_bytes(UART_BT, gga_buff, strlen(gga_buff), 1); + //send gga from Internet + // ntrip_push_tx_data((uint8_t*)gga_buff, strlen(gga_buff)); + + osSemaphoreRelease(g_sem_rtk_finish); + + // uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + // printf("uxhigh=%d\r\n",TASKRTD_STACK-uxHighWaterMark); + } +} + diff --git a/examples/OpenRTK330LI/RTK/src/user/user_config.c b/examples/OpenRTK330LI/RTK/src/user/user_config.c new file mode 100644 index 0000000..2f4b4d5 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/user/user_config.c @@ -0,0 +1,595 @@ +/** *************************************************************************** + * @file user_config.c + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ +#include "stm32f4xx_hal.h" +#include "string.h" +#include "app_version.h" +#include "platformAPI.h" +#include "eepromAPI.h" +#include "ntrip_client.h" +#include "user_config.h" +#include "Indices.h" +#include "configurationAPI.h" +#include "osapi.h" +#include "crc16.h" + +// Default user configuration structure +// Do Not remove - just add extra parameters if needed +// Change default settings if desired +const UserConfigurationStruct gDefaultUserConfig = { + .dataCRC = 0, + .dataSize = sizeof(UserConfigurationStruct), + .userPacketType = "s1", + .userPacketRate = 200, + // add default parameter values here, if desired + .leverArmBx = 0.0, + .leverArmBy = 0.0, + .leverArmBz = 0.0, + .pointOfInterestBx = 0.0, + .pointOfInterestBy = 0.0, + .pointOfInterestBz = 0.0, + .rotationRbvx = 0.0, + .rotationRbvy = 0.0, + .rotationRbvz = 0.0, + + // ethnet + .ethMode = ETHMODE_DHCP, + .staticIp = {192, 168, 1, 110}, + .netmask = {255, 255, 255, 0}, + .gateway = {192, 168, 1, 1}, + .mac = {2, 0, 0, 0, 0, 0}, + + // ntrip + .ip = "106.12.40.121", // rtk.ntrip.qxwz.com // rtk.aceinna.com + .port = 2201, + .mountPoint = "RTK", + .username = "ymj_123", + .password = "SIGEMZOOMQ1JDJI3", +}; + +CCMRAM UserConfigurationStruct gUserConfiguration; +const uint8_t *pUserConfigInFlash = (uint8_t *)APP_USER_CONFIG_ADDR; +BOOL configValid = FALSE; + +uint8_t* get_user_packet_type(void) +{ + return gUserConfiguration.userPacketType; +} + +uint16_t get_user_packet_rate(void) +{ + return gUserConfiguration.userPacketRate; +} + +float* get_user_ins_para() +{ + return &(gUserConfiguration.leverArmBx); +} + + +/** *************************************************************************** + * @name EEPROM_ValidateUserConfig - validating of user configuration structure + * in EEPROM + * changes should be made to gUserConfiguration before calling this function. + * @brief + * + * @param [in] userConfigSize - pointer to variable, which initialized with the + * size of user configuration structure + * @retval error (0), no error (1) + ******************************************************************************/ +BOOL EEPROM_ValidateUserConfig(uint16_t *userConfigSize) +{ + uint16_t crc, configCrc, size; + uint16_t *dataPtr = (uint16_t*)pUserConfigInFlash; + + configCrc = dataPtr[0]; // CRC + size = dataPtr[1]; // Total Number of bytes in user config structure in eeprom + if(size != *userConfigSize){ // check if image fits into user storage in RAM + return FALSE; + } + crc = CalculateCRC((uint8_t*)pUserConfigInFlash + 2, size - 2); + if(crc == configCrc){ + return TRUE; + } + return FALSE; // +} + +/** *************************************************************************** + * @name loadUserConfigInEeprom - loading user configuration structure from + * predefined flash sector + * changes should be made to gUserConfiguration before calling this function. + * @brief + * + * @param [in] N/A + * @retval error (0), no error (1) + ******************************************************************************/ +BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, uint16_t *ptrUserConfigSize) +{ + memcpy(ptrToUserConfigInRam, pUserConfigInFlash, *ptrUserConfigSize); + return TRUE; +} + +/** *************************************************************************** + * @name EEPROM_SaveUserConfig - saving of user configuration structure un the + * predefined flash sector + * changes should be made to gUserConfiguration before calling this function. + * @brief + * + * @param [in] N/A + * @retval error (0), no error (1) + ******************************************************************************/ +BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, uint16_t userConfigSize) +{ + HAL_StatusTypeDef status = HAL_OK; + FLASH_EraseInitTypeDef pEraseInit; + uint32_t PageError; + uint16_t offset = 0; + uint16_t num = userConfigSize; + uint32_t start = (uint32_t)pUserConfigInFlash; + uint32_t *dataPtr = (uint32_t*)ptrToUserConfigStruct; + uint16_t *paramPtr = (uint16_t*)ptrToUserConfigStruct; + + paramPtr[1] = num; // Total size of user config structure, including Crc and data size + paramPtr[0] = CalculateCRC((uint8_t*)ptrToUserConfigStruct + 2, num - 2); + // calculate CRC over user configuration structure + + ENTER_CRITICAL(); + + status = HAL_FLASH_Unlock(); + __HAL_FLASH_CLEAR_FLAG(0xffff); + + pEraseInit.Banks = FLASH_BANK_1; + pEraseInit.Sector = FLASH_SECTOR_10; + pEraseInit.NbSectors = 1; + pEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3; + pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; + + status = HAL_FLASHEx_Erase(&pEraseInit, &PageError); + if (status != HAL_OK) + { + EXIT_CRITICAL(); + return FALSE; + } + + while (num > 0) + { + status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, start + offset, *dataPtr++); + if (status != HAL_OK) + { + EXIT_CRITICAL(); + return FALSE; + } + offset += 4; + num -= 4; + } + + HAL_FLASH_Lock(); + + EXIT_CRITICAL(); + + return TRUE; +} + + + +void userInitConfigureUnit(void) +{ + uint16_t size = sizeof(gUserConfiguration); + + // Validate checksum of user configuration structure + configValid = EEPROM_ValidateUserConfig(&size); +#ifdef DEVICE_DEBUG + printf("configValid = %d\r\n", configValid); +#endif + + if (configValid == TRUE) { + // Here we have validated User configuration image. + // Load it from eeprom into ram on top of the default configuration + EEPROM_LoadUserConfig((uint8_t*)&gUserConfiguration, &size); + } else { + RestoreDefaultUserConfig(); + } + + update_system_para(); + + update_user_para(); +/* + printf("gUserConfiguration.leverArmBx = %f\r\n",gUserConfiguration.leverArmBx); + printf("gUserConfiguration.leverArmBy = %f\r\n",gUserConfiguration.leverArmBy); + printf("gUserConfiguration.leverArmBz = %f\r\n",gUserConfiguration.leverArmBz); + printf("gUserConfiguration.pointOfInterestBx = %f\r\n",gUserConfiguration.pointOfInterestBx); + printf("gUserConfiguration.pointOfInterestBy = %f\r\n",gUserConfiguration.pointOfInterestBy); + printf("gUserConfiguration.pointOfInterestBz = %f\r\n",gUserConfiguration.pointOfInterestBz); + printf("gUserConfiguration.rotationRbvx = %f\r\n",gUserConfiguration.rotationRbvx); + printf("gUserConfiguration.rotationRbvy = %f\r\n",gUserConfiguration.rotationRbvy); + printf("gUserConfiguration.rotationRbvz = %f\r\n",gUserConfiguration.rotationRbvz); +*/ +} + +void update_system_para(void) +{ + uint8_t *ptrSys = (uint8_t*)gUserConfiguration.userPacketType; + uint8_t offset = 0; + uint32_t i; + + for (i = USER_UART_PACKET_TYPE; i <= USER_LAST_SYSTEM_PARAM; i++) { + ptrSys = ptrSys + offset; + offset = UpdateSystemParameter(i, ptrSys); + } +} + +void update_user_para(void) +{ + uint8_t *ptrUser = (uint8_t*)&gUserConfiguration.leverArmBx; + uint8_t offset = 0; + uint32_t i; + + for (i = USER_LAST_SYSTEM_PARAM + 1; i < USER_MAX_PARAM; i++) { + ptrUser = ptrUser + offset; + offset = UpdateUserParameter(i, ptrUser); + } +} + +BOOL valid_user_config_parameter(uint8_t number, uint8_t *data) +{ + uint16_t userPacketRate; + // judge of APP VERSION + if (strstr(APP_VERSION_STRING, "RAWDATA")){ + // RAWDATA app always out 's1' with 50, 100, 200Hz + switch (number) + { + case USER_UART_PACKET_TYPE: + if (setUserPacketType(data, FALSE)) { + return TRUE; + } + break; + case USER_UART_PACKET_RATE: + userPacketRate = *(uint16_t*)data; + if (userPacketRate == 200 || userPacketRate == 100 || userPacketRate == 50){ + return TRUE; + } + break; + default: + break; + } + } else if (strstr(APP_VERSION_STRING, "RTK")){ + + } else if (strstr(APP_VERSION_STRING, "INS")){ + + } + + return FALSE; +} + +/** *************************************************************************** + * @name UpdateSystemParameter - updating of system configuration parameter based of user preferences + * @brief + * @param [in] number - parameter number in user configuration structure + * @param [in] data - value of the parameter in little endian format + * @retval len + ******************************************************************************/ +uint8_t UpdateSystemParameter(uint32_t number, uint8_t *data) +{ + uint8_t dataLen = 0; + BOOL fApply = TRUE; + + switch (number) + { + case USER_UART_PACKET_TYPE: + setUserPacketType(data, fApply); + dataLen = sizeof(gUserConfiguration.userPacketType); + break; + case USER_UART_PACKET_RATE: + configSetPacketRate(*(uint16_t*)data, fApply); + dataLen = 2; + break; + default: + break; + } + + return dataLen; +} + +/** *************************************************************************** + * @name UpdateSystemParameterValid + * @brief + * @param [in] number - parameter number in user configuration structure + * @param [in] data - value of the parameter in little endian format + * @retval error (1), no error (0) + ******************************************************************************/ +BOOL UpdateSystemParameterValid(uint32_t number, uint8_t *data, BOOL fApply) +{ + BOOL result = TRUE; + + if (number < USER_CRC || number > USER_LAST_SYSTEM_PARAM) { + return FALSE; + } + + switch (number) + { + case USER_UART_PACKET_TYPE: + result = setUserPacketType(data, fApply); + break; + case USER_UART_PACKET_RATE: + result = configSetPacketRate(*(uint16_t*)data, fApply); + break; + case USER_CRC: + case USER_DATA_SIZE: + return TRUE; + default: + result = FALSE; + break; + } + + if (result == TRUE){ + switch (number) + { + case USER_UART_PACKET_TYPE: + memcpy(gUserConfiguration.userPacketType, data, sizeof(gUserConfiguration.userPacketType)); + break; + case USER_UART_PACKET_RATE: + gUserConfiguration.userPacketRate = *(uint16_t*)data; + break; + default: + break; + } + } + + return result; +} + +/** *************************************************************************** + * @name UpdateUserParameter - updating of user configuration parameter based of user preferences + * @brief + * + * @param [in] number - parameter number in user configuration structure + * @param [in] data - value of the parameter in little endian format + * @retval error (0), no error (>=1) + ******************************************************************************/ +uint8_t UpdateUserParameter(uint32_t number, uint8_t* data) +{ + uint8_t dataLen = 0; + + if (number <= USER_LAST_SYSTEM_PARAM || number >= USER_MAX_PARAM ) + { + return 0; + } + + float *tmp; + switch (number) + { + case USER_LEVER_ARM_BX: + tmp = (float *)data; + gUserConfiguration.leverArmBx = *tmp; + dataLen = 4; + break; + case USER_LEVER_ARM_BY: + tmp = (float *)data; + gUserConfiguration.leverArmBy = *tmp; + dataLen = 4; + break; + case USER_LEVER_ARM_BZ: + tmp = (float *)data; + gUserConfiguration.leverArmBz = *tmp; + dataLen = 4; + break; + case USER_POINT_OF_INTEREST_BX: + tmp = (float *)data; + gUserConfiguration.pointOfInterestBx = *tmp; + dataLen = 4; + break; + case USER_POINT_OF_INTEREST_BY: + tmp = (float *)data; + gUserConfiguration.pointOfInterestBy = *tmp; + dataLen = 4; + break; + case USER_POINT_OF_INTEREST_BZ: + tmp = (float *)data; + gUserConfiguration.pointOfInterestBz = *tmp; + dataLen = 4; + break; + case USER_ROTATION_RBVX: + tmp = (float *)data; + gUserConfiguration.rotationRbvx = *tmp; + dataLen = 4; + break; + case USER_ROTATION_RBVY: + tmp = (float *)data; + gUserConfiguration.rotationRbvy = *tmp; + dataLen = 4; + break; + case USER_ROTATION_RBVZ: + tmp = (float *)data; + gUserConfiguration.rotationRbvz = *tmp; + dataLen = 4; + break; + + case USER_ETHERNET_ETHMODE: + gUserConfiguration.ethMode = *data; + dataLen = 1; + break; + case USER_ETHERNET_IP: + memcpy(gUserConfiguration.staticIp, data, 4); + dataLen = 4; + break; + case USER_ETHERNET_NETMASK: + memcpy(gUserConfiguration.netmask, data, 4); + dataLen = 4; + break; + case USER_ETHERNET_GATEWAY: + memcpy(gUserConfiguration.gateway, data, 4); + dataLen = 4; + break; + case USER_ETHERNET_MAC: + memcpy(gUserConfiguration.mac, data, 6); + dataLen = 6; + break; + + case USER_NTRIP_IP: + dataLen = sizeof(gUserConfiguration.ip); + memcpy(gUserConfiguration.ip, data, dataLen); + break; + case USER_NTRIP_PORT: + gUserConfiguration.port = *(uint16_t*)data; + dataLen = 2; + break; + case USER_NTRIP_MOUNTPOINT: + dataLen = sizeof(gUserConfiguration.mountPoint); + memcpy(gUserConfiguration.mountPoint, data, dataLen); + break; + case USER_NTRIP_USERNAME: + dataLen = sizeof(gUserConfiguration.username); + memcpy(gUserConfiguration.username, data, dataLen); + break; + case USER_NTRIP_PASSWORD: + dataLen = sizeof(gUserConfiguration.password); + memcpy(gUserConfiguration.password, data, dataLen); + break; + + default: + break; + } + + return dataLen; +} + +BOOL UpdateEthNtripConfig(uint32_t number) +{ + if (number >= USER_ETHERNET_ETHMODE && number <= USER_ETHERNET_GATEWAY) + { + netif_ethernet_config_changed(); + } + if (number >= USER_NTRIP_IP && number <= USER_NTRIP_PASSWORD) + { + netif_ntrip_config_changed(); + } + return true; +} + +/** **************************************************************************** + * @name UpdateUserParam + * @brief writes user data into user configuration structure, validates data if + * required, updates system parameters + * @param [in] pointer to userData payload in the packet + * @retval N/A + ******************************************************************************/ +BOOL UpdateUserParam(userParamPayload *pld, uint8_t *payloadLen) +{ + uint8_t ret = 0; + int32_t result = 0; + + if (pld->paramNum < USER_MAX_PARAM) { + if (pld->paramNum <= USER_LAST_SYSTEM_PARAM) { + ret = UpdateSystemParameterValid(pld->paramNum, pld->parameter, FALSE); + if (ret) { + ret = UpdateSystemParameterValid(pld->paramNum, pld->parameter, TRUE); + } + } else { + ret = UpdateUserParameter(pld->paramNum, pld->parameter); + if (ret > 0) { + UpdateEthNtripConfig(pld->paramNum); + } + } + + if (!ret){ + result = INVALID_VALUE; + } + } + else { + result = INVALID_PARAM; + } + + pld->paramNum = result; + *payloadLen = 4; + + return TRUE; +} + +/** **************************************************************************** + * @name GetAllUserParams + * @brief Retrieves specified number of user configuration parameters data for + * sending to the external host starting from specified offset in user + * configuration structure (refer to UserConfigParamOffset structure for + * specific value of offsets) + * @param [in] pointer to userData payload in the packet + * @retval N/A + ******************************************************************************/ +BOOL GetAllUserParams(uint8_t *payload, uint8_t *payloadLen) +{ + uint16_t size = sizeof(UserConfigurationStruct); + + memcpy(payload, &gUserConfiguration, size); + + *payloadLen = size; + + return TRUE; +} + + +/** *************************************************************************** + * @name SaveUserConfig - saving of user configuration structure on the + * predefined flash sector + * @brief + * + * @param [in] N/A + * @retval error (0), no error (1) + ******************************************************************************/ +BOOL SaveUserConfig(void) +{ + uint16_t size; + BOOL status; + + size = sizeof(UserConfigurationStruct); + status = EEPROM_SaveUserConfig((uint8_t *)&gUserConfiguration, size); + + if(status){ + return TRUE; + } + + return FALSE; +} + +/** *************************************************************************** + * @name RestoreDefaultUserConfig - restore user configuration structure from + * the default one + * @brief + * + * @param [in] N/A + * @retval error (0), no error (1) + ******************************************************************************/ +BOOL RestoreDefaultUserConfig(void) +{ + BOOL valid = TRUE; + uint32_t sn0 = *(uint32_t *)(0x1FFF7A10); + + memcpy((void*)&gUserConfiguration, (void*)&gDefaultUserConfig, sizeof(UserConfigurationStruct)); + gUserConfiguration.mac[3] = (sn0 >> 16) & 0xff; + gUserConfiguration.mac[4] = (sn0 >> 8) & 0xff; + gUserConfiguration.mac[5] = sn0 & 0xff; + + if(!SaveUserConfig()){ + valid = FALSE; + } + return valid; +} diff --git a/examples/OpenRTK330LI/RTK/src/user/user_config.h b/examples/OpenRTK330LI/RTK/src/user/user_config.h new file mode 100644 index 0000000..b3135d0 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/user/user_config.h @@ -0,0 +1,152 @@ +/** *************************************************************************** + * @file user_config.h + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + *****************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ + +#ifndef _USER_CONFIG_H +#define _USER_CONFIG_H + +#include + +#include "constants.h" +#include "user_message.h" + +/// User defined configuration strucrture +///Please notice, that parameters are 64 bit to accomodate double types as well as longer string types + +#pragma pack(4) + +typedef struct { + uint16_t dataCRC; /// CRC of user configuration structure CRC-16 + uint16_t dataSize; /// Size of the user configuration structure + + uint8_t userPacketType[2]; /// User packet to be continiously sent by unit + /// Packet types defined in structure UserOutPacketType + /// in file UserMessaging.h + + uint16_t userPacketRate; /// Packet rate for continiously output packet, Hz. + /// Valid settings are: 0 ,2, 5, 10, 20, 25, 50, 100, 200 + + // place new arbitrary configuration parameters here + // parameter size should even to 4 bytes + // Add parameter offset in UserConfigParamOffset structure if validation or + // special processing required + float leverArmBx; + float leverArmBy; + float leverArmBz; + float pointOfInterestBx; + float pointOfInterestBy; + float pointOfInterestBz; + float rotationRbvx; + float rotationRbvy; + float rotationRbvz; + + // ethnet + uint8_t ethMode; + uint8_t staticIp[4]; + uint8_t netmask[4]; + uint8_t gateway[4]; + uint8_t mac[6]; + + // ntrip + uint8_t ip[23]; + uint16_t port; + uint8_t mountPoint[20]; + uint8_t username[16]; + uint8_t password[24]; + +} UserConfigurationStruct; + +#pragma pack() + + + +typedef enum { +//***************************************************************************************** +// add system parameters here and reassign USER_LAST_SYSTEM_PARAM (DO NOT CHANGE THIS!!!) + USER_CRC = 0, + USER_DATA_SIZE , // 1 + USER_UART_PACKET_TYPE , + USER_UART_PACKET_RATE , + USER_LAST_SYSTEM_PARAM = USER_UART_PACKET_RATE, +//***************************************************************************************** +// add parameter enumerator here while adding new parameter in user UserConfigurationStruct + USER_LEVER_ARM_BX , + USER_LEVER_ARM_BY , + USER_LEVER_ARM_BZ , + USER_POINT_OF_INTEREST_BX , + USER_POINT_OF_INTEREST_BY , + USER_POINT_OF_INTEREST_BZ , + USER_ROTATION_RBVX , + USER_ROTATION_RBVY , + USER_ROTATION_RBVZ , + + USER_ETHERNET_ETHMODE , + USER_ETHERNET_IP , + USER_ETHERNET_NETMASK , + USER_ETHERNET_GATEWAY , + USER_ETHERNET_MAC , + + USER_NTRIP_IP , + USER_NTRIP_PORT , + USER_NTRIP_MOUNTPOINT , + USER_NTRIP_USERNAME , + USER_NTRIP_PASSWORD , + + USER_MAX_PARAM +} UserConfigParamNumber; + + +#define INVALID_PARAM -1 +#define INVALID_VALUE -2 +#define INVALID_PAYLOAD_SIZE -3 + +// app configuartion address +#define APP_USER_CONFIG_ADDR 0x080C0000 +#define BOOT_FLAG_ADDR 0x080A0000 + +// ethnet +#define ETHMODE_DHCP 0 +#define ETHMODE_STATIC 1 + +extern UserConfigurationStruct gUserConfiguration; + +void userInitConfigureUnit(void); +BOOL UpdateUserParam(userParamPayload* pld, uint8_t *payloadLen); +BOOL SaveUserConfig(void); +BOOL RestoreDefaultUserConfig(void); +BOOL GetAllUserParams(uint8_t *payload, uint8_t *payloadLen); +BOOL valid_user_config_parameter(uint8_t number, uint8_t *data); +void update_system_para(void); +void update_user_para(void); +BOOL UpdateSystemParameter(uint32_t number, uint8_t* data); +BOOL UpdateSystemParameterValid(uint32_t number, uint8_t *data, BOOL fApply); +uint8_t UpdateUserParameter(uint32_t number, uint8_t* data); + +BOOL EEPROM_SaveUserConfig(uint8_t *ptrToUserConfigStruct, uint16_t userConfigSize); +BOOL EEPROM_LoadUserConfig(uint8_t *ptrToUserConfigInRam, uint16_t *ptrUserConfigSize); + +uint8_t* get_user_packet_type(void); +uint16_t get_user_packet_rate(void); +float* get_user_ins_para(); + +#endif /* _USER_CONFIG_H */ diff --git a/examples/OpenRTK330LI/RTK/src/user/user_message.c b/examples/OpenRTK330LI/RTK/src/user/user_message.c new file mode 100644 index 0000000..243e52c --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/user/user_message.c @@ -0,0 +1,475 @@ +/** *************************************************************************** + * @file user_message.c + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ + +#include +#include +#include + +#include "app_version.h" +#include "platformAPI.h" +#include "configurationAPI.h" +#include "sensorsAPI.h" +#include "calibrationAPI.h" +#include "ucb_packet.h" +#include "user_message.h" +#include "user_config.h" +#include "timer.h" +#include "rtklib_core.h" +#include "rtcm.h" +#include "gnss_data_api.h" +#include "configuration.h" + + +/// List of allowed packet codes +usr_packet_t userInputPackets[] = { + {USR_IN_NONE, {0,0}}, + {USR_IN_PING, "pG"}, + {USR_IN_UPDATE_PARAM, "uP"}, + {USR_IN_SAVE_CONFIG, "sC"}, + {USR_IN_GET_ALL, "gA"}, + {USR_IN_GET_VERSION, "gV"}, +// place new input packet code here, before USR_IN_MAX + {USR_IN_MAX, {0xff, 0xff}}, // "" +}; + + +// packet codes here should be unique - +// should not overlap codes for input packets and system packets +// First byte of Packet code should have value >= 0x61 +usr_packet_t userOutputPackets[] = { +// Packet Type Packet Code + {USR_OUT_NONE, {0x00, 0x00}}, + {USR_OUT_SCALED1, "s1"}, + {USR_OUT_POS, "pS"}, + {USR_OUT_SKY, "sK"}, +// place new type and code here + {USR_OUT_MAX, {0xff, 0xff}}, // "" +}; + +static int _outputPacketType = USR_OUT_MAX; +static int _inputPacketType = USR_IN_MAX; + + +int checkUserPacketType(uint16_t receivedCode) +{ + int res = UCB_ERROR_INVALID_TYPE; + usr_packet_t *packet = &userInputPackets[1]; + uint16_t code; + + // validate packet code here and memorise for further processing + while(packet->packetType != USR_IN_MAX){ + code = (packet->packetCode[0] << 8) | packet->packetCode[1]; + if(code == receivedCode){ + _inputPacketType = packet->packetType; + return UCB_USER_IN; + } + packet++; + } + + packet = &userOutputPackets[1]; + + // validate packet code here and memorize for further processing + while(packet->packetType != USR_OUT_MAX){ + code = (packet->packetCode[0] << 8) | packet->packetCode[1]; + if(code == receivedCode){ + _outputPacketType = packet->packetType; + return UCB_USER_OUT; + } + packet++; + } + + return res; +} + +int checkUserOutPacketType(uint16_t receivedCode) +{ + usr_packet_t *packet = &userOutputPackets[1]; + uint16_t code; + + while(packet->packetType != USR_OUT_MAX){ + code = (packet->packetCode[0] << 8) | packet->packetCode[1]; + if(code == receivedCode){ + return UCB_USER_OUT; + } + packet++; + } + return UCB_ERROR_INVALID_TYPE; +} + +void userPacketTypeToBytes(uint8_t bytes[]) +{ + if(_inputPacketType && _inputPacketType < USR_IN_MAX){ + // response to request. Return same packet code + bytes[0] = userInputPackets[_inputPacketType].packetCode[0]; + bytes[1] = userInputPackets[_inputPacketType].packetCode[1]; + _inputPacketType = USR_IN_MAX; // wait for next input packet + return; + } + + if(_outputPacketType && _outputPacketType < USR_OUT_MAX){ + // continuous packet + bytes[0] = userOutputPackets[_outputPacketType].packetCode[0]; + bytes[1] = userOutputPackets[_outputPacketType].packetCode[1]; + } else { + bytes[0] = 0; + bytes[1] = 0; + } + +} + +/** *************************************************************************** + * @name setUserPacketType - set user output packet type + * @brief + * @param [in] packet type + * @retval - TRUE if success, FALSE otherwise + ******************************************************************************/ +BOOL setUserPacketType(uint8_t *data, BOOL fApply) +{ + int type = -1; + uint16_t *code = (uint16_t*)data; + uint16_t tmp; + BOOL result = TRUE; + + usr_packet_t *packet = &userOutputPackets[1]; + for(int i = 0; i < USR_OUT_MAX; i++, packet++){ + if(*code == *((uint16_t*)packet->packetCode)){ + type = packet->packetType; + break; + } + } + + switch(type){ + case USR_OUT_SCALED1: // packet with arbitrary data + _outputPacketType = type; + break; + default: + result = FALSE; + break; + } + + if (result == FALSE){ + return FALSE; + } + + tmp = (data[0] << 8) | data[1]; + + result = configSetOutputPacketCode(tmp, fApply); + + return result; +} + +/****************************************************************************** + * @name FillPingPacketPayload - API call ro prepare user output packet + * @brief general handler + * @param [in] payload pointer to put user data to + * @param [in/out] number of bytes in user payload + * @retval N/A + ******************************************************************************/ +static BOOL Fill_PingPacketPayload(uint8_t *payload, uint8_t *payloadLen) +{ + int len; + uint8_t *model = (uint8_t*)GetUnitVersion(); + uint8_t *rev = (uint8_t*)platformBuildInfo(); + unsigned int serialNum = GetUnitSerialNum(); + len = snprintf((char*)payload, 250, "%s %s %s SN:%u", PRODUCT_NAME_STRING, model, rev, serialNum ); + *payloadLen = len; + return TRUE; +} + +/****************************************************************************** + * @name FillVersionPacketPayload - API call ro prepare user output packet + * @brief general handler + * @param [in] payload pointer to put user data to + * @param [in/out] number of bytes in user payload + * @retval N/A + ******************************************************************************/ +static BOOL Fill_VersionPacketPayload(uint8_t *payload, uint8_t *payloadLen) +{ + int len = snprintf((char*)payload, 250, "%s", APP_VERSION_STRING ); + *payloadLen = len; + return TRUE; +} + +/****************************************************************************** + * @name Fills1PacketPayloadt - API call ro prepare user output packet + * @brief general handler + * @param [in] payload pointer to put user data to + * @param [in/out] number of bytes in user payload + * @retval N/A + ******************************************************************************/ +static BOOL Fill_s1PacketPayload(uint8_t *payload, uint8_t *payloadLen) +{ + scaled1_payload_t *pld = (scaled1_payload_t *)payload; + *payloadLen = sizeof(scaled1_payload_t); + + gtime_t time; + int week; + time.time = imu_time.time; + time.sec = (double)imu_time.msec/1000; + pld->timeOfWeek = time2gpst(time,&week); + + if (pld->timeOfWeek < 0){ + pld->week = 0; + pld->timeOfWeek = imu_time.time + (double)imu_time.msec/1000; + } else { + pld->week = week; + } + + //pld->temp_C = GetUnitTemp(); + GetAccelData_g(pld->accel_g); + GetRateData_radPerSec(pld->rate_dps); + + return TRUE; +} + +/****************************************************************************** + * @name Fill_posPacketPayload - API call ro prepare user output packet + * @brief general handler + * @param [in] payload pointer to put user data to + * @param [in/out] number of bytes in user payload + * @retval N/A + ******************************************************************************/ +static BOOL Fill_posPacketPayload(uint8_t *payload, uint8_t *payloadLen) +{ + // need to be filled your own data + pos_payload_t *pld = (pos_payload_t *)payload; + + pld->week = g_gnss_sol.gps_week; + pld->timeOfWeek = (double) g_gnss_sol.gps_tow / 1000; + + pld->positionMode = g_gnss_sol.gnss_fix_type; + pld->latitude = g_gnss_sol.latitude * RAD_TO_DEG; + pld->longitude = g_gnss_sol.longitude * RAD_TO_DEG; + pld->height = g_gnss_sol.height; + pld->numberOfSVs = g_gnss_sol.num_sats; + pld->hdop = g_gnss_sol.dops[2]; + + pld->velocityMode = g_gnss_sol.vel_mode; + pld->velocityNorth = g_gnss_sol.vel_ned[0]; + pld->velocityEast = g_gnss_sol.vel_ned[1]; + pld->velocityDown = g_gnss_sol.vel_ned[2]; + + pld->insStatus = 0; + pld->insPositionType = 0; + pld->roll = 0; + pld->pitch = 0; + pld->heading = 0; + + *payloadLen = sizeof(pos_payload_t); + return TRUE; +} + +/****************************************************************************** + * @name Fill_skyviewPacketPayload - API call ro prepare user output packet + * @brief general handler + * @param [in] payload pointer to put user data to + * @param [in/out] number of bytes in user payload + * @retval N/A + ******************************************************************************/ +static BOOL Fill_skyviewPacketPayload(uint8_t *payload, uint8_t *payloadLen) +{ + // need to be filled your own data + skyview_payload_t *pld = (skyview_payload_t *)payload; + obs_t* ptr_rover_obs = &g_ptr_gnss_data->rov; + uint8_t sys = 0; + uint8_t maxn = ptr_rover_obs->n; + static uint8_t index = 0; + uint8_t n = 0; + + if (maxn - index*10 <= 0) + { + index = 0; + *payloadLen = 0; + } + else if (maxn - index*10 > 10) + { + n = (index+1)*10; + *payloadLen = sizeof(skyview_payload_t) * 10; + } + else + { + n = maxn; + *payloadLen = sizeof(skyview_payload_t) * (maxn-index*10); + } + + for (uint8_t i = index*10; i < n; i++) + { + pld->timeOfWeek = (double) g_gnss_sol.gps_tow / 1000; + + pld->satelliteId = ptr_rover_obs->data[i].sat; + sys = satsys(ptr_rover_obs->data[i].sat, NULL); + if (sys == _SYS_GPS_) + { + pld->systemId = 0; + } + else if (sys == _SYS_GLO_) + { + pld->systemId = 1; + } + else if (sys == _SYS_GAL_) + { + pld->systemId = 2; + } + else if (sys == _SYS_QZS_) + { + pld->systemId = 3; + } + else if (sys == _SYS_BDS_) + { + pld->systemId = 4; + } + else if (sys == _SYS_SBS_) + { + pld->systemId = 5; + } + else + { + pld->systemId = 111; + } + pld->antennaId = 0; // 0,1... + pld->l1cn0 = ptr_rover_obs->data[i].SNR[0] / 4; + pld->l2cn0 = ptr_rover_obs->data[i].SNR[1] / 4; + + pld->azimuth = 0; + pld->elevation = 0; + + pld++; + } + + index++; + if (n == maxn) + { + index = 0; + } + + return true; +} + +/****************************************************************************** + * @name HandleUserInputPacket - API + * @brief general handler + * @param [out] packetPtr - filled in packet from the mapped physical port + * @retval N/A + ******************************************************************************/ +int HandleUserInputPacket(UcbPacketStruct *ptrUcbPacket) +{ + BOOL valid = TRUE; + int ret = USER_PACKET_OK; + + /// call appropriate function based on packet type + switch (_inputPacketType) { + case USR_IN_PING: + { + uint8_t len; + Fill_PingPacketPayload(ptrUcbPacket->payload, &len); + ptrUcbPacket->payloadLength = len; + } + // leave all the same - it will be bounced back unchanged + break; + case USR_IN_GET_VERSION: + { + uint8_t len; + Fill_VersionPacketPayload(ptrUcbPacket->payload, &len); + ptrUcbPacket->payloadLength = len; + } + break; + case USR_IN_UPDATE_PARAM: + UpdateUserParam((userParamPayload*)ptrUcbPacket->payload, &ptrUcbPacket->payloadLength); + break; + case USR_IN_SAVE_CONFIG: + // payload length does not change + if(!SaveUserConfig()){ + valid = FALSE; + } + break; + case USR_IN_GET_ALL: + if(!GetAllUserParams(ptrUcbPacket->payload, &ptrUcbPacket->payloadLength)){ + valid = FALSE; + } + break; + default: + /// default handler - unknown packet + valid = FALSE; + break; + } + + if(!valid){ + ptrUcbPacket->payloadLength = 0; + ret = USER_PACKET_ERROR; + } + + ptrUcbPacket->packetType = UCB_USER_OUT; // do not remove - done for proper packet routing + + return ret; +} + + +/****************************************************************************** + * @name HandleUserOutputPacket - API call ro prepare continuous user output packet + * @brief general handler + * @param [in] payload pointer to put user data to + * @param [in/out] number of bytes in user payload + * @retval N/A + ******************************************************************************/ +BOOL HandleUserOutputPacket(uint8_t *payload, uint8_t *payloadLen) +{ + BOOL ret = TRUE; + + switch (_outputPacketType) + { + case USR_OUT_SCALED1: + { + uint8_t len; + Fill_s1PacketPayload(payload, &len); + *payloadLen = len; + } + break; + + case USR_OUT_POS: + { + uint8_t len; + Fill_posPacketPayload(payload, &len); + *payloadLen = len; + } + break; + + case USR_OUT_SKY: // skyview + { + uint8_t len; + Fill_skyviewPacketPayload(payload, &len); + *payloadLen = len; + } + break; + + default: + { + *payloadLen = 0; + ret = FALSE; + } + break; /// unknown user packet, will send error in response + } + + return ret; +} diff --git a/examples/OpenRTK330LI/RTK/src/user/user_message.h b/examples/OpenRTK330LI/RTK/src/user/user_message.h new file mode 100644 index 0000000..4c076d8 --- /dev/null +++ b/examples/OpenRTK330LI/RTK/src/user/user_message.h @@ -0,0 +1,123 @@ +/** *************************************************************************** + * @file user_message.h + * + * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + * PARTICULAR PURPOSE. + * + ******************************************************************************/ +/******************************************************************************* +Copyright 2020 ACEINNA, INC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*******************************************************************************/ + +#ifndef _USER_MESSAGE_H +#define _USER_MESSAGE_H + +#include + +#include "constants.h" +#include "ucb_packet.h" + + +// total size of user packet structure should not exceed 255 bytes +#pragma pack(1) + +// example of user payload structure +typedef struct { + uint32_t paramNum; // parameter number in parameters structure (little endian) + uint8_t parameter[64]; // up to 30 64-bit parameters (little endian) +} userParamPayload; + +#pragma pack() + +typedef enum +{ + USR_IN_NONE = 0, + USR_IN_PING, + USR_IN_UPDATE_PARAM, + USR_IN_SAVE_CONFIG, + USR_IN_GET_ALL, + USR_IN_GET_VERSION, + USR_IN_MAX, +} UserInPacketType; + +// User output packet codes, change at will +typedef enum { + USR_OUT_NONE = 0, + USR_OUT_SCALED1, + USR_OUT_POS, + USR_OUT_SKY, + USR_OUT_MAX +} UserOutPacketType; + +// user out packet struct +#pragma pack(1) + +// payload structure of alternative IMU data message +typedef struct { + uint32_t week; + double timeOfWeek; + float accel_g[3]; + float rate_dps[3]; + //float temp_C; +} scaled1_payload_t; + +// payload structure of standard pos data message +typedef struct { + uint32_t week; + double timeOfWeek; + uint32_t positionMode; + double latitude; + double longitude; + double height; + uint32_t numberOfSVs; + float hdop; + uint32_t velocityMode; + float velocityNorth; + float velocityEast; + float velocityDown; + uint32_t insStatus; + uint32_t insPositionType; + float roll; + float pitch; + float heading; +} pos_payload_t; + +// payload structure of standard skyview data message +typedef struct { + double timeOfWeek; + uint8_t satelliteId; + uint8_t systemId; + uint8_t antennaId; + uint8_t l1cn0; + uint8_t l2cn0; + float azimuth; + float elevation; +} skyview_payload_t; + +#pragma pack() + + +int checkUserPacketType(uint16_t receivedCode); +int checkUserOutPacketType(uint16_t receivedCode); +void userPacketTypeToBytes(uint8_t bytes[]); + +BOOL setUserPacketType(uint8_t *data, BOOL fApply); + +int HandleUserInputPacket (UcbPacketStruct *ptrUcbPacket); +BOOL HandleUserOutputPacket(uint8_t *payload, uint8_t *payloadLen); + +#endif /* _USER_MESSAGE_H */ diff --git a/platform.json b/platform.json index 92d1e75..b20a274 100644 --- a/platform.json +++ b/platform.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/aceinna/platform-aceinna_imu.git" }, - "version": "1.2.7", + "version": "1.3.0", "packageRepositories": [ "https://dl.bintray.com/platformio/dl-packages/manifest.json", "http://dl.platformio.org/packages/manifest.json"