add I2C read

still not tested
This commit is contained in:
Kilian Bracher 2025-02-03 19:42:03 +01:00
parent fd1027523b
commit 81a1646ce6
Signed by: k.bracher
SSH Key Fingerprint: SHA256:mXpyZkK7RDiJ7qeHCKJX108woM0cl5TrCvNBJASu6lM
1 changed files with 108 additions and 1 deletions

View File

@ -346,7 +346,8 @@ HAL_StatusTypeDef amsSendI2C(uint8_t addresses[static N_BMS], uint8_t * data[sta
for (size_t i = 0; i < (packet_count * 3); i++) { //i - 1 is the number of data bytes sent so far (1 byte for the address)
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j))) continue; //skip BMS that are not selected
if (!(bms_mask & (1 << j)))
continue; //skip BMS that are not selected
if (i == 0) {
buffer[offset + 0] = I2C_SEND_START;
@ -388,3 +389,109 @@ HAL_StatusTypeDef amsSendI2C(uint8_t addresses[static N_BMS], uint8_t * data[sta
return HAL_OK;
}
HAL_StatusTypeDef amsReadI2C(uint8_t addresses[static N_BMS], uint8_t * data[static N_BMS], uint8_t datalens[static N_BMS], uint32_t bms_mask) {
uint8_t buffer[CMD_BUFFER_SIZE(COMM_GROUP_SIZE)] = {};
uint8_t max_datalen = 0;
for (size_t i = 0; i < N_BMS; i++) {
if (datalens[i] > max_datalen) {
max_datalen = datalens[i];
}
}
for (size_t i = 0; i < N_BMS; i++) {
size_t offset = BUFFER_BMS_OFFSET(i, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << i))) {
buffer[offset + 0] = I2C_SEND_NOTRANSFER;
buffer[offset + 2] = I2C_SEND_NOTRANSFER;
buffer[offset + 4] = I2C_SEND_NOTRANSFER;
continue;
}
}
size_t packet_count = ((max_datalen + 1) / 3) + ((max_datalen + 1) % 3 != 0);
for (size_t i = 0; i < (packet_count * 3);
i++) { // i - 1 is the number of data bytes sent so far (1 byte for the address)
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
if (i == 0) {
buffer[offset + 0] = I2C_SEND_START;
buffer[offset + 1] = addresses[j];
continue;
}
// add data to the buffer
// case 1: the last group of 3 bytes contained the last data byte, so we need to send a stop
if (datalens[j] - (int)i == -1) {
buffer[offset + ((i % 3) * 2)] = I2C_SEND_STOP;
continue;
}
// case 2: we are more than one byte past the end, so we don't need to receive any data
if (datalens[j] - (int)i < -1) {
buffer[offset + ((i % 3) * 2)] = I2C_SEND_NOTRANSFER;
continue;
}
// case 3: we are still receiving data
buffer[offset + ((i % 3) * 2)] = I2C_RECV_ACK;
}
// send the command data
if (i % 3 == 0 && i != 0) {
CHECK_RETURN(writeCMD(WRCOMM, buffer, COMM_GROUP_SIZE));
__pollCMD(STCOMM, 72); // wait 72 cycles for the I2C transfer to complete (datasheet page 43)
// TODO: not sure if this is correct for a daisy chain
// read the data
CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE));
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
for (size_t k = 0; k < 3; k++) {
if (datalens[j] - (int)i < -1) {
continue;
}
data[j][i - 1 + k] = buffer[offset + (k * 2) + 1];
}
}
}
}
// send the last packet
CHECK_RETURN(writeCMD(WRCOMM, buffer, COMM_GROUP_SIZE));
__pollCMD(STCOMM, 72);
// read the data
CHECK_RETURN(readCMD(RDCOMM, buffer, COMM_GROUP_SIZE));
for (size_t j = 0; j < N_BMS; j++) {
size_t offset = BUFFER_BMS_OFFSET(j, COMM_GROUP_SIZE);
if (!(bms_mask & (1 << j)))
continue; // skip BMS that are not selected
for (size_t k = 0; k < 3; k++) {
if (datalens[j] - (int)max_datalen < -1) {
continue;
}
data[j][max_datalen - 1 + k] = buffer[offset + (k * 2) + 1];
}
}
return HAL_OK;
}