SpenceKonde / megaTinyCore

Arduino core for the tinyAVR 0/1/2-series - Ones's digit 2,4,5,7 (pincount, 8,14,20,24), tens digit 0, 1, or 2 (featureset), preceded by flash in kb. Library maintainers: porting help available!
Other
551 stars 142 forks source link

Adding MFRC522 library support? #216

Closed sideswiper22 closed 3 years ago

sideswiper22 commented 4 years ago

I think this issue has been opened before but I'm not sure. All I know is that it's probably an issue with the F() macro but I don't know how to solve this problem. Using the Mifare RFID (MFRC522) library with megaTinyCore (and probably all megaAVR parts) causes a lot of compile errors in the console meaning it cannot be used with these parts. Any solution?

Here's the error log:

In file included from C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:7:0: C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp: In static member function 'static const FlashStringHelper MFRC522::GetStatusCodeName(MFRC522::StatusCode)': C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const FlashStringHelper*' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1282:29: note: in expansion of macro 'F' case STATUS_OK: return F("Success."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1283:31: note: in expansion of macro 'F' case STATUS_ERROR: return F("Error in communication."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1284:34: note: in expansion of macro 'F' case STATUS_COLLISION: return F("Collission detected."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1285:32: note: in expansion of macro 'F' case STATUS_TIMEOUT: return F("Timeout in communication."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1286:32: note: in expansion of macro 'F' case STATUS_NO_ROOM: return F("A buffer is not big enough."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1287:38: note: in expansion of macro 'F' case STATUS_INTERNAL_ERROR: return F("Internal error in the code. Should not happen."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1288:32: note: in expansion of macro 'F' case STATUS_INVALID: return F("Invalid argument."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1289:34: note: in expansion of macro 'F' case STATUS_CRC_WRONG: return F("The CRC_A does not match."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1290:35: note: in expansion of macro 'F' case STATUS_MIFARE_NACK: return F("A MIFARE PICC responded with NAK."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1291:23: note: in expansion of macro 'F' default: return F("Unknown error"); ^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp: In static member function 'static const FlashStringHelper MFRC522::PICC_GetTypeName(MFRC522::PICC_Type)': C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const FlashStringHelper*' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1330:39: note: in expansion of macro 'F' case PICC_TYPE_ISO_14443_4: return F("PICC compliant with ISO/IEC 14443-4"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1331:37: note: in expansion of macro 'F' case PICC_TYPE_ISO_18092: return F("PICC compliant with ISO/IEC 18092 (NFC)"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1332:39: note: in expansion of macro 'F' case PICC_TYPE_MIFARE_MINI: return F("MIFARE Mini, 320 bytes"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1333:37: note: in expansion of macro 'F' case PICC_TYPE_MIFARE_1K: return F("MIFARE 1KB"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1334:37: note: in expansion of macro 'F' case PICC_TYPE_MIFARE_4K: return F("MIFARE 4KB"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1335:37: note: in expansion of macro 'F' case PICC_TYPE_MIFARE_UL: return F("MIFARE Ultralight or Ultralight C"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1336:39: note: in expansion of macro 'F' case PICC_TYPE_MIFARE_PLUS: return F("MIFARE Plus"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1337:41: note: in expansion of macro 'F' case PICC_TYPE_MIFARE_DESFIRE: return F("MIFARE DESFire"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1338:36: note: in expansion of macro 'F' case PICC_TYPE_TNP3XXX: return F("MIFARE TNP3XXX"); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1339:39: note: in expansion of macro 'F' case PICC_TYPE_NOT_COMPLETE: return F("SAK indicates UID is not complete."); ^ C:\Users\Clyde Corpuz\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.0.5\cores\arduino/Arduino.h:30:20: error: cannot convert 'const char' to 'const __FlashStringHelper' in return

define F(str) (str)

^ C:\Users\Clyde Corpuz\Documents\Arduino\libraries\MFRC522-1.4.6\src\MFRC522.cpp:1341:24: note: in expansion of macro 'F' default: return F("Unknown type"); ^

SpenceKonde commented 4 years ago

uuuugh - link me to the github of the library.

SpenceKonde commented 4 years ago

(to be clear, I know exactly what the problem is, and the fix is not hard, but needs to be done in the library)

SpenceKonde commented 4 years ago

Also, your terminology is wrong. "megaAVR" according to Microchip refers to any ATmega parts. The (Arduino-only) name "megaavr" refers to the post-2016 parts which I refer to as "Modern AVR", or explicitly by their product lines (tinyAVR 0/1-series, megaAVR 0-series, and the Dx-series - though the latter has additional complications). Don't use "megaAVR" when you mean "megaavr" - the only place in megaTinyCore that should use that word is in the directory name, because that's what the official cores call this architectures, and it's required for library compatibility. And unfortunately it's alluded to by the name, because I was unaware of that distinction when I wrote the core!)

But yeah, refer me to the library, and I'll fork it and implement the fix, refer to you for testing, and if it works, submit as PR to library maintainer.

SpenceKonde commented 4 years ago

For that matter - PLEASE do that for any other libraries with that F() macro problem. Simple fix in the library, but impossible to fix in the general case from the core without significant adverse impacts

sideswiper22 commented 4 years ago

Alright here's the link to the library https://github.com/miguelbalboa/rfid I shall refer you to other libraries if I find any with similar problems in the future, thanks!

Also, I apologize for using the wrong terminology. Thanks for the correction!

SpenceKonde commented 4 years ago

I'll take a stab at fixing it - I hope I'm able to convince him to merge in my changes (since they will be fully transparent, and have no impact other than adding support for a huge number of parts) - he stated that he is no longer maintaining the library and will not add support for new parts. I don't want to have to keep my own fork just to support the new parts via like, a four-line change wrapped in #ifdefs!

sideswiper22 commented 4 years ago

Thank you!

TomWS1 commented 4 years ago

I submitted an issue to the MFRC522 library: https://github.com/miguelbalboa/rfid/issues/523 as I ran into this independently of sideswiper22.

TomWS1 commented 4 years ago

This was closed with the comment: "Must be fixed by the framework of the board. The simple solution was to typedef __FlashStringHelper as char and define F() macro which does not modify the string. But then the RAM consumption is high." I responded with "Not quite as simple as that as all functions that attempt to overload with _FlashStringHelper then fail as duplicate overloads. I suppose one way around it is to implement FlashStringHelper so that it beningly returns a char*" Which, in fact, may be the way to deal with this.

SpenceKonde commented 4 years ago

Can you provide an example of a library that does that overloading for analysis?

TomWS1 commented 4 years ago

You don't need a library. Methods in Print and String both fail on compile if I modify String.h as: //TWS class FlashStringHelper; typedef char FlashStringHelper;

define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

Both of these files include both const char and const __FlashStringHelper in their overloaded methods. For example: String & operator = (const char cstr); String & operator = (const __FlashStringHelper *str); <== this one fails during compiler

My brain dead workaround was to comment out all the duplicate overloaded methods. It got rid of the error messages but not very pretty.

Rotzbua commented 4 years ago

Arduino.h of megatinycore 2.0.5 does redefine F() with type char:

#undef F
#define F(str) (str)

String.h has a different definition of F() with type __FlashStringHelper.

That is basically the problem.


I tried something simple: added in Arduino.h:

#define __FlashStringHelper char

Worked. But no guarantee for safe usage.

Best.

TomWS1 commented 4 years ago

Can you provide an example of a library that does that overloading for analysis?

I realized you might mean from the MFRC522 library, so here is the method declaration: // old function used too much memory, now name moved to flash; if you need char, copy from flash to memory //const char *GetStatusCodeName(byte code); static const __FlashStringHelper *GetStatusCodeName(StatusCode code); static PICC_Type PICC_GetType(byte sak); // old function used too much memory, now name moved to flash; if you need char, copy from flash to memory //const char *PICC_GetTypeName(byte type); static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type);

sideswiper22 commented 3 years ago

Any progress on this?

TomWS1 commented 3 years ago

I worked around the problem by:

  1. putting:
    //TWS class __FlashStringHelper;
    typedef char __FlashStringHelper;

    it String.h and

  2. commenting out the overloaded methods in Print (.cpp & .h) and String (.cpp & .h) as in: //String(const __FlashStringHelper *str); This was, of course, only in the megaTinyCore package files.
SpenceKonde commented 3 years ago

I am investigating a few approaches to fixing the __FlashStringHelper issue in a universal manner


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: spencekonde@gmail.com

On Fri, Sep 18, 2020, 13:46 TomWS1 notifications@github.com wrote:

I worked around the problem by:

  1. putting:

//TWS class FlashStringHelper; typedef char FlashStringHelper;

it String.h and

  1. commenting out the overloaded methods in Print (.cpp & .h) and String (.cpp & .h) as in: //String(const __FlashStringHelper *str); This was, of course, only in the megaTinyCore package files.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/megaTinyCore/issues/216#issuecomment-695000751, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTXEWYDGV2ZL3YBWKFK7ZDSGOMJBANCNFSM4PRSPOFQ .

SpenceKonde commented 3 years ago

I took the easy way out, for now, and just reimlemented F() macro as it normally is. It's slower and less efficient, but compatible with all libraries.

The alternatives are like, really ugly :-(

sideswiper22 commented 3 years ago

Tested and working. Thank you!