Skip to content

Commit e0555e1

Browse files
andreashergert1984Andreas
and
Andreas
authored
Improvement pipsolar crc (esphome#3316)
Co-authored-by: Andreas <andreas.hergert@otrs.com>
1 parent 0939894 commit e0555e1

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

esphome/components/pipsolar/pipsolar.cpp

+37-25
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ uint8_t Pipsolar::check_incoming_length_(uint8_t length) {
768768

769769
uint8_t Pipsolar::check_incoming_crc_() {
770770
uint16_t crc16;
771-
crc16 = calc_crc_(read_buffer_, read_pos_ - 3);
771+
crc16 = cal_crc_half_(read_buffer_, read_pos_ - 3);
772772
ESP_LOGD(TAG, "checking crc on incoming message");
773773
if (((uint8_t)((crc16) >> 8)) == read_buffer_[read_pos_ - 3] &&
774774
((uint8_t)((crc16) &0xff)) == read_buffer_[read_pos_ - 2]) {
@@ -797,7 +797,7 @@ uint8_t Pipsolar::send_next_command_() {
797797
this->command_start_millis_ = millis();
798798
this->empty_uart_buffer_();
799799
this->read_pos_ = 0;
800-
crc16 = calc_crc_(byte_command, length);
800+
crc16 = cal_crc_half_(byte_command, length);
801801
this->write_str(command);
802802
// checksum
803803
this->write(((uint8_t)((crc16) >> 8))); // highbyte
@@ -824,8 +824,8 @@ void Pipsolar::send_next_poll_() {
824824
this->command_start_millis_ = millis();
825825
this->empty_uart_buffer_();
826826
this->read_pos_ = 0;
827-
crc16 = calc_crc_(this->used_polling_commands_[this->last_polling_command_].command,
828-
this->used_polling_commands_[this->last_polling_command_].length);
827+
crc16 = cal_crc_half_(this->used_polling_commands_[this->last_polling_command_].command,
828+
this->used_polling_commands_[this->last_polling_command_].length);
829829
this->write_array(this->used_polling_commands_[this->last_polling_command_].command,
830830
this->used_polling_commands_[this->last_polling_command_].length);
831831
// checksum
@@ -892,29 +892,41 @@ void Pipsolar::add_polling_command_(const char *command, ENUMPollingCommand poll
892892
}
893893
}
894894

895-
uint16_t Pipsolar::calc_crc_(uint8_t *msg, int n) {
896-
// Initial value. xmodem uses 0xFFFF but this example
897-
// requires an initial value of zero.
898-
uint16_t x = 0;
899-
while (n--) {
900-
x = crc_xmodem_update_(x, (uint16_t) *msg++);
901-
}
902-
return (x);
903-
}
895+
uint16_t Pipsolar::cal_crc_half_(uint8_t *msg, uint8_t len) {
896+
uint16_t crc;
904897

905-
// See bottom of this page: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
906-
// Polynomial: x^16 + x^12 + x^5 + 1 (0x1021)
907-
uint16_t Pipsolar::crc_xmodem_update_(uint16_t crc, uint8_t data) {
908-
int i;
909-
crc = crc ^ ((uint16_t) data << 8);
910-
for (i = 0; i < 8; i++) {
911-
if (crc & 0x8000) {
912-
crc = (crc << 1) ^ 0x1021; //(polynomial = 0x1021)
913-
} else {
914-
crc <<= 1;
915-
}
898+
uint8_t da;
899+
uint8_t *ptr;
900+
uint8_t b_crc_hign;
901+
uint8_t b_crc_low;
902+
903+
uint16_t crc_ta[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
904+
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef};
905+
906+
ptr = msg;
907+
crc = 0;
908+
909+
while (len-- != 0) {
910+
da = ((uint8_t)(crc >> 8)) >> 4;
911+
crc <<= 4;
912+
crc ^= crc_ta[da ^ (*ptr >> 4)];
913+
da = ((uint8_t)(crc >> 8)) >> 4;
914+
crc <<= 4;
915+
crc ^= crc_ta[da ^ (*ptr & 0x0f)];
916+
ptr++;
916917
}
917-
return crc;
918+
919+
b_crc_low = crc;
920+
b_crc_hign = (uint8_t)(crc >> 8);
921+
922+
if (b_crc_low == 0x28 || b_crc_low == 0x0d || b_crc_low == 0x0a)
923+
b_crc_low++;
924+
if (b_crc_hign == 0x28 || b_crc_hign == 0x0d || b_crc_hign == 0x0a)
925+
b_crc_hign++;
926+
927+
crc = ((uint16_t) b_crc_hign) << 8;
928+
crc += b_crc_low;
929+
return (crc);
918930
}
919931

920932
} // namespace pipsolar

esphome/components/pipsolar/pipsolar.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ class Pipsolar : public uart::UARTDevice, public PollingComponent {
193193
void empty_uart_buffer_();
194194
uint8_t check_incoming_crc_();
195195
uint8_t check_incoming_length_(uint8_t length);
196-
uint16_t calc_crc_(uint8_t *msg, int n);
197-
uint16_t crc_xmodem_update_(uint16_t crc, uint8_t data);
196+
uint16_t cal_crc_half_(uint8_t *msg, uint8_t len);
198197
uint8_t send_next_command_();
199198
void send_next_poll_();
200199
void queue_command_(const char *command, uint8_t length);

0 commit comments

Comments
 (0)