Skip to content
Snippets Groups Projects
Commit d95bbb0f authored by Christos Gentsos's avatar Christos Gentsos
Browse files

Refactor: make the PMBus commands model more practical

parent 1f159e35
No related branches found
No related tags found
No related merge requests found
......@@ -54,7 +54,7 @@ outside of `atmel_start_prj`.
- [x] Add I2C functionality to the bootloader, move remote
reprogramming functionality entirely there
- [x] Implement SMBus block write and block read commands
- [ ] Refactor the PMBus register model to make it more practical
- [x] Refactor the PMBus commands model to make it more practical
- [ ] Add I2C Packet Error Checking (PEC) for robustness (as described
in the [SMBus
specification](http://smbus.org/specs/smbus20.pdf), pp. 26-27)
......
......@@ -8,23 +8,47 @@
#include <checksums.h>
#define N_CMDS 10
static cmd_space_t cmds = {.n_cmds = N_CMDS,
.i2c_cmd_addrs = (uint8_t[N_CMDS]){1, 2, 3, 4, 5, 6, 11, 12, 13, 14},
.i2c_cmd_lengths = (int8_t[N_CMDS]){1, 2, 1, 2, 1, 2, 4, 4, 4, 4},
.i2c_cmd_pointers = (uint8_t*[N_CMDS]){},
.i2c_cmd_w_callback = (fp_t[N_CMDS]){},
.i2c_cmd_r_callback = (fp_t[N_CMDS]){}};
const char MFR_ID[] = "CERN (be/co)";
const char MFR_MODEL[] = "DIOT MoniMod (bl)";
const char MFR_REVISION[] = "0.1.0";
const char MFR_LOCATION[] = "Geneva";
const char MFR_DATE[] = "190801";
const char MFR_SERIAL[] = "123456789";
#define N_CMDS 12
static cmd_space_t cmds = {
N_CMDS,
(cmd_t[]){{1, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{2, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{3, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{4, 2, (uint8_t[]){0xde, 0xad}, (fp_t)NULL, (fp_t)NULL},
{5, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{6, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{0x99, -(int8_t)sizeof(MFR_ID), (uint8_t *)&MFR_ID, (fp_t)NULL, (fp_t)NULL},
{0x9A, -(int8_t)sizeof(MFR_MODEL), (uint8_t *)&MFR_MODEL, (fp_t)NULL, (fp_t)NULL},
{0x9B, -(int8_t)sizeof(MFR_REVISION), (uint8_t *)&MFR_REVISION, (fp_t)NULL, (fp_t)NULL},
{0x9C, -(int8_t)sizeof(MFR_LOCATION), (uint8_t *)&MFR_LOCATION, (fp_t)NULL, (fp_t)NULL},
{0x9D, -(int8_t)sizeof(MFR_DATE), (uint8_t *)&MFR_DATE, (fp_t)NULL, (fp_t)NULL},
{0x9E, -(int8_t)sizeof(MFR_SERIAL), (uint8_t *)&MFR_SERIAL, (fp_t)NULL, (fp_t)NULL}}
};
void written_fw_block();
void written_fw_checksum();
void uc_reset();
void boot_new_fw();
#define N_EXT_CMDS 6
static cmd_space_t ext_cmds = {.n_cmds = N_EXT_CMDS,
.i2c_cmd_addrs = (uint8_t[N_EXT_CMDS]){1, 2, 3, 4, 5, 6},
.i2c_cmd_lengths = (int8_t[N_EXT_CMDS]){2, 8, 2, 1, 1, 1},
.i2c_cmd_pointers = (uint8_t*[N_EXT_CMDS]){},
.i2c_cmd_w_callback = (fp_t[N_EXT_CMDS]){},
.i2c_cmd_r_callback = (fp_t[N_EXT_CMDS]){}};
static cmd_space_t ext_cmds = {
N_EXT_CMDS,
(cmd_t[]){{1, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{2, 8, (uint8_t *)NULL, &written_fw_block, (fp_t)NULL},
{3, 2, (uint8_t *)NULL, &written_fw_checksum, (fp_t)NULL},
{4, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{5, 1, (uint8_t *)NULL, &boot_new_fw, (fp_t)NULL},
{6, 1, (uint8_t *)NULL, &uc_reset, (fp_t)NULL}}
};
static uint8_t *fw_write_buf;
static uint8_t fw_write_cnt_octobyte;
......@@ -36,7 +60,7 @@ static uint16_t fw_local_checksum;
void written_fw_block()
{
for (uint8_t i = 0; i < 8; ++i)
fw_write_buf[i + 8*fw_write_cnt_octobyte] = ext_cmds.i2c_cmd_pointers[1][i];
fw_write_buf[i + 8*fw_write_cnt_octobyte] = ext_cmds.cmds[1].data_pnt[i];
if (fw_write_cnt_octobyte++ == FLASH_ROW_SIZE/8-1) { /* = 31 */
fw_write_cnt_octobyte = 0;
fw_write_pntr = fw_write_addr + (fw_write_cnt_page++)*FLASH_ROW_SIZE/4;
......@@ -63,7 +87,7 @@ void written_fw_checksum()
{
write_last_fw_block();
fw_local_checksum = sysv_checksum((uint8_t *)fw_write_addr, (uint8_t *)((uint32_t)fw_write_addr + 8*(*(uint16_t *)(&ext_cmds.i2c_cmd_pointers[0][0]))));
fw_local_checksum = sysv_checksum((uint8_t *)fw_write_addr, (uint8_t *)((uint32_t)fw_write_addr + 8*(*(uint16_t *)(&ext_cmds.cmds[0].data_pnt[0]))));
fw_write_cnt_page = 0;
fw_write_cnt_octobyte = 0;
......@@ -102,12 +126,6 @@ void setup_I2C_structs(cmd_space_t **impl_cmds, cmd_space_t **impl_ext_cmds)
init_addr_space(&ext_cmds);
*impl_cmds = &cmds;
*impl_ext_cmds = &ext_cmds;
cmds.i2c_cmd_pointers[3][0] = 0xde;
cmds.i2c_cmd_pointers[3][1] = 0xad;
ext_cmds.i2c_cmd_w_callback[1] = &written_fw_block;
ext_cmds.i2c_cmd_w_callback[2] = &written_fw_checksum;
ext_cmds.i2c_cmd_w_callback[4] = &boot_new_fw;
ext_cmds.i2c_cmd_w_callback[5] = &uc_reset;
fw_write_addr = (uint32_t *)0x2000;
fw_write_buf = (uint8_t *)malloc(FLASH_ROW_SIZE);
}
......@@ -12,13 +12,17 @@ typedef enum {
typedef void(*fp_t)(void);
typedef struct {
uint8_t addr;
int8_t data_len;
uint8_t *data_pnt;
fp_t w_callback;
fp_t r_callback;
} cmd_t;
typedef struct {
uint8_t n_cmds;
uint8_t *i2c_cmd_addrs;
int8_t *i2c_cmd_lengths;
uint8_t **i2c_cmd_pointers;
fp_t *i2c_cmd_w_callback;
fp_t *i2c_cmd_r_callback;
cmd_t *cmds;
} cmd_space_t;
void init_addr_space(cmd_space_t *addr_space);
......
......@@ -30,10 +30,12 @@ static cmd_space_t *ext_cmds;
void init_addr_space(cmd_space_t *addr_space)
{
for (uint8_t i = 0; i < addr_space->n_cmds; ++i) {
if (addr_space->i2c_cmd_lengths[i] > 0)
addr_space->i2c_cmd_pointers[i] = (uint8_t *)malloc(addr_space->i2c_cmd_lengths[i]);
else
addr_space->i2c_cmd_pointers[i] = (uint8_t *)malloc(-addr_space->i2c_cmd_lengths[i]);
if (!addr_space->cmds[i].data_pnt) {
if (addr_space->cmds[i].data_len > 0)
addr_space->cmds[i].data_pnt = (uint8_t *)malloc(addr_space->cmds[i].data_len);
else
addr_space->cmds[i].data_pnt = (uint8_t *)malloc(-addr_space->cmds[i].data_len);
}
}
}
......@@ -41,7 +43,7 @@ void init_addr_space(cmd_space_t *addr_space)
int16_t in_addr_space(cmd_space_t *addr_space, uint8_t addr)
{
for (uint8_t i = 0; i < addr_space->n_cmds; ++i)
if (addr == addr_space->i2c_cmd_addrs[i])
if (addr == addr_space->cmds[i].addr)
return i;
return -1;
}
......@@ -76,7 +78,7 @@ static void I2C_slave_rx_complete_int(const struct i2c_s_async_descriptor *const
} else if ((cmd_index = in_addr_space(cmds, std_cmd_addr)) != -1) {
ext_cmd_addr = 0;
cmd_len = 0;
if (cmds->i2c_cmd_lengths[cmd_index] < 0)
if (cmds->cmds[cmd_index].data_len < 0)
rx_state = BLK_GET_LEN;
else
rx_state = DATA;
......@@ -98,36 +100,36 @@ static void I2C_slave_rx_complete_int(const struct i2c_s_async_descriptor *const
}
break;
case DATA:
ret = io_read(io, &cmds->i2c_cmd_pointers[cmd_index][cmd_len], 1);
ret = io_read(io, &cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
#if PRINT_I2C_DEBUG > 1
debug("on rx_complete (DATA), cmd=%d, data=%d, idx=%d, status=%x, ret=%lu, length=%d",
std_cmd_addr, cmds->i2c_cmd_pointers[cmd_index][cmd_len],
cmd_len, status, ret, cmds->i2c_cmd_lengths[cmd_index]);
std_cmd_addr, cmds->cmds[cmd_index].data_pnt[cmd_len],
cmd_len, status, ret, cmds->cmds[cmd_index].data_len);
delay_ms(2);
#endif
++cmd_len;
if (cmd_len < abs(cmds->i2c_cmd_lengths[cmd_index])) {
if (cmd_len < abs(cmds->cmds[cmd_index].data_len)) {
send_ack(descr);
set_cmd(descr, 3);
} else {
send_ack(descr);
set_cmd(descr, 2);
rx_state = CMD;
if (cmds->i2c_cmd_w_callback[cmd_index])
cmds->i2c_cmd_w_callback[cmd_index]();
if (cmds->cmds[cmd_index].w_callback)
cmds->cmds[cmd_index].w_callback();
}
break;
case BLK_GET_LEN:
ret = io_read(io, (uint8_t *)&cmds->i2c_cmd_lengths[cmd_index], 1);
cmds->i2c_cmd_lengths[cmd_index] = -cmds->i2c_cmd_lengths[cmd_index];
if (cmds->i2c_cmd_pointers[cmd_index]) {
free(cmds->i2c_cmd_pointers[cmd_index]);
cmds->i2c_cmd_pointers[cmd_index] = malloc(-cmds->i2c_cmd_lengths[cmd_index]);
ret = io_read(io, (uint8_t *)&cmds->cmds[cmd_index].data_len, 1);
cmds->cmds[cmd_index].data_len = -cmds->cmds[cmd_index].data_len;
if (cmds->cmds[cmd_index].data_pnt) {
free(cmds->cmds[cmd_index].data_pnt);
cmds->cmds[cmd_index].data_pnt = malloc(-cmds->cmds[cmd_index].data_len);
}
#if PRINT_I2C_DEBUG > 1
debug("on rx_complete (BLK_GET_LEN), cmd=%d, data=%d, idx=%d, status=%x, ret=%lu, length=%d",
std_cmd_addr, cmds->i2c_cmd_pointers[cmd_index][cmd_len],
cmd_len, status, ret, cmds->i2c_cmd_lengths[cmd_index]);
std_cmd_addr, cmds->cmds[cmd_index].data_pnt[cmd_len],
cmd_len, status, ret, cmds->cmds[cmd_index].data_len);
delay_ms(2);
#endif
send_ack(descr);
......@@ -139,7 +141,7 @@ static void I2C_slave_rx_complete_int(const struct i2c_s_async_descriptor *const
if ((cmd_index = in_addr_space(ext_cmds, ext_cmd_addr)) != -1) {
send_ack(descr);
set_cmd(descr, 3);
if (ext_cmds->i2c_cmd_lengths[cmd_index] < 0)
if (ext_cmds->cmds[cmd_index].data_len < 0)
rx_state = EXT_BLK_GET_LEN;
else
rx_state = EXT_DATA;
......@@ -160,36 +162,36 @@ static void I2C_slave_rx_complete_int(const struct i2c_s_async_descriptor *const
}
break;
case EXT_DATA:
ret = io_read(io, &ext_cmds->i2c_cmd_pointers[cmd_index][cmd_len], 1);
ret = io_read(io, &ext_cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
#if PRINT_I2C_DEBUG > 1
debug("on rx_complete (EXT_DATA), ext_cmd=%d, data=%d, idx=%d, status=%x, ret=%lu, length=%d",
ext_cmd_addr, ext_cmds->i2c_cmd_pointers[cmd_index][cmd_len],
cmd_len, status, ret, ext_cmds->i2c_cmd_lengths[cmd_index]);
ext_cmd_addr, ext_cmds->cmds[cmd_index].data_pnt[cmd_len],
cmd_len, status, ret, ext_cmds->cmds[cmd_index].data_len);
delay_ms(2);
#endif
++cmd_len;
if (cmd_len < abs(ext_cmds->i2c_cmd_lengths[cmd_index])) {
if (cmd_len < abs(ext_cmds->cmds[cmd_index].data_len)) {
send_ack(descr);
set_cmd(descr, 3);
} else {
send_ack(descr);
set_cmd(descr, 2);
rx_state = CMD;
if (ext_cmds->i2c_cmd_w_callback[cmd_index])
ext_cmds->i2c_cmd_w_callback[cmd_index]();
if (ext_cmds->cmds[cmd_index].w_callback)
ext_cmds->cmds[cmd_index].w_callback();
}
break;
case EXT_BLK_GET_LEN:
ret = io_read(io, (uint8_t *)&ext_cmds->i2c_cmd_lengths[cmd_index], 1);
ext_cmds->i2c_cmd_lengths[cmd_index] = -ext_cmds->i2c_cmd_lengths[cmd_index];
if (ext_cmds->i2c_cmd_pointers[cmd_index]) {
free(ext_cmds->i2c_cmd_pointers[cmd_index]);
ext_cmds->i2c_cmd_pointers[cmd_index] = malloc(-ext_cmds->i2c_cmd_lengths[cmd_index]);
ret = io_read(io, (uint8_t *)&ext_cmds->cmds[cmd_index].data_len, 1);
ext_cmds->cmds[cmd_index].data_len = -ext_cmds->cmds[cmd_index].data_len;
if (ext_cmds->cmds[cmd_index].data_pnt) {
free(ext_cmds->cmds[cmd_index].data_pnt);
ext_cmds->cmds[cmd_index].data_pnt = malloc(-ext_cmds->cmds[cmd_index].data_len);
}
#if PRINT_I2C_DEBUG > 1
debug("on rx_complete (EXT_BLK_GET_LEN), ext_cmd=%d, data=%d, idx=%d, status=%x, ret=%lu, length=%d",
ext_cmd_addr, ext_cmds->i2c_cmd_pointers[cmd_index][cmd_len],
cmd_len, status, ret, ext_cmds->i2c_cmd_lengths[cmd_index]);
ext_cmd_addr, ext_cmds->cmds[cmd_index].data_pnt[cmd_len],
cmd_len, status, ret, ext_cmds->cmds[cmd_index].data_len);
delay_ms(2);
#endif
send_ack(descr);
......@@ -221,7 +223,7 @@ static void I2C_slave_tx_pending_int(const struct i2c_s_async_descriptor *const
return;
}
if (std_cmd_addr) {
reg_len = cmds->i2c_cmd_lengths[cmd_index];
reg_len = cmds->cmds[cmd_index].data_len;
if ((reg_len < 0) && (!blk_wrote_len_byte)) {
tmp = -reg_len;
ret = io_write(io, (uint8_t *)&tmp, 1);
......@@ -233,12 +235,12 @@ static void I2C_slave_tx_pending_int(const struct i2c_s_async_descriptor *const
delay_ms(2);
#endif
} else if (cmd_len < abs(reg_len)) {
ret = io_write(io, &cmds->i2c_cmd_pointers[cmd_index][cmd_len], 1);
ret = io_write(io, &cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
set_cmd(descr, 3);
#if PRINT_I2C_DEBUG > 1
debug("on tx_pending (ack), cmd=%d, status=%x, ret=%lu, length=%d, pos=%d, wrote=%d",
std_cmd_addr, status, ret, reg_len, cmd_len,
cmds->i2c_cmd_pointers[cmd_index][cmd_len]);
cmds->cmds[cmd_index].data_pnt[cmd_len]);
delay_ms(2);
#endif
++cmd_len;
......@@ -246,15 +248,15 @@ static void I2C_slave_tx_pending_int(const struct i2c_s_async_descriptor *const
ret = 0;
set_cmd(descr, 2);
rx_state = CMD;
if (cmds->i2c_cmd_r_callback[cmd_index])
cmds->i2c_cmd_r_callback[cmd_index]();
if (cmds->cmds[cmd_index].r_callback)
cmds->cmds[cmd_index].r_callback();
#if PRINT_I2C_DEBUG > 1
debug("on tx_pending (nack), cmd=%d, status=%x, ret=%lu", std_cmd_addr, status, ret);
delay_ms(2);
#endif
}
} else { /* extended command space */
reg_len = ext_cmds->i2c_cmd_lengths[cmd_index];
reg_len = ext_cmds->cmds[cmd_index].data_len;
if ((reg_len < 0) && (!blk_wrote_len_byte)) {
tmp = -reg_len;
ret = io_write(io, (uint8_t *)&tmp, 1);
......@@ -266,7 +268,7 @@ static void I2C_slave_tx_pending_int(const struct i2c_s_async_descriptor *const
delay_ms(2);
#endif
} else if (cmd_len < abs(reg_len)) {
ret = io_write(io, &ext_cmds->i2c_cmd_pointers[cmd_index][cmd_len], 1);
ret = io_write(io, &ext_cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
set_cmd(descr, 3);
#if PRINT_I2C_DEBUG > 1
debug("on ext tx_pending (ack), cmd=%d, status=%x, ret=%lu, length=%d, pos=%d",
......@@ -278,8 +280,8 @@ static void I2C_slave_tx_pending_int(const struct i2c_s_async_descriptor *const
ret = 0;
set_cmd(descr, 2);
rx_state = CMD;
if (ext_cmds->i2c_cmd_r_callback[cmd_index])
ext_cmds->i2c_cmd_r_callback[cmd_index]();
if (ext_cmds->cmds[cmd_index].r_callback)
ext_cmds->cmds[cmd_index].r_callback();
#if PRINT_I2C_DEBUG > 1
debug("on ext tx_pending (nack), cmd=%d, status=%x, ret=%lu", std_cmd_addr, status, ret);
delay_ms(2);
......
......@@ -19,21 +19,39 @@ extern uint32_t secondary_fw_start;
#define N_CMDS 12
static cmd_space_t cmds = {.n_cmds = N_CMDS,
.i2c_cmd_addrs = (uint8_t[N_CMDS]){1, 2, 3, 4, 5, 6, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E},
.i2c_cmd_lengths = (int8_t[N_CMDS]){1, 2, 1, 2, 1, 2, -1, -1, -1, -1, -1, -1},
.i2c_cmd_pointers = (uint8_t*[N_CMDS]){},
.i2c_cmd_w_callback = (fp_t[N_CMDS]){},
.i2c_cmd_r_callback = (fp_t[N_CMDS]){}};
#define N_EXT_CMDS 7
static cmd_space_t ext_cmds = {.n_cmds = N_EXT_CMDS,
.i2c_cmd_addrs = (uint8_t[N_EXT_CMDS]){1, 2, 3, 4, 5, 6, 10},
.i2c_cmd_lengths = (int8_t[N_EXT_CMDS]){2, 8, 2, 1, 1, 1, -1},
.i2c_cmd_pointers = (uint8_t*[N_EXT_CMDS]){},
.i2c_cmd_w_callback = (fp_t[N_EXT_CMDS]){},
.i2c_cmd_r_callback = (fp_t[N_EXT_CMDS]){}};
static cmd_space_t cmds = {
N_CMDS,
(cmd_t[]){{1, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{2, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{3, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{4, 2, (uint8_t[]){0xde, 0xad}, (fp_t)NULL, (fp_t)NULL},
{5, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{6, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{0x99, -(int8_t)sizeof(MFR_ID), (uint8_t *)&MFR_ID, (fp_t)NULL, (fp_t)NULL},
{0x9A, -(int8_t)sizeof(MFR_MODEL), (uint8_t *)&MFR_MODEL, (fp_t)NULL, (fp_t)NULL},
{0x9B, -(int8_t)sizeof(MFR_REVISION), (uint8_t *)&MFR_REVISION, (fp_t)NULL, (fp_t)NULL},
{0x9C, -(int8_t)sizeof(MFR_LOCATION), (uint8_t *)&MFR_LOCATION, (fp_t)NULL, (fp_t)NULL},
{0x9D, -(int8_t)sizeof(MFR_DATE), (uint8_t *)&MFR_DATE, (fp_t)NULL, (fp_t)NULL},
{0x9E, -(int8_t)sizeof(MFR_SERIAL), (uint8_t *)&MFR_SERIAL, (fp_t)NULL, (fp_t)NULL}}
};
void written_fw_block();
void written_fw_checksum();
void print_checksum();
void uc_reset();
void boot_new_fw();
#define N_EXT_CMDS 6
static cmd_space_t ext_cmds = {
N_EXT_CMDS,
(cmd_t[]){{1, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{2, 8, (uint8_t *)NULL, &written_fw_block, (fp_t)NULL},
{3, 2, (uint8_t *)NULL, &written_fw_checksum, (fp_t)NULL},
{4, 1, (uint8_t *)NULL, &print_checksum, (fp_t)NULL},
{5, 1, (uint8_t *)NULL, &boot_new_fw, (fp_t)NULL},
{6, 1, (uint8_t *)NULL, &uc_reset, (fp_t)NULL}}
};
static uint8_t *fw_write_buf;
static uint8_t fw_write_cnt_octobyte;
......@@ -45,7 +63,7 @@ static uint16_t fw_local_checksum;
void written_fw_block()
{
for (uint8_t i = 0; i < 8; ++i)
fw_write_buf[i + 8*fw_write_cnt_octobyte] = ext_cmds.i2c_cmd_pointers[1][i];
fw_write_buf[i + 8*fw_write_cnt_octobyte] = ext_cmds.cmds[1].data_pnt[i];
if (fw_write_cnt_octobyte++ == FLASH_ROW_SIZE/8-1) { /* = 31 */
fw_write_cnt_octobyte = 0;
fw_write_pntr = fw_write_addr + (fw_write_cnt_page++)*FLASH_ROW_SIZE/4;
......@@ -74,7 +92,7 @@ void written_fw_checksum()
{
write_last_fw_block();
fw_local_checksum = sysv_checksum((uint8_t *)fw_write_addr, (uint8_t *)((uint32_t)fw_write_addr + 8*(*(uint16_t *)(&ext_cmds.i2c_cmd_pointers[0][0]))));
fw_local_checksum = sysv_checksum((uint8_t *)fw_write_addr, (uint8_t *)((uint32_t)fw_write_addr + 8*(*(uint16_t *)(&ext_cmds.cmds[0].data_pnt[0]))));
fw_write_cnt_page = 0;
fw_write_cnt_octobyte = 0;
......@@ -83,10 +101,10 @@ void written_fw_checksum()
void print_checksum()
{
if (fw_local_checksum == *(uint16_t *)(&ext_cmds.i2c_cmd_pointers[2][0])) {
if (fw_local_checksum == *(uint16_t *)(&ext_cmds.cmds[2].data_pnt[0])) {
debug("locally computed checksum %u is correct!", fw_local_checksum);
} else {
debug("locally computed checksum %u differs from %u!", fw_local_checksum, *(uint16_t *)(&ext_cmds.i2c_cmd_pointers[2][0]));
debug("locally computed checksum %u differs from %u!", fw_local_checksum, *(uint16_t *)(&ext_cmds.cmds[2].data_pnt[0]));
}
}
......@@ -123,29 +141,10 @@ void boot_new_fw()
void setup_I2C_structs(cmd_space_t **impl_cmds, cmd_space_t **impl_ext_cmds)
{
cmds.i2c_cmd_lengths[6] = -(1 + (int8_t)strlen(MFR_ID));
cmds.i2c_cmd_lengths[7] = -(1 + (int8_t)strlen(MFR_MODEL));
cmds.i2c_cmd_lengths[8] = -(1 + (int8_t)strlen(MFR_REVISION));
cmds.i2c_cmd_lengths[9] = -(1 + (int8_t)strlen(MFR_LOCATION));
cmds.i2c_cmd_lengths[10] = -(1 + (int8_t)strlen(MFR_DATE));
cmds.i2c_cmd_lengths[11] = -(1 + (int8_t)strlen(MFR_SERIAL));
init_addr_space(&cmds);
init_addr_space(&ext_cmds);
*impl_cmds = &cmds;
*impl_ext_cmds = &ext_cmds;
cmds.i2c_cmd_pointers[3][0] = 0xde;
cmds.i2c_cmd_pointers[3][1] = 0xad;
strcpy((char *)cmds.i2c_cmd_pointers[6], MFR_ID);
strcpy((char *)cmds.i2c_cmd_pointers[7], MFR_MODEL);
strcpy((char *)cmds.i2c_cmd_pointers[8], MFR_REVISION);
strcpy((char *)cmds.i2c_cmd_pointers[9], MFR_LOCATION);
strcpy((char *)cmds.i2c_cmd_pointers[10], MFR_DATE);
strcpy((char *)cmds.i2c_cmd_pointers[11], MFR_SERIAL);
ext_cmds.i2c_cmd_w_callback[1] = &written_fw_block;
ext_cmds.i2c_cmd_w_callback[2] = &written_fw_checksum;
ext_cmds.i2c_cmd_w_callback[3] = &print_checksum;
ext_cmds.i2c_cmd_w_callback[4] = &boot_new_fw;
ext_cmds.i2c_cmd_w_callback[5] = &uc_reset;
fw_write_addr = (uint32_t *)0x22000;
fw_write_buf = (uint8_t *)malloc(FLASH_ROW_SIZE);
}
......@@ -7,26 +7,51 @@
#include <checksums.h>
#include <usb_debug.h>
const char MFR_ID[] = "CERN (be/co)";
const char MFR_MODEL[] = "DIOT MoniMod (st)";
const char MFR_REVISION[] = "0.1.0";
const char MFR_LOCATION[] = "Geneva";
const char MFR_DATE[] = "190801";
const char MFR_SERIAL[] = "123456789";
extern uint32_t secondary_fw_start;
#define N_CMDS 10
extern uint32_t secondary_fw_start;
static cmd_space_t cmds = {.n_cmds = N_CMDS,
.i2c_cmd_addrs = (uint8_t[N_CMDS]){1, 2, 3, 4, 5, 6, 11, 12, 13, 14},
.i2c_cmd_lengths = (int8_t[N_CMDS]){1, 2, 1, 2, 1, 2, 4, 4, 4, 4},
.i2c_cmd_pointers = (uint8_t*[N_CMDS]){},
.i2c_cmd_w_callback = (fp_t[N_CMDS]){},
.i2c_cmd_r_callback = (fp_t[N_CMDS]){}};
#define N_CMDS 12
static cmd_space_t cmds = {
N_CMDS,
(cmd_t[]){{1, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{2, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{3, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{4, 2, (uint8_t[]){0xde, 0xad}, (fp_t)NULL, (fp_t)NULL},
{5, 1, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{6, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{0x99, -(int8_t)sizeof(MFR_ID), (uint8_t *)&MFR_ID, (fp_t)NULL, (fp_t)NULL},
{0x9A, -(int8_t)sizeof(MFR_MODEL), (uint8_t *)&MFR_MODEL, (fp_t)NULL, (fp_t)NULL},
{0x9B, -(int8_t)sizeof(MFR_REVISION), (uint8_t *)&MFR_REVISION, (fp_t)NULL, (fp_t)NULL},
{0x9C, -(int8_t)sizeof(MFR_LOCATION), (uint8_t *)&MFR_LOCATION, (fp_t)NULL, (fp_t)NULL},
{0x9D, -(int8_t)sizeof(MFR_DATE), (uint8_t *)&MFR_DATE, (fp_t)NULL, (fp_t)NULL},
{0x9E, -(int8_t)sizeof(MFR_SERIAL), (uint8_t *)&MFR_SERIAL, (fp_t)NULL, (fp_t)NULL}}
};
void written_fw_block();
void written_fw_checksum();
void print_checksum();
void uc_reset();
void boot_new_fw();
#define N_EXT_CMDS 6
static cmd_space_t ext_cmds = {.n_cmds = N_EXT_CMDS,
.i2c_cmd_addrs = (uint8_t[N_EXT_CMDS]){1, 2, 3, 4, 5, 6},
.i2c_cmd_lengths = (int8_t[N_EXT_CMDS]){2, 8, 2, 1, 1, 1},
.i2c_cmd_pointers = (uint8_t*[N_EXT_CMDS]){},
.i2c_cmd_w_callback = (fp_t[N_EXT_CMDS]){},
.i2c_cmd_r_callback = (fp_t[N_EXT_CMDS]){}};
static cmd_space_t ext_cmds = {
N_EXT_CMDS,
(cmd_t[]){{1, 2, (uint8_t *)NULL, (fp_t)NULL, (fp_t)NULL},
{2, 8, (uint8_t *)NULL, &written_fw_block, (fp_t)NULL},
{3, 2, (uint8_t *)NULL, &written_fw_checksum, (fp_t)NULL},
{4, 1, (uint8_t *)NULL, &print_checksum, (fp_t)NULL},
{5, 1, (uint8_t *)NULL, &boot_new_fw, (fp_t)NULL},
{6, 1, (uint8_t *)NULL, &uc_reset, (fp_t)NULL}}
};
static uint8_t *fw_write_buf;
static uint8_t fw_write_cnt_octobyte;
......@@ -38,7 +63,7 @@ static uint16_t fw_local_checksum;
void written_fw_block()
{
for (uint8_t i = 0; i < 8; ++i)
fw_write_buf[i + 8*fw_write_cnt_octobyte] = ext_cmds.i2c_cmd_pointers[1][i];
fw_write_buf[i + 8*fw_write_cnt_octobyte] = ext_cmds.cmds[1].data_pnt[i];
if (fw_write_cnt_octobyte++ == FLASH_ROW_SIZE/8-1) { /* = 31 */
fw_write_cnt_octobyte = 0;
fw_write_pntr = fw_write_addr + (fw_write_cnt_page++)*FLASH_ROW_SIZE/4;
......@@ -67,7 +92,7 @@ void written_fw_checksum()
{
write_last_fw_block();
fw_local_checksum = sysv_checksum((uint8_t *)fw_write_addr, (uint8_t *)((uint32_t)fw_write_addr + 8*(*(uint16_t *)(&ext_cmds.i2c_cmd_pointers[0][0]))));
fw_local_checksum = sysv_checksum((uint8_t *)fw_write_addr, (uint8_t *)((uint32_t)fw_write_addr + 8*(*(uint16_t *)(&ext_cmds.cmds[0].data_pnt[0]))));
fw_write_cnt_page = 0;
fw_write_cnt_octobyte = 0;
......@@ -76,10 +101,10 @@ void written_fw_checksum()
void print_checksum()
{
if (fw_local_checksum == *(uint16_t *)(&ext_cmds.i2c_cmd_pointers[2][0])) {
if (fw_local_checksum == *(uint16_t *)(&ext_cmds.cmds[2].data_pnt[0])) {
debug("locally computed checksum %u is correct!", fw_local_checksum);
} else {
debug("locally computed checksum %u differs from %u!", fw_local_checksum, *(uint16_t *)(&ext_cmds.i2c_cmd_pointers[2][0]));
debug("locally computed checksum %u differs from %u!", fw_local_checksum, *(uint16_t *)(&ext_cmds.cmds[2].data_pnt[0]));
}
}
......@@ -120,13 +145,6 @@ void setup_I2C_structs(cmd_space_t **impl_cmds, cmd_space_t **impl_ext_cmds)
init_addr_space(&ext_cmds);
*impl_cmds = &cmds;
*impl_ext_cmds = &ext_cmds;
cmds.i2c_cmd_pointers[3][0] = 0xde;
cmds.i2c_cmd_pointers[3][1] = 0xad;
ext_cmds.i2c_cmd_w_callback[1] = &written_fw_block;
ext_cmds.i2c_cmd_w_callback[2] = &written_fw_checksum;
ext_cmds.i2c_cmd_w_callback[3] = &print_checksum;
ext_cmds.i2c_cmd_w_callback[4] = &boot_new_fw;
ext_cmds.i2c_cmd_w_callback[5] = &uc_reset;
fw_write_addr = (uint32_t *)0x22000;
fw_write_buf = (uint8_t *)malloc(FLASH_ROW_SIZE);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment