|
|
|
|
@ -1,6 +1,9 @@
|
|
|
|
|
|
|
|
|
|
#include "Arduino.h"
|
|
|
|
|
#include "Wire.h"
|
|
|
|
|
// Annoyingly, we need to include SPI for the Adafuit Bus IO library to work
|
|
|
|
|
#include "Adafruit_MPRLS.h"
|
|
|
|
|
#include "SPI.h"
|
|
|
|
|
#include "io.h"
|
|
|
|
|
|
|
|
|
|
#include "i2c_comms.h"
|
|
|
|
|
@ -20,9 +23,13 @@ static TaskHandle_t i2c_comms_task_handle = NULL;
|
|
|
|
|
static SemaphoreHandle_t motor_status_semaphore;
|
|
|
|
|
static xQueueHandle motor_status_queue;
|
|
|
|
|
|
|
|
|
|
static SemaphoreHandle_t pipe_pressure_semaphore;
|
|
|
|
|
static xQueueHandle pipe_pressure_queue;
|
|
|
|
|
|
|
|
|
|
static xQueueHandle motor_control_queue;
|
|
|
|
|
static xQueueHandle motor_parameter_queue;
|
|
|
|
|
|
|
|
|
|
Adafruit_MPRLS mpr_sensor = Adafruit_MPRLS(-1, -1);
|
|
|
|
|
|
|
|
|
|
// Ask the I2C task to get a status update from the motor ESP32
|
|
|
|
|
void request_motor_status_update() {
|
|
|
|
|
@ -36,24 +43,54 @@ bool get_motor_status_update(motor_status_packet_t *status_packet) {
|
|
|
|
|
return (xQueueReceive(motor_status_queue, status_packet, 0) == pdTRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ask the I2C task to get a status update from the motor ESP32
|
|
|
|
|
void request_pipe_pressure_update() {
|
|
|
|
|
xSemaphoreGive(pipe_pressure_semaphore);
|
|
|
|
|
// Wake up task
|
|
|
|
|
xTaskNotifyGive(i2c_comms_task_handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get a pipe pressure status update, if one exists. Returns True if a new update was copied out.
|
|
|
|
|
bool get_pipe_pressure_status_update(pipe_pressure_status_t *status_update) {
|
|
|
|
|
return (xQueueReceive(pipe_pressure_queue, status_update, 0) == pdTRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ask the I2C task to send a control packet
|
|
|
|
|
void set_motor_control(motor_control_group_t new_motor_control){
|
|
|
|
|
void set_motor_control(motor_control_group_t new_motor_control) {
|
|
|
|
|
xQueueOverwrite(motor_control_queue, &new_motor_control);
|
|
|
|
|
// Wake up task
|
|
|
|
|
xTaskNotifyGive(i2c_comms_task_handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ask the I2C task to send a motor parameter packet
|
|
|
|
|
void set_motor_parameters(motor_parameters_group_t new_motor_parameters){
|
|
|
|
|
void set_motor_parameters(motor_parameters_group_t new_motor_parameters) {
|
|
|
|
|
xQueueOverwrite(motor_parameter_queue, &new_motor_parameters);
|
|
|
|
|
// Wake up task
|
|
|
|
|
xTaskNotifyGive(i2c_comms_task_handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define TCAADDR 0x70
|
|
|
|
|
|
|
|
|
|
// Sends command to the TCA9548 I2C mux to connect a different pressure sensor. Returns value from Wire transmission.
|
|
|
|
|
uint8_t select_pipe_sensor(uint8_t i) {
|
|
|
|
|
if (i > 7)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
Wire.beginTransmission(TCAADDR);
|
|
|
|
|
Wire.write(1 << i);
|
|
|
|
|
return Wire.endTransmission();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void i2c_comms_task(void *pvParameters) {
|
|
|
|
|
uint8_t reply_bytecount;
|
|
|
|
|
motor_status_packet_t i2c_reply;
|
|
|
|
|
motor_write_packet_t motor_write_packet;
|
|
|
|
|
pipe_pressure_status_t pipe_pressure_status;
|
|
|
|
|
|
|
|
|
|
// After power on, I2C mux has no bus selected
|
|
|
|
|
select_pipe_sensor(0);
|
|
|
|
|
// irritatingly, this includes a 10ms delay
|
|
|
|
|
mpr_sensor.begin();
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
// Only need to run this task when there is something to do on the I2C bus
|
|
|
|
|
@ -71,10 +108,32 @@ static void i2c_comms_task(void *pvParameters) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO Get pipe pressure update
|
|
|
|
|
if (xSemaphoreTake(pipe_pressure_semaphore, 0) == pdTRUE) {
|
|
|
|
|
// Need to have short-circuit logic here on I2C errors, as otherwise we can easily wind up spending whole
|
|
|
|
|
// seconds with all of the transaction timeouts
|
|
|
|
|
|
|
|
|
|
bool valid_measurement = true;
|
|
|
|
|
|
|
|
|
|
for (int p_id = 0; p_id < 8; p_id++) {
|
|
|
|
|
if (select_pipe_sensor(p_id) != 0) {
|
|
|
|
|
valid_measurement = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
pipe_pressure_status.pipes[p_id] = mpr_sensor.readPressure();
|
|
|
|
|
if (pipe_pressure_status.pipes[p_id] == NAN) {
|
|
|
|
|
valid_measurement = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (valid_measurement) {
|
|
|
|
|
// Pass the pipe pressure status back to the main task
|
|
|
|
|
xQueueOverwrite(pipe_pressure_queue, &pipe_pressure_status);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Send a motor control packet if requested
|
|
|
|
|
if (xQueueReceive(motor_control_queue, &motor_write_packet.control, 0)==pdTRUE){
|
|
|
|
|
if (xQueueReceive(motor_control_queue, &motor_write_packet.control, 0) == pdTRUE) {
|
|
|
|
|
motor_write_packet.packet_type = MOTOR_CONTROL_PACKET;
|
|
|
|
|
Wire.beginTransmission(MOTOR_ESP32_SLAVE_I2C_ADDR);
|
|
|
|
|
Wire.write((byte *)&motor_write_packet, sizeof(motor_write_packet));
|
|
|
|
|
@ -82,7 +141,7 @@ static void i2c_comms_task(void *pvParameters) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Send a motor parameter packet if requested
|
|
|
|
|
if (xQueueReceive(motor_parameter_queue, &motor_write_packet.params, 0)==pdTRUE){
|
|
|
|
|
if (xQueueReceive(motor_parameter_queue, &motor_write_packet.params, 0) == pdTRUE) {
|
|
|
|
|
motor_write_packet.packet_type = MOTOR_PARAMETERS_PACKET;
|
|
|
|
|
Wire.beginTransmission(MOTOR_ESP32_SLAVE_I2C_ADDR);
|
|
|
|
|
Wire.write((byte *)&motor_write_packet, sizeof(motor_write_packet));
|
|
|
|
|
@ -94,11 +153,15 @@ static void i2c_comms_task(void *pvParameters) {
|
|
|
|
|
void i2c_comms_setup(void) {
|
|
|
|
|
// Initialise the I2C master
|
|
|
|
|
Wire.begin(GPIO_I2C_SDA, GPIO_I2C_SCL, (uint32_t)I2C_FREQUENCY);
|
|
|
|
|
Wire.setTimeOut(10);
|
|
|
|
|
|
|
|
|
|
// Initialise our queues and semaphores
|
|
|
|
|
motor_status_semaphore = xSemaphoreCreateBinary();
|
|
|
|
|
motor_status_queue = xQueueCreate(1, sizeof(motor_status_packet_t));
|
|
|
|
|
|
|
|
|
|
pipe_pressure_semaphore = xSemaphoreCreateBinary();
|
|
|
|
|
pipe_pressure_queue = xQueueCreate(1, sizeof(pipe_pressure_status_t));
|
|
|
|
|
|
|
|
|
|
motor_control_queue = xQueueCreate(1, sizeof(motor_control_group_t));
|
|
|
|
|
motor_parameter_queue = xQueueCreate(1, sizeof(motor_parameters_group_t));
|
|
|
|
|
|
|
|
|
|
|