mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
[FL-3179] 1-Wire Overdrive Mode (#2522)
* Separate ibutton to its own module, add one_wire to f18 * Move onewire cli to a separate app * Add definitions for normal and overdrive timings * Update api definitions * Add rough overdrive timings definition for onewire emulation * Remove one_wire_host_timing.h * Add rough overdrive timings for onewire host * Improve overdrive mode * Working overdrive mode from flipper to flipper * Update thermometer example app * Turn on otg power when running thermometer example app * Implement reset overdrive switching * Always exit out of overdrive mode * Improve overdrive timings * Fix typos * Fix reset behaviour * Use overdrive mode everywhere in DS1996 * Improve comments * Bump API version Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -1,10 +1,54 @@
|
||||
#include <furi.h>
|
||||
|
||||
/**
|
||||
* Timings based on Application Note 126:
|
||||
* https://www.analog.com/media/en/technical-documentation/tech-articles/1wire-communication-through-software--maxim-integrated.pdf
|
||||
*/
|
||||
|
||||
#include "one_wire_host.h"
|
||||
#include "one_wire_host_timing.h"
|
||||
|
||||
typedef struct {
|
||||
uint16_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
uint16_t d;
|
||||
uint16_t e;
|
||||
uint16_t f;
|
||||
uint16_t g;
|
||||
uint16_t h;
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
} OneWireHostTimings;
|
||||
|
||||
static const OneWireHostTimings onewire_host_timings_normal = {
|
||||
.a = 9,
|
||||
.b = 64,
|
||||
.c = 64,
|
||||
.d = 14,
|
||||
.e = 9,
|
||||
.f = 55,
|
||||
.g = 0,
|
||||
.h = 480,
|
||||
.i = 70,
|
||||
.j = 410,
|
||||
};
|
||||
|
||||
static const OneWireHostTimings onewire_host_timings_overdrive = {
|
||||
.a = 1,
|
||||
.b = 8,
|
||||
.c = 8,
|
||||
.d = 3,
|
||||
.e = 1,
|
||||
.f = 7,
|
||||
.g = 3,
|
||||
.h = 70,
|
||||
.i = 9,
|
||||
.j = 40,
|
||||
};
|
||||
|
||||
struct OneWireHost {
|
||||
const GpioPin* gpio_pin;
|
||||
const OneWireHostTimings* timings;
|
||||
unsigned char saved_rom[8]; /** < global search state */
|
||||
uint8_t last_discrepancy;
|
||||
uint8_t last_family_discrepancy;
|
||||
@@ -15,6 +59,7 @@ OneWireHost* onewire_host_alloc(const GpioPin* gpio_pin) {
|
||||
OneWireHost* host = malloc(sizeof(OneWireHost));
|
||||
host->gpio_pin = gpio_pin;
|
||||
onewire_host_reset_search(host);
|
||||
onewire_host_set_overdrive(host, false);
|
||||
return host;
|
||||
}
|
||||
|
||||
@@ -27,6 +72,8 @@ bool onewire_host_reset(OneWireHost* host) {
|
||||
uint8_t r;
|
||||
uint8_t retries = 125;
|
||||
|
||||
const OneWireHostTimings* timings = host->timings;
|
||||
|
||||
// wait until the gpio is high
|
||||
furi_hal_gpio_write(host->gpio_pin, true);
|
||||
do {
|
||||
@@ -35,19 +82,19 @@ bool onewire_host_reset(OneWireHost* host) {
|
||||
} while(!furi_hal_gpio_read(host->gpio_pin));
|
||||
|
||||
// pre delay
|
||||
furi_delay_us(OWH_RESET_DELAY_PRE);
|
||||
furi_delay_us(timings->g);
|
||||
|
||||
// drive low
|
||||
furi_hal_gpio_write(host->gpio_pin, false);
|
||||
furi_delay_us(OWH_RESET_DRIVE);
|
||||
furi_delay_us(timings->h);
|
||||
|
||||
// release
|
||||
furi_hal_gpio_write(host->gpio_pin, true);
|
||||
furi_delay_us(OWH_RESET_RELEASE);
|
||||
furi_delay_us(timings->i);
|
||||
|
||||
// read and post delay
|
||||
r = !furi_hal_gpio_read(host->gpio_pin);
|
||||
furi_delay_us(OWH_RESET_DELAY_POST);
|
||||
furi_delay_us(timings->j);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -55,17 +102,19 @@ bool onewire_host_reset(OneWireHost* host) {
|
||||
bool onewire_host_read_bit(OneWireHost* host) {
|
||||
bool result;
|
||||
|
||||
const OneWireHostTimings* timings = host->timings;
|
||||
|
||||
// drive low
|
||||
furi_hal_gpio_write(host->gpio_pin, false);
|
||||
furi_delay_us(OWH_READ_DRIVE);
|
||||
furi_delay_us(timings->a);
|
||||
|
||||
// release
|
||||
furi_hal_gpio_write(host->gpio_pin, true);
|
||||
furi_delay_us(OWH_READ_RELEASE);
|
||||
furi_delay_us(timings->e);
|
||||
|
||||
// read and post delay
|
||||
result = furi_hal_gpio_read(host->gpio_pin);
|
||||
furi_delay_us(OWH_READ_DELAY_POST);
|
||||
furi_delay_us(timings->f);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -89,22 +138,24 @@ void onewire_host_read_bytes(OneWireHost* host, uint8_t* buffer, uint16_t count)
|
||||
}
|
||||
|
||||
void onewire_host_write_bit(OneWireHost* host, bool value) {
|
||||
const OneWireHostTimings* timings = host->timings;
|
||||
|
||||
if(value) {
|
||||
// drive low
|
||||
furi_hal_gpio_write(host->gpio_pin, false);
|
||||
furi_delay_us(OWH_WRITE_1_DRIVE);
|
||||
furi_delay_us(timings->a);
|
||||
|
||||
// release
|
||||
furi_hal_gpio_write(host->gpio_pin, true);
|
||||
furi_delay_us(OWH_WRITE_1_RELEASE);
|
||||
furi_delay_us(timings->b);
|
||||
} else {
|
||||
// drive low
|
||||
furi_hal_gpio_write(host->gpio_pin, false);
|
||||
furi_delay_us(OWH_WRITE_0_DRIVE);
|
||||
furi_delay_us(timings->c);
|
||||
|
||||
// release
|
||||
furi_hal_gpio_write(host->gpio_pin, true);
|
||||
furi_delay_us(OWH_WRITE_0_RELEASE);
|
||||
furi_delay_us(timings->d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,10 +173,6 @@ void onewire_host_write_bytes(OneWireHost* host, const uint8_t* buffer, uint16_t
|
||||
}
|
||||
}
|
||||
|
||||
void onewire_host_skip(OneWireHost* host) {
|
||||
onewire_host_write(host, 0xCC);
|
||||
}
|
||||
|
||||
void onewire_host_start(OneWireHost* host) {
|
||||
furi_hal_gpio_write(host->gpio_pin, true);
|
||||
furi_hal_gpio_init(host->gpio_pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
|
||||
@@ -154,7 +201,7 @@ void onewire_host_target_search(OneWireHost* host, uint8_t family_code) {
|
||||
host->last_device_flag = false;
|
||||
}
|
||||
|
||||
uint8_t onewire_host_search(OneWireHost* host, uint8_t* new_addr, OneWireHostSearchMode mode) {
|
||||
bool onewire_host_search(OneWireHost* host, uint8_t* new_addr, OneWireHostSearchMode mode) {
|
||||
uint8_t id_bit_number;
|
||||
uint8_t last_zero, rom_byte_number, search_result;
|
||||
uint8_t id_bit, cmp_id_bit;
|
||||
@@ -268,3 +315,7 @@ uint8_t onewire_host_search(OneWireHost* host, uint8_t* new_addr, OneWireHostSea
|
||||
|
||||
return search_result;
|
||||
}
|
||||
|
||||
void onewire_host_set_overdrive(OneWireHost* host, bool set) {
|
||||
host->timings = set ? &onewire_host_timings_overdrive : &onewire_host_timings_normal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user