diff --git a/KPI_Rover/Communication/ProtocolHandler.c b/KPI_Rover/Communication/ProtocolHandler.c index a19a9ad..2f9c739 100644 --- a/KPI_Rover/Communication/ProtocolHandler.c +++ b/KPI_Rover/Communication/ProtocolHandler.c @@ -4,6 +4,8 @@ #include #include "cmsis_os2.h" +#include "Database/ulDatabase.h" + #define SEND_BUFFER_SIZE 64 #define RECV_BUFFER_SIZE 32 @@ -17,31 +19,41 @@ static osThreadAttr_t ta = { .stack_size = 64 * 4 }; -static void dispatch_00(void) {} +static int32_t switch_endianness_int32(const uint8_t * const address) +{ + return (int32_t) ((((uint32_t)address[0]) << 24) + (((uint32_t)address[1]) << 16) + (((uint32_t)address[2]) << 8) + ((uint32_t)address[3])); +} -static void dispatch_01(void) +static void dispatch_not_a_command(void) {} + +static void dispatch_get_api_version(void) { sendBuffer[0] = 0x01; sendBuffer[1] = 0x01; UARTTransport_send(sendBuffer, 2); } -static void dispatch_02(void) +static void dispatch_set_motor_speed(void) { sendBuffer[0] = 0x02; + sendBuffer[1] = 0x00; + + static int32_t target_value; + + target_value = switch_endianness_int32(&(recvBuffer[2])); // big (network) to little (host) switch (recvBuffer[1]) { case 0: - sendBuffer[1] = 0x0; + ulDatabase_setInt32(TARGET_MOTOR_FL_RPM, target_value); break; case 1: - sendBuffer[1] = 0x0; + ulDatabase_setInt32(TARGET_MOTOR_RL_RPM, target_value); break; case 2: - sendBuffer[1] = 0x0; + ulDatabase_setInt32(TARGET_MOTOR_FR_RPM, target_value); break; case 3: - sendBuffer[1] = 0x0; + ulDatabase_setInt32(TARGET_MOTOR_RR_RPM, target_value); break; default: sendBuffer[1] = 0x01; @@ -51,37 +63,110 @@ static void dispatch_02(void) UARTTransport_send(sendBuffer, 2); } -static void dispatch_03(void) +static void dispatch_set_all_motors_speed(void) { + static int32_t target_value_fl, target_value_rl, target_value_fr, target_value_rr; + + target_value_fl = switch_endianness_int32(&(recvBuffer[1])); + target_value_rl = switch_endianness_int32(&(recvBuffer[5])); + target_value_fr = switch_endianness_int32(&(recvBuffer[9])); + target_value_rr = switch_endianness_int32(&(recvBuffer[13])); + + ulDatabase_setInt32(TARGET_MOTOR_FL_RPM, target_value_fl); + ulDatabase_setInt32(TARGET_MOTOR_RL_RPM, target_value_rl); + ulDatabase_setInt32(TARGET_MOTOR_FR_RPM, target_value_fr); + ulDatabase_setInt32(TARGET_MOTOR_RR_RPM, target_value_rr); + sendBuffer[0] = 0x03; sendBuffer[1] = 0x00; UARTTransport_send(sendBuffer, 2); } -static void dispatch_04(void) {} +static void dispatch_get_encoder(void) +{ + sendBuffer[0] = 0x04; + + static int32_t source_value; -static void dispatch_05(void) + switch (recvBuffer[1]) { + case 0: + ulDatabase_getInt32(ENCODER_MOTOR_FL_RPM, &source_value); + break; + case 1: + ulDatabase_getInt32(ENCODER_MOTOR_RL_RPM, &source_value); + break; + case 2: + ulDatabase_getInt32(ENCODER_MOTOR_FR_RPM, &source_value); + break; + case 3: + ulDatabase_getInt32(ENCODER_MOTOR_RR_RPM, &source_value); + break; + default: + // failure is not an option in the protocol + break; + } + + source_value = switch_endianness_int32((uint8_t *) &source_value); // little (host) to big (network) + memcpy(&(sendBuffer[1]), &source_value, sizeof(source_value)); + + UARTTransport_send(sendBuffer, 5); +} + +static void dispatch_get_all_encoders(void) { + static int32_t source_value_fl, source_value_rl, source_value_fr, source_value_rr; + + ulDatabase_getInt32(ENCODER_MOTOR_FL_RPM, &source_value_fl); + ulDatabase_getInt32(ENCODER_MOTOR_RL_RPM, &source_value_rl); + ulDatabase_getInt32(ENCODER_MOTOR_FR_RPM, &source_value_fr); + ulDatabase_getInt32(ENCODER_MOTOR_RR_RPM, &source_value_rr); + + source_value_fl = switch_endianness_int32((uint8_t *) &source_value_fl); + source_value_rl = switch_endianness_int32((uint8_t *) &source_value_rl); + source_value_fr = switch_endianness_int32((uint8_t *) &source_value_fr); + source_value_rr = switch_endianness_int32((uint8_t *) &source_value_rr); + sendBuffer[0] = 0x05; - memset(sendBuffer + 1, 0xBB, 16); + memcpy(&(sendBuffer[1]), &source_value_fl, sizeof(source_value_fl)); + memcpy(&(sendBuffer[5]), &source_value_rl, sizeof(source_value_rl)); + memcpy(&(sendBuffer[9]), &source_value_fr, sizeof(source_value_fr)); + memcpy(&(sendBuffer[13]), &source_value_rr, sizeof(source_value_rr)); + UARTTransport_send(sendBuffer, 17); } -static void dispatch_06(void) +static void dispatch_get_imu(void) { sendBuffer[0] = 0x06; - memset(sendBuffer + 1, 0xCC, 52); + + ulDatabase_getFloat(IMU_ACCEL_X, (float *) (sendBuffer + 1)); + ulDatabase_getFloat(IMU_ACCEL_Y, (float *) (sendBuffer + 5)); + ulDatabase_getFloat(IMU_ACCEL_Z, (float *) (sendBuffer + 9)); + + ulDatabase_getFloat(IMU_GYRO_X, (float *) (sendBuffer + 13)); + ulDatabase_getFloat(IMU_GYRO_Y, (float *) (sendBuffer + 17)); + ulDatabase_getFloat(IMU_GYRO_Z, (float *) (sendBuffer + 21)); + + ulDatabase_getFloat(IMU_MAG_X, (float *) (sendBuffer + 25)); + ulDatabase_getFloat(IMU_MAG_Y, (float *) (sendBuffer + 29)); + ulDatabase_getFloat(IMU_MAG_Z, (float *) (sendBuffer + 33)); + + ulDatabase_getFloat(IMU_QUAT_X, (float *) (sendBuffer + 37)); + ulDatabase_getFloat(IMU_QUAT_X, (float *) (sendBuffer + 41)); + ulDatabase_getFloat(IMU_QUAT_Y, (float *) (sendBuffer + 45)); + ulDatabase_getFloat(IMU_QUAT_Z, (float *) (sendBuffer + 49)); + UARTTransport_send(sendBuffer, 53); } static const void (*dispatch_table[])(void) = { - dispatch_00, - dispatch_01, - dispatch_02, - dispatch_03, - dispatch_04, - dispatch_05, - dispatch_06, + dispatch_not_a_command, + dispatch_get_api_version, + dispatch_set_motor_speed, + dispatch_set_all_motors_speed, + dispatch_get_encoder, + dispatch_get_all_encoders, + dispatch_get_imu, }; void ProtocolHandler_processTask(void *d) diff --git a/KPI_Rover/Database/ulDatabase.h b/KPI_Rover/Database/ulDatabase.h index a065695..cb087cf 100644 --- a/KPI_Rover/Database/ulDatabase.h +++ b/KPI_Rover/Database/ulDatabase.h @@ -19,16 +19,27 @@ enum ulDatabase_ParamType { enum ulDatabase_ParamId { ENCODER_CONTROL_PERIOD_MS, ENCODER_TICKS_PER_REVOLUTION, - MOTOR_FL_RPM, - MOTOR_FR_RPM, - MOTOR_RL_RPM, - MOTOR_RR_RPM, + ENCODER_MOTOR_FL_RPM, + ENCODER_MOTOR_FR_RPM, + ENCODER_MOTOR_RL_RPM, + ENCODER_MOTOR_RR_RPM, + TARGET_MOTOR_FL_RPM, + TARGET_MOTOR_FR_RPM, + TARGET_MOTOR_RL_RPM, + TARGET_MOTOR_RR_RPM, IMU_ACCEL_X, IMU_ACCEL_Y, IMU_ACCEL_Z, IMU_GYRO_X, IMU_GYRO_Y, IMU_GYRO_Z, + IMU_MAG_X, + IMU_MAG_Y, + IMU_MAG_Z, + IMU_QUAT_W, + IMU_QUAT_X, + IMU_QUAT_Y, + IMU_QUAT_Z, IMU_CALIB_CMD, IMU_CALIB_STATUS, IMU_IS_CALIBRATED, diff --git a/KPI_Rover/Encoders/ulEncoder.c b/KPI_Rover/Encoders/ulEncoder.c index 9004ba0..1a204aa 100644 --- a/KPI_Rover/Encoders/ulEncoder.c +++ b/KPI_Rover/Encoders/ulEncoder.c @@ -35,7 +35,7 @@ static void ulEncoder_TimerCallback(void *argument) { float rpm = ticks_per_sec * 60.0f / encoder_ticks_per_rev; int32_t rpm_to_db = (int32_t)rpm; - ulDatabase_setInt32(MOTOR_FL_RPM + i, rpm_to_db); + ulDatabase_setInt32(ENCODER_MOTOR_FL_RPM + i, rpm_to_db); lastTicks_RPM[i] = currentTicks; } diff --git a/KPI_Rover/KPIRover.c b/KPI_Rover/KPIRover.c index 99cb3e7..efc2c0d 100644 --- a/KPI_Rover/KPIRover.c +++ b/KPI_Rover/KPIRover.c @@ -13,16 +13,27 @@ static struct ulDatabase_ParamMetadata ulDatabase_params[] = { {0, UINT16, true, 5}, // ENCODER_CONTROL_PERIOD_MS, {0, FLOAT, true, 820.0f}, // ENCODER_TICKS_PER_REVOLUTION, - {0, INT32, false, 0}, // MOTOR_FL_RPM, - {0, INT32, false, 0}, // MOTOR_FR_RPM, - {0, INT32, false, 0}, // MOTOR_RL_RPM, - {0, INT32, false, 0}, // MOTOR_RR_RPM, + {0, INT32, false, 0}, // ENCODER_MOTOR_FL_RPM, + {0, INT32, false, 0}, // ENCODER_MOTOR_FR_RPM, + {0, INT32, false, 0}, // ENCODER_MOTOR_RL_RPM, + {0, INT32, false, 0}, // ENCODER_MOTOR_RR_RPM, + {0, INT32, false, 0}, // TARGET_MOTOR_FL_RPM, + {0, INT32, false, 0}, // TARGET_MOTOR_FR_RPM, + {0, INT32, false, 0}, // TARGET_MOTOR_RL_RPM, + {0, INT32, false, 0}, // TARGET_MOTOR_RR_RPM, {0, FLOAT, false, 0.0f}, // IMU_ACCEL_X {0, FLOAT, false, 0.0f}, // IMU_ACCEL_Y {0, FLOAT, false, 0.0f}, // IMU_ACCEL_Z {0, FLOAT, false, 0.0f}, // IMU_GYRO_X {0, FLOAT, false, 0.0f}, // IMU_GYRO_Y {0, FLOAT, false, 0.0f}, // IMU_GYRO_Z + {0, FLOAT, false, 0.0f}, // IMU_MAG_X + {0, FLOAT, false, 0.0f}, // IMU_MAG_Y + {0, FLOAT, false, 0.0f}, // IMU_MAG_Z + {0, FLOAT, false, 0.0f}, // IMU_QUAT_W + {0, FLOAT, false, 0.0f}, // IMU_QUAT_X + {0, FLOAT, false, 0.0f}, // IMU_QUAT_Y + {0, FLOAT, false, 0.0f}, // IMU_QUAT_Z {0, UINT8, false, 0}, // IMU_CALIB_CMD {0, UINT8, false, 0}, // IMU_CALIB_STATUS {0, UINT8, false, 0}, // IMU_IS_CALIBRATED