Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2017
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 71.34 KB | None | 0 0
  1. /* Copyright (c) 2002-2007  Marek Michalkiewicz
  2.    Copyright (c) 2006, Carlos Lamas
  3.    Copyright (c) 2009-2010, Jan Waclawek
  4.    All rights reserved.
  5.  
  6.    Redistribution and use in source and binary forms, with or without
  7.    modification, are permitted provided that the following conditions are met:
  8.  
  9.    * Redistributions of source code must retain the above copyright
  10.      notice, this list of conditions and the following disclaimer.
  11.    * Redistributions in binary form must reproduce the above copyright
  12.      notice, this list of conditions and the following disclaimer in
  13.      the documentation and/or other materials provided with the
  14.      distribution.
  15.    * Neither the name of the copyright holders nor the names of
  16.      contributors may be used to endorse or promote products derived
  17.      from this software without specific prior written permission.
  18.  
  19.   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20.   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21.   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22.   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23.   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24.   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25.   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26.   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27.   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28.   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29.   POSSIBILITY OF SUCH DAMAGE. */
  30.  
  31. /* $Id$ */
  32.  
  33. /*
  34.    pgmspace.h
  35.  
  36.    Contributors:
  37.      Created by Marek Michalkiewicz <marekm@linux.org.pl>
  38.      Eric B. Weddington <eric@ecentral.com>
  39.      Wolfgang Haidinger <wh@vmars.tuwien.ac.at> (pgm_read_dword())
  40.      Ivanov Anton <anton@arc.com.ru> (pgm_read_float())
  41.  */
  42.  
  43. /** \file */
  44. /** \defgroup avr_pgmspace <avr/pgmspace.h>: Program Space Utilities
  45.     \code
  46.     #include <avr/io.h>
  47.     #include <avr/pgmspace.h>
  48.     \endcode
  49.  
  50.     The functions in this module provide interfaces for a program to access
  51.     data stored in program space (flash memory) of the device.  In order to
  52.     use these functions, the target device must support either the \c LPM or
  53.     \c ELPM instructions.
  54.  
  55.     \note These functions are an attempt to provide some compatibility with
  56.     header files that come with IAR C, to make porting applications between
  57.     different compilers easier.  This is not 100% compatibility though (GCC
  58.     does not have full support for multiple address spaces yet).
  59.  
  60.     \note If you are working with strings which are completely based in ram,
  61.     use the standard string functions described in \ref avr_string.
  62.  
  63.     \note If possible, put your constant tables in the lower 64 KB and use
  64.     pgm_read_byte_near() or pgm_read_word_near() instead of
  65.     pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that
  66.     way, and you can still use the upper 64K for executable code.
  67.     All functions that are suffixed with a \c _P \e require their
  68.     arguments to be in the lower 64 KB of the flash ROM, as they do
  69.     not use ELPM instructions.  This is normally not a big concern as
  70.     the linker setup arranges any program space constants declared
  71.     using the macros from this header file so they are placed right after
  72.     the interrupt vectors, and in front of any executable code.  However,
  73.     it can become a problem if there are too many of these constants, or
  74.     for bootloaders on devices with more than 64 KB of ROM.
  75.     <em>All these functions will not work in that situation.</em>
  76.  
  77.     \note For <b>Xmega</b> devices, make sure the NVM controller
  78.     command register (\c NVM.CMD or \c NVM_CMD) is set to 0x00 (NOP)
  79.     before using any of these functions.
  80. */
  81.  
  82. #ifndef __PGMSPACE_H_
  83. #define __PGMSPACE_H_ 1
  84.  
  85. #ifndef __DOXYGEN__
  86. #define __need_size_t
  87. #endif
  88. #include <inttypes.h>
  89. #include <stddef.h>
  90. #include <avr/io.h>
  91.  
  92. #ifndef __DOXYGEN__
  93. #ifndef __ATTR_CONST__
  94. #define __ATTR_CONST__ __attribute__((__const__))
  95. #endif
  96.  
  97. #ifndef __ATTR_PROGMEM__
  98. #define __ATTR_PROGMEM__ __attribute__((__progmem__))
  99. #endif
  100.  
  101. #ifndef __ATTR_PURE__
  102. #define __ATTR_PURE__ __attribute__((__pure__))
  103. #endif
  104. #endif  /* !__DOXYGEN__ */
  105.  
  106. /**
  107.    \ingroup avr_pgmspace
  108.    \def PROGMEM
  109.  
  110.    Attribute to use in order to declare an object being located in
  111.    flash ROM.
  112.  */
  113. #define PROGMEM __ATTR_PROGMEM__
  114.  
  115. #ifdef __cplusplus
  116. extern "C" {
  117. #endif
  118.  
  119. #if defined(__DOXYGEN__)
  120. /*
  121.  * Doxygen doesn't grok the appended attribute syntax of
  122.  * GCC, and confuses the typedefs with function decls, so
  123.  * supply a doxygen-friendly view.
  124.  */
  125.  
  126. /**
  127.    \ingroup avr_pgmspace
  128.    \typedef prog_void
  129.    \note DEPRECATED
  130.  
  131.    This typedef is now deprecated because the usage of the __progmem__
  132.    attribute on a type is not supported in GCC. However, the use of the
  133.    __progmem__ attribute on a variable declaration is supported, and this is
  134.    now the recommended usage.
  135.  
  136.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  137.    has been defined before including <avr/pgmspace.h> (either by a
  138.    \c \#define directive, or by a -D compiler option.)
  139.  
  140.    Type of a "void" object located in flash ROM.  Does not make much
  141.    sense by itself, but can be used to declare a "void *" object in
  142.    flash ROM.
  143. */
  144. typedef void PROGMEM prog_void;
  145.  
  146. /**
  147.    \ingroup avr_pgmspace
  148.    \typedef prog_char
  149.    \note DEPRECATED
  150.  
  151.    This typedef is now deprecated because the usage of the __progmem__
  152.    attribute on a type is not supported in GCC. However, the use of the
  153.    __progmem__ attribute on a variable declaration is supported, and this is
  154.    now the recommended usage.
  155.  
  156.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  157.    has been defined before including <avr/pgmspace.h> (either by a
  158.    \c \#define directive, or by a -D compiler option.)
  159.  
  160.    Type of a "char" object located in flash ROM.
  161. */
  162. typedef char PROGMEM prog_char;
  163.  
  164. /**
  165.    \ingroup avr_pgmspace
  166.    \typedef prog_uchar
  167.    \note DEPRECATED
  168.  
  169.    This typedef is now deprecated because the usage of the __progmem__
  170.    attribute on a type is not supported in GCC. However, the use of the
  171.    __progmem__ attribute on a variable declaration is supported, and this is
  172.    now the recommended usage.
  173.  
  174.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  175.    has been defined before including <avr/pgmspace.h> (either by a
  176.    \c \#define directive, or by a -D compiler option.)
  177.  
  178.    Type of an "unsigned char" object located in flash ROM.
  179. */
  180. typedef unsigned char PROGMEM prog_uchar;
  181.  
  182. /**
  183.    \ingroup avr_pgmspace
  184.    \typedef prog_int8_t
  185.    \note DEPRECATED
  186.  
  187.    This typedef is now deprecated because the usage of the __progmem__
  188.    attribute on a type is not supported in GCC. However, the use of the
  189.    __progmem__ attribute on a variable declaration is supported, and this is
  190.    now the recommended usage.
  191.  
  192.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  193.    has been defined before including <avr/pgmspace.h> (either by a
  194.    \c \#define directive, or by a -D compiler option.)
  195.  
  196.    Type of an "int8_t" object located in flash ROM.
  197. */
  198. typedef int8_t PROGMEM prog_int8_t;
  199.  
  200. /**
  201.    \ingroup avr_pgmspace
  202.    \typedef prog_uint8_t
  203.    \note DEPRECATED
  204.  
  205.    This typedef is now deprecated because the usage of the __progmem__
  206.    attribute on a type is not supported in GCC. However, the use of the
  207.    __progmem__ attribute on a variable declaration is supported, and this is
  208.    now the recommended usage.
  209.  
  210.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  211.    has been defined before including <avr/pgmspace.h> (either by a
  212.    \c \#define directive, or by a -D compiler option.)
  213.  
  214.    Type of an "uint8_t" object located in flash ROM.
  215. */
  216. typedef uint8_t PROGMEM prog_uint8_t;
  217.  
  218. /**
  219.    \ingroup avr_pgmspace
  220.    \typedef prog_int16_t
  221.    \note DEPRECATED
  222.  
  223.    This typedef is now deprecated because the usage of the __progmem__
  224.    attribute on a type is not supported in GCC. However, the use of the
  225.    __progmem__ attribute on a variable declaration is supported, and this is
  226.    now the recommended usage.
  227.  
  228.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  229.    has been defined before including <avr/pgmspace.h> (either by a
  230.    \c \#define directive, or by a -D compiler option.)
  231.  
  232.    Type of an "int16_t" object located in flash ROM.
  233. */
  234. typedef int16_t PROGMEM prog_int16_t;
  235.  
  236. /**
  237.    \ingroup avr_pgmspace
  238.    \typedef prog_uint16_t
  239.    \note DEPRECATED
  240.  
  241.    This typedef is now deprecated because the usage of the __progmem__
  242.    attribute on a type is not supported in GCC. However, the use of the
  243.    __progmem__ attribute on a variable declaration is supported, and this is
  244.    now the recommended usage.
  245.  
  246.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  247.    has been defined before including <avr/pgmspace.h> (either by a
  248.    \c \#define directive, or by a -D compiler option.)
  249.  
  250.    Type of an "uint16_t" object located in flash ROM.
  251. */
  252. typedef uint16_t PROGMEM prog_uint16_t;
  253.  
  254. /**
  255.    \ingroup avr_pgmspace
  256.    \typedef prog_int32_t
  257.    \note DEPRECATED
  258.  
  259.    This typedef is now deprecated because the usage of the __progmem__
  260.    attribute on a type is not supported in GCC. However, the use of the
  261.    __progmem__ attribute on a variable declaration is supported, and this is
  262.    now the recommended usage.
  263.  
  264.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  265.    has been defined before including <avr/pgmspace.h> (either by a
  266.    \c \#define directive, or by a -D compiler option.)
  267.  
  268.    Type of an "int32_t" object located in flash ROM.
  269. */
  270. typedef int32_t PROGMEM prog_int32_t;
  271.  
  272. /**
  273.    \ingroup avr_pgmspace
  274.    \typedef prog_uint32_t
  275.    \note DEPRECATED
  276.  
  277.    This typedef is now deprecated because the usage of the __progmem__
  278.    attribute on a type is not supported in GCC. However, the use of the
  279.    __progmem__ attribute on a variable declaration is supported, and this is
  280.    now the recommended usage.
  281.  
  282.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  283.    has been defined before including <avr/pgmspace.h> (either by a
  284.    \c \#define directive, or by a -D compiler option.)
  285.  
  286.    Type of an "uint32_t" object located in flash ROM.
  287. */
  288. typedef uint32_t PROGMEM prog_uint32_t;
  289.  
  290. /**
  291.    \ingroup avr_pgmspace
  292.    \typedef prog_int64_t
  293.    \note DEPRECATED
  294.  
  295.    This typedef is now deprecated because the usage of the __progmem__
  296.    attribute on a type is not supported in GCC. However, the use of the
  297.    __progmem__ attribute on a variable declaration is supported, and this is
  298.    now the recommended usage.
  299.  
  300.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  301.    has been defined before including <avr/pgmspace.h> (either by a
  302.    \c \#define directive, or by a -D compiler option.)
  303.  
  304.    Type of an "int64_t" object located in flash ROM.
  305.  
  306.    \note This type is not available when the compiler
  307.    option -mint8 is in effect.
  308. */
  309. typedef int64_t PROGMEM prog_int64_t;
  310.  
  311. /**
  312.    \ingroup avr_pgmspace
  313.    \typedef prog_uint64_t
  314.    \note DEPRECATED
  315.  
  316.    This typedef is now deprecated because the usage of the __progmem__
  317.    attribute on a type is not supported in GCC. However, the use of the
  318.    __progmem__ attribute on a variable declaration is supported, and this is
  319.    now the recommended usage.
  320.  
  321.    The typedef is only visible if the macro __PROG_TYPES_COMPAT__
  322.    has been defined before including <avr/pgmspace.h> (either by a
  323.    \c \#define directive, or by a -D compiler option.)
  324.  
  325.    Type of an "uint64_t" object located in flash ROM.
  326.  
  327.    \note This type is not available when the compiler
  328.    option -mint8 is in effect.
  329. */
  330. typedef uint64_t PROGMEM prog_uint64_t;
  331.  
  332. /** \ingroup avr_pgmspace
  333.     \def PGM_P
  334.  
  335.     Used to declare a variable that is a pointer to a string in program
  336.     space. */
  337.  
  338. #ifndef PGM_P
  339. #define PGM_P const char *
  340. #endif
  341.  
  342. /** \ingroup avr_pgmspace
  343.     \def PGM_VOID_P
  344.  
  345.     Used to declare a generic pointer to an object in program space. */
  346.  
  347. #ifndef PGM_VOID_P
  348. #define PGM_VOID_P const void *
  349. #endif
  350.  
  351. #elif defined(__PROG_TYPES_COMPAT__)  /* !DOXYGEN */
  352.  
  353. typedef void prog_void __attribute__((__progmem__,deprecated("prog_void type is deprecated.")));
  354. typedef char prog_char __attribute__((__progmem__,deprecated("prog_char type is deprecated.")));
  355. typedef unsigned char prog_uchar __attribute__((__progmem__,deprecated("prog_uchar type is deprecated.")));
  356. typedef int8_t    prog_int8_t   __attribute__((__progmem__,deprecated("prog_int8_t type is deprecated.")));
  357. typedef uint8_t   prog_uint8_t  __attribute__((__progmem__,deprecated("prog_uint8_t type is deprecated.")));
  358. typedef int16_t   prog_int16_t  __attribute__((__progmem__,deprecated("prog_int16_t type is deprecated.")));
  359. typedef uint16_t  prog_uint16_t __attribute__((__progmem__,deprecated("prog_uint16_t type is deprecated.")));
  360. typedef int32_t   prog_int32_t  __attribute__((__progmem__,deprecated("prog_int32_t type is deprecated.")));
  361. typedef uint32_t  prog_uint32_t __attribute__((__progmem__,deprecated("prog_uint32_t type is deprecated.")));
  362. #if !__USING_MINT8
  363. typedef int64_t   prog_int64_t  __attribute__((__progmem__,deprecated("prog_int64_t type is deprecated.")));
  364. typedef uint64_t  prog_uint64_t __attribute__((__progmem__,deprecated("prog_uint64_t type is deprecated.")));
  365. #endif
  366.  
  367. #ifndef PGM_P
  368. #define PGM_P const prog_char *
  369. #endif
  370.  
  371. #ifndef PGM_VOID_P
  372. #define PGM_VOID_P const prog_void *
  373. #endif
  374.  
  375. #else /* !defined(__DOXYGEN__), !defined(__PROG_TYPES_COMPAT__) */
  376.  
  377. #ifndef PGM_P
  378. #define PGM_P const char *
  379. #endif
  380.  
  381. #ifndef PGM_VOID_P
  382. #define PGM_VOID_P const void *
  383. #endif
  384. #endif /* defined(__DOXYGEN__), defined(__PROG_TYPES_COMPAT__) */
  385.  
  386. /* Although in C, we can get away with just using __c, it does not work in
  387.    C++. We need to use &__c[0] to avoid the compiler puking. Dave Hylands
  388.    explaned it thusly,
  389.  
  390.      Let's suppose that we use PSTR("Test"). In this case, the type returned
  391.      by __c is a prog_char[5] and not a prog_char *. While these are
  392.      compatible, they aren't the same thing (especially in C++). The type
  393.      returned by &__c[0] is a prog_char *, which explains why it works
  394.      fine. */
  395.  
  396. #if defined(__DOXYGEN__)
  397. /*
  398.  * The #define below is just a dummy that serves documentation
  399.  * purposes only.
  400.  */
  401. /** \ingroup avr_pgmspace
  402.     \def PSTR(s)
  403.  
  404.     Used to declare a static pointer to a string in program space. */
  405. # define PSTR(s) ((const PROGMEM char *)(s))
  406. #else  /* !DOXYGEN */
  407. /* The real thing. */
  408. # define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
  409. #endif /* DOXYGEN */
  410.  
  411. #ifndef __DOXYGEN__ /* Internal macros, not documented. */
  412. #define __LPM_classic__(addr)   \
  413. (__extension__({                \
  414.     uint16_t __addr16 = (uint16_t)(addr); \
  415.     uint8_t __result;           \
  416.     __asm__ __volatile__        \
  417.     (                           \
  418.         "lpm" "\n\t"            \
  419.         "mov %0, r0" "\n\t"     \
  420.         : "=r" (__result)       \
  421.         : "z" (__addr16)        \
  422.         : "r0"                  \
  423.     );                          \
  424.     __result;                   \
  425. }))
  426.  
  427. #define __LPM_tiny__(addr)      \
  428. (__extension__({                \
  429.     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
  430.     uint8_t __result;           \
  431.     __asm__                     \
  432.     (                           \
  433.         "ld %0, z" "\n\t"       \
  434.         : "=r" (__result)       \
  435.         : "z" (__addr16)        \
  436.     );                          \
  437.     __result;                   \
  438. }))
  439.  
  440. #define __LPM_enhanced__(addr)  \
  441. (__extension__({                \
  442.     uint16_t __addr16 = (uint16_t)(addr); \
  443.     uint8_t __result;           \
  444.     __asm__ __volatile__        \
  445.     (                           \
  446.         "lpm %0, Z" "\n\t"      \
  447.         : "=r" (__result)       \
  448.         : "z" (__addr16)        \
  449.     );                          \
  450.     __result;                   \
  451. }))
  452.  
  453. #define __LPM_word_classic__(addr)          \
  454. (__extension__({                            \
  455.     uint16_t __addr16 = (uint16_t)(addr);   \
  456.     uint16_t __result;                      \
  457.     __asm__ __volatile__                    \
  458.     (                                       \
  459.         "lpm"           "\n\t"              \
  460.         "mov %A0, r0"   "\n\t"              \
  461.         "adiw r30, 1"   "\n\t"              \
  462.         "lpm"           "\n\t"              \
  463.         "mov %B0, r0"   "\n\t"              \
  464.         : "=r" (__result), "=z" (__addr16)  \
  465.         : "1" (__addr16)                    \
  466.         : "r0"                              \
  467.     );                                      \
  468.     __result;                               \
  469. }))
  470.  
  471. #define __LPM_word_tiny__(addr)             \
  472. (__extension__({                            \
  473.     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
  474.     uint16_t __result;                      \
  475.     __asm__                                 \
  476.     (                                       \
  477.         "ld %A0, z+"     "\n\t"             \
  478.         "ld %B0, z"      "\n\t"             \
  479.         : "=r" (__result), "=z" (__addr16)  \
  480.         : "1" (__addr16)                    \
  481.     );                                      \
  482.     __result;                               \
  483. }))
  484.  
  485. #define __LPM_word_enhanced__(addr)         \
  486. (__extension__({                            \
  487.     uint16_t __addr16 = (uint16_t)(addr);   \
  488.     uint16_t __result;                      \
  489.     __asm__ __volatile__                    \
  490.     (                                       \
  491.         "lpm %A0, Z+"   "\n\t"              \
  492.         "lpm %B0, Z"    "\n\t"              \
  493.         : "=r" (__result), "=z" (__addr16)  \
  494.         : "1" (__addr16)                    \
  495.     );                                      \
  496.     __result;                               \
  497. }))
  498.  
  499. #define __LPM_dword_classic__(addr)         \
  500. (__extension__({                            \
  501.     uint16_t __addr16 = (uint16_t)(addr);   \
  502.     uint32_t __result;                      \
  503.     __asm__ __volatile__                    \
  504.     (                                       \
  505.         "lpm"           "\n\t"              \
  506.         "mov %A0, r0"   "\n\t"              \
  507.         "adiw r30, 1"   "\n\t"              \
  508.         "lpm"           "\n\t"              \
  509.         "mov %B0, r0"   "\n\t"              \
  510.         "adiw r30, 1"   "\n\t"              \
  511.         "lpm"           "\n\t"              \
  512.         "mov %C0, r0"   "\n\t"              \
  513.         "adiw r30, 1"   "\n\t"              \
  514.         "lpm"           "\n\t"              \
  515.         "mov %D0, r0"   "\n\t"              \
  516.         : "=r" (__result), "=z" (__addr16)  \
  517.         : "1" (__addr16)                    \
  518.         : "r0"                              \
  519.     );                                      \
  520.     __result;                               \
  521. }))
  522.  
  523. #define __LPM_dword_tiny__(addr)            \
  524. (__extension__({                            \
  525.     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
  526.     uint32_t __result;                      \
  527.     __asm__                                 \
  528.     (                                       \
  529.         "ld %A0, z+"    "\n\t"              \
  530.         "ld %B0, z+"    "\n\t"              \
  531.         "ld %C0, z+"    "\n\t"              \
  532.         "ld %D0, z"     "\n\t"              \
  533.         : "=r" (__result), "=z" (__addr16)  \
  534.         : "1" (__addr16)                    \
  535.     );                                      \
  536.     __result;                               \
  537. }))
  538.  
  539. #define __LPM_dword_enhanced__(addr)        \
  540. (__extension__({                            \
  541.     uint16_t __addr16 = (uint16_t)(addr);   \
  542.     uint32_t __result;                      \
  543.     __asm__ __volatile__                    \
  544.     (                                       \
  545.         "lpm %A0, Z+"   "\n\t"              \
  546.         "lpm %B0, Z+"   "\n\t"              \
  547.         "lpm %C0, Z+"   "\n\t"              \
  548.         "lpm %D0, Z"    "\n\t"              \
  549.         : "=r" (__result), "=z" (__addr16)  \
  550.         : "1" (__addr16)                    \
  551.     );                                      \
  552.     __result;                               \
  553. }))
  554.  
  555. #define __LPM_float_classic__(addr)         \
  556. (__extension__({                            \
  557.     uint16_t __addr16 = (uint16_t)(addr);   \
  558.     float __result;                         \
  559.     __asm__ __volatile__                    \
  560.     (                                       \
  561.         "lpm"           "\n\t"              \
  562.         "mov %A0, r0"   "\n\t"              \
  563.         "adiw r30, 1"   "\n\t"              \
  564.         "lpm"           "\n\t"              \
  565.         "mov %B0, r0"   "\n\t"              \
  566.         "adiw r30, 1"   "\n\t"              \
  567.         "lpm"           "\n\t"              \
  568.         "mov %C0, r0"   "\n\t"              \
  569.         "adiw r30, 1"   "\n\t"              \
  570.         "lpm"           "\n\t"              \
  571.         "mov %D0, r0"   "\n\t"              \
  572.         : "=r" (__result), "=z" (__addr16)  \
  573.         : "1" (__addr16)                    \
  574.         : "r0"                              \
  575.     );                                      \
  576.     __result;                               \
  577. }))
  578.  
  579. #define __LPM_float_tiny__(addr)            \
  580. (__extension__({                            \
  581.     uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
  582.     float __result;                         \
  583.     __asm__                                 \
  584.     (                                       \
  585.         "ld %A0, z+"   "\n\t"               \
  586.         "ld %B0, z+"   "\n\t"               \
  587.         "ld %C0, z+"   "\n\t"               \
  588.         "ld %D0, z"    "\n\t"               \
  589.         : "=r" (__result), "=z" (__addr16)  \
  590.         : "1" (__addr16)                    \
  591.     );                                      \
  592.     __result;                               \
  593. }))
  594.  
  595. #define __LPM_float_enhanced__(addr)        \
  596. (__extension__({                            \
  597.     uint16_t __addr16 = (uint16_t)(addr);   \
  598.     float __result;                         \
  599.     __asm__ __volatile__                    \
  600.     (                                       \
  601.         "lpm %A0, Z+"   "\n\t"              \
  602.         "lpm %B0, Z+"   "\n\t"              \
  603.         "lpm %C0, Z+"   "\n\t"              \
  604.         "lpm %D0, Z"    "\n\t"              \
  605.         : "=r" (__result), "=z" (__addr16)  \
  606.         : "1" (__addr16)                    \
  607.     );                                      \
  608.     __result;                               \
  609. }))
  610.  
  611. #if defined (__AVR_HAVE_LPMX__)
  612. #define __LPM(addr)         __LPM_enhanced__(addr)
  613. #define __LPM_word(addr)    __LPM_word_enhanced__(addr)
  614. #define __LPM_dword(addr)   __LPM_dword_enhanced__(addr)
  615. #define __LPM_float(addr)   __LPM_float_enhanced__(addr)
  616. /*
  617. Macro to read data from program memory for avr tiny parts(tiny 4/5/9/10/20/40).
  618. why:
  619. - LPM instruction is not available in AVR_TINY instruction set.
  620. - Programs are executed starting from address 0x0000 in program memory.
  621. But it must be addressed starting from 0x4000 when accessed via data memory.
  622. Reference: TINY device (ATTiny 4,5,9,10,20 and 40) datasheets
  623. Bug: avrtc-536
  624. */
  625. #elif defined (__AVR_TINY__)
  626. #define __LPM(addr)         __LPM_tiny__(addr)
  627. #define __LPM_word(addr)    __LPM_word_tiny__(addr)
  628. #define __LPM_dword(addr)   __LPM_dword_tiny__(addr)
  629. #define __LPM_float(addr)   __LPM_float_tiny__(addr)
  630. #else
  631. #define __LPM(addr)         __LPM_classic__(addr)
  632. #define __LPM_word(addr)    __LPM_word_classic__(addr)
  633. #define __LPM_dword(addr)   __LPM_dword_classic__(addr)
  634. #define __LPM_float(addr)   __LPM_float_classic__(addr)
  635. #endif
  636.  
  637. #endif  /* !__DOXYGEN__ */
  638.  
  639. /** \ingroup avr_pgmspace
  640.     \def pgm_read_byte_near(address_short)
  641.     Read a byte from the program space with a 16-bit (near) address.
  642.     \note The address is a byte address.
  643.     The address is in the program space. */
  644.  
  645. #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
  646.  
  647. /** \ingroup avr_pgmspace
  648.     \def pgm_read_word_near(address_short)
  649.     Read a word from the program space with a 16-bit (near) address.
  650.     \note The address is a byte address.
  651.     The address is in the program space. */
  652.  
  653. #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
  654.  
  655. /** \ingroup avr_pgmspace
  656.     \def pgm_read_dword_near(address_short)
  657.     Read a double word from the program space with a 16-bit (near) address.
  658.     \note The address is a byte address.
  659.     The address is in the program space. */
  660.  
  661. #define pgm_read_dword_near(address_short) \
  662.     __LPM_dword((uint16_t)(address_short))
  663.  
  664. /** \ingroup avr_pgmspace
  665.     \def pgm_read_float_near(address_short)
  666.     Read a float from the program space with a 16-bit (near) address.
  667.     \note The address is a byte address.
  668.     The address is in the program space. */
  669.  
  670. #define pgm_read_float_near(address_short) \
  671.     __LPM_float((uint16_t)(address_short))
  672.  
  673. /** \ingroup avr_pgmspace
  674.     \def pgm_read_ptr_near(address_short)
  675.     Read a pointer from the program space with a 16-bit (near) address.
  676.     \note The address is a byte address.
  677.     The address is in the program space. */
  678.  
  679. #define pgm_read_ptr_near(address_short) \
  680.     (void*)__LPM_word((uint16_t)(address_short))
  681.  
  682. #if defined(RAMPZ) || defined(__DOXYGEN__)
  683.  
  684. /* Only for devices with more than 64K of program memory.
  685.    RAMPZ must be defined (see iom103.h, iom128.h).
  686. */
  687.  
  688. /* The classic functions are needed for ATmega103. */
  689. #ifndef __DOXYGEN__     /* These are internal macros, avoid "is
  690.                    not documented" warnings. */
  691. #define __ELPM_classic__(addr)      \
  692. (__extension__({                    \
  693.    uint32_t __addr32 = (uint32_t)(addr); \
  694.    uint8_t __result;               \
  695.    __asm__ __volatile__            \
  696.    (                               \
  697.        "out %2, %C1" "\n\t"        \
  698.        "mov r31, %B1" "\n\t"       \
  699.        "mov r30, %A1" "\n\t"       \
  700.        "elpm" "\n\t"               \
  701.        "mov %0, r0" "\n\t"         \
  702.        : "=r" (__result)           \
  703.        : "r" (__addr32),           \
  704.          "I" (_SFR_IO_ADDR(RAMPZ)) \
  705.        : "r0", "r30", "r31"        \
  706.    );                              \
  707.    __result;                       \
  708. }))
  709.  
  710. #define __ELPM_enhanced__(addr)     \
  711. (__extension__({                    \
  712.    uint32_t __addr32 = (uint32_t)(addr); \
  713.    uint8_t __result;               \
  714.    __asm__ __volatile__            \
  715.    (                               \
  716.        "out %2, %C1" "\n\t"        \
  717.        "movw r30, %1" "\n\t"       \
  718.        "elpm %0, Z+" "\n\t"        \
  719.        : "=r" (__result)           \
  720.        : "r" (__addr32),           \
  721.          "I" (_SFR_IO_ADDR(RAMPZ)) \
  722.        : "r30", "r31"              \
  723.    );                              \
  724.    __result;                       \
  725. }))
  726.  
  727. #define __ELPM_xmega__(addr)        \
  728. (__extension__({                    \
  729.    uint32_t __addr32 = (uint32_t)(addr); \
  730.    uint8_t __result;               \
  731.    __asm__ __volatile__            \
  732.    (                               \
  733.        "in __tmp_reg__, %2" "\n\t" \
  734.        "out %2, %C1" "\n\t"        \
  735.        "movw r30, %1" "\n\t"       \
  736.        "elpm %0, Z+" "\n\t"        \
  737.        "out %2, __tmp_reg__"       \
  738.        : "=r" (__result)           \
  739.        : "r" (__addr32),           \
  740.          "I" (_SFR_IO_ADDR(RAMPZ)) \
  741.        : "r30", "r31"              \
  742.    );                              \
  743.    __result;                       \
  744. }))
  745.  
  746. #define __ELPM_word_classic__(addr)     \
  747. (__extension__({                        \
  748.    uint32_t __addr32 = (uint32_t)(addr); \
  749.    uint16_t __result;                  \
  750.    __asm__ __volatile__                \
  751.    (                                   \
  752.        "out %2, %C1"   "\n\t"          \
  753.        "mov r31, %B1"  "\n\t"          \
  754.        "mov r30, %A1"  "\n\t"          \
  755.        "elpm"          "\n\t"          \
  756.        "mov %A0, r0"   "\n\t"          \
  757.        "in r0, %2"     "\n\t"          \
  758.        "adiw r30, 1"   "\n\t"          \
  759.        "adc r0, __zero_reg__" "\n\t"   \
  760.        "out %2, r0"    "\n\t"          \
  761.        "elpm"          "\n\t"          \
  762.        "mov %B0, r0"   "\n\t"          \
  763.        : "=r" (__result)               \
  764.        : "r" (__addr32),               \
  765.          "I" (_SFR_IO_ADDR(RAMPZ))     \
  766.        : "r0", "r30", "r31"            \
  767.    );                                  \
  768.    __result;                           \
  769. }))
  770.  
  771. #define __ELPM_word_enhanced__(addr)    \
  772. (__extension__({                        \
  773.    uint32_t __addr32 = (uint32_t)(addr); \
  774.    uint16_t __result;                  \
  775.    __asm__ __volatile__                \
  776.    (                                   \
  777.        "out %2, %C1"   "\n\t"          \
  778.        "movw r30, %1"  "\n\t"          \
  779.        "elpm %A0, Z+"  "\n\t"          \
  780.        "elpm %B0, Z"   "\n\t"          \
  781.        : "=r" (__result)               \
  782.        : "r" (__addr32),               \
  783.          "I" (_SFR_IO_ADDR(RAMPZ))     \
  784.        : "r30", "r31"                  \
  785.    );                                  \
  786.    __result;                           \
  787. }))
  788.  
  789. #define __ELPM_word_xmega__(addr)       \
  790. (__extension__({                        \
  791.    uint32_t __addr32 = (uint32_t)(addr); \
  792.    uint16_t __result;                  \
  793.    __asm__ __volatile__                \
  794.    (                                   \
  795.        "in __tmp_reg__, %2" "\n\t"     \
  796.        "out %2, %C1"   "\n\t"          \
  797.        "movw r30, %1"  "\n\t"          \
  798.        "elpm %A0, Z+"  "\n\t"          \
  799.        "elpm %B0, Z"   "\n\t"          \
  800.        "out %2, __tmp_reg__"           \
  801.        : "=r" (__result)               \
  802.        : "r" (__addr32),               \
  803.          "I" (_SFR_IO_ADDR(RAMPZ))     \
  804.        : "r30", "r31"                  \
  805.    );                                  \
  806.    __result;                           \
  807. }))
  808.  
  809. #define __ELPM_dword_classic__(addr)      \
  810. (__extension__({                          \
  811.    uint32_t __addr32 = (uint32_t)(addr); \
  812.    uint32_t __result;                    \
  813.    __asm__ __volatile__                  \
  814.    (                                     \
  815.        "out %2, %C1"          "\n\t"     \
  816.        "mov r31, %B1"         "\n\t"     \
  817.        "mov r30, %A1"         "\n\t"     \
  818.        "elpm"                 "\n\t"     \
  819.        "mov %A0, r0"          "\n\t"     \
  820.        "in r0, %2"            "\n\t"     \
  821.        "adiw r30, 1"          "\n\t"     \
  822.        "adc r0, __zero_reg__" "\n\t"     \
  823.        "out %2, r0"           "\n\t"     \
  824.        "elpm"                 "\n\t"     \
  825.        "mov %B0, r0"          "\n\t"     \
  826.        "in r0, %2"            "\n\t"     \
  827.        "adiw r30, 1"          "\n\t"     \
  828.        "adc r0, __zero_reg__" "\n\t"     \
  829.        "out %2, r0"           "\n\t"     \
  830.        "elpm"                 "\n\t"     \
  831.        "mov %C0, r0"          "\n\t"     \
  832.        "in r0, %2"            "\n\t"     \
  833.        "adiw r30, 1"          "\n\t"     \
  834.        "adc r0, __zero_reg__" "\n\t"     \
  835.        "out %2, r0"           "\n\t"     \
  836.        "elpm"                 "\n\t"     \
  837.        "mov %D0, r0"          "\n\t"     \
  838.        : "=r" (__result)                 \
  839.        : "r" (__addr32),                 \
  840.          "I" (_SFR_IO_ADDR(RAMPZ))       \
  841.        : "r0", "r30", "r31"              \
  842.    );                                    \
  843.    __result;                             \
  844. }))
  845.  
  846. #define __ELPM_dword_enhanced__(addr)     \
  847. (__extension__({                          \
  848.    uint32_t __addr32 = (uint32_t)(addr); \
  849.    uint32_t __result;                    \
  850.    __asm__ __volatile__                  \
  851.    (                                     \
  852.        "out %2, %C1"   "\n\t"            \
  853.        "movw r30, %1"  "\n\t"            \
  854.        "elpm %A0, Z+"  "\n\t"            \
  855.        "elpm %B0, Z+"  "\n\t"            \
  856.        "elpm %C0, Z+"  "\n\t"            \
  857.        "elpm %D0, Z"   "\n\t"            \
  858.        : "=r" (__result)                 \
  859.        : "r" (__addr32),                 \
  860.          "I" (_SFR_IO_ADDR(RAMPZ))       \
  861.        : "r30", "r31"                    \
  862.    );                                    \
  863.    __result;                             \
  864. }))
  865.  
  866. #define __ELPM_dword_xmega__(addr)        \
  867. (__extension__({                          \
  868.    uint32_t __addr32 = (uint32_t)(addr); \
  869.    uint32_t __result;                    \
  870.    __asm__ __volatile__                  \
  871.    (                                     \
  872.        "in __tmp_reg__, %2" "\n\t"       \
  873.        "out %2, %C1"   "\n\t"            \
  874.        "movw r30, %1"  "\n\t"            \
  875.        "elpm %A0, Z+"  "\n\t"            \
  876.        "elpm %B0, Z+"  "\n\t"            \
  877.        "elpm %C0, Z+"  "\n\t"            \
  878.        "elpm %D0, Z"   "\n\t"            \
  879.        "out %2, __tmp_reg__"             \
  880.        : "=r" (__result)                 \
  881.        : "r" (__addr32),                 \
  882.          "I" (_SFR_IO_ADDR(RAMPZ))       \
  883.        : "r30", "r31"                    \
  884.    );                                    \
  885.    __result;                             \
  886. }))
  887.  
  888. #define __ELPM_float_classic__(addr)      \
  889. (__extension__({                          \
  890.    uint32_t __addr32 = (uint32_t)(addr); \
  891.    float __result;                       \
  892.    __asm__ __volatile__                  \
  893.    (                                     \
  894.        "out %2, %C1"          "\n\t"     \
  895.        "mov r31, %B1"         "\n\t"     \
  896.        "mov r30, %A1"         "\n\t"     \
  897.        "elpm"                 "\n\t"     \
  898.        "mov %A0, r0"          "\n\t"     \
  899.        "in r0, %2"            "\n\t"     \
  900.        "adiw r30, 1"          "\n\t"     \
  901.        "adc r0, __zero_reg__" "\n\t"     \
  902.        "out %2, r0"           "\n\t"     \
  903.        "elpm"                 "\n\t"     \
  904.        "mov %B0, r0"          "\n\t"     \
  905.        "in r0, %2"            "\n\t"     \
  906.        "adiw r30, 1"          "\n\t"     \
  907.        "adc r0, __zero_reg__" "\n\t"     \
  908.        "out %2, r0"           "\n\t"     \
  909.        "elpm"                 "\n\t"     \
  910.        "mov %C0, r0"          "\n\t"     \
  911.        "in r0, %2"            "\n\t"     \
  912.        "adiw r30, 1"          "\n\t"     \
  913.        "adc r0, __zero_reg__" "\n\t"     \
  914.        "out %2, r0"           "\n\t"     \
  915.        "elpm"                 "\n\t"     \
  916.        "mov %D0, r0"          "\n\t"     \
  917.        : "=r" (__result)                 \
  918.        : "r" (__addr32),                 \
  919.          "I" (_SFR_IO_ADDR(RAMPZ))       \
  920.        : "r0", "r30", "r31"              \
  921.    );                                    \
  922.    __result;                             \
  923. }))
  924.  
  925. #define __ELPM_float_enhanced__(addr)     \
  926. (__extension__({                          \
  927.    uint32_t __addr32 = (uint32_t)(addr); \
  928.    float __result;                       \
  929.    __asm__ __volatile__                  \
  930.    (                                     \
  931.        "out %2, %C1"   "\n\t"            \
  932.        "movw r30, %1"  "\n\t"            \
  933.        "elpm %A0, Z+"  "\n\t"            \
  934.        "elpm %B0, Z+"  "\n\t"            \
  935.        "elpm %C0, Z+"  "\n\t"            \
  936.        "elpm %D0, Z"   "\n\t"            \
  937.        : "=r" (__result)                 \
  938.        : "r" (__addr32),                 \
  939.          "I" (_SFR_IO_ADDR(RAMPZ))       \
  940.        : "r30", "r31"                    \
  941.    );                                    \
  942.    __result;                             \
  943. }))
  944.  
  945. #define __ELPM_float_xmega__(addr)        \
  946. (__extension__({                          \
  947.    uint32_t __addr32 = (uint32_t)(addr); \
  948.    float __result;                       \
  949.    __asm__ __volatile__                  \
  950.    (                                     \
  951.        "in __tmp_reg__, %2" "\n\t"       \
  952.        "out %2, %C1"   "\n\t"            \
  953.        "movw r30, %1"  "\n\t"            \
  954.        "elpm %A0, Z+"  "\n\t"            \
  955.        "elpm %B0, Z+"  "\n\t"            \
  956.        "elpm %C0, Z+"  "\n\t"            \
  957.        "elpm %D0, Z"   "\n\t"            \
  958.        "out %2, __tmp_reg__"             \
  959.        : "=r" (__result)                 \
  960.        : "r" (__addr32),                 \
  961.          "I" (_SFR_IO_ADDR(RAMPZ))       \
  962.        : "r30", "r31"                    \
  963.    );                                    \
  964.    __result;                             \
  965. }))
  966.  
  967. /*
  968. Check for architectures that implement RAMPD (avrxmega5, avrxmega7)
  969. as they need to save/restore RAMPZ for ELPM macros so it does
  970. not interfere with data accesses.
  971. */
  972. #if defined (__AVR_HAVE_RAMPD__)
  973.  
  974. #define __ELPM(addr)        __ELPM_xmega__(addr)
  975. #define __ELPM_word(addr)   __ELPM_word_xmega__(addr)
  976. #define __ELPM_dword(addr)  __ELPM_dword_xmega__(addr)
  977. #define __ELPM_float(addr)  __ELPM_float_xmega__(addr)
  978.  
  979. #else
  980.  
  981. #if defined (__AVR_HAVE_LPMX__)
  982.  
  983. #define __ELPM(addr)        __ELPM_enhanced__(addr)
  984. #define __ELPM_word(addr)   __ELPM_word_enhanced__(addr)
  985. #define __ELPM_dword(addr)  __ELPM_dword_enhanced__(addr)
  986. #define __ELPM_float(addr)  __ELPM_float_enhanced__(addr)
  987.  
  988. #else
  989.  
  990. #define __ELPM(addr)        __ELPM_classic__(addr)
  991. #define __ELPM_word(addr)   __ELPM_word_classic__(addr)
  992. #define __ELPM_dword(addr)  __ELPM_dword_classic__(addr)
  993. #define __ELPM_float(addr)  __ELPM_float_classic__(addr)
  994.  
  995. #endif  /* __AVR_HAVE_LPMX__ */
  996.  
  997. #endif  /* __AVR_HAVE_RAMPD__ */
  998.  
  999. #endif  /* !__DOXYGEN__ */
  1000.  
  1001. /** \ingroup avr_pgmspace
  1002.    \def pgm_read_byte_far(address_long)
  1003.    Read a byte from the program space with a 32-bit (far) address.
  1004.  
  1005.    \note The address is a byte address.
  1006.    The address is in the program space. */
  1007.  
  1008. #define pgm_read_byte_far(address_long)  __ELPM((uint32_t)(address_long))
  1009.  
  1010. /** \ingroup avr_pgmspace
  1011.    \def pgm_read_word_far(address_long)
  1012.    Read a word from the program space with a 32-bit (far) address.
  1013.  
  1014.    \note The address is a byte address.
  1015.    The address is in the program space. */
  1016.  
  1017. #define pgm_read_word_far(address_long)  __ELPM_word((uint32_t)(address_long))
  1018.  
  1019. /** \ingroup avr_pgmspace
  1020.    \def pgm_read_dword_far(address_long)
  1021.    Read a double word from the program space with a 32-bit (far) address.
  1022.  
  1023.    \note The address is a byte address.
  1024.    The address is in the program space. */
  1025.  
  1026. #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
  1027.  
  1028. /** \ingroup avr_pgmspace
  1029.    \def pgm_read_float_far(address_long)
  1030.    Read a float from the program space with a 32-bit (far) address.
  1031.  
  1032.    \note The address is a byte address.
  1033.    The address is in the program space. */
  1034.  
  1035. #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
  1036.  
  1037. /** \ingroup avr_pgmspace
  1038.    \def pgm_read_ptr_far(address_long)
  1039.    Read a pointer from the program space with a 32-bit (far) address.
  1040.  
  1041.    \note The address is a byte address.
  1042.    The address is in the program space. */
  1043.  
  1044. #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
  1045.  
  1046. #endif /* RAMPZ or __DOXYGEN__ */
  1047.  
  1048. /** \ingroup avr_pgmspace
  1049.    \def pgm_read_byte(address_short)
  1050.    Read a byte from the program space with a 16-bit (near) address.
  1051.  
  1052.    \note The address is a byte address.
  1053.    The address is in the program space. */
  1054.  
  1055. #define pgm_read_byte(address_short)    pgm_read_byte_near(address_short)
  1056.  
  1057. /** \ingroup avr_pgmspace
  1058.    \def pgm_read_word(address_short)
  1059.    Read a word from the program space with a 16-bit (near) address.
  1060.  
  1061.    \note The address is a byte address.
  1062.    The address is in the program space. */
  1063.  
  1064. #define pgm_read_word(address_short)    pgm_read_word_near(address_short)
  1065.  
  1066. /** \ingroup avr_pgmspace
  1067.    \def pgm_read_dword(address_short)
  1068.    Read a double word from the program space with a 16-bit (near) address.
  1069.  
  1070.    \note The address is a byte address.
  1071.    The address is in the program space. */
  1072.  
  1073. #define pgm_read_dword(address_short)   pgm_read_dword_near(address_short)
  1074.  
  1075. /** \ingroup avr_pgmspace
  1076.    \def pgm_read_float(address_short)
  1077.    Read a float from the program space with a 16-bit (near) address.
  1078.  
  1079.    \note The address is a byte address.
  1080.    The address is in the program space. */
  1081.  
  1082. #define pgm_read_float(address_short)   pgm_read_float_near(address_short)
  1083.  
  1084. /** \ingroup avr_pgmspace
  1085.    \def pgm_read_ptr(address_short)
  1086.    Read a pointer from the program space with a 16-bit (near) address.
  1087.  
  1088.    \note The address is a byte address.
  1089.    The address is in the program space. */
  1090.  
  1091. #define pgm_read_ptr(address_short)     pgm_read_ptr_near(address_short)
  1092.  
  1093. /** \ingroup avr_pgmspace
  1094.    \def pgm_get_far_address(var)
  1095.  
  1096.   This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
  1097.   used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
  1098.   is similar to the '&' operator, with some limitations.
  1099.  
  1100.   Comments:
  1101.  
  1102.   - The overhead is minimal and it's mainly due to the 32 bit size operation.
  1103.  
  1104.   - 24 bit sizes guarantees the code compatibility for use in future devices.
  1105.  
  1106.   - hh8() is an undocumented feature but seems to give the third significant byte
  1107.     of a 32 bit data and accepts symbols, complementing the functionality of hi8()
  1108.     and lo8(). There is not an equivalent assembler function to get the high
  1109.     significant byte.
  1110.  
  1111.   - 'var' has to be resolved at linking time as an existing symbol, i.e, a simple
  1112.     type variable name, an array name (not an indexed element of the array, if the
  1113.     index is a constant the compiler does not complain but fails to get the address
  1114.     if optimization is enabled), a struct name or a struct field name, a function
  1115.     identifier, a linker defined identifier,...
  1116.  
  1117.   - The returned value is the identifier's VMA (virtual memory address) determined
  1118.     by the linker and falls in the corresponding memory region. The AVR Harvard
  1119.     architecture requires non overlapping VMA areas for the multiple address spaces
  1120.     in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
  1121.     0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the linker
  1122.     script used and linker options. The value returned can be seen then as a
  1123.     universal pointer.
  1124. */
  1125.  
  1126. #define pgm_get_far_address(var)                          \
  1127. ({                                                    \
  1128.     uint_farptr_t tmp;                                \
  1129.                                                      \
  1130.     __asm__ __volatile__(                             \
  1131.                                                      \
  1132.             "ldi    %A0, lo8(%1)"           "\n\t"    \
  1133.             "ldi    %B0, hi8(%1)"           "\n\t"    \
  1134.             "ldi    %C0, hh8(%1)"           "\n\t"    \
  1135.             "clr    %D0"                    "\n\t"    \
  1136.         :                                             \
  1137.             "=d" (tmp)                                \
  1138.         :                                             \
  1139.             "p"  (&(var))                             \
  1140.     );                                                \
  1141.     tmp;                                              \
  1142. })
  1143.  
  1144.  
  1145.  
  1146. /** \ingroup avr_pgmspace
  1147.    \fn const void * memchr_P(const void *s, int val, size_t len)
  1148.    \brief Scan flash memory for a character.
  1149.  
  1150.    The memchr_P() function scans the first \p len bytes of the flash
  1151.    memory area pointed to by \p s for the character \p val.  The first
  1152.    byte to match \p val (interpreted as an unsigned character) stops
  1153.    the operation.
  1154.  
  1155.    \return The memchr_P() function returns a pointer to the matching
  1156.    byte or \c NULL if the character does not occur in the given memory
  1157.     area.   */
  1158. extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
  1159.  
  1160. /** \ingroup avr_pgmspace
  1161.    \fn int memcmp_P(const void *s1, const void *s2, size_t len)
  1162.    \brief Compare memory areas
  1163.  
  1164.    The memcmp_P() function compares the first \p len bytes of the memory
  1165.    areas \p s1 and flash \p s2. The comparision is performed using unsigned
  1166.    char operations.
  1167.  
  1168.    \returns The memcmp_P() function returns an integer less than, equal
  1169.    to, or greater than zero if the first \p len bytes of \p s1 is found,
  1170.    respectively, to be less than, to match, or be greater than the first
  1171.     \p len bytes of \p s2.  */
  1172. extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
  1173.  
  1174. /** \ingroup avr_pgmspace
  1175.    \fn void *memccpy_P (void *dest, const void *src, int val, size_t len)
  1176.  
  1177.    This function is similar to memccpy() except that \p src is pointer
  1178.     to a string in program space.   */
  1179. extern void *memccpy_P(void *, const void *, int __val, size_t);
  1180.  
  1181. /** \ingroup avr_pgmspace
  1182.    \fn void *memcpy_P(void *dest, const void *src, size_t n)
  1183.  
  1184.    The memcpy_P() function is similar to memcpy(), except the src string
  1185.    resides in program space.
  1186.  
  1187.    \returns The memcpy_P() function returns a pointer to dest.  */
  1188. extern void *memcpy_P(void *, const void *, size_t);
  1189.  
  1190. /** \ingroup avr_pgmspace
  1191.    \fn void *memmem_P(const void *s1, size_t len1, const void *s2, size_t len2)
  1192.  
  1193.    The memmem_P() function is similar to memmem() except that \p s2 is
  1194.     pointer to a string in program space.   */
  1195. extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
  1196.  
  1197. /** \ingroup avr_pgmspace
  1198.    \fn const void +memrchr_P(const void *src, int val, size_t len)
  1199.  
  1200.    The memrchr_P() function is like the memchr_P() function, except
  1201.    that it searches backwards from the end of the \p len bytes pointed
  1202.    to by \p src instead of forwards from the front. (Glibc, GNU extension.)
  1203.  
  1204.    \return The memrchr_P() function returns a pointer to the matching
  1205.    byte or \c NULL if the character does not occur in the given memory
  1206.     area.   */
  1207. extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
  1208.  
  1209. /** \ingroup avr_pgmspace
  1210.    \fn char *strcat_P(char *dest, const char *src)
  1211.  
  1212.    The strcat_P() function is similar to strcat() except that the \e src
  1213.    string must be located in program space (flash).
  1214.  
  1215.    \returns The strcat() function returns a pointer to the resulting string
  1216.    \e dest. */
  1217. extern char *strcat_P(char *, const char *);
  1218.  
  1219. /** \ingroup avr_pgmspace
  1220.    \fn const char *strchr_P(const char *s, int val)
  1221.    \brief Locate character in program space string.
  1222.  
  1223.    The strchr_P() function locates the first occurrence of \p val
  1224.    (converted to a char) in the string pointed to by \p s in program
  1225.    space. The terminating null character is considered to be part of
  1226.    the string.
  1227.  
  1228.    The strchr_P() function is similar to strchr() except that \p s is
  1229.    pointer to a string in program space.
  1230.  
  1231.    \returns The strchr_P() function returns a pointer to the matched
  1232.    character or \c NULL if the character is not found. */
  1233. extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
  1234.  
  1235. /** \ingroup avr_pgmspace
  1236.    \fn const char *strchrnul_P(const char *s, int c)
  1237.  
  1238.    The strchrnul_P() function is like strchr_P() except that if \p c is
  1239.    not found in \p s, then it returns a pointer to the null byte at the
  1240.    end of \p s, rather than \c NULL. (Glibc, GNU extension.)
  1241.  
  1242.    \return The strchrnul_P() function returns a pointer to the matched
  1243.    character, or a pointer to the null byte at the end of \p s (i.e.,
  1244.     \c s+strlen(s)) if the character is not found.  */
  1245. extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
  1246.  
  1247. /** \ingroup avr_pgmspace
  1248.    \fn int strcmp_P(const char *s1, const char *s2)
  1249.  
  1250.    The strcmp_P() function is similar to strcmp() except that \p s2 is
  1251.    pointer to a string in program space.
  1252.  
  1253.    \returns The strcmp_P() function returns an integer less than, equal
  1254.    to, or greater than zero if \p s1 is found, respectively, to be less
  1255.    than, to match, or be greater than \p s2. A consequence of the
  1256.    ordering used by strcmp_P() is that if \p s1 is an initial substring
  1257.    of \p s2, then \p s1 is considered to be "less than" \p s2. */
  1258. extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
  1259.  
  1260. /** \ingroup avr_pgmspace
  1261.    \fn char *strcpy_P(char *dest, const char *src)
  1262.  
  1263.    The strcpy_P() function is similar to strcpy() except that src is a
  1264.    pointer to a string in program space.
  1265.  
  1266.    \returns The strcpy_P() function returns a pointer to the destination
  1267.    string dest. */
  1268. extern char *strcpy_P(char *, const char *);
  1269.  
  1270. /** \ingroup avr_pgmspace
  1271.    \fn int strcasecmp_P(const char *s1, const char *s2)
  1272.    \brief Compare two strings ignoring case.
  1273.  
  1274.    The strcasecmp_P() function compares the two strings \p s1 and \p s2,
  1275.    ignoring the case of the characters.
  1276.  
  1277.    \param s1 A pointer to a string in the devices SRAM.
  1278.    \param s2 A pointer to a string in the devices Flash.
  1279.  
  1280.    \returns The strcasecmp_P() function returns an integer less than,
  1281.    equal to, or greater than zero if \p s1 is found, respectively, to
  1282.    be less than, to match, or be greater than \p s2. A consequence of
  1283.    the ordering used by strcasecmp_P() is that if \p s1 is an initial
  1284.    substring of \p s2, then \p s1 is considered to be "less than" \p s2. */
  1285. extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
  1286.  
  1287. /** \ingroup avr_pgmspace
  1288.    \fn char *strcasestr_P(const char *s1, const char *s2)
  1289.  
  1290.    This funtion is similar to strcasestr() except that \p s2 is pointer
  1291.     to a string in program space.   */
  1292. extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
  1293.  
  1294. /** \ingroup avr_pgmspace
  1295.    \fn size_t strcspn_P(const char *s, const char *reject)
  1296.  
  1297.    The strcspn_P() function calculates the length of the initial segment
  1298.    of \p s which consists entirely of characters not in \p reject. This
  1299.    function is similar to strcspn() except that \p reject is a pointer
  1300.    to a string in program space.
  1301.  
  1302.    \return The strcspn_P() function returns the number of characters in
  1303.    the initial segment of \p s which are not in the string \p reject.
  1304.     The terminating zero is not considered as a part of string. */
  1305. extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
  1306.  
  1307. /** \ingroup avr_pgmspace
  1308.    \fn size_t strlcat_P(char *dst, const char *src, size_t siz)
  1309.    \brief Concatenate two strings.
  1310.  
  1311.    The strlcat_P() function is similar to strlcat(), except that the \p src
  1312.    string must be located in program space (flash).
  1313.  
  1314.    Appends \p src to string \p dst of size \p siz (unlike strncat(),
  1315.    \p siz is the full size of \p dst, not space left).  At most \p siz-1
  1316.    characters will be copied.  Always NULL terminates (unless \p siz <=
  1317.    \p strlen(dst)).
  1318.  
  1319.    \returns The strlcat_P() function returns strlen(src) + MIN(siz,
  1320.     strlen(initial dst)).  If retval >= siz, truncation occurred.   */
  1321. extern size_t strlcat_P (char *, const char *, size_t );
  1322.  
  1323. /** \ingroup avr_pgmspace
  1324.    \fn size_t strlcpy_P(char *dst, const char *src, size_t siz)
  1325.    \brief Copy a string from progmem to RAM.
  1326.  
  1327.    Copy \p src to string \p dst of size \p siz.  At most \p siz-1
  1328.    characters will be copied.  Always NULL terminates (unless \p siz == 0).
  1329.    The strlcpy_P() function is similar to strlcpy() except that the
  1330.    \p src is pointer to a string in memory space.
  1331.  
  1332.    \returns The strlcpy_P() function returns strlen(src). If
  1333.    retval >= siz, truncation occurred.  */
  1334. extern size_t strlcpy_P (char *, const char *, size_t );
  1335.  
  1336. /** \ingroup avr_pgmspace
  1337.    \fn size_t strnlen_P(const char *src, size_t len)
  1338.    \brief Determine the length of a fixed-size string.
  1339.  
  1340.    The strnlen_P() function is similar to strnlen(), except that \c src is a
  1341.    pointer to a string in program space.
  1342.  
  1343.    \returns The strnlen_P function returns strlen_P(src), if that is less than
  1344.    \c len, or \c len if there is no '\\0' character among the first \c len
  1345.    characters pointed to by \c src. */
  1346. extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__; /* program memory can't change */
  1347.  
  1348. /** \ingroup avr_pgmspace
  1349.    \fn int strncmp_P(const char *s1, const char *s2, size_t n)
  1350.  
  1351.    The strncmp_P() function is similar to strcmp_P() except it only compares
  1352.    the first (at most) n characters of s1 and s2.
  1353.  
  1354.    \returns The strncmp_P() function returns an integer less than, equal to,
  1355.    or greater than zero if s1 (or the first n bytes thereof) is found,
  1356.    respectively, to be less than, to match, or be greater than s2.  */
  1357. extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
  1358.  
  1359. /** \ingroup avr_pgmspace
  1360.    \fn int strncasecmp_P(const char *s1, const char *s2, size_t n)
  1361.    \brief Compare two strings ignoring case.
  1362.  
  1363.    The strncasecmp_P() function is similar to strcasecmp_P(), except it
  1364.    only compares the first \p n characters of \p s1.
  1365.  
  1366.    \param s1 A pointer to a string in the devices SRAM.
  1367.    \param s2 A pointer to a string in the devices Flash.
  1368.    \param n The maximum number of bytes to compare.
  1369.  
  1370.    \returns The strncasecmp_P() function returns an integer less than,
  1371.    equal to, or greater than zero if \p s1 (or the first \p n bytes
  1372.    thereof) is found, respectively, to be less than, to match, or be
  1373.    greater than \p s2. A consequence of the ordering used by
  1374.    strncasecmp_P() is that if \p s1 is an initial substring of \p s2,
  1375.    then \p s1 is considered to be "less than" \p s2.  */
  1376. extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
  1377.  
  1378. /** \ingroup avr_pgmspace
  1379.    \fn char *strncat_P(char *dest, const char *src, size_t len)
  1380.    \brief Concatenate two strings.
  1381.  
  1382.    The strncat_P() function is similar to strncat(), except that the \e src
  1383.    string must be located in program space (flash).
  1384.  
  1385.    \returns The strncat_P() function returns a pointer to the resulting string
  1386.    dest.  */
  1387. extern char *strncat_P(char *, const char *, size_t);
  1388.  
  1389. /** \ingroup avr_pgmspace
  1390.    \fn char *strncpy_P(char *dest, const char *src, size_t n)
  1391.  
  1392.    The strncpy_P() function is similar to strcpy_P() except that not more
  1393.    than n bytes of src are copied.  Thus, if there is no null byte among the
  1394.    first n bytes of src, the result will not be null-terminated.
  1395.  
  1396.    In the case where the length of src is less than that of n, the remainder
  1397.    of dest will be padded with nulls.
  1398.  
  1399.    \returns The strncpy_P() function returns a pointer to the destination
  1400.    string dest.  */
  1401. extern char *strncpy_P(char *, const char *, size_t);
  1402.  
  1403. /** \ingroup avr_pgmspace
  1404.    \fn char *strpbrk_P(const char *s, const char *accept)
  1405.  
  1406.    The strpbrk_P() function locates the first occurrence in the string
  1407.    \p s of any of the characters in the flash string \p accept. This
  1408.    function is similar to strpbrk() except that \p accept is a pointer
  1409.    to a string in program space.
  1410.  
  1411.    \return  The strpbrk_P() function returns a pointer to the character
  1412.    in \p s that matches one of the characters in \p accept, or \c NULL
  1413.    if no such character is found. The terminating zero is not considered
  1414.    as a part of string: if one or both args are empty, the result will
  1415.    \c NULL. */
  1416. extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
  1417.  
  1418. /** \ingroup avr_pgmspace
  1419.    \fn const char *strrchr_P(const char *s, int val)
  1420.    \brief Locate character in string.
  1421.  
  1422.    The strrchr_P() function returns a pointer to the last occurrence of
  1423.    the character \p val in the flash string \p s.
  1424.  
  1425.    \return The strrchr_P() function returns a pointer to the matched
  1426.    character or \c NULL if the character is not found. */
  1427. extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
  1428.  
  1429. /** \ingroup avr_pgmspace
  1430.    \fn char *strsep_P(char **sp, const char *delim)
  1431.    \brief Parse a string into tokens.
  1432.  
  1433.    The strsep_P() function locates, in the string referenced by \p *sp,
  1434.    the first occurrence of any character in the string \p delim (or the
  1435.    terminating '\\0' character) and replaces it with a '\\0'.  The
  1436.    location of the next character after the delimiter character (or \c
  1437.    NULL, if the end of the string was reached) is stored in \p *sp. An
  1438.    ``empty'' field, i.e. one caused by two adjacent delimiter
  1439.    characters, can be detected by comparing the location referenced by
  1440.    the pointer returned in \p *sp to '\\0'. This function is similar to
  1441.    strsep() except that \p delim is a pointer to a string in program
  1442.    space.
  1443.  
  1444.    \return The strsep_P() function returns a pointer to the original
  1445.    value of \p *sp. If \p *sp is initially \c NULL, strsep_P() returns
  1446.    \c NULL. */
  1447. extern char *strsep_P(char **__sp, const char * __delim);
  1448.  
  1449. /** \ingroup avr_pgmspace
  1450.    \fn size_t strspn_P(const char *s, const char *accept)
  1451.  
  1452.    The strspn_P() function calculates the length of the initial segment
  1453.    of \p s which consists entirely of characters in \p accept. This
  1454.    function is similar to strspn() except that \p accept is a pointer
  1455.    to a string in program space.
  1456.  
  1457.    \return  The strspn_P() function returns the number of characters in
  1458.    the initial segment of \p s which consist only of characters from \p
  1459.     accept. The terminating zero is not considered as a part of string. */
  1460. extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
  1461.  
  1462. /** \ingroup avr_pgmspace
  1463.    \fn char *strstr_P(const char *s1, const char *s2)
  1464.    \brief Locate a substring.
  1465.  
  1466.    The strstr_P() function finds the first occurrence of the substring
  1467.    \p s2 in the string \p s1.  The terminating '\\0' characters are not
  1468.    compared. The strstr_P() function is similar to strstr() except that
  1469.    \p s2 is pointer to a string in program space.
  1470.  
  1471.    \returns The strstr_P() function returns a pointer to the beginning
  1472.    of the substring, or NULL if the substring is not found. If \p s2
  1473.    points to a string of zero length, the function returns \p s1. */
  1474. extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
  1475.  
  1476. /** \ingroup avr_pgmspace
  1477.    \fn char *strtok_P(char *s, const char * delim)
  1478.    \brief Parses the string into tokens.
  1479.  
  1480.    strtok_P() parses the string \p s into tokens. The first call to
  1481.    strtok_P() should have \p s as its first argument. Subsequent calls
  1482.    should have the first argument set to NULL. If a token ends with a
  1483.    delimiter, this delimiting character is overwritten with a '\\0' and a
  1484.    pointer to the next character is saved for the next call to strtok_P().
  1485.    The delimiter string \p delim may be different for each call.
  1486.  
  1487.    The strtok_P() function is similar to strtok() except that \p delim
  1488.    is pointer to a string in program space.
  1489.  
  1490.    \returns The strtok_P() function returns a pointer to the next token or
  1491.    NULL when no more tokens are found.
  1492.  
  1493.    \note strtok_P() is NOT reentrant. For a reentrant version of this
  1494.    function see strtok_rP().
  1495. */
  1496. extern char *strtok_P(char *__s, const char * __delim);
  1497.  
  1498. /** \ingroup avr_pgmspace
  1499.    \fn char *strtok_rP (char *string, const char *delim, char **last)
  1500.    \brief Parses string into tokens.
  1501.  
  1502.    The strtok_rP() function parses \p string into tokens. The first call to
  1503.    strtok_rP() should have string as its first argument. Subsequent calls
  1504.    should have the first argument set to NULL. If a token ends with a
  1505.    delimiter, this delimiting character is overwritten with a '\\0' and a
  1506.    pointer to the next character is saved for the next call to strtok_rP().
  1507.    The delimiter string \p delim may be different for each call. \p last is
  1508.    a user allocated char* pointer. It must be the same while parsing the
  1509.    same string. strtok_rP() is a reentrant version of strtok_P().
  1510.  
  1511.    The strtok_rP() function is similar to strtok_r() except that \p delim
  1512.    is pointer to a string in program space.
  1513.  
  1514.    \returns The strtok_rP() function returns a pointer to the next token or
  1515.    NULL when no more tokens are found. */
  1516. extern char *strtok_rP(char *__s, const char * __delim, char **__last);
  1517.  
  1518. /** \ingroup avr_pgmspace
  1519.    \fn size_t strlen_PF(uint_farptr_t s)
  1520.    \brief Obtain the length of a string
  1521.  
  1522.    The strlen_PF() function is similar to strlen(), except that \e s is a
  1523.    far pointer to a string in program space.
  1524.  
  1525.    \param s A far pointer to the string in flash
  1526.  
  1527.    \returns The strlen_PF() function returns the number of characters in
  1528.    \e s. The contents of RAMPZ SFR are undefined when the function returns. */
  1529. extern size_t strlen_PF(uint_farptr_t src) __ATTR_CONST__; /* program memory can't change */
  1530.  
  1531. /** \ingroup avr_pgmspace
  1532.    \fn size_t strnlen_PF(uint_farptr_t s, size_t len)
  1533.    \brief Determine the length of a fixed-size string
  1534.  
  1535.    The strnlen_PF() function is similar to strnlen(), except that \e s is a
  1536.    far pointer to a string in program space.
  1537.  
  1538.    \param s A far pointer to the string in Flash
  1539.    \param len The maximum number of length to return
  1540.  
  1541.    \returns The strnlen_PF function returns strlen_P(\e s), if that is less
  1542.    than \e len, or \e len if there is no '\\0' character among the first \e
  1543.    len characters pointed to by \e s. The contents of RAMPZ SFR are
  1544.    undefined when the function returns. */
  1545. extern size_t strnlen_PF(uint_farptr_t src, size_t len) __ATTR_CONST__; /* program memory can't change */
  1546.  
  1547. /** \ingroup avr_pgmspace
  1548.    \fn void *memcpy_PF(void *dest, uint_farptr_t src, size_t n)
  1549.    \brief Copy a memory block from flash to SRAM
  1550.  
  1551.    The memcpy_PF() function is similar to memcpy(), except the data
  1552.    is copied from the program space and is addressed using a far pointer.
  1553.  
  1554.    \param dest A pointer to the destination buffer
  1555.    \param src A far pointer to the origin of data in flash memory
  1556.    \param n The number of bytes to be copied
  1557.  
  1558.    \returns The memcpy_PF() function returns a pointer to \e dst. The contents
  1559.    of RAMPZ SFR are undefined when the function returns. */
  1560. extern void *memcpy_PF(void *dest, uint_farptr_t src, size_t len);
  1561.  
  1562. /** \ingroup avr_pgmspace
  1563.    \fn char *strcpy_PF(char *dst, uint_farptr_t src)
  1564.    \brief Duplicate a string
  1565.  
  1566.    The strcpy_PF() function is similar to strcpy() except that \e src is a far
  1567.    pointer to a string in program space.
  1568.  
  1569.    \param dst A pointer to the destination string in SRAM
  1570.    \param src A far pointer to the source string in Flash
  1571.  
  1572.    \returns The strcpy_PF() function returns a pointer to the destination
  1573.    string \e dst. The contents of RAMPZ SFR are undefined when the funcion
  1574.    returns. */
  1575. extern char *strcpy_PF(char *dest, uint_farptr_t src);
  1576.  
  1577. /** \ingroup avr_pgmspace
  1578.    \fn char *strncpy_PF(char *dst, uint_farptr_t src, size_t n)
  1579.    \brief Duplicate a string until a limited length
  1580.  
  1581.    The strncpy_PF() function is similar to strcpy_PF() except that not more
  1582.    than \e n bytes of \e src are copied.  Thus, if there is no null byte among
  1583.    the first \e n bytes of \e src, the result will not be null-terminated.
  1584.  
  1585.    In the case where the length of \e src is less than that of \e n, the
  1586.    remainder of \e dst will be padded with nulls.
  1587.  
  1588.    \param dst A pointer to the destination string in SRAM
  1589.    \param src A far pointer to the source string in Flash
  1590.    \param n The maximum number of bytes to copy
  1591.  
  1592.    \returns The strncpy_PF() function returns a pointer to the destination
  1593.    string \e dst. The contents of RAMPZ SFR are undefined when the function
  1594.    returns. */
  1595. extern char *strncpy_PF(char *dest, uint_farptr_t src, size_t len);
  1596.  
  1597. /** \ingroup avr_pgmspace
  1598.    \fn char *strcat_PF(char *dst, uint_farptr_t src)
  1599.    \brief Concatenates two strings
  1600.  
  1601.    The strcat_PF() function is similar to strcat() except that the \e src
  1602.    string must be located in program space (flash) and is addressed using
  1603.    a far pointer
  1604.  
  1605.    \param dst A pointer to the destination string in SRAM
  1606.    \param src A far pointer to the string to be appended in Flash
  1607.  
  1608.    \returns The strcat_PF() function returns a pointer to the resulting
  1609.    string \e dst. The contents of RAMPZ SFR are undefined when the function
  1610.    returns */
  1611. extern char *strcat_PF(char *dest, uint_farptr_t src);
  1612.  
  1613. /** \ingroup avr_pgmspace
  1614.    \fn size_t strlcat_PF(char *dst, uint_farptr_t src, size_t n)
  1615.    \brief Concatenate two strings
  1616.  
  1617.    The strlcat_PF() function is similar to strlcat(), except that the \e src
  1618.    string must be located in program space (flash) and is addressed using
  1619.    a far pointer.
  1620.  
  1621.    Appends src to string dst of size \e n (unlike strncat(), \e n is the
  1622.    full size of \e dst, not space left).  At most \e n-1 characters
  1623.    will be copied.  Always NULL terminates (unless \e n <= strlen(\e dst)).
  1624.  
  1625.    \param dst A pointer to the destination string in SRAM
  1626.    \param src A far pointer to the source string in Flash
  1627.    \param n The total number of bytes allocated to the destination string
  1628.  
  1629.    \returns The strlcat_PF() function returns strlen(\e src) + MIN(\e n,
  1630.    strlen(initial \e dst)).  If retval >= \e n, truncation occurred. The
  1631.    contents of RAMPZ SFR are undefined when the funcion returns. */
  1632. extern size_t strlcat_PF(char *dst, uint_farptr_t src, size_t siz);
  1633.  
  1634. /** \ingroup avr_pgmspace
  1635.    \fn char *strncat_PF(char *dst, uint_farptr_t src, size_t n)
  1636.    \brief Concatenate two strings
  1637.  
  1638.    The strncat_PF() function is similar to strncat(), except that the \e src
  1639.    string must be located in program space (flash) and is addressed using a
  1640.    far pointer.
  1641.  
  1642.    \param dst A pointer to the destination string in SRAM
  1643.    \param src A far pointer to the source string in Flash
  1644.    \param n The maximum number of bytes to append
  1645.  
  1646.    \returns The strncat_PF() function returns a pointer to the resulting
  1647.    string \e dst. The contents of RAMPZ SFR are undefined when the function
  1648.    returns. */
  1649. extern char *strncat_PF(char *dest, uint_farptr_t src, size_t len);
  1650.  
  1651. /** \ingroup avr_pgmspace
  1652.    \fn int strcmp_PF(const char *s1, uint_farptr_t s2)
  1653.    \brief Compares two strings
  1654.  
  1655.    The strcmp_PF() function is similar to strcmp() except that \e s2 is a far
  1656.    pointer to a string in program space.
  1657.  
  1658.    \param s1 A pointer to the first string in SRAM
  1659.    \param s2 A far pointer to the second string in Flash
  1660.  
  1661.    \returns The strcmp_PF() function returns an integer less than, equal to,
  1662.    or greater than zero if \e s1 is found, respectively, to be less than, to
  1663.    match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
  1664.    when the function returns. */
  1665. extern int strcmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__;
  1666.  
  1667. /** \ingroup avr_pgmspace
  1668.    \fn int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n)
  1669.    \brief Compare two strings with limited length
  1670.  
  1671.    The strncmp_PF() function is similar to strcmp_PF() except it only
  1672.    compares the first (at most) \e n characters of \e s1 and \e s2.
  1673.  
  1674.    \param s1 A pointer to the first string in SRAM
  1675.    \param s2 A far pointer to the second string in Flash
  1676.    \param n The maximum number of bytes to compare
  1677.  
  1678.    \returns The strncmp_PF() function returns an integer less than, equal
  1679.    to, or greater than zero if \e s1 (or the first \e n bytes thereof) is found,
  1680.    respectively, to be less than, to match, or be greater than \e s2. The
  1681.    contents of RAMPZ SFR are undefined when the function returns. */
  1682. extern int strncmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
  1683.  
  1684. /** \ingroup avr_pgmspace
  1685.    \fn int strcasecmp_PF(const char *s1, uint_farptr_t s2)
  1686.    \brief Compare two strings ignoring case
  1687.  
  1688.    The strcasecmp_PF() function compares the two strings \e s1 and \e s2, ignoring
  1689.    the case of the characters.
  1690.  
  1691.    \param s1 A pointer to the first string in SRAM
  1692.    \param s2 A far pointer to the second string in Flash
  1693.  
  1694.    \returns The strcasecmp_PF() function returns an integer less than, equal
  1695.    to, or greater than zero if \e s1 is found, respectively, to be less than, to
  1696.    match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
  1697.    when the function returns. */
  1698. extern int strcasecmp_PF(const char *s1, uint_farptr_t s2) __ATTR_PURE__;
  1699.  
  1700. /** \ingroup avr_pgmspace
  1701.    \fn int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n)
  1702.    \brief Compare two strings ignoring case
  1703.  
  1704.    The strncasecmp_PF() function is similar to strcasecmp_PF(), except it
  1705.    only compares the first \e n characters of \e s1 and the string in flash is
  1706.    addressed using a far pointer.
  1707.  
  1708.    \param s1 A pointer to a string in SRAM
  1709.    \param s2 A far pointer to a string in Flash
  1710.    \param n The maximum number of bytes to compare
  1711.  
  1712.    \returns The strncasecmp_PF() function returns an integer less than, equal
  1713.    to, or greater than zero if \e s1 (or the first \e n bytes thereof) is found,
  1714.    respectively, to be less than, to match, or be greater than \e s2. The
  1715.    contents of RAMPZ SFR are undefined when the function returns.  */
  1716. extern int strncasecmp_PF(const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
  1717.  
  1718. /** \ingroup avr_pgmspace
  1719.    \fn char *strstr_PF(const char *s1, uint_farptr_t s2)
  1720.    \brief Locate a substring.
  1721.  
  1722.    The strstr_PF() function finds the first occurrence of the substring \c s2
  1723.    in the string \c s1.  The terminating '\\0' characters are not
  1724.    compared.
  1725.    The strstr_PF() function is similar to strstr() except that \c s2 is a
  1726.    far pointer to a string in program space.
  1727.  
  1728.    \returns The strstr_PF() function returns a pointer to the beginning of the
  1729.    substring, or NULL if the substring is not found.
  1730.    If \c s2 points to a string of zero length, the function returns \c s1. The
  1731.    contents of RAMPZ SFR are undefined when the function returns. */
  1732. extern char *strstr_PF(const char *s1, uint_farptr_t s2);
  1733.  
  1734. /** \ingroup avr_pgmspace
  1735.    \fn size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz)
  1736.    \brief Copy a string from progmem to RAM.
  1737.  
  1738.    Copy src to string dst of size siz.  At most siz-1 characters will be
  1739.    copied. Always NULL terminates (unless siz == 0).
  1740.  
  1741.    \returns The strlcpy_PF() function returns strlen(src). If retval >= siz,
  1742.    truncation occurred.  The contents of RAMPZ SFR are undefined when the
  1743.    function returns. */
  1744. extern size_t strlcpy_PF(char *dst, uint_farptr_t src, size_t siz);
  1745.  
  1746. /** \ingroup avr_pgmspace
  1747.    \fn int memcmp_PF(const void *s1, uint_farptr_t s2, size_t len)
  1748.    \brief Compare memory areas
  1749.  
  1750.    The memcmp_PF() function compares the first \p len bytes of the memory
  1751.    areas \p s1 and flash \p s2. The comparision is performed using unsigned
  1752.    char operations. It is an equivalent of memcmp_P() function, except
  1753.    that it is capable working on all FLASH including the exteded area
  1754.    above 64kB.
  1755.  
  1756.    \returns The memcmp_PF() function returns an integer less than, equal
  1757.    to, or greater than zero if the first \p len bytes of \p s1 is found,
  1758.    respectively, to be less than, to match, or be greater than the first
  1759.    \p len bytes of \p s2.  */
  1760. extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
  1761.  
  1762. #ifdef __DOXYGEN__
  1763. /** \ingroup avr_pgmspace
  1764.    \fn size_t strlen_P(const char *src)
  1765.  
  1766.    The strlen_P() function is similar to strlen(), except that src is a
  1767.    pointer to a string in program space.
  1768.  
  1769.    \returns The strlen_P() function returns the number of characters in src.
  1770.  
  1771.    \note strlen_P() is implemented as an inline function in the avr/pgmspace.h
  1772.    header file, which will check if the length of the string is a constant
  1773.    and known at compile time. If it is not known at compile time, the macro
  1774.    will issue a call to __strlen_P() which will then calculate the length
  1775.    of the string as normal.
  1776. */
  1777. static inline size_t strlen_P(const char * s);
  1778. #else
  1779. extern size_t __strlen_P(const char *) __ATTR_CONST__;  /* internal helper function */
  1780. __attribute__((__always_inline__)) static __inline__ size_t strlen_P(const char * s);
  1781. static __inline__ size_t strlen_P(const char *s) {
  1782.  return __builtin_constant_p(__builtin_strlen(s))
  1783.     ? __builtin_strlen(s) : __strlen_P(s);
  1784. }
  1785. #endif
  1786.  
  1787. #ifdef __cplusplus
  1788. }
  1789. #endif
  1790.  
  1791. #endif /* __PGMSPACE_H_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement