feat: add ASSI lamp control and CAN protocol docs
This commit is contained in:
@@ -66,12 +66,20 @@ typedef struct
|
||||
#define CAN_HEARTBEAT_PERIOD_MS 1000U
|
||||
#define PWM_TIMEOUT_MS 1000U
|
||||
|
||||
#define CAN_HEARTBEAT_STD_ID 0x100U
|
||||
#define CAN_GPIO_REPORT_STD_ID 0x330U
|
||||
#define CAN_ADC_REPORT_STD_ID 0x102U
|
||||
#define CAN_PWM_REPORT_STD_ID 0x103U
|
||||
#define CAN_DAC_CMD_STD_ID 0x321U
|
||||
#define CAN_DAC_ACK_STD_ID 0x322U
|
||||
#define CAN_HEARTBEAT_STD_ID 0x6A0U
|
||||
#define CAN_ADC_REPORT_STD_ID 0x6A1U
|
||||
#define CAN_PWM_REPORT_STD_ID 0x6A2U
|
||||
#define CAN_DAC_CMD_STD_ID 0x6A3U
|
||||
#define CAN_DAC_ACK_STD_ID 0x6A4U
|
||||
#define CAN_ASSI_LAMP_CMD_STD_ID 0x6A5U
|
||||
#define CAN_GPIO_REPORT_STD_ID 0x6A6U
|
||||
|
||||
#define ASSI_LAMP_FLASH_HALF_PERIOD_MS 250U
|
||||
#define ASSI_STATE_OFF 0U
|
||||
#define ASSI_STATE_READY 1U
|
||||
#define ASSI_STATE_DRIVING 2U
|
||||
#define ASSI_STATE_EMERGENCY 3U
|
||||
#define ASSI_STATE_FINISHED 4U
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
@@ -110,7 +118,8 @@ static uint32_t adc_filter_sum;
|
||||
static uint8_t adc_filter_count;
|
||||
static uint8_t adc_filter_index;
|
||||
static char uart_line[UART_LINE_SIZE];
|
||||
static uint8_t uart_line_len;
|
||||
static uint8_t uart_line_len;
|
||||
static uint8_t assi_lamp_state;
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
@@ -133,8 +142,10 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name);
|
||||
static void PollCaptureChannels(void);
|
||||
static void PollGpioChanges(void);
|
||||
static void SendPeriodicReport(void);
|
||||
static void ServiceHeartbeat(void);
|
||||
static void SendCanHeartbeat(void);
|
||||
static void ServiceHeartbeat(void);
|
||||
static void ServiceAssiLamp(void);
|
||||
static void SendCanHeartbeat(void);
|
||||
static void HandleAssiLampSetRequest(const char *source, uint8_t state);
|
||||
static void HandleTextCommand(const char *source, const char *line);
|
||||
static void HandleDacSetRequest(const char *source, uint8_t dac_id, uint16_t millivolts);
|
||||
static void UartWrite(const char *text);
|
||||
@@ -221,9 +232,10 @@ int main(void)
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
PollUart();
|
||||
PollCanBus(&hcan1, "CAN1");
|
||||
PollCanBus(&hcan2, "CAN2");
|
||||
PollCaptureChannels();
|
||||
PollCanBus(&hcan1, "CAN1");
|
||||
PollCanBus(&hcan2, "CAN2");
|
||||
ServiceAssiLamp();
|
||||
PollCaptureChannels();
|
||||
PollGpioChanges();
|
||||
SendPeriodicReport();
|
||||
ServiceHeartbeat();
|
||||
@@ -666,7 +678,7 @@ static void MX_GPIO_Init(void)
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pins : PD8 PD9 PD10 PD11
|
||||
PD12 PD13 PD14 PD0
|
||||
@@ -687,8 +699,8 @@ static void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PE0 PE1 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
|
||||
/*Configure GPIO pins : PE0 PE1 PE9 PE10 PE11 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
@@ -753,14 +765,16 @@ static void AppInit(void)
|
||||
adc_filter_sum = 0U;
|
||||
adc_filter_count = 0U;
|
||||
adc_filter_index = 0U;
|
||||
uart_line_len = 0U;
|
||||
uart_line_len = 0U;
|
||||
assi_lamp_state = ASSI_STATE_OFF;
|
||||
|
||||
(void)DacSetMillivolts(1U, 0U);
|
||||
(void)DacSetMillivolts(2U, 0U);
|
||||
|
||||
UartWrite("\r\nA11 F407 monitor ready\r\n");
|
||||
UartWrite("UART: DAC1 1.234 or DAC2 2500\r\n");
|
||||
UartWrite("CAN cmd 0x321: [dac_id][mV_L][mV_H] or ASCII text\r\n");
|
||||
UartWrite("CAN cmd 0x6A3: [dac_id][mV_L][mV_H] or ASCII text\r\n");
|
||||
UartWrite("CAN cmd 0x6A5: [ASSI state 0=OFF,1=READY,2=DRIVING,3=EMERGENCY,4=FINISHED]\r\n");
|
||||
BroadcastGpioReport(0U, gpio_last_state);
|
||||
}
|
||||
|
||||
@@ -810,7 +824,7 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rx_header.StdId == CAN_DAC_CMD_STD_ID)
|
||||
if (rx_header.StdId == CAN_DAC_CMD_STD_ID)
|
||||
{
|
||||
if ((rx_header.DLC >= 3U) && (rx_data[0] >= 1U) && (rx_data[0] <= 2U))
|
||||
{
|
||||
@@ -825,8 +839,15 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name)
|
||||
memcpy(line, rx_data, length);
|
||||
line[length] = '\0';
|
||||
HandleTextCommand(name, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rx_header.StdId == CAN_ASSI_LAMP_CMD_STD_ID)
|
||||
{
|
||||
if ((rx_header.DLC >= 1U) && (rx_data[0] <= ASSI_STATE_FINISHED))
|
||||
{
|
||||
HandleAssiLampSetRequest(name, rx_data[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,7 +939,7 @@ static void SendPeriodicReport(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void ServiceHeartbeat(void)
|
||||
static void ServiceHeartbeat(void)
|
||||
{
|
||||
uint32_t now = HAL_GetTick();
|
||||
|
||||
@@ -927,7 +948,53 @@ static void ServiceHeartbeat(void)
|
||||
last_heartbeat_ms = now;
|
||||
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ServiceAssiLamp(void)
|
||||
{
|
||||
GPIO_PinState red = GPIO_PIN_RESET;
|
||||
GPIO_PinState green = GPIO_PIN_RESET;
|
||||
GPIO_PinState blue = GPIO_PIN_RESET;
|
||||
bool flash_on = ((HAL_GetTick() / ASSI_LAMP_FLASH_HALF_PERIOD_MS) & 1U) == 0U;
|
||||
|
||||
switch (assi_lamp_state)
|
||||
{
|
||||
case ASSI_STATE_READY:
|
||||
red = GPIO_PIN_SET;
|
||||
green = GPIO_PIN_SET;
|
||||
break;
|
||||
|
||||
case ASSI_STATE_DRIVING:
|
||||
red = flash_on ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
green = flash_on ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
break;
|
||||
|
||||
case ASSI_STATE_EMERGENCY:
|
||||
blue = flash_on ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
||||
break;
|
||||
|
||||
case ASSI_STATE_FINISHED:
|
||||
blue = GPIO_PIN_SET;
|
||||
break;
|
||||
|
||||
case ASSI_STATE_OFF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, red);
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, green);
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, blue);
|
||||
}
|
||||
|
||||
static void HandleAssiLampSetRequest(const char *source, uint8_t state)
|
||||
{
|
||||
char reply[64];
|
||||
|
||||
assi_lamp_state = state;
|
||||
snprintf(reply, sizeof(reply), "OK %s ASSI state=%u\r\n", source, (unsigned int)state);
|
||||
UartWrite(reply);
|
||||
}
|
||||
|
||||
static void SendCanHeartbeat(void)
|
||||
{
|
||||
@@ -945,7 +1012,7 @@ static void SendCanHeartbeat(void)
|
||||
can_heartbeat_sequence++;
|
||||
gpio_state = ReadGpioInputState();
|
||||
|
||||
/* CAN ID 0x100, sent independently on CAN1 and CAN2:
|
||||
/* CAN ID 0x6A0, sent independently on CAN1 and CAN2:
|
||||
* [0] 0xA1 board identifier; [1] firmware protocol version 1;
|
||||
* [2..3] sequence counter, little-endian; [4..7] uptime in ms, little-endian.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user