unleashed-firmware/lib/onewire/one_wire_master.cpp

116 lines
2.3 KiB
C++
Raw Normal View History

#include "one_wire_master.h"
2020-11-16 14:21:58 +03:00
#include "one_wire_timings.h"
OneWireMaster::OneWireMaster(const GpioPin* one_wire_gpio) {
2020-11-16 14:21:58 +03:00
gpio = one_wire_gpio;
}
OneWireMaster::~OneWireMaster() {
2020-11-16 14:21:58 +03:00
stop();
}
void OneWireMaster::start(void) {
2020-11-16 14:21:58 +03:00
gpio_init(gpio, GpioModeOutputOpenDrain);
}
void OneWireMaster::stop(void) {
2020-11-16 14:21:58 +03:00
gpio_init(gpio, GpioModeAnalog);
}
bool OneWireMaster::reset(void) {
2020-11-16 14:21:58 +03:00
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) {
2020-11-16 14:21:58 +03:00
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) {
2020-11-16 14:21:58 +03:00
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) {
2020-11-16 14:21:58 +03:00
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) {
2020-11-16 14:21:58 +03:00
for(uint16_t i = 0; i < count; i++) {
buffer[i] = read();
}
}
void OneWireMaster::write(uint8_t value) {
2020-11-16 14:21:58 +03:00
uint8_t bitMask;
for(bitMask = 0x01; bitMask; bitMask <<= 1) {
write_bit((bitMask & value) ? 1 : 0);
}
}
void OneWireMaster::skip(void) {
write(0xCC);
}