one_wire: add search impl

This commit is contained in:
Miao Wang 2021-05-21 16:48:57 +08:00
parent e3b8c5fc5f
commit 08074f4051
3 changed files with 223 additions and 13 deletions

View File

@ -14,14 +14,28 @@ typedef struct {
uint8_t (*read_dq)(void *handle); uint8_t (*read_dq)(void *handle);
} onewire_cb_t; } onewire_cb_t;
typedef struct {
uint8_t rom_num[8];
} onewire_rom_num_t;
typedef struct {
int LastDiscrepancy;
int LastFamilyDiscrepancy;
int LastDeviceFlag;
uint8_t crc8;
onewire_rom_num_t rom_num;
} onewire_search_t;
typedef struct { typedef struct {
void *user_data; void *user_data;
onewire_cb_t cb; onewire_cb_t cb;
onewire_search_t _search_state;
} onewire_t; } onewire_t;
uint8_t onewire_bus_reset(onewire_t *ow); uint8_t onewire_bus_reset(onewire_t *ow);
onewire_ret_t onewire_bus_write_byte(onewire_t *ow, uint8_t byte); onewire_ret_t onewire_bus_write_byte(onewire_t *ow, uint8_t byte);
uint8_t onewire_bus_read_byte(onewire_t *ow); uint8_t onewire_bus_read_byte(onewire_t *ow);
onewire_ret_t onewire_bus_search_devices(onewire_t *ow); onewire_ret_t onewire_bus_search_init(onewire_t *ow);
onewire_ret_t onewire_bus_search_nextdev(onewire_t *ow, onewire_rom_num_t *rom);
#endif #endif

View File

@ -108,7 +108,13 @@ int main(void)
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
onewire_bus_reset(&g_ow); onewire_bus_reset(&g_ow);
onewire_bus_search_devices(&g_ow);
onewire_rom_num_t rom_num;
onewire_bus_search_init(&g_ow);
while(onewire_bus_search_nextdev(&g_ow, &rom_num)){
//register_ow_dev(rom_num);
}
/* USER CODE END 2 */ /* USER CODE END 2 */

View File

@ -87,15 +87,19 @@ uint8_t onewire_bus_reset(onewire_t *ow) {
return device_response ? 0 : 1; 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 onewire_bus_write_byte(onewire_t *ow, uint8_t byte) { onewire_ret_t onewire_bus_write_byte(onewire_t *ow, uint8_t byte) {
for(uint8_t i = 0; i < 8; i++) { for(uint8_t i = 0; i < 8; i++) {
if(byte & 0x01) { onewire_op_write_bit(ow, byte & 0x01);
onewire_op_write_one_bit(ow);
}
else {
onewire_op_write_zero_bit(ow);
}
byte >>= 1U; byte >>= 1U;
} }
@ -115,11 +119,197 @@ uint8_t onewire_bus_read_byte(onewire_t *ow) {
return result; return result;
} }
onewire_ret_t onewire_bus_search_devices(onewire_t *ow) { static uint8_t dscrc_table[] = {
onewire_bus_write_byte(ow, 0xF0); // Search ROM command. 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};
// Perform a binary search on the bus const int FALSE = 0;
const int TRUE = 1;
return OW_OK; //--------------------------------------------------------------------------
// 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);
}