#include "one_wire.h" #define OW_SLOT_A 6 #define OW_SLOT_B 64 #define OW_SLOT_C 60 #define OW_SLOT_D 10 #define OW_SLOT_E 9 #define OW_SLOT_F 55 #define OW_SLOT_G 10 #define OW_SLOT_H 480 #define OW_SLOT_I 70 #define OW_SLOT_J 410 #define DRIVE_DQ(x) ow->cb.drive_dq(ow->user_data, x) #define DELAY_US(x) ow->cb.delay_usec(ow->user_data, x) #define READ_DQ() ow->cb.read_dq(ow->user_data) static inline uint8_t onewire_op_reset(onewire_t *ow) { uint8_t sample_result; // Delay G DRIVE_DQ(1); DELAY_US(OW_SLOT_G); // Drive bus low, delay H DRIVE_DQ(0); DELAY_US(OW_SLOT_H); // Release bus, delay I DRIVE_DQ(1); DELAY_US(OW_SLOT_I); // Sample bus, delay J sample_result = READ_DQ(); DELAY_US(OW_SLOT_J); return sample_result; } static inline onewire_ret_t onewire_op_write_one_bit(onewire_t *ow) { // Drive bus low, delay A DRIVE_DQ(0); DELAY_US(OW_SLOT_A); // Release bus, delay B DRIVE_DQ(1); DELAY_US(OW_SLOT_B); return OW_OK; } static inline onewire_ret_t onewire_op_write_zero_bit(onewire_t *ow) { // Drive bus low, delay C DRIVE_DQ(0); DELAY_US(OW_SLOT_C); // Release bus, delay D DRIVE_DQ(1); DELAY_US(OW_SLOT_D); return OW_OK; } static inline uint8_t onewire_op_read_bit(onewire_t *ow) { uint8_t sample_value; // Drive bus low, delay A DRIVE_DQ(0); DELAY_US(OW_SLOT_A); // Release bus, delay E DRIVE_DQ(1); DELAY_US(OW_SLOT_E); // Sample bus to read bit from slave, delay F sample_value = READ_DQ(); DELAY_US(OW_SLOT_F); return sample_value; } uint8_t onewire_bus_reset(onewire_t *ow) { uint8_t device_response = onewire_op_reset(ow); return device_response ? 0 : 1; } static inline onewire_ret_t onewire_op_write_bit(onewire_t *ow, uint8_t bit) { if(bit) { onewire_op_write_one_bit(ow); }else{ onewire_op_write_zero_bit(ow); } return OW_OK; } onewire_ret_t onrwire_bus_write_bit(onewire_t *ow, uint8_t bit) { if(bit) onewire_op_write_one_bit(ow); else onewire_op_write_zero_bit(ow); return OW_OK; } uint8_t onewire_bus_read_bit(onewire_t *ow) { return onewire_op_read_bit(ow); } onewire_ret_t onewire_bus_write_byte(onewire_t *ow, uint8_t byte) { for(uint8_t i = 0; i < 8; i++) { onewire_op_write_bit(ow, byte & 0x01); byte >>= 1U; } return OW_OK; } uint8_t onewire_bus_read_byte(onewire_t *ow) { uint8_t result = 0x00; for(uint8_t i = 0; i < 8; i++) { result >>= 1U; if(onewire_op_read_bit(ow)) { result |= 0x80U; } } return result; } static uint8_t dscrc_table[] = { 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; const int FALSE = 0; const int TRUE = 1; //-------------------------------------------------------------------------- // Calculate the CRC8 of the byte value provided with the current // crc8_state. // Returns current crc8_state value // uint8_t update_crc8(uint8_t *crc8_state, uint8_t value) { // See Application Note 27 // TEST BUILD *crc8_state = dscrc_table[*crc8_state ^ value]; return *crc8_state; } //-------------------------------------------------------------------------- // Init device discovery on the 1-Wire bus // Return OW_OK // onewire_ret_t onewire_bus_search_init(onewire_t *ow) { // reset the search state ow->_search_state.LastDiscrepancy = 0; ow->_search_state.LastDeviceFlag = FALSE; ow->_search_state.LastFamilyDiscrepancy = 0; return OW_OK; } //-------------------------------------------------------------------------- // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing // search state. // Return OW_OK : device found, ROM number in ROM_NO buffer // OW_ERROR : device not found, end of search // static inline onewire_ret_t onewire_bus_search(onewire_t *ow, onewire_rom_num_t *rom) { int id_bit_number; int last_zero, rom_byte_number, search_result; int id_bit, cmp_id_bit; uint8_t rom_byte_mask, search_direction; // initialize for search id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = 0; ow->_search_state.crc8 = 0; // if the last call was not the last one if (!ow->_search_state.LastDeviceFlag) { // 1-Wire reset if (!onewire_bus_reset(ow)) { // reset the search ow->_search_state.LastDiscrepancy = 0; ow->_search_state.LastDeviceFlag = FALSE; ow->_search_state.LastFamilyDiscrepancy = 0; return OW_ERROR; } // issue the search command onewire_bus_write_byte(ow, 0xF0); // loop to do the search do { // read a bit and its complement id_bit = onewire_op_read_bit(ow); cmp_id_bit = onewire_op_read_bit(ow); // check for no devices on 1-wire if ((id_bit == 1) && (cmp_id_bit == 1)) break; else { // all devices coupled have 0 or 1 if (id_bit != cmp_id_bit) search_direction = id_bit; // bit write value for search else { // if this discrepancy if before the Last Discrepancy // on a previous next then pick the same as last time if (id_bit_number < ow->_search_state.LastDiscrepancy) search_direction = ((ow->_search_state.rom_num.rom_num[rom_byte_number] & rom_byte_mask) > 0); else // if equal to last pick 1, if not then pick 0 search_direction = (id_bit_number == ow->_search_state.LastDiscrepancy); // if 0 was picked then record its position in LastZero if (search_direction == 0) { last_zero = id_bit_number; // check for Last discrepancy in family if (last_zero < 9) ow->_search_state.LastFamilyDiscrepancy = last_zero; } } // set or clear the bit in the ROM byte rom_byte_number // with mask rom_byte_mask if (search_direction == 1) ow->_search_state.rom_num.rom_num[rom_byte_number] |= rom_byte_mask; else ow->_search_state.rom_num.rom_num[rom_byte_number] &= ~rom_byte_mask; // serial number search direction write bit onewire_op_write_bit(ow, search_direction); // increment the byte counter id_bit_number // and shift the mask rom_byte_mask id_bit_number++; rom_byte_mask <<= 1; // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask if (rom_byte_mask == 0) { update_crc8(&ow->_search_state.crc8, ow->_search_state.rom_num.rom_num[rom_byte_number]); // accumulate the CRC rom_byte_number++; rom_byte_mask = 1; } } } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 // if the search was successful then if (!((id_bit_number < 65) || (ow->_search_state.crc8 != 0))) { // search successful so set LastDiscrepancy,LastDeviceFlag,search_result ow->_search_state.LastDiscrepancy = last_zero; // check for last device if (ow->_search_state.LastDiscrepancy == 0) ow->_search_state.LastDeviceFlag = TRUE; search_result = TRUE; } } // if no device found then reset counters so next 'search' will be like a first if (!search_result || !ow->_search_state.rom_num.rom_num[0]) { ow->_search_state.LastDiscrepancy = 0; ow->_search_state.LastDeviceFlag = FALSE; ow->_search_state.LastFamilyDiscrepancy = 0; search_result = FALSE; } if (search_result){ *rom = ow->_search_state.rom_num; return OW_OK; }else{ return OW_ERROR; } } //-------------------------------------------------------------------------- // Find the 'next' devices on the 1-Wire bus // Return OW_OK : device found, ROM number in rom buffer // OW_ERROR : device not found, end of search // onewire_ret_t onewire_bus_search_nextdev(onewire_t *ow, onewire_rom_num_t *rom) { // leave the search state alone return onewire_bus_search(ow, rom); }