| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- #pragma once
- #include "flipper.h"
- #include "flipper_v2.h"
- #include "one_wire_timings.h"
- class OneWireGpioSlave {
- private:
- GpioPin* gpio;
- public:
- OneWireGpioSlave(GpioPin* one_wire_gpio);
- ~OneWireGpioSlave();
- void start(void);
- void stop(void);
- bool emulate(uint8_t* buffer, uint8_t length);
- bool check_reset(void);
- bool show_presence(void);
- bool receive_and_process_cmd(void);
- bool receive(uint8_t* data, const uint8_t data_length);
- bool receiveBit(void);
- bool overdrive_mode = false;
- OneWiteTimeType wait_while_gpio(volatile OneWiteTimeType retries, const bool pin_value);
- };
- OneWireGpioSlave::OneWireGpioSlave(GpioPin* one_wire_gpio) {
- gpio = one_wire_gpio;
- }
- OneWireGpioSlave::~OneWireGpioSlave() {
- stop();
- }
- void OneWireGpioSlave::start(void) {
- gpio_init(gpio, GpioModeOutputOpenDrain);
- }
- void OneWireGpioSlave::stop(void) {
- gpio_init(gpio, GpioModeAnalog);
- }
- bool OneWireGpioSlave::emulate(uint8_t* buffer, uint8_t length) {
- if(!check_reset()) {
- printf("reset error\n");
- return false;
- }
- if(!show_presence()) {
- printf("presence error\n");
- return false;
- }
- if(!receive_and_process_cmd()) {
- printf("receive_and_process_cmd error\n");
- return false;
- }
- printf("ok\n");
- return true;
- }
- OneWiteTimeType OneWireGpioSlave::wait_while_gpio(OneWiteTimeType time, const bool pin_value) {
- uint32_t start = DWT->CYCCNT;
- uint32_t time_ticks = time * (SystemCoreClock / 1000000.0f);
- while(((DWT->CYCCNT - start) < time_ticks)) {
- if(gpio_read(gpio) != pin_value) {
- uint32_t time = (DWT->CYCCNT - start);
- time /= (SystemCoreClock / 1000000.0f);
- return time;
- }
- }
- return 0;
- }
- bool OneWireGpioSlave::check_reset(void) {
- while(gpio_read(gpio) == true) {
- }
- /*if(wait_while_gpio(OneWireEmulateTiming::RESET_TIMEOUT * 20, true) == 0) {
- printf("RESET_TIMEOUT\n");
- return false;
- }*/
- const OneWiteTimeType time_remaining =
- wait_while_gpio(OneWireEmulateTiming::RESET_MAX[0], false);
- if(time_remaining == 0) {
- return false;
- }
- if(overdrive_mode && ((OneWireEmulateTiming::RESET_MAX[0] -
- OneWireEmulateTiming::RESET_MIN[0]) <= time_remaining)) {
- // normal reset detected
- overdrive_mode = false;
- };
- bool result = (time_remaining <= OneWireEmulateTiming::RESET_MAX[0]) &&
- time_remaining >= OneWireEmulateTiming::RESET_MIN[overdrive_mode];
- return result;
- }
- bool OneWireGpioSlave::show_presence(void) {
- wait_while_gpio(OneWireEmulateTiming::PRESENCE_TIMEOUT, true);
- gpio_write(gpio, false);
- delay_us(OneWireEmulateTiming::PRESENCE_MIN[overdrive_mode]);
- gpio_write(gpio, true);
- /*OneWiteTimeType wait_time = OneWireEmulateTiming::PRESENCE_MAX[overdrive_mode] -
- OneWireEmulateTiming::PRESENCE_MIN[overdrive_mode];
- if(wait_while_gpio(wait_time, false) == 0) {
- return false;
- }*/
- return true;
- }
- bool OneWireGpioSlave::receive_and_process_cmd(void) {
- uint8_t cmd;
- receive(&cmd, 1);
- printf("cmd %x\n", cmd);
- return false;
- }
- bool OneWireGpioSlave::receiveBit(void) {
- // wait while bus is HIGH
- OneWiteTimeType time = OneWireEmulateTiming::SLOT_MAX[overdrive_mode];
- time = wait_while_gpio(time, true);
- if(time == 0) {
- printf("RESET_IN_PROGRESS\n");
- return false;
- }
- /*while ((DIRECT_READ(pin_baseReg, pin_bitMask) == 0) && (--retries != 0));
- if (retries == 0)
- {
- _error = Error::RESET_IN_PROGRESS;
- return false;
- }*/
- // wait while bus is LOW
- time = OneWireEmulateTiming::MSG_HIGH_TIMEOUT;
- time = wait_while_gpio(time, false);
- if(time == 0) {
- printf("TIMEOUT_HIGH\n");
- return false;
- }
- /*while ((DIRECT_READ(pin_baseReg, pin_bitMask) != 0) && (--retries != 0));
- if (retries == 0)
- {
- _error = Error::AWAIT_TIMESLOT_TIMEOUT_HIGH;
- return false;
- }*/
- // wait a specific time to do a read (data is valid by then), // first difference to inner-loop of write()
- time = OneWireEmulateTiming::READ_MIN[overdrive_mode];
- time = wait_while_gpio(time, true);
- //while ((DIRECT_READ(pin_baseReg, pin_bitMask) == 0) && (--retries != 0));
- return (time > 0);
- }
- bool OneWireGpioSlave::receive(uint8_t* data, const uint8_t data_length) {
- uint8_t bytes_received = 0;
- for(; bytes_received < data_length; ++bytes_received) {
- uint8_t value = 0;
- for(uint8_t bitMask = 0x01; bitMask != 0; bitMask <<= 1) {
- if(receiveBit()) value |= bitMask;
- }
- data[bytes_received] = value;
- }
- return (bytes_received != data_length);
- }
|