Redid i2c upload to work with stm32 client device

This commit is contained in:
2021-06-02 22:56:54 +02:00
parent 8cc1594b96
commit e9eccf43c1
5 changed files with 68 additions and 60 deletions

View File

@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "firmware.h"
#include "control.h"
@@ -75,66 +76,74 @@ void firmware_update() {
break;
case TARGET_I2C: {
// Get the I2C address
uint8_t address = 0;
HAL_UART_Receive(&huart2, &address, 1, 1000);
HAL_UART_Receive(&huart2, &address, 1, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart2, &address, sizeof(ack), HAL_MAX_DELAY);
// Check if we can read the version string
uint8_t version_command[] = {0x01};
HAL_I2C_Master_Transmit(&hi2c1, address << 1, version_command, sizeof(version_command), 1000);
uint8_t version_string[16] = {0};
HAL_I2C_Master_Receive(&hi2c1, address << 1, version_string, sizeof(version_string), 1000);
// Check if the device is available or if we need to reboot to bootloader
/* if (HAL_I2C_IsDeviceReady(&hi2c1, address << 1, 10, HAL_MAX_DELAY) != HAL_OK) { */
/* // Reset the device to the bootloader */
/* HAL_UART_Transmit(&huart2, nack, sizeof(nack), HAL_MAX_DELAY); */
/* return; */
/* } */
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
// Check the version string
if (version_string[0] == 'T' && version_string[1] == 'W' && version_string[2] == 'I') {
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
} else {
uint8_t reboot_command[] = {0xFF};
HAL_I2C_Master_Transmit(&hi2c1, address << 1, reboot_command, sizeof(reboot_command), 1000);
uint8_t rebooting[] = {0x02};
HAL_UART_Transmit(&huart2, rebooting, sizeof(rebooting), HAL_MAX_DELAY);
}
while (HAL_I2C_IsDeviceReady(&hi2c1, address << 1, 10, 1000) != HAL_OK);
// Wait for the device to be ready
/* while (HAL_I2C_IsDeviceReady(&hi2c1, address << 1, 10, HAL_MAX_DELAY) != HAL_OK); */
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
uint8_t abort_command[] = {0x00};
HAL_I2C_Master_Transmit(&hi2c1, address << 1, abort_command, sizeof(abort_command), 1000);
uint8_t command[] = {0xAF};
HAL_I2C_Master_Transmit(&hi2c1, address << 1, command, sizeof(command), HAL_MAX_DELAY);
// Re-read the version string in case we rebooted
HAL_I2C_Master_Transmit(&hi2c1, address << 1, version_command, sizeof(version_command), 1000);
HAL_I2C_Master_Receive(&hi2c1, address << 1, version_string, sizeof(version_string), 1000);
HAL_UART_Transmit(&huart2, version_string, sizeof(version_string), HAL_MAX_DELAY);
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
uint8_t upload_command[4 + 0x80];
upload_command[0] = 0x02;
upload_command[1] = 0x01;
uint16_t remaining = length;
for (uint8_t offset = 0; remaining > 0; ++offset) {
upload_command[2] = ((offset*0x80) >> 8) & 0xFF;
upload_command[3] = (offset*0x80) & 0xFF;
uint8_t amount = remaining > 0x80 ? 0x80 : remaining;
remaining -= amount;
// We need to handle the last section properly
memcpy(&upload_command[4], &data[offset*0x80], amount);
HAL_I2C_Master_Transmit(&hi2c1, address << 1, upload_command, sizeof(upload_command), 1000);
while (HAL_I2C_IsDeviceReady(&hi2c1, address << 1, 10, 1000) != HAL_OK);
uint8_t progress[] = {(length-remaining) & 0xFF, (length-remaining) >> 8};
HAL_UART_Transmit(&huart2, progress, sizeof(progress), HAL_MAX_DELAY);
// Send length to i2c device and confirm
HAL_I2C_Master_Transmit(&hi2c1, address << 1, length_buffer, sizeof(length_buffer), HAL_MAX_DELAY);
uint8_t received_length_buffer[2];
HAL_I2C_Master_Receive(&hi2c1, address << 1, received_length_buffer, sizeof(received_length_buffer), HAL_MAX_DELAY);
if (received_length_buffer[0] == length_buffer[0] && received_length_buffer[1] == length_buffer[1]) {
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
HAL_I2C_Master_Transmit(&hi2c1, address << 1, ack, sizeof(ack), HAL_MAX_DELAY);
} else {
HAL_UART_Transmit(&huart2, nack, sizeof(nack), HAL_MAX_DELAY);
HAL_I2C_Master_Transmit(&hi2c1, address << 1, nack, sizeof(nack), HAL_MAX_DELAY);
break;
}
// Start application
uint8_t start_command[] = {0x01, 0x80};
HAL_I2C_Master_Transmit(&hi2c1, address << 1, start_command, sizeof(start_command), 1000);
// @todo Put a limit timeout in place
// Wait for the device to be ready to receive
uint8_t status = 0;
while (status != 0x01) {
HAL_I2C_Master_Receive(&hi2c1, address << 1, &status, 1, HAL_MAX_DELAY);
}
HAL_I2C_Master_Transmit(&hi2c1, address << 1, data, length, HAL_MAX_DELAY);
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
// Verify the crc32
uint8_t received_c[4] = {0};
while (received_c[0] == 0 && received_c[1] == 0 && received_c[2] == 0 && received_c[3] == 0) {
HAL_I2C_Master_Receive(&hi2c1, address << 1, received_c, sizeof(received_c), HAL_MAX_DELAY);
}
if (c[0] == received_c[0] && c[1] == received_c[1] && c[2] == received_c[2] && c[3] == received_c[3]) {
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
HAL_I2C_Master_Transmit(&hi2c1, address << 1, ack, sizeof(ack), HAL_MAX_DELAY);
} else {
HAL_UART_Transmit(&huart2, nack, sizeof(nack), HAL_MAX_DELAY);
HAL_I2C_Master_Transmit(&hi2c1, address << 1, nack, sizeof(nack), HAL_MAX_DELAY);
break;
}
// Wait for programming to complete
status = 0;
while (status != 0x01) {
HAL_I2C_Master_Receive(&hi2c1, address << 1, &status, 1, HAL_MAX_DELAY);
}
// Done
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
break;
@@ -147,4 +156,3 @@ void firmware_update() {
printf("Complete!\n\r");
}

View File

@@ -90,13 +90,13 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
request_restart_to_bootloader();
break;
// Upload firmware
// Upload firmware
case 'u':
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
firmware_update();
break;
// Send over for bload
// Send over for bload
case 'l':
// @todo Implement this
break;
@@ -110,7 +110,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
command_mode = 1;
HAL_UART_Transmit(&huart2, ack, sizeof(ack), HAL_MAX_DELAY);
} else {
HAL_I2C_Master_Transmit(&hi2c1, 0x29 << 1, &byte, 1, 1000);
HAL_I2C_Master_Transmit(&hi2c1, 0x29 << 1, &byte, 1, 1);
}
HAL_UART_Receive_IT(&huart2, &byte, 1);
@@ -358,7 +358,7 @@ static void MX_I2C1_Init(void)
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.ClockSpeed = 10000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;