bool I2C_SerialDongle::Write ( I2C_Addr_t slaveAddr, ///< I2C Address of the slave device uint8_t cmd, ///< Command (type of write being performed) const Buffer *buf ///< Buffer of data to send down to the device ) { LOG( "Write SlaveAddr:0x%02x Cmd:0x%02x\n", slaveAddr, cmd ); // On the i2c bus, the following will take place (M=Master, S=Slave): // // M->S: Start // M->S: slave-addr w/ W // M->S: command // M->S: len // M->S: data (first byte should be address of master) // M->S: CRC // M->S: Stop PKT_Packet pkt; uint8_t len = buf->dataLen; if ( len > ( sizeof( pkt.data ) - 4 )) { LogError( "I2C_SerialDongle::Write len (%d) is too big for packet (%d)\n", len, sizeof( pkt.data )); len = sizeof( pkt.data ) - 4; } uint8_t *pd = &pkt.data[ 0 ]; uint8_t crc = 0; *pd++ = WritePacket; // Not send on i2c bus, therefore not included in crc *pd = ( slaveAddr << 1 ) | SlaveWrite; crc = Crc8( crc, *pd ); pd++; *pd = cmd; crc = Crc8( crc, *pd ); pd++; *pd = len; crc = Crc8( crc, *pd ); pd++; for ( int i = 0; i < len; i++ ) { *pd = buf->data[ i ]; crc = Crc8( crc, *pd ); pd++; } *pd++ = crc; pkt.len = pd - &pkt.data[ 0 ]; return SendPacketWaitForResponse( &pkt, WriteReplyPacket, 0, NULL ); } // Write
uint8_t Crc8Block( uint8_t crc, uint8_t *data, uint8_t len ) { while ( len > 0 ) { crc = Crc8( crc, *data++ ); len--; } return crc; } // Crc8Block
bool I2C_SerialDongle::Read ( I2C_Addr_t slaveAddr, ///< I2C Address of the slave device uint8_t cmd, ///< Command (type of read being performed) Buffer *buf ///< Buffer to place results in ) { LOG( "Read SlaveAddr:0x%02x Cmd:0x%02x\n", slaveAddr, cmd ); // On the i2c bus, the following will take place (M=Master, S=Slave): // // M->S: Start // M->S: slave-addr w/ W // M->S: command // M->S: Repeated Start // M->S: slave-addr w/ R // S->M: len // S->M: data (first byte should be address of slave) // S->M: CRC // M->S: Stop PKT_Packet pkt; uint8_t *pd = &pkt.data[ 0 ]; uint8_t crc = 0; *pd++ = ReadPacket; // Not send on i2c bus, therefore not included in crc *pd = ( slaveAddr << 1 ) | SlaveWrite; crc = Crc8( crc, *pd ); pd++; *pd = cmd; crc = Crc8( crc, *pd ); pd++; *pd = ( slaveAddr << 1 ) | SlaveRead; crc = Crc8( crc, *pd ); pd++; pkt.len = pd - &pkt.data[ 0 ]; // Since this is a synchronous call, we need to wait for the data to // arrive. return SendPacketWaitForResponse( &pkt, ReadReplyPacket, crc, buf ); } // Read
/************************************************** * Function name : * Created by : * Date created : * Description : * Notes : ***************************************************/ void sensor_read (U8 command) { DIS_command = command; write_packet.write_pos.start_byte = 0xAA; write_packet.write_pos.cmd_number = command; write_packet.write_pos.CRC = Crc8(write_packet.write_frame, 6); for(U8 i = 0; i < 8; i++) { read_packet.read_frame[i] = 0x00; } ss_low(); SPI_transfer (write_packet.write_frame, read_packet.read_frame, 7, read_callback); }
// call the handler in accordance with the identifier received block static bool ParsePacket(uint8_t *buf) { uint8_t len = 0; uint8_t i = 0; while ((handlerTable[i].id != buf[1]) && (handlerTable[i].func != NULL)) ++i; if (handlerTable[i].func == NULL) return FALSE; len = handlerTable[i].func(buf + 2); // formation of the response packet buf[0] = (uint8_t)slave_addr; // response ID is SLAVE_ADDR_RS485 buf[1]++; // id buf[2] = len + 4; buf[len + 3] = Crc8(buf, len + 3); return TRUE; }
void Comm_Task(void *param) { uint8_t buf_rec[BUFSIZE], i; uint16_t cnt = 0; static uint16_t datasize = 0; // init rs485 InitRS(USART1, 115200, e8N1, 100); while (1) { if (Read(buf_rec + datasize, 1) == 1) { ++datasize; if (datasize == 1) // address verification { if (buf_rec[0] == (uint8_t)slave_addr) { buf_rec[1] = BUFSIZE; // temporary maximum packet length memset(buf_rec + 2, 0, BUFSIZE - 2); } else datasize = 0; } else if (datasize == 2) // reception id { datasize = datasize; } else if (datasize == 3) // receiving a packet length { if ((buf_rec[2] > BUFSIZE) || (buf_rec[2] < 4)) { // incorrect packet length datasize = 0; } } else if (datasize >= buf_rec[2]) { uint16_t n = buf_rec[2] - 1; // checksum is OK? if (Crc8(buf_rec, n) == buf_rec[n]) { // parser packet memcpy(buf_tr, buf_rec, buf_rec[2]); if (ParsePacket(buf_tr)) Write(USART1, buf_tr, buf_tr[2]); // treated to remove the package from the buffer datasize = 0; } else { // response when the checksum does not match for (i = 0; i < 1; i++) buf_tr[i] = cnt++; Write(USART1, buf_tr, 1); // checksum is invalid datasize = 0; } } } else { // reception timeout Purge(); datasize = 0; } taskYIELD(); } }
int get(uint8_t DIS_num, uint8_t cmd) { uint8_t curr_total_att = ATT_TOTAL; uint8_t curr_a5_att = ATT_A5; uint8_t curr_got_a5_att = ATT_GOT_A5; char read_tmp_buf[7]; char dummy_byte = 0x55; char tmp = 0x55; uint8_t success = 0; // Стандартный стартовый байт write_packet.write_pos.start_byte = 0xAA; // Запишем команду write_packet.write_pos.cmd_number = cmd; // Данные - нули for (uint8_t i = 0; i < 4; i++) { write_packet.write_pos.data[i] = 0x00; } // Считаем CRC write_packet.write_pos.crc = Crc8(write_packet.write_frame, 6); // Начинаем пробовать получить 0хА5 while (curr_total_att) { curr_total_att--; // printf("Chip select... \n"); chipSelect(DIS_num); // printf("Done Chip select... \n"); bcm2835_spi_transfernb((char*) write_packet.write_frame, read_tmp_buf, 7); // printf("Transferred cmd... \n"); // ждем получения 0хА5 while (curr_a5_att) { curr_a5_att--; bcm2835_spi_transfernb(&dummy_byte, &tmp, 1); bcm2835_delay(1); // если получили, то перестаем ждать if (0xA5 == tmp) { break; } } // если был получен А5 if (tmp == 0xA5) { // printf("Got 0xA5 \n"); // ждем пока пройдут все A5 while (((tmp == 0xA5) || (tmp == 0x55)) && curr_got_a5_att) { curr_got_a5_att--; bcm2835_spi_transfernb(&dummy_byte, &tmp, 1); } // получаем сами данные if (curr_got_a5_att) { // printf("Got data \n"); bcm2835_spi_transfernb(&dummy_byte, (char*) read_packet.read_frame, 5); success = 1; chipSelect(DIS_NONE); break; } curr_got_a5_att = ATT_GOT_A5; } else { curr_a5_att = ATT_A5; } chipSelect(DIS_NONE); } if (success == 1) { // скопируем в буфер данные for(uint8_t i = 0; i < 4; i++){ usr_data_buf_ptr[i] = read_packet.read_pos.data[i]; read_packet.read_pos.data[i] = 0; } return 0; } else { printf("Failed to get \n"); return 1; } }
byte UnityConnector::mCRC(const byte *data, int len) { return Crc8(data, len) & 0x7F; }
void I2C_SerialDongle::PacketReceived( PKT_Packet *packet ) { uint8_t *pd = &packet->data[ 0 ]; PacketType packetType = (PacketType)*pd++; uint8_t crc = 0; uint8_t len = 0; if ( m_debugDongleData ) { DumpMem( "PktRcvd", 0, packet->data, packet->len ); } if ( packetType == ErrorPacket ) { m_response.m_errorCode = *pd; LogError( "Rcvd Error packet, error code:%d '%s'\n", m_response.m_errorCode, ErrorStr( m_response.m_errorCode )); } else if ( packetType == m_response.m_responseType ) { // This is the type of packet that the caller is waiting for. crc = m_response.m_partialCrc; if ( packet->len > 1 ) { // Check the CRC to see if it's valid len = *pd; crc = Crc8( crc, *pd ); pd++; // Sanity check the length. The packet length should equal the i2c len // plus 3 (1 for packet type, 1 for len, 1 for CRC) if (( len + 3 ) != packet->len ) { LogError( "I2C_SerialDongle::PacketReceived Inconsistent packet length. Serial packetLen = %d, i2c packetLen = %d (expecting %d)\n", packet->len, len, packet->len - 3 ); m_response.m_errorCode = I2C_ERROR_BAD_LEN; packetType = ErrorPacket; } else { for ( int i = 0; i < len; i++ ) { crc = Crc8( crc, pd[ i ]); } if ( crc != pd[ len ] ) { LogError( "I2C_SerialDongle::PacketReceived CRC failure. Found 0x%02x, expecting 0x%02x\n", pd[ len ], crc ); m_response.m_errorCode = I2C_ERROR_BAD_CRC; packetType = ErrorPacket; } } // We've received a good packet, and we're waiting for this type // of packet. Wakeup the reader if ( len < 1 ) { LogError( "I2C_SerialDongle::PacketReceived packet len too small (%d). Needs to be at least 1 to store address of sender\n", len ); len = 1; } if ( len > m_response.m_buf->dataLen ) { LogError( "I2C_SerialDongle::PacketReceived packet buffer too small. bufferSize = %d, received %d\n", m_response.m_buf->dataLen, len ); len = m_response.m_buf->dataLen; } m_response.m_buf->dataLen = len; if (( len > 0 ) && ( m_response.m_buf != NULL )) { memcpy( &m_response.m_buf->data[ 0 ], &pd[ 0 ], len ); } } } if (( packetType == m_response.m_responseType ) || ( packetType == ErrorPacket )) { // Setting m_responseType to NoPacket signals that we're no longer // waiting for a packet. m_response.m_responseType = NoPacket; sem_post( &m_response.m_semaphore ); return; } // Call the registered callback to report the received packet if ( m_callback != NULL ) { m_callback->PacketReceived( m_response.m_buf ); } else { LogError( "m_callback == NULL\n" ); LogError( "packetType:%d m_response.m_responseType:%d\n", packetType, m_response.m_responseType ); LogError( "packet len: %d\n", packet->len ); DumpMem( " pkt", 0, packet->data, packet->len ); } } // PacketReceived
bool I2C_SerialDongle::Call ( I2C_Addr_t slaveAddr, ///< I2C Address of the slave device uint8_t cmd, ///< Command (type of call being performed) const Buffer *writeBuf, ///< Buffer of data to send down to the device Buffer *readBuf ///< Buffer to place results in ) { LOG( "Call SlaveAddr:0x%02x Cmd:0x%02x\n", slaveAddr, cmd ); //------------------------------------------------------------------------ // Does a Write/Read (aka Process Call) with an i2c slave // // On the i2c bus, the following will take place (M=Master, S=Slave): // // M->S: Start // M->S: slave-addr w/ W // M->S: command // M->S: len // M->S: data (first byte should be address of master) // M->S: Repeated Start // M->S: slave-addr w/ R // S->M: len // S->M: data (first byte should be address of slave) // S->M: CRC // M->S: Stop PKT_Packet pkt; uint8_t len = writeBuf->dataLen; if ( len > ( sizeof( pkt.data ) - 5 )) { LogError( "I2C_SerialDongle::Call len (%d) is too big for packet (%d)\n", len, sizeof( pkt.data )); len = sizeof( pkt.data ) - 5; } uint8_t *pd = &pkt.data[ 0 ]; uint8_t crc = 0; *pd++ = CallPacket; // Not sent on i2c bus, therefore not included in crc *pd = ( slaveAddr << 1 ) | SlaveWrite; crc = Crc8( crc, *pd ); pd++; *pd = cmd; crc = Crc8( crc, *pd ); pd++; *pd = len; crc = Crc8( crc, *pd ); pd++; for ( int i = 0; i < len; i++ ) { *pd = writeBuf->data[ i ]; crc = Crc8( crc, *pd ); pd++; } *pd = ( slaveAddr << 1 ) | SlaveRead; crc = Crc8( crc, *pd ); pd++; pkt.len = pd - &pkt.data[ 0 ]; // Since this is a synchronous call, we need to wait for the data to // arrive. return SendPacketWaitForResponse( &pkt, CallReplyPacket, crc, readBuf ); } // Call