Skip to content

Commit 072bb87

Browse files
committedJul 30, 2024
Add advanced error handling and retry mechanisms.
1 parent e49d6a8 commit 072bb87

File tree

1 file changed

+119
-9
lines changed

1 file changed

+119
-9
lines changed
 

‎UPDI_Programmer.c

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// UPDI_Programmer.c
22
// STK500 compatible UPDI programmer firmware for Arduino
3-
// Version 1.2
3+
// Version 1.4
44

55
#include <avr/io.h>
66
#include <util/delay.h>
@@ -57,6 +57,10 @@
5757
// Buffer sizes
5858
#define MAX_BUFFER_SIZE 275
5959

60+
// Error handling constants
61+
#define MAX_RETRIES 3
62+
#define RETRY_DELAY_MS 100
63+
6064
// Function prototypes
6165
void uart_init(void);
6266
void uart_send_byte(uint8_t data);
@@ -74,6 +78,9 @@ void updi_write_cs(uint8_t address, uint8_t value);
7478
uint8_t updi_read_cs(uint8_t address);
7579
void updi_write_data(uint32_t address, uint8_t *data, uint16_t len);
7680
void updi_read_data(uint32_t address, uint8_t *data, uint16_t len);
81+
uint8_t updi_write_data_with_retry(uint32_t address, uint8_t *data, uint16_t len);
82+
uint8_t updi_read_data_with_retry(uint32_t address, uint8_t *data, uint16_t len);
83+
void log_error(const char *message);
7784

7885
// Global variables
7986
uint8_t rx_buffer[MAX_BUFFER_SIZE];
@@ -231,7 +238,7 @@ void handle_sync_error(uint8_t attempt) {
231238
uint16_t backoff_time = (1 << attempt) * 100; // Exponential backoff in milliseconds
232239
if (backoff_time > 5000) backoff_time = 5000; // Cap at 5 seconds
233240

234-
// TODO: Implement error logging or reporting mechanism
241+
log_error("UPDI synchronization failed");
235242

236243
_delay_ms(backoff_time);
237244
}
@@ -253,7 +260,7 @@ void process_stk500_command(void) {
253260

254261
// Receive token
255262
if (uart_receive_byte() != TOKEN) {
256-
// Invalid token, discard message
263+
log_error("Invalid STK500 token received");
257264
return;
258265
}
259266

@@ -288,6 +295,7 @@ void process_stk500_command(void) {
288295
if (updi_sync()) {
289296
stk500_send_response(STATUS_CMD_OK, NULL, 0);
290297
} else {
298+
log_error("Failed to enter programming mode");
291299
stk500_send_response(STATUS_CMD_FAILED, NULL, 0);
292300
}
293301
break;
@@ -305,22 +313,31 @@ void process_stk500_command(void) {
305313
case CMD_READ_FLASH:
306314
{
307315
uint16_t num_bytes = (rx_buffer[0] << 8) | rx_buffer[1];
308-
updi_read_data(current_address, tx_buffer, num_bytes);
309-
stk500_send_response(STATUS_CMD_OK, tx_buffer, num_bytes);
310-
current_address += num_bytes;
316+
if (updi_read_data_with_retry(current_address, tx_buffer, num_bytes)) {
317+
stk500_send_response(STATUS_CMD_OK, tx_buffer, num_bytes);
318+
current_address += num_bytes;
319+
} else {
320+
log_error("Failed to read flash memory");
321+
stk500_send_response(STATUS_CMD_FAILED, NULL, 0);
322+
}
311323
}
312324
break;
313325

314326
case CMD_WRITE_FLASH:
315327
{
316328
uint16_t num_bytes = (rx_buffer[0] << 8) | rx_buffer[1];
317-
updi_write_data(current_address, &rx_buffer[2], num_bytes);
318-
stk500_send_response(STATUS_CMD_OK, NULL, 0);
319-
current_address += num_bytes;
329+
if (updi_write_data_with_retry(current_address, &rx_buffer[2], num_bytes)) {
330+
stk500_send_response(STATUS_CMD_OK, NULL, 0);
331+
current_address += num_bytes;
332+
} else {
333+
log_error("Failed to write flash memory");
334+
stk500_send_response(STATUS_CMD_FAILED, NULL, 0);
335+
}
320336
}
321337
break;
322338

323339
default:
340+
log_error("Unknown STK500 command received");
324341
stk500_send_response(STATUS_CMD_FAILED, NULL, 0);
325342
break;
326343
}
@@ -387,3 +404,96 @@ void updi_read_data(uint32_t address, uint8_t *data, uint16_t len) {
387404
data[i] = updi_receive_byte();
388405
}
389406
}
407+
408+
// Write data to UPDI with retry mechanism
409+
uint8_t updi_write_data_with_retry(uint32_t address, uint8_t *data, uint16_t len) {
410+
uint8_t retries = 0;
411+
uint8_t success = 0;
412+
413+
while (retries < MAX_RETRIES && !success) {
414+
updi_write_data(address, data, len);
415+
416+
// Verify written data
417+
uint8_t verify_buffer[len];
418+
updi_read_data(address, verify_buffer, len);
419+
420+
if (memcmp(data, verify_buffer, len) == 0) {
421+
success = 1;
422+
} else {
423+
retries++;
424+
log_error("UPDI write verification failed, retrying...");
425+
_delay_ms(RETRY_DELAY_MS);
426+
}
427+
}
428+
429+
return success;
430+
}
431+
432+
// Read data from UPDI with retry mechanism
433+
uint8_t updi_read_data_with_retry(uint32_t address, uint8_t *data, uint16_t len) {
434+
uint8_t retries = 0;
435+
uint8_t success = 0;
436+
437+
while (retries < MAX_RETRIES && !success) {
438+
updi_read_data(address, data, len);
439+
440+
// Verify read data (read twice and compare)
441+
uint8_t verify_buffer[len];
442+
updi_read_data(address, verify_buffer, len);
443+
444+
if (memcmp(data, verify_buffer, len) == 0) {
445+
success = 1;
446+
} else {
447+
retries++;
448+
log_error("UPDI read verification failed, retrying...");
449+
_delay_ms(RETRY_DELAY_MS);
450+
}
451+
}
452+
453+
return success;
454+
}
455+
456+
// Log error message (placeholder implementation)
457+
void log_error(const char *message) {
458+
// For now, we'll just send it over UART for debugging purposes.
459+
while (*message) {
460+
uart_send_byte(*message++);
461+
}
462+
uart_send_byte('\r');
463+
uart_send_byte('\n');
464+
}
465+
466+
// CRC16 calculation for error checking
467+
uint16_t calculate_crc16(uint8_t *data, uint16_t length) {
468+
uint16_t crc = 0xFFFF;
469+
for (uint16_t i = 0; i < length; i++) {
470+
crc ^= (uint16_t)data[i];
471+
for (uint8_t j = 0; j < 8; j++) {
472+
if (crc & 0x0001) {
473+
crc = (crc >> 1) ^ 0xA001;
474+
} else {
475+
crc >>= 1;
476+
}
477+
}
478+
}
479+
return crc;
480+
}
481+
482+
// Advanced error recovery function
483+
void perform_error_recovery(void) {
484+
log_error("Performing error recovery...");
485+
486+
// Reset UPDI interface
487+
updi_send_break();
488+
489+
// Re-synchronize
490+
if (!updi_sync()) {
491+
log_error("Error recovery failed: unable to re-synchronize UPDI");
492+
return;
493+
}
494+
495+
// Reset device (if applicable)
496+
// TODO: Implement device-specific reset procedure
497+
498+
log_error("Error recovery complete");
499+
}

0 commit comments

Comments
 (0)