summaryrefslogtreecommitdiff
path: root/src/master.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/master.c')
-rw-r--r--src/master.c272
1 files changed, 184 insertions, 88 deletions
diff --git a/src/master.c b/src/master.c
index 09b6b66..4cad251 100644
--- a/src/master.c
+++ b/src/master.c
@@ -48,12 +48,16 @@ uint32_t allocated[4]={0};
uint8_t dev_sts[BUS_DEVICE_LIMIT] = {OFFLINE};
uint8_t data_idx;
-_datapoint routing_buffer[ROUTING_BUFSIZE];
-/* Index information for each datapoint */
-uint8_t routing_idx_buffer[ROUTING_BUFSIZE];
-/* Pointer to tail of both data and idx buffers */
-uint32_t routing_ptr = 0;
+_datapoint routing_buffer[ROUTING_BUFSIZE]; /*< Buffer to store data to be routed */
+uint8_t *cmd_routing_buf[ROUTING_BUFSIZE]; /*< Buffer to store commands to be routed */
+uint8_t routing_idx_buffer[ROUTING_BUFSIZE]; /*< Index information for data source */
+uint8_t cmd_src_idx_rbuf[ROUTING_BUFSIZE]; /*< Index information for command source */
+uint8_t cmd_dst_idx_rbuf[ROUTING_BUFSIZE]; /*< Index information for command dest */
+
+uint32_t routing_ptr = 0; /*< Pointer to tail of both data and data index buffers */
+uint32_t cmd_routing_ptr = 0; /*< Pointer to tail of cmd and cmd index buffers */
+
/* Function prototypes */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
@@ -63,6 +67,8 @@ static void MX_USART1_UART_Init(void);
hs_status_t handshake(uint32_t i2c_addr);
dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t routing_buf_idx);
bool routing(void);
+bool cmd_routing(void);
+uint8_t get_CTS(uint8_t i2c_addr);
bool todo_hs_or_not_todo_hs(uint8_t i2c_addr);
state_t get_state_from_hs_status(uint16_t device_addr, hs_status_t hs_status);
bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args);
@@ -100,16 +106,15 @@ int main(void)
#endif /* MASTER */
#endif /* TESTING_ENABLE */
- uint8_t priority_counter = 0, debug_buf[128];
+ uint8_t priority_counter = 0, debug_buf[128] = {0};
/* Handshake */
while (1) {
if (priority_counter == 0) {
hs_status_t hs_status;
- /* for (uint8_t curr_addr=5; curr_addr == 5; curr_addr++) { */
- for (uint8_t curr_addr=0x1; curr_addr <= BUS_DEVICE_LIMIT; curr_addr++) {
- if (todo_hs_or_not_todo_hs(curr_addr)) {
- hs_status = handshake(curr_addr);
- dev_sts[GET_IDX_FROM_ADDR(curr_addr)] = get_state_from_hs_status(curr_addr, hs_status);
+ for (int dev_idx = 0; dev_idx < BUS_DEVICE_LIMIT-1; dev_idx++) {
+ if (todo_hs_or_not_todo_hs(GET_ADDR_FROM_IDX(dev_idx))) {
+ hs_status = handshake(GET_ADDR_FROM_IDX(dev_idx));
+ dev_sts[dev_idx] = get_state_from_hs_status(GET_ADDR_FROM_IDX(dev_idx), hs_status);
}
}
}
@@ -124,12 +129,9 @@ int main(void)
}
}
routing();
+ cmd_routing();
}
priority_counter = ((priority_counter+1)%10);
-
- sprintf((char*)debug_buf, "Routing pointer: %ld\r\n", routing_ptr);
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
}
}
@@ -147,7 +149,7 @@ hs_status_t handshake(uint32_t i2c_addr)
s2m_MDR_response MDR_res_message = s2m_MDR_response_init_default;
#if defined(TESTING_ENABLE) || defined(DEBUG_ENABLE)
- uint8_t debug_buf[128];
+ uint8_t debug_buf[128] = {0};
#endif
#ifdef TESTING_ENABLE
uint8_t term[] = "\r\n";
@@ -305,7 +307,7 @@ __TESTING_BLOCK_END:
{
goto __DEBUG_BLOCK_END;
__HS_MDR_REQ_I2C_ERROR:
- sprintf((char*)debug_buf, "Unable to send MDR request to %lx. I2C error: %ld\r\n", i2c_addr, HAL_I2C_GetError(&hi2c1));
+ sprintf((char*)debug_buf, "Unable to send MDR request to %lx. I2C error: %ld\r\n", i2c_addr>>1, HAL_I2C_GetError(&hi2c1));
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
goto __HS_MDR_REQ_I2C_ERROR_END;
@@ -337,13 +339,16 @@ __TESTING_BLOCK_END:
return hs_sts;
}
-dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t rbuf_data_idx)
+dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t rbuf_idx)
{
uint8_t dev_idx = GET_IDX_FROM_ADDR(i2c_addr);
dataflow_status_t df_status = DF_IDLE;
-
+ uint8_t CTS_buf[2] = {0x2, 0xFF};
+
uint8_t DOC_buf[4];
uint8_t *data_buf;
+ uint8_t cmd_dest;
+
uint32_t AF_error_counter = 0;
uint32_t data_len = 0;
_datapoint datapoints[16];
@@ -351,10 +356,7 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
/* TODO Add default values to the CTS message in proto */
s2m_data data_message = s2m_data_init_zero;
#if defined(TESTING_ENABLE) || defined(DEBUG_ENABLE)
- uint8_t debug_buf[128];
-#endif
-#ifdef TESTING_ENABLE
- uint8_t term[] = "\r\n";
+ uint8_t debug_buf[128]={0};
#endif
while (df_status != DF_SUCCESS && df_status != DF_FAIL) {
@@ -376,11 +378,10 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
df_status = DF_RX_DOC;
}
else if (SOR_code == SLAVE_RX_DATAPOINT) {
- /* TODO */
- df_status = DF_LEN_TX;
+ df_status = DF_TX_DATA;
}
else if (SOR_code == SLAVE_RX_COMMAND) {
- /* TODO */
+ df_status = DF_TX_CMD;
}
}
break;
@@ -392,7 +393,7 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
HAL_Delay(MASTER_I2C_BUS_INTERVAL);
AF_error_counter = 0;
while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr,
- (uint8_t*)DOC_buf, 4, 10000) != HAL_OK) {
+ (uint8_t*)DOC_buf, 4, 0xffff) != HAL_OK) {
if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
df_status = DF_FAIL;
#ifdef DEBUG_ENABLE
@@ -413,7 +414,9 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
data_len = DOC_buf[3];
}
else if (DOC_buf[1] == CMD_UNICAST) {
- /* TODO */
+ df_status = DF_CTS;
+ cmd_dest = DOC_buf[0];
+ data_len = DOC_buf[3];
}
else if (DOC_buf[1] == CMD_MULTICAST) {
/* TODO */
@@ -430,7 +433,6 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
case (DF_CTS):
{
HAL_Delay(MASTER_I2C_BUS_INTERVAL);
- uint8_t CTS_buf[2] = {0x2, 0xFF};
if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, CTS_buf, 2, 10000) != HAL_OK) {
df_status = DF_FAIL;
#ifdef DEBUG_ENABLE
@@ -444,7 +446,9 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
df_status = DF_RX_DATA;
}
else {
- /* TODO RX CMD stuff */
+ if (DOC_buf[1] == CMD_UNICAST) {
+ df_status = DF_RX_CMD;
+ }
}
}
break;
@@ -498,61 +502,75 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
}
break;
}
- case (DF_LEN_TX):
+ case (DF_TX_DATA):
{
HAL_Delay(MASTER_I2C_BUS_INTERVAL);
/* TODO error checking */
/* Will need to package datapoint and MDR to know their lengths
Once cached, will not need to do this */
- /* Do this after handshake to cache ================================================== */
+ /* Do this after handshake to cache ==================================== */
uint8_t MDR_buf[128], data_buf[128], CTS_buf[2];
- uint8_t src_device_idx = routing_idx_buffer[rbuf_data_idx];
+ uint8_t src_device_idx = routing_idx_buffer[rbuf_idx];
s2m_MDR_response data_src_MDR = device_info[src_device_idx]->MDR;
pb_ostream_t MDR_ostream = pb_ostream_from_buffer(MDR_buf, sizeof(MDR_buf));
data_src_MDR.subscriptions.funcs.encode=master_encode_MDR_callback;
pb_encode(&MDR_ostream, s2m_MDR_response_fields, &data_src_MDR);
uint8_t MDR_len = MDR_ostream.bytes_written;
- /* =================================================================================== */
+ /* ==================================================================== */
- _datapoint data = routing_buffer[rbuf_data_idx];
+ _datapoint data = routing_buffer[rbuf_idx];
pb_ostream_t data_ostream = pb_ostream_from_buffer(data_buf, sizeof(data_buf));
pb_encode(&data_ostream, _datapoint_fields, &data);
uint8_t data_len = data_ostream.bytes_written;
uint8_t data_MDR_len_buf[4] = {0, MDR_len, 0, data_len};
- AF_error_counter = 0;
- while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, CTS_buf, 2, 10000) != HAL_OK) {
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
- df_status = DF_FAIL;
- }
- if (++AF_error_counter > 3000) {
- df_status = DF_FAIL;
- }
- if (df_status == DF_FAIL) {
- sprintf((char*)debug_buf, "Failed to get LEN CTS\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
- break;
- }
- }
-
+ uint8_t status = get_CTS(i2c_addr);
HAL_Delay(MASTER_I2C_BUS_INTERVAL);
- if (df_status != DF_FAIL &&
- HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, data_MDR_len_buf, 4, 10000) == HAL_OK) {
+ if (status != 0 &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr,
+ data_MDR_len_buf, 4, 10000) == HAL_OK) {
+#ifdef DEBUG_ENABLE
sprintf((char*)debug_buf, "MDR len: %d data len: %d SENT\r\n", MDR_len, data_len);
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
+#endif
}
else {
+#ifdef DEBUG_ENABLE
sprintf((char*)debug_buf, "Failed to send lengths\r\n");
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
+#endif
+ }
+
+ status = get_CTS(i2c_addr);
+ if (status != 0 &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, MDR_buf,
+ MDR_len, 10000) == HAL_OK &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, data_buf,
+ data_len, 10000) == HAL_OK) {
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Data and MDR sent\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+#endif
+ df_status = DF_SUCCESS;
}
+ else {
+ df_status = DF_FAIL;
+ }
+ break;
+ }
+ case (DF_RX_CMD):
+ {
+ uint8_t *cmd_buf;
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ cmd_buf = (uint8_t*)malloc(data_len);
AF_error_counter = 0;
- while (df_status != DF_FAIL &&
- HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, CTS_buf, 2, 10000) != HAL_OK) {
+ while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, cmd_buf,
+ data_len, 10000) != HAL_OK) {
if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
df_status = DF_FAIL;
}
@@ -560,49 +578,78 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
df_status = DF_FAIL;
}
if (df_status == DF_FAIL) {
- sprintf((char*)debug_buf, "Failed to get TX CTS\r\n");
+ free(cmd_buf);
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Failed to get command, expected len: %ld\r\n", data_len);
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
+#endif
break;
}
}
+ if (df_status != DF_FAIL) {
+ cmd_routing_buf[cmd_routing_ptr] = malloc(sizeof(uint8_t)*data_len);
+ memcpy(cmd_routing_buf[cmd_routing_ptr], cmd_buf, data_len);
+ free(cmd_buf);
+
+ cmd_src_idx_rbuf[cmd_routing_ptr] = dev_idx;
+ cmd_dst_idx_rbuf[cmd_routing_ptr] = cmd_dest;
+ cmd_routing_ptr++;
-
-#ifdef TESTING_ENABLE
- uint8_t buf_title[64];
- sprintf((char*)buf_title, "MDR buffer: ");
- HAL_UART_Transmit(&huart1, buf_title, sizeof(buf_title), 100);
- memset(buf_title, 0, 64);
- for(int x=0; x<MDR_len; x++)
- sprintf((char*)debug_buf+x, "%x", MDR_buf[x]);
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- HAL_UART_Transmit(&huart1, term, 2, 100);
- memset(debug_buf, 0, 128);
-
- sprintf((char*)buf_title, "Data buffer: ");
- HAL_UART_Transmit(&huart1, buf_title, sizeof(buf_title), 100);
- memset(buf_title, 0, 64);
- for(int x=0; x<data_len; x++)
- sprintf((char*)debug_buf+x, "%x", data_buf[x]);
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- HAL_UART_Transmit(&huart1, term, 2, 100);
- memset(debug_buf, 0, 128);
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Got command\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
#endif
+ df_status = DF_SUCCESS;
+ }
+ break;
+ }
+ case (DF_TX_CMD):
+ {
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ uint8_t data_len = sizeof(cmd_routing_buf[rbuf_idx]);
+ uint8_t len_buf[] = {0x0, data_len, 0x0, 0x0};
- if (df_status != DF_FAIL &&
- HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, MDR_buf, MDR_len, 10000) == HAL_OK &&
- HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, data_buf, data_len, 10000) == HAL_OK) {
- sprintf((char*)debug_buf, "Data and MDR SENT\r\n");
+ uint8_t status = get_CTS(i2c_addr);
+ if (status != 0 &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, len_buf,
+ 4, 10000) != HAL_OK) {
+ df_status = DF_FAIL;
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Failed to send cmd len buf to %ld\r\n", i2c_addr>>1);
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
-
- df_status = DF_SUCCESS;
+#endif
+ }
+
+ if (df_status != DF_FAIL) {
+ uint8_t status = get_CTS(i2c_addr);
+ if (status != 0 &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr,
+ cmd_routing_buf[rbuf_idx],
+ 4, 10000) == HAL_OK) {
+ df_status = DF_SUCCESS;
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Routed cmd to %ld\r\n", i2c_addr>>1);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+#endif
+ }
+ else {
+ df_status = DF_FAIL;
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Failed to send cmd to %ld\r\n", i2c_addr>>1);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+#endif
+ }
}
break;
}
case DF_SUCCESS:
case DF_FAIL:
- break;
+ break;
}
}
@@ -619,7 +666,7 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
goto __DF_DEBUG_BLOCK_END;
__DF_SOR_I2C_ERROR:
sprintf((char*)debug_buf, "Unable to send SOR request to %d. I2C error: %ld\r\n",
- i2c_addr, HAL_I2C_GetError(&hi2c1));
+ i2c_addr>>1, HAL_I2C_GetError(&hi2c1));
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
goto __DF_SOR_I2C_ERROR_END;
@@ -651,6 +698,32 @@ dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t r
return df_status;
}
+uint8_t get_CTS(uint8_t i2c_addr)
+{
+ uint8_t CTS_buf[2], AF_error_counter = 0, debug_buf[20] = {0};
+ uint8_t status = 1;
+ while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, CTS_buf, 2, 10000) != HAL_OK) {
+ if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
+ status = 0;
+ }
+ if (++AF_error_counter > 1000) {
+ status = 0;
+ }
+ if (status == 0) {
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Failed to get CTS\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+#endif
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Dataflow routing
+ *
+ */
bool routing(void)
{
/* This table holds information on where to send each datapoint in the routing buffer */
@@ -660,12 +733,14 @@ bool routing(void)
for (uint8_t rbuf_data_idx = 0; rbuf_data_idx < routing_ptr; rbuf_data_idx++) {
uint8_t src_module_idx = routing_idx_buffer[rbuf_data_idx];
for (uint8_t dev_idx = 0; dev_idx < BUS_DEVICE_LIMIT; dev_idx++) {
- if (!(GET_BIT_FROM_IDX(allocated, dev_idx)&&1)) { // No module at this index
+ if (!(GET_BIT_FROM_IDX(allocated, dev_idx) && 1)) { // No module at this index
continue;
}
bool alloc = false;
- for (uint8_t dev_sub_idx = 0; dev_sub_idx < subs_info[dev_idx]->mod_idx && !alloc; dev_sub_idx++) {
- if (subs_info[dev_idx]->module_ids[dev_sub_idx] == device_info[src_module_idx]->MDR.module_id) {
+ for (uint8_t dev_sub_idx = 0;
+ dev_sub_idx < subs_info[dev_idx]->mod_idx && !alloc; dev_sub_idx++) {
+ if (subs_info[dev_idx]->module_ids[dev_sub_idx] ==
+ device_info[src_module_idx]->MDR.module_id) {
SET_BIT_FROM_IDX(routing_table[rbuf_data_idx], dev_idx);
alloc = true;
}
@@ -688,6 +763,27 @@ bool routing(void)
return true;
}
+/**
+ * @brief Routing specific to commands. Currently only supports Unicast commands, multicast and
+ * broadcast support to be added in a later version if deemed necessary.
+ *
+ */
+bool cmd_routing(void)
+{
+ /* uint32_t routing_table[4]; */
+ for (uint8_t rbuf_cmd_idx = 0; rbuf_cmd_idx < cmd_routing_ptr; rbuf_cmd_idx++) {
+ uint8_t dst_module_idx = cmd_dst_idx_rbuf[rbuf_cmd_idx];
+ for (int dev_idx = 0; dev_idx < BUS_DEVICE_LIMIT; dev_idx++) {
+ if (GET_BIT_FROM_IDX(allocated, dev_idx) &&
+ device_info[dev_idx]->MDR.module_id == dst_module_idx) {
+ device_dataflow(GET_ADDR_FROM_IDX(dev_idx), SLAVE_RX_COMMAND, rbuf_cmd_idx);
+ }
+ }
+ }
+ cmd_routing_ptr = 0;
+ return true;
+}
+
bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args)
{
_subscriptions subs;
@@ -889,7 +985,7 @@ void SystemClock_Config(void)
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
- hi2c1.Init.ClockSpeed = 400000;
+ hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;