Skip to content

Doesn't work on xMega, Mega-0 or "XTiny" AVRs (including "Arduino Uno WiFi 2") #64

@WestfW

Description

@WestfW

http://forum.arduino.cc/index.php?topic=580188.0

THe OneWire_direct_gpio.h file contains code like:

#if defined(__AVR__)
#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))

#define DIRECT_READ(base, mask)         (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask)   ((*((base)+1)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask)  ((*((base)+1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask)    ((*((base)+2)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask)   ((*((base)+2)) |= (mask))

This assumes that All "AVR" processors have a similar structure for their IO registers, which isn't true of the "XTiny", XMega, and Mega-0 chips. In particular, the OneWire library doesn't work on the new "Arduino Uno WiFi 2", which uses the ATmega4809 (mega-0 series.)

The 4809, at least, has a set of VPORTs that I believe are compatible with the older AVR port layouts. You can convert from the "standard" Arduino data structures to VPORTs with something like:

static inline  __attribute__((always_inline)) void _dwfast(int pin, int val) {
/*
 * Mega-0, Tiny-1 style IOPORTs
 * (assumes VPORTs exist starting at 0 for each PORT structure)
 */
    uint8_t mask = 1<<digital_pin_to_bit_position[pin];
    uint8_t port = digital_pin_to_port[pin];
    VPORT_t *vport;
    /*
     * Old style port logic is a small integer 0 for PORTA, 1 for PORTB, etc. 
     */
    vport = (VPORT_t *)(port * 4);
    if (val) {
	vport->OUT |= mask;
    } else {
	vport->OUT &= ~mask;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions