123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /* Copyright (C) 2015-2016 Andrew J. Kroll
- and
- Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Contact information
- -------------------
-
- Circuits At Home, LTD
- Web : https://www.circuitsathome.com
- e-mail : support@circuitsathome.com
- */
-
- #ifndef MACROS_H
- #define MACROS_H
- #include "macro_logic.h"
- /*
- * Universal Arduino(tm) "IDE" fixups.
- */
-
-
- // Just in case...
- #ifndef SERIAL_PORT_MONITOR
- #define SERIAL_PORT_MONITOR Serial
- #endif
-
- #ifndef INT16_MIN
- #define INT16_MIN -32768
- #endif
- // require 10607+
- #if defined(ARDUINO) && ARDUINO >=10607
- // nop :-)
- #else
- #error "Arduino version too old, and must be at least 1.6.7"
- #endif
-
- // Nuke screwed up macro junk from the IDE.
- #ifdef __cplusplus
- #ifdef true
- #undef true
- #endif
- #ifdef false
- #undef false
- #endif
- #endif
-
-
- #ifndef UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE
-
- #ifndef UHS_BIG_FLASH
-
- #if defined(FLASHEND) && defined(FLASHSTART)
- #if (FLASHEND - FLASHSTART) > 0x0FFFFU
- #define UHS_BIG_FLASH 1
- #else
- #define UHS_BIG_FLASH 0
- #endif
-
- #elif defined(__PIC32_FLASH_SIZE)
- #if __PIC32_FLASH_SIZE > 511
- #define UHS_BIG_FLASH 1
- #else
- #define UHS_BIG_FLASH 0
- #endif
-
- #elif defined(FLASHEND) && !defined(FLASHSTART)
- // Assumes flash starts at 0x00000, is this a safe assumption?
- // 192K + should be OK
- #if FLASHEND > 0x02FFFFU
- #define UHS_BIG_FLASH 1
- #else
- #define UHS_BIG_FLASH 0
- #endif
-
- #elif defined(IFLASH_SIZE)
- #if IFLASH_SIZE > 0x0FFFFU
- #define UHS_BIG_FLASH 1
- #else
- #define UHS_BIG_FLASH 0
- #endif
-
- #elif defined(ESP8266)
- #define UHS_BIG_FLASH 1
- #define SYSTEM_OR_SPECIAL_YIELD(...) yield()
-
- #elif defined(__arm__) && defined(CORE_TEENSY)
- #define UHS_BIG_FLASH 1
-
- #elif defined(ARDUINO_spresense_ast)
- #define UHS_BIG_FLASH 1
- #else
- // safe default
- #warning Small flash?
- #define UHS_BIG_FLASH 0
- #endif
- #endif
-
- #if UHS_BIG_FLASH
- #define UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE 1
- #else
- #define UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE 0
- #endif
- #endif
-
- #if defined(__arm__) && defined(CORE_TEENSY)
- #define UHS_PIN_WRITE(p, v) digitalWriteFast(p, v)
- #define UHS_PIN_READ(p) digitalReadFast(p)
- #endif
- // TODO: Fast inline code for AVR and SAM based microcontrollers
- // This can be done pretty easily.
- // For now, this will just work out-of-the-box.
- #ifndef UHS_PIN_WRITE
- #define UHS_PIN_WRITE(p, v) digitalWrite(p, v)
- #endif
- #ifndef UHS_PIN_READ
- #define UHS_PIN_READ(p) digitalRead(p)
- #endif
-
- #if defined( __PIC32MX__ ) && !defined(interrupts) // compiling with Microchip XC32 compiler
- #define interrupts() __builtin_enable_interrupts()
- #edfine noInterrupts() __builtin_disable_interrupts()
- #endif
-
- #ifndef ARDUINO_SAMD_ZERO
- #ifdef ARDUINO_AVR_ADK
- #define UHS_GET_DPI(x) (x == 54 ? 6 : digitalPinToInterrupt(x))
- #else
- #define UHS_GET_DPI(x) digitalPinToInterrupt(x)
- #endif
- #else
- #define UHS_GET_DPI(x) (x)
- #endif
-
- #include "../../../../HAL/shared/progmem.h"
-
- ////////////////////////////////////////////////////////////////////////////////
- // HANDY MACROS
- ////////////////////////////////////////////////////////////////////////////////
-
- // Atomically set/clear single bits using bitbands.
- // Believe it or not, this boils down to a constant,
- // and is less code than using |= &= operators.
- // Bonus, it makes code easier to read too.
- // Bitbanding is a wonderful thing.
- #define BITNR(i) (i&0x1?0:i&0x2?1:i&0x4?2:i&0x8?3:i&0x10?4:i&0x20?5:i&0x40?6:i&0x80?7:i&0x100?8:i&0x200?9:i&0x400?10:i&0x800?11:i&0x1000?12:i&0x2000?13:i&0x4000?14:i&0x8000?15:i&0x10000?16:i&0x20000?17:i&0x40000?18:i&0x80000?19:i&0x100000?20:i&0x200000?21:i&0x400000?22:i&0x800000?23:i&0x1000000?24:i&0x2000000?25:i&0x4000000?26:i&0x8000000?27:i&0x10000000?28:i&0x20000000?29:i&0x40000000?30:i&0x80000000?31:32)
- #define UHS_KIO_BITBAND_ADDR(r, i) (((uint32_t)&(r) - 0x40000000) * 32 + (i) * 4 + 0x42000000)
- #define UHS_KIO_SETBIT_ATOMIC(r, m) (*(uint32_t *)UHS_KIO_BITBAND_ADDR((r), BITNR((m)))) = 1
- #define UHS_KIO_CLRBIT_ATOMIC(r, m) (*(uint32_t *)UHS_KIO_BITBAND_ADDR((r), BITNR((m)))) = 0
-
-
- #define VALUE_BETWEEN(v,l,h) (((v)>(l)) && ((v)<(h)))
- #define VALUE_WITHIN(v,l,h) (((v)>=(l)) && ((v)<=(h)))
- #define output_pgm_message(wa,fp,mp,el) wa = &mp, fp((char *)pgm_read_pointer(wa), el)
- #define output_if_between(v,l,h,wa,fp,mp,el) if(VALUE_BETWEEN(v,l,h)) output_pgm_message(wa,fp,mp[v-(l+1)],el);
-
- #define UHS_SWAP_VALUES(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
- #ifndef __BYTE_GRABBING_DEFINED__
- #define __BYTE_GRABBING_DEFINED__ 1
- #ifdef BROKEN_OPTIMIZER_LITTLE_ENDIAN
- // Note: Use this if your compiler generates horrible assembler!
- #define UHS_UINT8_BYTE0(__usi__) (((uint8_t *)&(__usi__))[0])
- #define UHS_UINT8_BYTE1(__usi__) (((uint8_t *)&(__usi__))[1])
- #define UHS_UINT8_BYTE2(__usi__) (((uint8_t *)&(__usi__))[2])
- #define UHS_UINT8_BYTE3(__usi__) (((uint8_t *)&(__usi__))[3])
- #define UHS_UINT8_BYTE4(__usi__) (((uint8_t *)&(__usi__))[4])
- #define UHS_UINT8_BYTE5(__usi__) (((uint8_t *)&(__usi__))[5])
- #define UHS_UINT8_BYTE6(__usi__) (((uint8_t *)&(__usi__))[6])
- #define UHS_UINT8_BYTE7(__usi__) (((uint8_t *)&(__usi__))[7])
- #else
- // Note: The cast alone to uint8_t is actually enough.
- // GCC throws out the "& 0xFF", and the size is no different.
- // Some compilers need it.
- #define UHS_UINT8_BYTE0(__usi__) ((uint8_t)((__usi__) & 0xFF ))
- #define UHS_UINT8_BYTE1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xFF))
- #define UHS_UINT8_BYTE2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xFF))
- #define UHS_UINT8_BYTE3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xFF))
- #define UHS_UINT8_BYTE4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xFF))
- #define UHS_UINT8_BYTE5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xFF))
- #define UHS_UINT8_BYTE6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xFF))
- #define UHS_UINT8_BYTE7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xFF))
- #endif
- #define UHS_UINT16_SET_BYTE1(__usi__) ((uint16_t)(__usi__) << 8)
- #define UHS_UINT32_SET_BYTE1(__usi__) ((uint32_t)(__usi__) << 8)
- #define UHS_UINT64_SET_BYTE1(__usi__) ((uint64_t)(__usi__) << 8)
- #define UHS_UINT32_SET_BYTE2(__usi__) ((uint32_t)(__usi__) << 16)
- #define UHS_UINT64_SET_BYTE2(__usi__) ((uint64_t)(__usi__) << 16)
- #define UHS_UINT32_SET_BYTE3(__usi__) ((uint32_t)(__usi__) << 24)
- #define UHS_UINT64_SET_BYTE3(__usi__) ((uint64_t)(__usi__) << 24)
- #define UHS_UINT64_SET_BYTE4(__usi__) ((uint64_t)(__usi__) << 32)
- #define UHS_UINT64_SET_BYTE5(__usi__) ((uint64_t)(__usi__) << 40)
- #define UHS_UINT64_SET_BYTE6(__usi__) ((uint64_t)(__usi__) << 48)
- #define UHS_UINT64_SET_BYTE7(__usi__) ((uint64_t)(__usi__) << 56)
-
- // These are the smallest and fastest ways I have found so far in pure C/C++.
- #define UHS_BYTES_TO_UINT16(__usc1__,__usc0__) ((uint16_t)((uint16_t)(__usc0__) | (uint16_t)UHS_UINT16_SET_BYTE1(__usc1__)))
- #define UHS_BYTES_TO_UINT32(__usc3__,__usc2__,__usc1__,__usc0__) ((uint32_t)((uint32_t)(__usc0__) | UHS_UINT32_SET_BYTE1(__usc1__) | UHS_UINT32_SET_BYTE2(__usc2__) | UHS_UINT32_SET_BYTE3(__usc3__)))
- #define UHS_BYTES_TO_UINT64(__usc7__,__usc6__,__usc5__,__usc4__,__usc3__,__usc2__,__usc1__,__usc0__) ((uint64_t)((uint64_t)__usc0__ | UHS_UINT64_SET_BYTE1(__usc1__) | UHS_UINT64_SET_BYTE2(__usc2__) | UHS_UINT64_SET_BYTE3(__usc3__) | UHS_UINT64_SET_BYTE4(__usc4__) | UHS_UINT64_SET_BYTE5(__usc5__) | UHS_UINT64_SET_BYTE6(__usc6__) | UHS_UINT64_SET_BYTE7(__usc7__)))
- #endif
- /*
- * Debug macros.
- * Useful when porting from UHS2.
- * Do not use these for any new code.
- * Change to better debugging after port is completed.
- * Strings are stored in progmem (flash) instead of RAM.
- */
- #define USBTRACE1(s,l) (Notify(PSTR(s), l))
- #define USBTRACE(s) (USBTRACE1((s), 0x80)); USB_HOST_SERIAL.flush()
- #define USBTRACE3(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l), Notify(PSTR("\r\n"), l))
- #define USBTRACE3X(s,r,l) (Notify(PSTR(s), l), D_PrintHex((r), l))
- #define USBTRACE2(s,r) (USBTRACE3((s),(r),0x80)); USB_HOST_SERIAL.flush()
- #define USBTRACE2X(s,r) (USBTRACE3X((s),(r),0x80)); USB_HOST_SERIAL.flush()
-
- #define VOID0 ((void)0)
- #ifndef NOTUSED
- #define NOTUSED(...) __VA_ARGS__ __attribute__((unused))
- #endif
- #endif /* MACROS_H */
|