uint8_t modbus_rxstart(uint8_t *data, uint8_t len, int16_t *recv_len) { #ifdef MODBUS_CLIENT_SUPPORT if (data[0] == MODBUS_ADDRESS || data[0] == MODBUS_BROADCAST) { modbus_client_process(data, len, recv_len); if (data[0] == MODBUS_ADDRESS) return 1; } #endif if (modbus_data.crc_len != 0) return 0; /* There is an packet on the way */ /* enable the transmitter */ PIN_SET(MODBUS_TX); modbus_recv_len_ptr = recv_len; modbus_data.crc = modbus_crc_calc(data, len); modbus_data.crc_len = 2; modbus_data.data = data; modbus_data.len = len; /* Enable the tx interrupt and send the first character */ modbus_data.sent = 1; usart(UCSR,B) |= _BV(usart(TXCIE)); usart(UDR) = data[0]; return 1; }
void modbus_periodic(void) { if (modbus_recv_timer == 0) return; modbus_recv_timer--; if (!modbus_recv_len_ptr) { #ifdef MODBUS_CLIENT_SUPPORT if (modbus_recv_timer == 0) { /* check the crc */ uint16_t crc = modbus_crc_calc(modbus_client_state.data, modbus_client_state.len - 2); uint16_t crc_recv = ((modbus_client_state.data[modbus_client_state.len - 1]) << 8) | modbus_client_state.data[modbus_client_state.len - 2]; if (crc != crc_recv) { modbus_client_state.len = 0; return; } /* See if we are the receiver */ if (!(modbus_client_state.data[0] == MODBUS_ADDRESS || modbus_client_state.data[0] == MODBUS_BROADCAST)) return; modbus_client_state.len -= 2; /* A message for our own modbus stack */ int16_t recv_len; modbus_client_process(modbus_client_state.data, modbus_client_state.len, &recv_len); if (recv_len) { PIN_SET(MODBUS_TX); modbus_data.data = modbus_client_state.data; modbus_data.len = recv_len; /* Enable the tx interrupt and send the first character */ modbus_data.sent = 1; usart(UCSR,B) |= _BV(usart(TXCIE)); usart(UDR) = modbus_client_state.data[0]; } modbus_client_state.len = 0; } #endif return; } if (modbus_recv_timer != 0) return; *modbus_recv_len_ptr = modbus_data.len; if (*modbus_recv_len_ptr < 2) *modbus_recv_len_ptr = -1; if (modbus_data.data[0] != modbus_last_address) { *modbus_recv_len_ptr = -1; } modbus_recv_len_ptr = NULL; }