#pragma once #include "one_wire_master.h" #include "one_wire_timings.h" OneWireMaster::OneWireMaster(const GpioPin* one_wire_gpio) { gpio = one_wire_gpio; } OneWireMaster::~OneWireMaster() { stop(); } void OneWireMaster::start(void) { gpio_init(gpio, GpioModeOutputOpenDrain); } void OneWireMaster::stop(void) { gpio_init(gpio, GpioModeAnalog); } bool OneWireMaster::reset(void) { uint8_t r; uint8_t retries = 125; // wait until the gpio is high gpio_write(gpio, true); do { if(--retries == 0) return 0; delay_us(2); } while(!gpio_read(gpio)); // pre delay delay_us(OneWireTiming::RESET_DELAY_PRE); // drive low gpio_write(gpio, false); delay_us(OneWireTiming::RESET_DRIVE); // release gpio_write(gpio, true); delay_us(OneWireTiming::RESET_RELEASE); // read and post delay r = !gpio_read(gpio); delay_us(OneWireTiming::RESET_DELAY_POST); return r; } bool OneWireMaster::read_bit(void) { bool result; // drive low gpio_write(gpio, false); delay_us(OneWireTiming::READ_DRIVE); // release gpio_write(gpio, true); delay_us(OneWireTiming::READ_RELEASE); // read and post delay result = gpio_read(gpio); delay_us(OneWireTiming::READ_DELAY_POST); return result; } void OneWireMaster::write_bit(bool value) { if(value) { // drive low gpio_write(gpio, false); delay_us(OneWireTiming::WRITE_1_DRIVE); // release gpio_write(gpio, true); delay_us(OneWireTiming::WRITE_1_RELEASE); } else { // drive low gpio_write(gpio, false); delay_us(OneWireTiming::WRITE_0_DRIVE); // release gpio_write(gpio, true); delay_us(OneWireTiming::WRITE_0_RELEASE); } } uint8_t OneWireMaster::read(void) { uint8_t result = 0; for(uint8_t bitMask = 0x01; bitMask; bitMask <<= 1) { if(read_bit()) { result |= bitMask; } } return result; } void OneWireMaster::read_bytes(uint8_t* buffer, uint16_t count) { for(uint16_t i = 0; i < count; i++) { buffer[i] = read(); } } void OneWireMaster::write(uint8_t value) { uint8_t bitMask; for(bitMask = 0x01; bitMask; bitMask <<= 1) { write_bit((bitMask & value) ? 1 : 0); } } void OneWireMaster::skip(void) { write(0xCC); }