orgua / OneWireHub

OneWire slave device emulator
GNU General Public License v3.0
343 stars 86 forks source link

Atmel Studio 7 - atmega328PB - compiling errors #66

Open pir0c0pter0 opened 5 years ago

pir0c0pter0 commented 5 years ago

I got same errors as this post here with AtmelStudio 7 and ATMEGA328PB. By adding thoses flags, most errors got solved, but im still getting

invalid conversion from 'unsigned char' to 'unsigned char*' [-fpermissive]

in:

T1 * portInputRegister(const T1 port) { return port; };

My pin declaration:

constexpr uint8_t pin_onewire   { 4 };

auto hub     = OneWireHub(pin_onewire);
kutukvpavel commented 5 years ago

Well, certainly it is a bug. Under no circumstances that line you included will compile. But should it even do so? To my mind there should be a static assertion explicitly saying that you are doing it wrong (if you are just a user of this lib). Have you even looked at the file the line is from? If you are not a complete newbie, then I am sure you would have understood it right away.

Are you using barebones AS7? Then why would you expect Arduino lib to compile? Look at https://github.com/orgua/OneWireHub/blob/master/src/platform.h If the Hub is unable to detect Arduino it uses so-called "fallback" (mockup) HAL functions. What it really means is this lib is not supposed to work out-of-the-box outside of Arduino environment. You'll have to provide your own HAL functions for GPIO access. Actually, it's pretty easy: choose a name for your barebones-arch, define it somewhere and add yet another #elif section to platform.h. Then define all the required macros and you are good to go (chances are on ATmega32 you won't even have to recalibrate hub), which is trivial for ATmega-s:

define MY_ATmega328_ARCH

define OWH_BASEREG PINB //PINC, PIND etc. If you are lazy put it somewhere before #include "Onewirehub.h" in your code

//...

elif defined(MY_ATmega328_ARCH)

define PIN_TO_BASEREG(pin) &(OWH_BASEREG) //Again if you are lazy, one can come up with a good implementation

define PIN_TO_BITMASK(pin) (1 << (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))

using io_reg_t = uint8_t; // define special datatype for register-access constexpr uint8_t VALUE_IPL {13}; // instructions per loop, compare 0 takes 11, compare 1 takes 13 cycles //...

Something like that. Port register is defined manually and pin number now represents pin number inside selected port, i.e. PORTB 7 etc (has nothing to do with arduino pinout anymore).

If your goal is to get rid of [large and useless for mature projects, but useful for prototyping] Arduino codebase then all of the above is a valid suggestion. However, if you just want to use a comprehensive IDE, then you might want to install Visual Micro addon. It will bring arduino environment there and all the arduino libs will work out-of-the-box.

P.S. Dug deeper into HAL and realised that it is not as simple as i thought is was. You'll also have to define basic arduino functions like noInterrupts(), delayMicroseconds() and so on (look at #ifndef ARDUINO at the bottom). While it is damn easy for the ones above (just call avr-libc _delay_us() or cli()), micros() will make you setup a hardware timer. Still pretty easy for anyone at least a little experienced though.