Multiple cleanups/tweaks for onewire driver
Use onewire_addr_t for onewire addresses Move internal defines out of onewire.h Remove global variables for search state use taskENTER_CRITICAL instead of portDISABLE_INTERRUPTS remove unnecessary onewire_init function Remove unnecessary critical sections Use GPIO_OUT_OPEN_DRAIN reformat/style cleanup
This commit is contained in:
		
							parent
							
								
									02c35d8a71
								
							
						
					
					
						commit
						a2b9d688ea
					
				
					 4 changed files with 304 additions and 359 deletions
				
			
		|  | @ -17,27 +17,28 @@ | |||
| #define DS1820_CONVERT_T        0x44 | ||||
| 
 | ||||
| uint8_t ds18b20_read_all(uint8_t pin, ds_sensor_t *result) { | ||||
|      | ||||
|     uint8_t addr[8]; | ||||
|     onewire_addr_t addr; | ||||
|     onewire_search_t search; | ||||
|     uint8_t sensor_id = 0; | ||||
|     onewire_reset_search(pin); | ||||
| 
 | ||||
|     onewire_search_start(&search); | ||||
|      | ||||
|     while(onewire_search(pin, addr)){ | ||||
|         uint8_t crc = onewire_crc8(addr, 7); | ||||
|         if (crc != addr[7]){ | ||||
|             printf("CRC check failed: %02X %02X\n", addr[7], crc); | ||||
|     while ((addr = onewire_search_next(&search, pin)) != ONEWIRE_NONE) { | ||||
|         uint8_t crc = onewire_crc8((uint8_t *)&addr, 7); | ||||
|         if (crc != (addr >> 56)){ | ||||
|             printf("CRC check failed: %02X %02X\n", (unsigned)(addr >> 56), crc); | ||||
|             return 0; | ||||
|         } | ||||
| 
 | ||||
|         onewire_reset(pin); | ||||
|         onewire_select(pin, addr); | ||||
|         onewire_write(pin, DS1820_CONVERT_T, ONEWIRE_DEFAULT_POWER); | ||||
|         onewire_write(pin, DS1820_CONVERT_T); | ||||
|          | ||||
|         vTaskDelay(750 / portTICK_RATE_MS); | ||||
|          | ||||
|         onewire_reset(pin); | ||||
|         onewire_select(pin, addr); | ||||
|         onewire_write(pin, DS1820_READ_SCRATCHPAD, ONEWIRE_DEFAULT_POWER); | ||||
|         onewire_write(pin, DS1820_READ_SCRATCHPAD); | ||||
| 
 | ||||
|         uint8_t get[10]; | ||||
| 
 | ||||
|  | @ -71,15 +72,14 @@ uint8_t ds18b20_read_all(uint8_t pin, ds_sensor_t *result) { | |||
| float ds18b20_read_single(uint8_t pin) { | ||||
|    | ||||
|     onewire_reset(pin); | ||||
| 
 | ||||
|     onewire_write(pin, DS1820_SKIP_ROM, ONEWIRE_DEFAULT_POWER); | ||||
|     onewire_write(pin, DS1820_CONVERT_T, ONEWIRE_DEFAULT_POWER); | ||||
|     onewire_skip_rom(pin); | ||||
|     onewire_write(pin, DS1820_CONVERT_T); | ||||
| 
 | ||||
|     vTaskDelay(750 / portTICK_RATE_MS); | ||||
| 
 | ||||
|     onewire_reset(pin); | ||||
|     onewire_write(pin, DS1820_SKIP_ROM, ONEWIRE_DEFAULT_POWER); | ||||
|     onewire_write(pin, DS1820_READ_SCRATCHPAD, ONEWIRE_DEFAULT_POWER); | ||||
|     onewire_skip_rom(pin); | ||||
|     onewire_write(pin, DS1820_READ_SCRATCHPAD); | ||||
|      | ||||
|     uint8_t get[10]; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,206 +1,176 @@ | |||
| #include "onewire.h" | ||||
| 
 | ||||
| // global search state
 | ||||
| static unsigned char ROM_NO[ONEWIRE_NUM][8]; | ||||
| static uint8_t LastDiscrepancy[ONEWIRE_NUM]; | ||||
| static uint8_t LastFamilyDiscrepancy[ONEWIRE_NUM]; | ||||
| static uint8_t LastDeviceFlag[ONEWIRE_NUM]; | ||||
| 
 | ||||
| void onewire_init(uint8_t pin) | ||||
| { | ||||
|   gpio_enable(pin, GPIO_INPUT);   | ||||
|   onewire_reset_search(pin); | ||||
| } | ||||
| #include "string.h" | ||||
| #include "task.h" | ||||
| #include "esp/gpio.h" | ||||
| 
 | ||||
| // Perform the onewire reset function.  We will wait up to 250uS for
 | ||||
| // the bus to come high, if it doesn't then it is broken or shorted
 | ||||
| // and we return a 0;
 | ||||
| // and we return false;
 | ||||
| //
 | ||||
| // Returns 1 if a device asserted a presence pulse, 0 otherwise.
 | ||||
| // Returns true if a device asserted a presence pulse, false otherwise.
 | ||||
| //
 | ||||
| uint8_t onewire_reset(uint8_t pin) | ||||
| { | ||||
| 	uint8_t r; | ||||
| 	uint8_t retries = 125; | ||||
| bool onewire_reset(int pin) { | ||||
|     bool r; | ||||
|     const int retries = 50; | ||||
| 
 | ||||
| 	noInterrupts(); | ||||
| 	DIRECT_MODE_INPUT(pin); | ||||
| 	interrupts(); | ||||
| 	// wait until the wire is high... just in case
 | ||||
| 	do { | ||||
| 		if (--retries == 0) return 0; | ||||
| 		delayMicroseconds(2); | ||||
| 	} while ( !DIRECT_READ(pin)); | ||||
|     gpio_enable(pin, GPIO_OUT_OPEN_DRAIN); | ||||
|     gpio_write(pin, 1); | ||||
|     // wait until the wire is high... just in case
 | ||||
|     for (int i = 0; i < retries; i++) { | ||||
|         if (gpio_read(pin)) break; | ||||
|         sdk_os_delay_us(5); | ||||
|     } | ||||
|     if (!gpio_read(pin)) { | ||||
|         // Bus shorted?
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
| 	noInterrupts(); | ||||
| 	DIRECT_WRITE_LOW(pin); | ||||
| 	DIRECT_MODE_OUTPUT(pin);	// drive output low
 | ||||
| 	interrupts(); | ||||
| 	delayMicroseconds(480); | ||||
| 	noInterrupts(); | ||||
| 	DIRECT_MODE_INPUT(pin);	// allow it to float
 | ||||
| 	delayMicroseconds(70); | ||||
| 	r = !DIRECT_READ(pin); | ||||
| 	interrupts(); | ||||
| 	delayMicroseconds(410); | ||||
| 	return r; | ||||
|     gpio_write(pin, 0); | ||||
|     sdk_os_delay_us(480); | ||||
| 
 | ||||
|     taskENTER_CRITICAL(); | ||||
|     gpio_write(pin, 1); // allow it to float
 | ||||
|     sdk_os_delay_us(70); | ||||
|     r = !gpio_read(pin); | ||||
|     taskEXIT_CRITICAL(); | ||||
| 
 | ||||
|     // Wait for all devices to finish pulling the bus low before returning
 | ||||
|     for (int i = 0; i < retries; i++) { | ||||
|         if (gpio_read(pin)) break; | ||||
|         sdk_os_delay_us(5); | ||||
|     } | ||||
|     sdk_os_delay_us(2); | ||||
| 
 | ||||
|     return r; | ||||
| } | ||||
| 
 | ||||
| // Write a bit. Port and bit is used to cut lookup time and provide
 | ||||
| // more certain timing.
 | ||||
| //
 | ||||
| static void onewire_write_bit(uint8_t pin, uint8_t v) | ||||
| { | ||||
| 	if (v & 1) { | ||||
| 		noInterrupts(); | ||||
| 		DIRECT_WRITE_LOW(pin); | ||||
| 		DIRECT_MODE_OUTPUT(pin);	// drive output low
 | ||||
| 		delayMicroseconds(10); | ||||
| 		DIRECT_WRITE_HIGH(pin);	// drive output high
 | ||||
| 		interrupts(); | ||||
| 		delayMicroseconds(55); | ||||
| 	} else { | ||||
| 		noInterrupts(); | ||||
| 		DIRECT_WRITE_LOW(pin); | ||||
| 		DIRECT_MODE_OUTPUT(pin);	// drive output low
 | ||||
| 		delayMicroseconds(65); | ||||
| 		DIRECT_WRITE_HIGH(pin);	// drive output high
 | ||||
| 		interrupts(); | ||||
| 		delayMicroseconds(5); | ||||
| 	} | ||||
| static void onewire_write_bit(int pin, uint8_t v) { | ||||
|     //TODO: should verify that the bus is high before starting
 | ||||
|     if (v & 1) { | ||||
|         taskENTER_CRITICAL(); | ||||
|         gpio_write(pin, 0);  // drive output low
 | ||||
|         sdk_os_delay_us(10); | ||||
|         gpio_write(pin, 1);  // allow output high
 | ||||
|         taskEXIT_CRITICAL(); | ||||
|         sdk_os_delay_us(55); | ||||
|     } else { | ||||
|         taskENTER_CRITICAL(); | ||||
|         gpio_write(pin, 0);  // drive output low
 | ||||
|         sdk_os_delay_us(65); | ||||
|         gpio_write(pin, 1); // allow output high
 | ||||
|         taskEXIT_CRITICAL(); | ||||
|     } | ||||
|     sdk_os_delay_us(1); | ||||
| } | ||||
| 
 | ||||
| // Read a bit. Port and bit is used to cut lookup time and provide
 | ||||
| // more certain timing.
 | ||||
| //
 | ||||
| static uint8_t onewire_read_bit(uint8_t pin) | ||||
| { | ||||
| 	uint8_t r; | ||||
| static int onewire_read_bit(int pin) { | ||||
|     int r; | ||||
| 
 | ||||
| 	noInterrupts(); | ||||
| 	DIRECT_MODE_OUTPUT(pin); | ||||
| 	DIRECT_WRITE_LOW(pin); | ||||
| 	delayMicroseconds(3); | ||||
| 	DIRECT_MODE_INPUT(pin);	// let pin float, pull up will raise
 | ||||
| 	delayMicroseconds(10); | ||||
| 	r = DIRECT_READ(pin); | ||||
| 	interrupts(); | ||||
| 	delayMicroseconds(53); | ||||
| 	return r; | ||||
|     //TODO: should verify that the bus is high before starting
 | ||||
|     taskENTER_CRITICAL(); | ||||
|     gpio_write(pin, 0); | ||||
|     sdk_os_delay_us(2); | ||||
|     gpio_write(pin, 1);  // let pin float, pull up will raise
 | ||||
|     sdk_os_delay_us(11); | ||||
|     r = gpio_read(pin);  // Must sample within 15us of start
 | ||||
|     taskEXIT_CRITICAL(); | ||||
|     sdk_os_delay_us(48); | ||||
| 
 | ||||
|     return r; | ||||
| } | ||||
| 
 | ||||
| // Write a byte. The writing code uses the active drivers to raise the
 | ||||
| // pin high, if you need power after the write (e.g. DS18S20 in
 | ||||
| // parasite power mode) then set 'power' to 1, otherwise the pin will
 | ||||
| // go tri-state at the end of the write to avoid heating in a short or
 | ||||
| // other mishap.
 | ||||
| // Write a byte. The writing code uses open-drain mode and expects the pullup
 | ||||
| // resistor to pull the line high when not driven low.  If you need strong
 | ||||
| // power after the write (e.g. DS18B20 in parasite power mode) then call
 | ||||
| // onewire_power() after this is complete to actively drive the line high.
 | ||||
| //
 | ||||
| void onewire_write(uint8_t pin, uint8_t v, uint8_t power /* = 0 */) { | ||||
|   uint8_t bitMask; | ||||
| void onewire_write(int pin, uint8_t v) { | ||||
|     uint8_t bitMask; | ||||
| 
 | ||||
|   for (bitMask = 0x01; bitMask; bitMask <<= 1) { | ||||
| 	  onewire_write_bit(pin, (bitMask & v)?1:0); | ||||
|   } | ||||
|   if ( !power) { | ||||
|   	noInterrupts(); | ||||
|   	DIRECT_MODE_INPUT(pin); | ||||
|   	DIRECT_WRITE_LOW(pin); | ||||
|   	interrupts(); | ||||
|   } | ||||
|     for (bitMask = 0x01; bitMask; bitMask <<= 1) { | ||||
|         onewire_write_bit(pin, (bitMask & v)?1:0); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool power /* = 0 */) { | ||||
|   uint16_t i; | ||||
|   for (i = 0 ; i < count ; i++) | ||||
|     onewire_write(pin, buf[i], ONEWIRE_DEFAULT_POWER); | ||||
|   if (!power) { | ||||
|     noInterrupts(); | ||||
|     DIRECT_MODE_INPUT(pin); | ||||
|     DIRECT_WRITE_LOW(pin); | ||||
|     interrupts(); | ||||
|   } | ||||
| void onewire_write_bytes(int pin, const uint8_t *buf, size_t count) { | ||||
|     size_t i; | ||||
| 
 | ||||
|     for (i = 0 ; i < count ; i++) { | ||||
|         onewire_write(pin, buf[i]); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Read a byte
 | ||||
| //
 | ||||
| uint8_t onewire_read(uint8_t pin) { | ||||
|   uint8_t bitMask; | ||||
|   uint8_t r = 0; | ||||
| uint8_t onewire_read(int pin) { | ||||
|     uint8_t bitMask; | ||||
|     uint8_t r = 0; | ||||
| 
 | ||||
|   for (bitMask = 0x01; bitMask; bitMask <<= 1) { | ||||
|   	if (onewire_read_bit(pin)) r |= bitMask; | ||||
|   } | ||||
|   return r; | ||||
|     for (bitMask = 0x01; bitMask; bitMask <<= 1) { | ||||
|         if (onewire_read_bit(pin)) r |= bitMask; | ||||
|     } | ||||
|     return r; | ||||
| } | ||||
| 
 | ||||
| void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count) { | ||||
|   uint16_t i; | ||||
|   for (i = 0 ; i < count ; i++) | ||||
|     buf[i] = onewire_read(pin); | ||||
| void onewire_read_bytes(int pin, uint8_t *buf, size_t count) { | ||||
|     size_t i; | ||||
| 
 | ||||
|     for (i = 0 ; i < count ; i++) { | ||||
|         buf[i] = onewire_read(pin); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Do a ROM select
 | ||||
| //
 | ||||
| void onewire_select(uint8_t pin, const uint8_t rom[8]) | ||||
| { | ||||
| void onewire_select(int pin, onewire_addr_t rom) { | ||||
|     uint8_t i; | ||||
| 
 | ||||
|     onewire_write(pin, 0x55, ONEWIRE_DEFAULT_POWER);           // Choose ROM
 | ||||
|     onewire_write(pin, 0x55);  // Choose ROM
 | ||||
| 
 | ||||
|     for (i = 0; i < 8; i++) onewire_write(pin, rom[i], ONEWIRE_DEFAULT_POWER); | ||||
|     for (i = 0; i < 8; i++) { | ||||
|         onewire_write(pin, rom & 0xff); | ||||
|         rom >>= 8; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Do a ROM skip
 | ||||
| //
 | ||||
| void onewire_skip(uint8_t pin) | ||||
| { | ||||
|     onewire_write(pin, 0xCC, ONEWIRE_DEFAULT_POWER);           // Skip ROM
 | ||||
| void onewire_skip_rom(int pin) { | ||||
|     onewire_write(pin, 0xCC);  // Skip ROM
 | ||||
| } | ||||
| 
 | ||||
| void onewire_depower(uint8_t pin) | ||||
| { | ||||
| 	noInterrupts(); | ||||
| 	DIRECT_MODE_INPUT(pin); | ||||
| 	interrupts(); | ||||
| void onewire_power(int pin) { | ||||
|     gpio_enable(pin, GPIO_OUTPUT); | ||||
|     gpio_write(pin, 1); | ||||
| } | ||||
| 
 | ||||
| // You need to use this function to start a search again from the beginning.
 | ||||
| // You do not need to do it for the first search, though you could.
 | ||||
| //
 | ||||
| void onewire_reset_search(uint8_t pin) | ||||
| { | ||||
|   // reset the search state
 | ||||
|   LastDiscrepancy[pin] = 0; | ||||
|   LastDeviceFlag[pin] = 0; | ||||
|   LastFamilyDiscrepancy[pin] = 0; | ||||
|   int i; | ||||
|   for(i = 7; ; i--) { | ||||
|     ROM_NO[pin][i] = 0; | ||||
|     if ( i == 0) break; | ||||
|   } | ||||
| void onewire_depower(int pin) { | ||||
|     gpio_enable(pin, GPIO_OUT_OPEN_DRAIN); | ||||
| } | ||||
| 
 | ||||
| void onewire_search_start(onewire_search_t *search) { | ||||
|     // reset the search state
 | ||||
|     memset(search, 0, sizeof(*search)); | ||||
| } | ||||
| 
 | ||||
| // Setup the search to find the device type 'family_code' on the next call
 | ||||
| // to search(*newAddr) if it is present.
 | ||||
| //
 | ||||
| void onewire_target_search(uint8_t pin, uint8_t family_code) | ||||
| { | ||||
|    // set the search state to find SearchFamily type devices
 | ||||
|    ROM_NO[pin][0] = family_code; | ||||
|    uint8_t i; | ||||
|    for (i = 1; i < 8; i++) | ||||
|       ROM_NO[pin][i] = 0; | ||||
|    LastDiscrepancy[pin] = 64; | ||||
|    LastFamilyDiscrepancy[pin] = 0; | ||||
|    LastDeviceFlag[pin] = 0; | ||||
| void onewire_search_prefix(onewire_search_t *search, uint8_t family_code) { | ||||
|     uint8_t i; | ||||
| 
 | ||||
|     search->rom_no[0] = family_code; | ||||
|     for (i = 1; i < 8; i++) { | ||||
|         search->rom_no[i] = 0; | ||||
|     } | ||||
|     search->last_discrepancy = 64; | ||||
|     search->last_device_found = false; | ||||
| } | ||||
| 
 | ||||
| // Perform a search. If this function returns a '1' then it has
 | ||||
| // enumerated the next device and you may retrieve the ROM from the
 | ||||
| // OneWire::address variable. If there are no devices, no further
 | ||||
| // Perform a search. If the next device has been successfully enumerated, its
 | ||||
| // ROM address will be returned.  If there are no devices, no further
 | ||||
| // devices, or something horrible happens in the middle of the
 | ||||
| // enumeration then a 0 is returned.  If a new device is found then
 | ||||
| // its address is copied to newAddr.  Use OneWire::reset_search() to
 | ||||
| // enumeration then ONEWIRE_NONE is returned.  Use OneWire::reset_search() to
 | ||||
| // start over.
 | ||||
| //
 | ||||
| // --- Replaced by the one from the Dallas Semiconductor web site ---
 | ||||
|  | @ -210,129 +180,115 @@ void onewire_target_search(uint8_t pin, uint8_t family_code) | |||
| // Return 1 : device found, ROM number in ROM_NO buffer
 | ||||
| //        0 : device not found, end of search
 | ||||
| //
 | ||||
| uint8_t onewire_search(uint8_t pin, uint8_t *newAddr) | ||||
| { | ||||
|    uint8_t id_bit_number; | ||||
|    uint8_t last_zero, rom_byte_number, search_result; | ||||
|    uint8_t id_bit, cmp_id_bit; | ||||
| onewire_addr_t onewire_search_next(onewire_search_t *search, int pin) { | ||||
|     uint8_t id_bit_number; | ||||
|     uint8_t last_zero, search_result; | ||||
|     int rom_byte_number; | ||||
|     uint8_t id_bit, cmp_id_bit; | ||||
|     onewire_addr_t addr; | ||||
| 
 | ||||
|    unsigned char rom_byte_mask, search_direction; | ||||
|     unsigned char 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; | ||||
|     // initialize for search
 | ||||
|     id_bit_number = 1; | ||||
|     last_zero = 0; | ||||
|     rom_byte_number = 0; | ||||
|     rom_byte_mask = 1; | ||||
|     search_result = 0; | ||||
|     | ||||
|    // if the last call was not the last one
 | ||||
|    if (!LastDeviceFlag[pin]) | ||||
|    { | ||||
|       // 1-Wire reset
 | ||||
|       if (!onewire_reset(pin)) | ||||
|       { | ||||
|          // reset the search
 | ||||
|          LastDiscrepancy[pin] = 0; | ||||
|          LastDeviceFlag[pin] = 0; | ||||
|          LastFamilyDiscrepancy[pin] = 0; | ||||
|          return 0; | ||||
|       } | ||||
|     // if the last call was not the last one
 | ||||
|     if (!search->last_device_found) { | ||||
|         // 1-Wire reset
 | ||||
|         if (!onewire_reset(pin)) { | ||||
|             // reset the search
 | ||||
|             search->last_discrepancy = 0; | ||||
|             search->last_device_found = false; | ||||
|             return ONEWIRE_NONE; | ||||
|         } | ||||
| 
 | ||||
|       // issue the search command
 | ||||
|       onewire_write(pin, 0xF0, ONEWIRE_DEFAULT_POWER); | ||||
|         // issue the search command
 | ||||
|         onewire_write(pin, 0xF0); | ||||
| 
 | ||||
|       // loop to do the search
 | ||||
|       do | ||||
|       { | ||||
|          // read a bit and its complement
 | ||||
|          id_bit = onewire_read_bit(pin); | ||||
|          cmp_id_bit = onewire_read_bit(pin); | ||||
|         // loop to do the search
 | ||||
|         do { | ||||
|             // read a bit and its complement
 | ||||
|             id_bit = onewire_read_bit(pin); | ||||
|             cmp_id_bit = onewire_read_bit(pin); | ||||
| 
 | ||||
|          // 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 < LastDiscrepancy[pin]) | ||||
|                   search_direction = ((ROM_NO[pin][rom_byte_number] & rom_byte_mask) > 0); | ||||
|                else | ||||
|                   // if equal to last pick 1, if not then pick 0
 | ||||
|                   search_direction = (id_bit_number == LastDiscrepancy[pin]); | ||||
|             // 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 < search->last_discrepancy) { | ||||
|                         search_direction = ((search->rom_no[rom_byte_number] & rom_byte_mask) > 0); | ||||
|                     } else { | ||||
|                         // if equal to last pick 1, if not then pick 0
 | ||||
|                         search_direction = (id_bit_number == search->last_discrepancy); | ||||
|                     } | ||||
| 
 | ||||
|                // if 0 was picked then record its position in LastZero
 | ||||
|                if (search_direction == 0) | ||||
|                { | ||||
|                   last_zero = id_bit_number; | ||||
|                     // 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) | ||||
|                      LastFamilyDiscrepancy[pin] = last_zero; | ||||
|                } | ||||
|                 // set or clear the bit in the ROM byte rom_byte_number
 | ||||
|                 // with mask rom_byte_mask
 | ||||
|                 if (search_direction == 1) { | ||||
|                     search->rom_no[rom_byte_number] |= rom_byte_mask; | ||||
|                 } else { | ||||
|                     search->rom_no[rom_byte_number] &= ~rom_byte_mask; | ||||
|                 } | ||||
| 
 | ||||
|                 // serial number search direction write bit
 | ||||
|                 onewire_write_bit(pin, 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) { | ||||
|                     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)) { | ||||
|             // search successful so set last_discrepancy,last_device_found,search_result
 | ||||
|             search->last_discrepancy = last_zero; | ||||
| 
 | ||||
|             // check for last device
 | ||||
|             if (search->last_discrepancy == 0) { | ||||
|                 search->last_device_found = true; | ||||
|             } | ||||
| 
 | ||||
|             // set or clear the bit in the ROM byte rom_byte_number
 | ||||
|             // with mask rom_byte_mask
 | ||||
|             if (search_direction == 1) | ||||
|               ROM_NO[pin][rom_byte_number] |= rom_byte_mask; | ||||
|             else | ||||
|               ROM_NO[pin][rom_byte_number] &= ~rom_byte_mask; | ||||
|             search_result = 1; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|             // serial number search direction write bit
 | ||||
|             onewire_write_bit(pin, 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) | ||||
|             { | ||||
|                 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)) | ||||
|       { | ||||
|          // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
 | ||||
|          LastDiscrepancy[pin] = last_zero; | ||||
| 
 | ||||
|          // check for last device
 | ||||
|          if (LastDiscrepancy[pin] == 0) | ||||
|             LastDeviceFlag[pin] = 1; | ||||
| 
 | ||||
|          search_result = 1; | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    // if no device found then reset counters so next 'search' will be like a first
 | ||||
|    if (!search_result || !ROM_NO[pin][0]) | ||||
|    { | ||||
|       LastDiscrepancy[pin] = 0; | ||||
|       LastDeviceFlag[pin] = 0; | ||||
|       LastFamilyDiscrepancy[pin] = 0; | ||||
|       search_result = 0; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       for (rom_byte_number = 0; rom_byte_number < 8; rom_byte_number++) | ||||
|       { | ||||
|          newAddr[rom_byte_number] = ROM_NO[pin][rom_byte_number]; | ||||
|          //printf("Ok I found something at %d - %x...\n",rom_byte_number, newAddr[rom_byte_number]);
 | ||||
|       } | ||||
|    } | ||||
|    return search_result; | ||||
|     // if no device found then reset counters so next 'search' will be like a first
 | ||||
|     if (!search_result || !search->rom_no[0]) { | ||||
|         search->last_discrepancy = 0; | ||||
|         search->last_device_found = false; | ||||
|         return ONEWIRE_NONE; | ||||
|     } else { | ||||
|         addr = 0; | ||||
|         for (rom_byte_number = 7; rom_byte_number >= 0; rom_byte_number--) { | ||||
|             addr = (addr << 8) | search->rom_no[rom_byte_number]; | ||||
|         } | ||||
|         //printf("Ok I found something at %08x%08x...\n", (uint32_t)(addr >> 32), (uint32_t)addr);
 | ||||
|     } | ||||
|     return addr; | ||||
| } | ||||
| 
 | ||||
| // The 1-Wire CRC scheme is described in Maxim Application Note 27:
 | ||||
|  | @ -371,41 +327,38 @@ static const uint8_t dscrc_table[] = { | |||
| // compared to all those delayMicrosecond() calls.  But I got
 | ||||
| // confused, so I use this table from the examples.)
 | ||||
| //
 | ||||
| uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) | ||||
| { | ||||
| 	uint8_t crc = 0; | ||||
| uint8_t onewire_crc8(const uint8_t *data, uint8_t len) { | ||||
|     uint8_t crc = 0; | ||||
| 
 | ||||
| 	while (len--) { | ||||
| 		crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); | ||||
| 	} | ||||
| 	return crc; | ||||
|     while (len--) { | ||||
|         crc = pgm_read_byte(dscrc_table + (crc ^ *data++)); | ||||
|     } | ||||
|     return crc; | ||||
| } | ||||
| #else | ||||
| //
 | ||||
| // Compute a Dallas Semiconductor 8 bit CRC directly.
 | ||||
| // this is much slower, but much smaller, than the lookup table.
 | ||||
| //
 | ||||
| uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) | ||||
| { | ||||
| 	uint8_t crc = 0; | ||||
| 	 | ||||
| 	while (len--) { | ||||
| 		uint8_t inbyte = *addr++; | ||||
|     uint8_t i; | ||||
| 		for (i = 8; i; i--) { | ||||
| 			uint8_t mix = (crc ^ inbyte) & 0x01; | ||||
| 			crc >>= 1; | ||||
| 			if (mix) crc ^= 0x8C; | ||||
| 			inbyte >>= 1; | ||||
| 		} | ||||
| 	} | ||||
| 	return crc; | ||||
| uint8_t onewire_crc8(const uint8_t *data, uint8_t len) { | ||||
|     uint8_t crc = 0; | ||||
|      | ||||
|     while (len--) { | ||||
|         uint8_t inbyte = *data++; | ||||
|         for (int i = 8; i; i--) { | ||||
|             uint8_t mix = (crc ^ inbyte) & 0x01; | ||||
|             crc >>= 1; | ||||
|             if (mix) crc ^= 0x8C; | ||||
|             inbyte >>= 1; | ||||
|         } | ||||
|     } | ||||
|     return crc; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| // Compute the 1-Wire CRC16 and compare it against the received CRC.
 | ||||
| // Example usage (reading a DS2408):
 | ||||
|     //    // Put everything in a buffer so we can compute the CRC easily.
 | ||||
| //    // Put everything in a buffer so we can compute the CRC easily.
 | ||||
| //    uint8_t buf[13];
 | ||||
| //    buf[0] = 0xF0;    // Read PIO Registers
 | ||||
| //    buf[1] = 0x88;    // LSB address
 | ||||
|  | @ -423,9 +376,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) | |||
| //                       *not* at a 16-bit integer.
 | ||||
| // @param crc - The crc starting value (optional)
 | ||||
| // @return 1, iff the CRC matches.
 | ||||
| bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) | ||||
| { | ||||
|     crc = ~onewire_crc16(input, len, crc); | ||||
| bool onewire_check_crc16(const uint8_t* input, size_t len, const uint8_t* inverted_crc, uint16_t crc_iv) { | ||||
|     uint16_t crc = ~onewire_crc16(input, len, crc_iv); | ||||
|     return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; | ||||
| } | ||||
| 
 | ||||
|  | @ -441,8 +393,8 @@ bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inve | |||
| // @param len - How many bytes to use.
 | ||||
| // @param crc - The crc starting value (optional)
 | ||||
| // @return The CRC16, as defined by Dallas Semiconductor.
 | ||||
| uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc) | ||||
| { | ||||
| uint16_t onewire_crc16(const uint8_t* input, size_t len, uint16_t crc_iv) { | ||||
|     uint16_t crc = crc_iv; | ||||
|     static const uint8_t oddparity[16] = | ||||
|         { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; | ||||
| 
 | ||||
|  | @ -463,4 +415,4 @@ uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc) | |||
|       crc ^= cdata; | ||||
|     } | ||||
|     return crc; | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -29,75 +29,72 @@ | |||
| #define ONEWIRE_CRC8_TABLE 0 | ||||
| #endif | ||||
| 
 | ||||
| // Platform specific I/O definitions
 | ||||
| #define noInterrupts portDISABLE_INTERRUPTS | ||||
| #define interrupts portENABLE_INTERRUPTS | ||||
| #define delayMicroseconds sdk_os_delay_us | ||||
| typedef uint64_t onewire_addr_t; | ||||
| 
 | ||||
| #define DIRECT_READ(pin)         gpio_read(pin) | ||||
| #define DIRECT_MODE_INPUT(pin)   gpio_enable(pin, GPIO_INPUT) | ||||
| #define DIRECT_MODE_OUTPUT(pin)  gpio_enable(pin, GPIO_OUTPUT) | ||||
| #define DIRECT_WRITE_LOW(pin)    gpio_write(pin, 0) | ||||
| #define DIRECT_WRITE_HIGH(pin)   gpio_write(pin, 1) | ||||
| typedef struct { | ||||
|     uint8_t rom_no[8]; | ||||
|     uint8_t last_discrepancy; | ||||
|     bool last_device_found; | ||||
| } onewire_search_t; | ||||
| 
 | ||||
| void onewire_init(uint8_t pin); | ||||
| // The following is an invalid ROM address that will never occur in a device
 | ||||
| // (CRC mismatch), and so can be useful as an indicator for "no-such-device",
 | ||||
| // etc.
 | ||||
| #define ONEWIRE_NONE ((onewire_addr_t)(0xffffffffffffffffLL)) | ||||
| 
 | ||||
| // Perform a 1-Wire reset cycle. Returns 1 if a device responds
 | ||||
| // with a presence pulse.  Returns 0 if there is no device or the
 | ||||
| // bus is shorted or otherwise held low for more than 250uS
 | ||||
| uint8_t onewire_reset(uint8_t pin); | ||||
| bool onewire_reset(int pin); | ||||
| 
 | ||||
| // Issue a 1-Wire rom select command, you do the reset first.
 | ||||
| void onewire_select(uint8_t pin, const uint8_t rom[8]); | ||||
| void onewire_select(int pin, const onewire_addr_t rom); | ||||
| 
 | ||||
| // Issue a 1-Wire rom skip command, to address all on bus.
 | ||||
| void onewire_skip(uint8_t pin); | ||||
| void onewire_skip_rom(int pin); | ||||
| 
 | ||||
| // Write a byte. If 'power' is one then the wire is held high at
 | ||||
| // the end for parasitically powered devices. You are responsible
 | ||||
| // for eventually depowering it by calling depower() or doing
 | ||||
| // another read or write.
 | ||||
| void onewire_write(uint8_t pin, uint8_t v, uint8_t power); | ||||
| // Write a byte. The writing code uses open-drain mode and expects the pullup
 | ||||
| // resistor to pull the line high when not driven low.  If you need strong
 | ||||
| // power after the write (e.g. DS18B20 in parasite power mode) then call
 | ||||
| // onewire_power() after this is complete to actively drive the line high.
 | ||||
| void onewire_write(int pin, uint8_t v); | ||||
| 
 | ||||
| void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool power); | ||||
| void onewire_write_bytes(int pin, const uint8_t *buf, size_t count); | ||||
| 
 | ||||
| // Read a byte.
 | ||||
| uint8_t onewire_read(uint8_t pin); | ||||
| uint8_t onewire_read(int pin); | ||||
| 
 | ||||
| void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count); | ||||
| void onewire_read_bytes(int pin, uint8_t *buf, size_t count); | ||||
| 
 | ||||
| // Write a bit. The bus is always left powered at the end, see
 | ||||
| // note in write() about that.
 | ||||
| // void onewire_write_bit(uint8_t pin, uint8_t v);
 | ||||
| 
 | ||||
| // Read a bit.
 | ||||
| // uint8_t onewire_read_bit(uint8_t pin);
 | ||||
| // Actively drive the bus high to provide extra power for certain operations of
 | ||||
| // parasitically-powered devices.
 | ||||
| void onewire_power(int pin); | ||||
| 
 | ||||
| // Stop forcing power onto the bus. You only need to do this if
 | ||||
| // you used the 'power' flag to write() or used a write_bit() call
 | ||||
| // and aren't about to do another read or write. You would rather
 | ||||
| // not leave this powered if you don't have to, just in case
 | ||||
| // someone shorts your bus.
 | ||||
| void onewire_depower(uint8_t pin); | ||||
| // you previously called onewire_power() to drive the bus high and now want to
 | ||||
| // allow it to float instead.  Note that onewire_reset() will also
 | ||||
| // automatically depower the bus first, so you do not need to call this first
 | ||||
| // if you just want to start a new operation.
 | ||||
| void onewire_depower(int pin); | ||||
| 
 | ||||
| // Clear the search state so that if will start from the beginning again.
 | ||||
| void onewire_reset_search(uint8_t pin); | ||||
| void onewire_search_start(onewire_search_t *search); | ||||
| 
 | ||||
| // Setup the search to find the device type 'family_code' on the next call
 | ||||
| // to search(*newAddr) if it is present.
 | ||||
| void onewire_target_search(uint8_t pin, uint8_t family_code); | ||||
| void onewire_search_prefix(onewire_search_t *search, uint8_t family_code); | ||||
| 
 | ||||
| // Look for the next device. Returns 1 if a new address has been
 | ||||
| // returned. A zero might mean that the bus is shorted, there are
 | ||||
| // no devices, or you have already retrieved all of them.  It
 | ||||
| // might be a good idea to check the CRC to make sure you didn't
 | ||||
| // get garbage.  The order is deterministic. You will always get
 | ||||
| // the same devices in the same order.
 | ||||
| uint8_t onewire_search(uint8_t pin, uint8_t *newAddr); | ||||
| // Look for the next device. Returns the address of the next device on the bus,
 | ||||
| // or ONEWIRE_NONE if there is no next address.  ONEWIRE_NONE might mean that
 | ||||
| // the bus is shorted, there are no devices, or you have already retrieved all
 | ||||
| // of them.  It might be a good idea to check the CRC to make sure you didn't
 | ||||
| // get garbage.  The order is deterministic. You will always get the same
 | ||||
| // devices in the same order.
 | ||||
| onewire_addr_t onewire_search_next(onewire_search_t *search, int pin); | ||||
| 
 | ||||
| // Compute a Dallas Semiconductor 8 bit CRC, these are used in the
 | ||||
| // ROM and scratchpad registers.
 | ||||
| uint8_t onewire_crc8(const uint8_t *addr, uint8_t len); | ||||
| uint8_t onewire_crc8(const uint8_t *data, uint8_t len); | ||||
| 
 | ||||
| // Compute the 1-Wire CRC16 and compare it against the received CRC.
 | ||||
| // Example usage (reading a DS2408):
 | ||||
|  | @ -117,9 +114,9 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len); | |||
| // @param inverted_crc - The two CRC16 bytes in the received data.
 | ||||
| //                       This should just point into the received data,
 | ||||
| //                       *not* at a 16-bit integer.
 | ||||
| // @param crc - The crc starting value (optional)
 | ||||
| // @param crc_iv - The crc starting value (optional)
 | ||||
| // @return True, iff the CRC matches.
 | ||||
| bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc); | ||||
| bool onewire_check_crc16(const uint8_t* input, size_t len, const uint8_t* inverted_crc, uint16_t crc_iv); | ||||
| 
 | ||||
| // Compute a Dallas Semiconductor 16 bit CRC.  This is required to check
 | ||||
| // the integrity of data received from many 1-Wire devices.  Note that the
 | ||||
|  | @ -131,8 +128,8 @@ bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inve | |||
| //      byte order than the two bytes you get from 1-Wire.
 | ||||
| // @param input - Array of bytes to checksum.
 | ||||
| // @param len - How many bytes to use.
 | ||||
| // @param crc - The crc starting value (optional)
 | ||||
| // @param crc_iv - The crc starting value (optional)
 | ||||
| // @return The CRC16, as defined by Dallas Semiconductor.
 | ||||
| uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc); | ||||
| uint16_t onewire_crc16(const uint8_t* input, size_t len, uint16_t crc_iv); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue