From ae747f0dd3df2111ca73971303f2c1e560de3e98 Mon Sep 17 00:00:00 2001 From: Harshith <75681883+Harshith-10@users.noreply.github.com> Date: Sun, 12 Feb 2023 11:29:38 +0530 Subject: [PATCH 1/4] Add Print::printf() method for sanity --- api/Print.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/api/Print.cpp b/api/Print.cpp index 8c3e1930..23f2a6de 100644 --- a/api/Print.cpp +++ b/api/Print.cpp @@ -16,6 +16,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include #include @@ -235,6 +236,53 @@ size_t Print::println(const Printable& x) return n; } +size_t Print::printf(const char *format, ...) { + va_list arg; + va_start(arg, format); + char temp[64]; + char* buffer = temp; + size_t len = vsnprintf(temp, sizeof(temp), format, arg); + va_end(arg); + if (len > sizeof(temp) - 1) { + buffer = new char[len + 1]; + if (!buffer) { + return 0; + } + va_start(arg, format); + vsnprintf(buffer, len + 1, format, arg); + va_end(arg); + } + len = write((const uint8_t*) buffer, len); + if (buffer != temp) { + delete[] buffer; + } + return len; +} + +// TODO - must be better way than cut-n-paste! +size_t Print::printf_P(const char *format, ...) { + va_list arg; + va_start(arg, format); + char temp[64]; + char* buffer = temp; + size_t len = vsnprintf(temp, sizeof(temp), format, arg); + va_end(arg); + if (len > sizeof(temp) - 1) { + buffer = new char[len + 1]; + if (!buffer) { + return 0; + } + va_start(arg, format); + vsnprintf(buffer, len + 1, format, arg); + va_end(arg); + } + len = write((const uint8_t*) buffer, len); + if (buffer != temp) { + delete[] buffer; + } + return len; +} + // Private Methods ///////////////////////////////////////////////////////////// size_t Print::printNumber(unsigned long n, uint8_t base) From c7d7087aba70e55cf91c4c0471250c3e1ca215aa Mon Sep 17 00:00:00 2001 From: Harshith <75681883+Harshith-10@users.noreply.github.com> Date: Sun, 12 Feb 2023 11:31:16 +0530 Subject: [PATCH 2/4] Add Print::printf() method for sanity --- api/Print.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/Print.h b/api/Print.h index 5a19fe78..09b0c2bc 100644 --- a/api/Print.h +++ b/api/Print.h @@ -88,9 +88,11 @@ class Print size_t println(double, int = 2); size_t println(const Printable&); size_t println(void); + size_t printf(const char *format, ...); + size_t printf_P(const char *format, ...); virtual void flush() { /* Empty implementation for backward compatibility */ } }; } -using arduino::Print; \ No newline at end of file +using arduino::Print; From 32423f2f4d2cbf191cb9424422aa70873ab1ce97 Mon Sep 17 00:00:00 2001 From: Harshith <75681883+Harshith-10@users.noreply.github.com> Date: Sun, 12 Feb 2023 11:33:10 +0530 Subject: [PATCH 3/4] Allow misaligned accesses for pgm_read_XXX --- api/deprecated-avr-comp/avr/pgmspace.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api/deprecated-avr-comp/avr/pgmspace.h b/api/deprecated-avr-comp/avr/pgmspace.h index 95897d75..b890af95 100644 --- a/api/deprecated-avr-comp/avr/pgmspace.h +++ b/api/deprecated-avr-comp/avr/pgmspace.h @@ -99,11 +99,29 @@ typedef const void* uint_farptr_t; #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) +#if 0 +// Requires natural aligned addresses #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_ptr(addr) (*(void *const *)(addr)) +#else +// Supports misaligned addresses +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) ((unsigned short)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8))) +#define pgm_read_dword(addr) ((unsigned long)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8)) | \ + (pgm_read_byte((intptr_t)addr + 2) << 16) | (pgm_read_byte((intptr_t)addr + 3) << 24)) +#define pgm_read_ptr(addr) ((void *)pgm_read_dword(addr)) +static inline float pgm_read_float(const void *addr) { + union { + void *p; + float f; + } x; + x.p = pgm_read_ptr(addr); + return x.f; +} +#endif #define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_word_near(addr) pgm_read_word(addr) From 53d5c6b40edb6a076d00fbf58feefd0d005cfa47 Mon Sep 17 00:00:00 2001 From: Harshith <75681883+Harshith-10@users.noreply.github.com> Date: Sun, 12 Feb 2023 11:36:41 +0530 Subject: [PATCH 4/4] Fix pgm_read* macros by using inline functions --- api/deprecated-avr-comp/avr/pgmspace.h | 28 +++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/api/deprecated-avr-comp/avr/pgmspace.h b/api/deprecated-avr-comp/avr/pgmspace.h index b890af95..e9f59aac 100644 --- a/api/deprecated-avr-comp/avr/pgmspace.h +++ b/api/deprecated-avr-comp/avr/pgmspace.h @@ -98,6 +98,8 @@ typedef const void* uint_farptr_t; #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) +#define vsprintf_P(s, f, ...) vsprintf((s), (f), __VA_ARGS__) +#define vsnprintf_P(s, f, ...) vsnprintf((s), (f), __VA_ARGS__) #if 0 // Requires natural aligned addresses @@ -108,11 +110,23 @@ typedef const void* uint_farptr_t; #define pgm_read_ptr(addr) (*(void *const *)(addr)) #else // Supports misaligned addresses -#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#define pgm_read_word(addr) ((unsigned short)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8))) -#define pgm_read_dword(addr) ((unsigned long)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8)) | \ - (pgm_read_byte((intptr_t)addr + 2) << 16) | (pgm_read_byte((intptr_t)addr + 3) << 24)) -#define pgm_read_ptr(addr) ((void *)pgm_read_dword(addr)) +#ifdef __cplusplus +extern "C"{ +#endif +static inline unsigned char pgm_read_byte(const void *addr) { + return *(const unsigned char *)(addr); +} +static inline unsigned short pgm_read_word(const void *addr) { + const unsigned char *a = (const unsigned char *)addr; + return pgm_read_byte(a) | ( pgm_read_byte(a + 1) << 8 ); +} +static inline unsigned long pgm_read_dword(const void *addr) { + const unsigned char *a = (const unsigned char *)addr; + return pgm_read_byte(a) | ( pgm_read_byte(a + 1) << 8 ) | ( pgm_read_byte(a + 2) << 16 ) | ( pgm_read_byte(a + 3) << 24 ); +} +static inline void *pgm_read_ptr(const void *addr) { + return (void*) pgm_read_dword(addr); +} static inline float pgm_read_float(const void *addr) { union { void *p; @@ -121,6 +135,10 @@ static inline float pgm_read_float(const void *addr) { x.p = pgm_read_ptr(addr); return x.f; } +#ifdef __cplusplus +} +#endif + #endif #define pgm_read_byte_near(addr) pgm_read_byte(addr)