Skip to content
Open
125 changes: 105 additions & 20 deletions KPI_Rover/Communication/ProtocolHandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdint.h>
#include "cmsis_os2.h"

#include "Database/ulDatabase.h"

#define SEND_BUFFER_SIZE 64
#define RECV_BUFFER_SIZE 32

Expand All @@ -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;
Expand All @@ -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)
Expand Down
19 changes: 15 additions & 4 deletions KPI_Rover/Database/ulDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion KPI_Rover/Encoders/ulEncoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
19 changes: 15 additions & 4 deletions KPI_Rover/KPIRover.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down