00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #ifndef __PGMSPACE_H_
00083 #define __PGMSPACE_H_ 1
00084
00085 #define __need_size_t
00086 #include <inttypes.h>
00087 #include <stddef.h>
00088 #include <avr/io.h>
00089
00090 #ifndef __ATTR_CONST__
00091 #define __ATTR_CONST__ __attribute__((__const__))
00092 #endif
00093
00094 #ifndef __ATTR_PROGMEM__
00095 #define __ATTR_PROGMEM__ __attribute__((__progmem__))
00096 #endif
00097
00098 #ifndef __ATTR_PURE__
00099 #define __ATTR_PURE__ __attribute__((__pure__))
00100 #endif
00101
00102
00103
00104
00105
00106
00107
00108
00109 #define PROGMEM __ATTR_PROGMEM__
00110
00111 #ifdef __cplusplus
00112 extern "C" {
00113 #endif
00114
00115 #if defined(__DOXYGEN__)
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 typedef void PROGMEM prog_void;
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 typedef char PROGMEM prog_char;
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 typedef unsigned char PROGMEM prog_uchar;
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 typedef int8_t PROGMEM prog_int8_t;
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 typedef uint8_t PROGMEM prog_uint8_t;
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 typedef int16_t PROGMEM prog_int16_t;
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 typedef uint16_t PROGMEM prog_uint16_t;
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 typedef int32_t PROGMEM prog_int32_t;
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 typedef uint32_t PROGMEM prog_uint32_t;
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 typedef int64_t PROGMEM prog_int64_t;
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 typedef uint64_t PROGMEM prog_uint64_t;
00327
00328
00329
00330
00331
00332
00333
00334 #ifndef PGM_P
00335 #define PGM_P const char *
00336 #endif
00337
00338
00339
00340
00341
00342
00343 #ifndef PGM_VOID_P
00344 #define PGM_VOID_P const void *
00345 #endif
00346
00347 #elif defined(__PROG_TYPES_COMPAT__)
00348
00349 typedef void prog_void __attribute__((__progmem__,deprecated("prog_void type is deprecated.")));
00350 typedef char prog_char __attribute__((__progmem__,deprecated("prog_char type is deprecated.")));
00351 typedef unsigned char prog_uchar __attribute__((__progmem__,deprecated("prog_uchar type is deprecated.")));
00352 typedef int8_t prog_int8_t __attribute__((__progmem__,deprecated("prog_int8_t type is deprecated.")));
00353 typedef uint8_t prog_uint8_t __attribute__((__progmem__,deprecated("prog_uint8_t type is deprecated.")));
00354 typedef int16_t prog_int16_t __attribute__((__progmem__,deprecated("prog_int16_t type is deprecated.")));
00355 typedef uint16_t prog_uint16_t __attribute__((__progmem__,deprecated("prog_uint16_t type is deprecated.")));
00356 typedef int32_t prog_int32_t __attribute__((__progmem__,deprecated("prog_int32_t type is deprecated.")));
00357 typedef uint32_t prog_uint32_t __attribute__((__progmem__,deprecated("prog_uint32_t type is deprecated.")));
00358 #if !__USING_MINT8
00359 typedef int64_t prog_int64_t __attribute__((__progmem__,deprecated("prog_int64_t type is deprecated.")));
00360 typedef uint64_t prog_uint64_t __attribute__((__progmem__,deprecated("prog_uint64_t type is deprecated.")));
00361 #endif
00362
00363 #ifndef PGM_P
00364 #define PGM_P const prog_char *
00365 #endif
00366
00367 #ifndef PGM_VOID_P
00368 #define PGM_VOID_P const prog_void *
00369 #endif
00370
00371 #else
00372
00373 #ifndef PGM_P
00374 #define PGM_P const char *
00375 #endif
00376
00377 #ifndef PGM_VOID_P
00378 #define PGM_VOID_P const void *
00379 #endif
00380 #endif
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 #if defined(__DOXYGEN__)
00393
00394
00395
00396
00397
00398
00399
00400
00401 # define PSTR(s) ((const PROGMEM char *)(s))
00402 #else
00403
00404 # define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
00405 #endif
00406
00407 #define __LPM_classic__(addr) \
00408 (__extension__({ \
00409 uint16_t __addr16 = (uint16_t)(addr); \
00410 uint8_t __result; \
00411 __asm__ __volatile__ \
00412 ( \
00413 "lpm" "\n\t" \
00414 "mov %0, r0" "\n\t" \
00415 : "=r" (__result) \
00416 : "z" (__addr16) \
00417 : "r0" \
00418 ); \
00419 __result; \
00420 }))
00421
00422 #define __LPM_tiny__(addr) \
00423 (__extension__({ \
00424 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00425 uint8_t __result; \
00426 __asm__ \
00427 ( \
00428 "ld %0, z" "\n\t" \
00429 : "=r" (__result) \
00430 : "z" (__addr16) \
00431 ); \
00432 __result; \
00433 }))
00434
00435 #define __LPM_enhanced__(addr) \
00436 (__extension__({ \
00437 uint16_t __addr16 = (uint16_t)(addr); \
00438 uint8_t __result; \
00439 __asm__ __volatile__ \
00440 ( \
00441 "lpm %0, Z" "\n\t" \
00442 : "=r" (__result) \
00443 : "z" (__addr16) \
00444 ); \
00445 __result; \
00446 }))
00447
00448 #define __LPM_word_classic__(addr) \
00449 (__extension__({ \
00450 uint16_t __addr16 = (uint16_t)(addr); \
00451 uint16_t __result; \
00452 __asm__ __volatile__ \
00453 ( \
00454 "lpm" "\n\t" \
00455 "mov %A0, r0" "\n\t" \
00456 "adiw r30, 1" "\n\t" \
00457 "lpm" "\n\t" \
00458 "mov %B0, r0" "\n\t" \
00459 : "=r" (__result), "=z" (__addr16) \
00460 : "1" (__addr16) \
00461 : "r0" \
00462 ); \
00463 __result; \
00464 }))
00465
00466 #define __LPM_word_tiny__(addr) \
00467 (__extension__({ \
00468 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00469 uint16_t __result; \
00470 __asm__ \
00471 ( \
00472 "ld %A0, z+" "\n\t" \
00473 "ld %B0, z" "\n\t" \
00474 : "=r" (__result), "=z" (__addr16) \
00475 : "1" (__addr16) \
00476 ); \
00477 __result; \
00478 }))
00479
00480 #define __LPM_word_enhanced__(addr) \
00481 (__extension__({ \
00482 uint16_t __addr16 = (uint16_t)(addr); \
00483 uint16_t __result; \
00484 __asm__ __volatile__ \
00485 ( \
00486 "lpm %A0, Z+" "\n\t" \
00487 "lpm %B0, Z" "\n\t" \
00488 : "=r" (__result), "=z" (__addr16) \
00489 : "1" (__addr16) \
00490 ); \
00491 __result; \
00492 }))
00493
00494 #define __LPM_dword_classic__(addr) \
00495 (__extension__({ \
00496 uint16_t __addr16 = (uint16_t)(addr); \
00497 uint32_t __result; \
00498 __asm__ __volatile__ \
00499 ( \
00500 "lpm" "\n\t" \
00501 "mov %A0, r0" "\n\t" \
00502 "adiw r30, 1" "\n\t" \
00503 "lpm" "\n\t" \
00504 "mov %B0, r0" "\n\t" \
00505 "adiw r30, 1" "\n\t" \
00506 "lpm" "\n\t" \
00507 "mov %C0, r0" "\n\t" \
00508 "adiw r30, 1" "\n\t" \
00509 "lpm" "\n\t" \
00510 "mov %D0, r0" "\n\t" \
00511 : "=r" (__result), "=z" (__addr16) \
00512 : "1" (__addr16) \
00513 : "r0" \
00514 ); \
00515 __result; \
00516 }))
00517
00518 #define __LPM_dword_tiny__(addr) \
00519 (__extension__({ \
00520 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00521 uint32_t __result; \
00522 __asm__ \
00523 ( \
00524 "ld %A0, z+" "\n\t" \
00525 "ld %B0, z+" "\n\t" \
00526 "ld %C0, z+" "\n\t" \
00527 "ld %D0, z" "\n\t" \
00528 : "=r" (__result), "=z" (__addr16) \
00529 : "1" (__addr16) \
00530 ); \
00531 __result; \
00532 }))
00533
00534 #define __LPM_dword_enhanced__(addr) \
00535 (__extension__({ \
00536 uint16_t __addr16 = (uint16_t)(addr); \
00537 uint32_t __result; \
00538 __asm__ __volatile__ \
00539 ( \
00540 "lpm %A0, Z+" "\n\t" \
00541 "lpm %B0, Z+" "\n\t" \
00542 "lpm %C0, Z+" "\n\t" \
00543 "lpm %D0, Z" "\n\t" \
00544 : "=r" (__result), "=z" (__addr16) \
00545 : "1" (__addr16) \
00546 ); \
00547 __result; \
00548 }))
00549
00550 #define __LPM_float_classic__(addr) \
00551 (__extension__({ \
00552 uint16_t __addr16 = (uint16_t)(addr); \
00553 float __result; \
00554 __asm__ __volatile__ \
00555 ( \
00556 "lpm" "\n\t" \
00557 "mov %A0, r0" "\n\t" \
00558 "adiw r30, 1" "\n\t" \
00559 "lpm" "\n\t" \
00560 "mov %B0, r0" "\n\t" \
00561 "adiw r30, 1" "\n\t" \
00562 "lpm" "\n\t" \
00563 "mov %C0, r0" "\n\t" \
00564 "adiw r30, 1" "\n\t" \
00565 "lpm" "\n\t" \
00566 "mov %D0, r0" "\n\t" \
00567 : "=r" (__result), "=z" (__addr16) \
00568 : "1" (__addr16) \
00569 : "r0" \
00570 ); \
00571 __result; \
00572 }))
00573
00574 #define __LPM_float_tiny__(addr) \
00575 (__extension__({ \
00576 uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
00577 float __result; \
00578 __asm__ \
00579 ( \
00580 "ld %A0, z+" "\n\t" \
00581 "ld %B0, z+" "\n\t" \
00582 "ld %C0, z+" "\n\t" \
00583 "ld %D0, z" "\n\t" \
00584 : "=r" (__result), "=z" (__addr16) \
00585 : "1" (__addr16) \
00586 ); \
00587 __result; \
00588 }))
00589
00590 #define __LPM_float_enhanced__(addr) \
00591 (__extension__({ \
00592 uint16_t __addr16 = (uint16_t)(addr); \
00593 float __result; \
00594 __asm__ __volatile__ \
00595 ( \
00596 "lpm %A0, Z+" "\n\t" \
00597 "lpm %B0, Z+" "\n\t" \
00598 "lpm %C0, Z+" "\n\t" \
00599 "lpm %D0, Z" "\n\t" \
00600 : "=r" (__result), "=z" (__addr16) \
00601 : "1" (__addr16) \
00602 ); \
00603 __result; \
00604 }))
00605
00606 #if defined (__AVR_HAVE_LPMX__)
00607 #define __LPM(addr) __LPM_enhanced__(addr)
00608 #define __LPM_word(addr) __LPM_word_enhanced__(addr)
00609 #define __LPM_dword(addr) __LPM_dword_enhanced__(addr)
00610 #define __LPM_float(addr) __LPM_float_enhanced__(addr)
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 #elif defined (__AVR_TINY__)
00621 #define __LPM(addr) __LPM_tiny__(addr)
00622 #define __LPM_word(addr) __LPM_word_tiny__(addr)
00623 #define __LPM_dword(addr) __LPM_dword_tiny__(addr)
00624 #define __LPM_float(addr) __LPM_float_tiny__(addr)
00625 #else
00626 #define __LPM(addr) __LPM_classic__(addr)
00627 #define __LPM_word(addr) __LPM_word_classic__(addr)
00628 #define __LPM_dword(addr) __LPM_dword_classic__(addr)
00629 #define __LPM_float(addr) __LPM_float_classic__(addr)
00630 #endif
00631
00632
00633
00634
00635
00636
00637
00638 #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
00639
00640
00641
00642
00643
00644
00645
00646 #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short))
00647
00648
00649
00650
00651
00652
00653
00654 #define pgm_read_dword_near(address_short) \
00655 __LPM_dword((uint16_t)(address_short))
00656
00657
00658
00659
00660
00661
00662
00663 #define pgm_read_float_near(address_short) \
00664 __LPM_float((uint16_t)(address_short))
00665
00666
00667
00668
00669
00670
00671
00672 #define pgm_read_ptr_near(address_short) \
00673 (void*)__LPM_word((uint16_t)(address_short))
00674
00675 #if defined(RAMPZ) || defined(__DOXYGEN__)
00676
00677
00678
00679
00680
00681
00682
00683 #define __ELPM_classic__(addr) \
00684 (__extension__({ \
00685 uint32_t __addr32 = (uint32_t)(addr); \
00686 uint8_t __result; \
00687 __asm__ __volatile__ \
00688 ( \
00689 "out %2, %C1" "\n\t" \
00690 "mov r31, %B1" "\n\t" \
00691 "mov r30, %A1" "\n\t" \
00692 "elpm" "\n\t" \
00693 "mov %0, r0" "\n\t" \
00694 : "=r" (__result) \
00695 : "r" (__addr32), \
00696 "I" (_SFR_IO_ADDR(RAMPZ)) \
00697 : "r0", "r30", "r31" \
00698 ); \
00699 __result; \
00700 }))
00701
00702 #define __ELPM_enhanced__(addr) \
00703 (__extension__({ \
00704 uint32_t __addr32 = (uint32_t)(addr); \
00705 uint8_t __result; \
00706 __asm__ __volatile__ \
00707 ( \
00708 "out %2, %C1" "\n\t" \
00709 "movw r30, %1" "\n\t" \
00710 "elpm %0, Z+" "\n\t" \
00711 : "=r" (__result) \
00712 : "r" (__addr32), \
00713 "I" (_SFR_IO_ADDR(RAMPZ)) \
00714 : "r30", "r31" \
00715 ); \
00716 __result; \
00717 }))
00718
00719 #define __ELPM_xmega__(addr) \
00720 (__extension__({ \
00721 uint32_t __addr32 = (uint32_t)(addr); \
00722 uint8_t __result; \
00723 __asm__ __volatile__ \
00724 ( \
00725 "in __tmp_reg__, %2" "\n\t" \
00726 "out %2, %C1" "\n\t" \
00727 "movw r30, %1" "\n\t" \
00728 "elpm %0, Z+" "\n\t" \
00729 "out %2, __tmp_reg__" \
00730 : "=r" (__result) \
00731 : "r" (__addr32), \
00732 "I" (_SFR_IO_ADDR(RAMPZ)) \
00733 : "r30", "r31" \
00734 ); \
00735 __result; \
00736 }))
00737
00738 #define __ELPM_word_classic__(addr) \
00739 (__extension__({ \
00740 uint32_t __addr32 = (uint32_t)(addr); \
00741 uint16_t __result; \
00742 __asm__ __volatile__ \
00743 ( \
00744 "out %2, %C1" "\n\t" \
00745 "mov r31, %B1" "\n\t" \
00746 "mov r30, %A1" "\n\t" \
00747 "elpm" "\n\t" \
00748 "mov %A0, r0" "\n\t" \
00749 "in r0, %2" "\n\t" \
00750 "adiw r30, 1" "\n\t" \
00751 "adc r0, __zero_reg__" "\n\t" \
00752 "out %2, r0" "\n\t" \
00753 "elpm" "\n\t" \
00754 "mov %B0, r0" "\n\t" \
00755 : "=r" (__result) \
00756 : "r" (__addr32), \
00757 "I" (_SFR_IO_ADDR(RAMPZ)) \
00758 : "r0", "r30", "r31" \
00759 ); \
00760 __result; \
00761 }))
00762
00763 #define __ELPM_word_enhanced__(addr) \
00764 (__extension__({ \
00765 uint32_t __addr32 = (uint32_t)(addr); \
00766 uint16_t __result; \
00767 __asm__ __volatile__ \
00768 ( \
00769 "out %2, %C1" "\n\t" \
00770 "movw r30, %1" "\n\t" \
00771 "elpm %A0, Z+" "\n\t" \
00772 "elpm %B0, Z" "\n\t" \
00773 : "=r" (__result) \
00774 : "r" (__addr32), \
00775 "I" (_SFR_IO_ADDR(RAMPZ)) \
00776 : "r30", "r31" \
00777 ); \
00778 __result; \
00779 }))
00780
00781 #define __ELPM_word_xmega__(addr) \
00782 (__extension__({ \
00783 uint32_t __addr32 = (uint32_t)(addr); \
00784 uint16_t __result; \
00785 __asm__ __volatile__ \
00786 ( \
00787 "in __tmp_reg__, %2" "\n\t" \
00788 "out %2, %C1" "\n\t" \
00789 "movw r30, %1" "\n\t" \
00790 "elpm %A0, Z+" "\n\t" \
00791 "elpm %B0, Z" "\n\t" \
00792 "out %2, __tmp_reg__" \
00793 : "=r" (__result) \
00794 : "r" (__addr32), \
00795 "I" (_SFR_IO_ADDR(RAMPZ)) \
00796 : "r30", "r31" \
00797 ); \
00798 __result; \
00799 }))
00800
00801 #define __ELPM_dword_classic__(addr) \
00802 (__extension__({ \
00803 uint32_t __addr32 = (uint32_t)(addr); \
00804 uint32_t __result; \
00805 __asm__ __volatile__ \
00806 ( \
00807 "out %2, %C1" "\n\t" \
00808 "mov r31, %B1" "\n\t" \
00809 "mov r30, %A1" "\n\t" \
00810 "elpm" "\n\t" \
00811 "mov %A0, r0" "\n\t" \
00812 "in r0, %2" "\n\t" \
00813 "adiw r30, 1" "\n\t" \
00814 "adc r0, __zero_reg__" "\n\t" \
00815 "out %2, r0" "\n\t" \
00816 "elpm" "\n\t" \
00817 "mov %B0, r0" "\n\t" \
00818 "in r0, %2" "\n\t" \
00819 "adiw r30, 1" "\n\t" \
00820 "adc r0, __zero_reg__" "\n\t" \
00821 "out %2, r0" "\n\t" \
00822 "elpm" "\n\t" \
00823 "mov %C0, r0" "\n\t" \
00824 "in r0, %2" "\n\t" \
00825 "adiw r30, 1" "\n\t" \
00826 "adc r0, __zero_reg__" "\n\t" \
00827 "out %2, r0" "\n\t" \
00828 "elpm" "\n\t" \
00829 "mov %D0, r0" "\n\t" \
00830 : "=r" (__result) \
00831 : "r" (__addr32), \
00832 "I" (_SFR_IO_ADDR(RAMPZ)) \
00833 : "r0", "r30", "r31" \
00834 ); \
00835 __result; \
00836 }))
00837
00838 #define __ELPM_dword_enhanced__(addr) \
00839 (__extension__({ \
00840 uint32_t __addr32 = (uint32_t)(addr); \
00841 uint32_t __result; \
00842 __asm__ __volatile__ \
00843 ( \
00844 "out %2, %C1" "\n\t" \
00845 "movw r30, %1" "\n\t" \
00846 "elpm %A0, Z+" "\n\t" \
00847 "elpm %B0, Z+" "\n\t" \
00848 "elpm %C0, Z+" "\n\t" \
00849 "elpm %D0, Z" "\n\t" \
00850 : "=r" (__result) \
00851 : "r" (__addr32), \
00852 "I" (_SFR_IO_ADDR(RAMPZ)) \
00853 : "r30", "r31" \
00854 ); \
00855 __result; \
00856 }))
00857
00858 #define __ELPM_dword_xmega__(addr) \
00859 (__extension__({ \
00860 uint32_t __addr32 = (uint32_t)(addr); \
00861 uint32_t __result; \
00862 __asm__ __volatile__ \
00863 ( \
00864 "in __tmp_reg__, %2" "\n\t" \
00865 "out %2, %C1" "\n\t" \
00866 "movw r30, %1" "\n\t" \
00867 "elpm %A0, Z+" "\n\t" \
00868 "elpm %B0, Z+" "\n\t" \
00869 "elpm %C0, Z+" "\n\t" \
00870 "elpm %D0, Z" "\n\t" \
00871 "out %2, __tmp_reg__" \
00872 : "=r" (__result) \
00873 : "r" (__addr32), \
00874 "I" (_SFR_IO_ADDR(RAMPZ)) \
00875 : "r30", "r31" \
00876 ); \
00877 __result; \
00878 }))
00879
00880 #define __ELPM_float_classic__(addr) \
00881 (__extension__({ \
00882 uint32_t __addr32 = (uint32_t)(addr); \
00883 float __result; \
00884 __asm__ __volatile__ \
00885 ( \
00886 "out %2, %C1" "\n\t" \
00887 "mov r31, %B1" "\n\t" \
00888 "mov r30, %A1" "\n\t" \
00889 "elpm" "\n\t" \
00890 "mov %A0, r0" "\n\t" \
00891 "in r0, %2" "\n\t" \
00892 "adiw r30, 1" "\n\t" \
00893 "adc r0, __zero_reg__" "\n\t" \
00894 "out %2, r0" "\n\t" \
00895 "elpm" "\n\t" \
00896 "mov %B0, r0" "\n\t" \
00897 "in r0, %2" "\n\t" \
00898 "adiw r30, 1" "\n\t" \
00899 "adc r0, __zero_reg__" "\n\t" \
00900 "out %2, r0" "\n\t" \
00901 "elpm" "\n\t" \
00902 "mov %C0, r0" "\n\t" \
00903 "in r0, %2" "\n\t" \
00904 "adiw r30, 1" "\n\t" \
00905 "adc r0, __zero_reg__" "\n\t" \
00906 "out %2, r0" "\n\t" \
00907 "elpm" "\n\t" \
00908 "mov %D0, r0" "\n\t" \
00909 : "=r" (__result) \
00910 : "r" (__addr32), \
00911 "I" (_SFR_IO_ADDR(RAMPZ)) \
00912 : "r0", "r30", "r31" \
00913 ); \
00914 __result; \
00915 }))
00916
00917 #define __ELPM_float_enhanced__(addr) \
00918 (__extension__({ \
00919 uint32_t __addr32 = (uint32_t)(addr); \
00920 float __result; \
00921 __asm__ __volatile__ \
00922 ( \
00923 "out %2, %C1" "\n\t" \
00924 "movw r30, %1" "\n\t" \
00925 "elpm %A0, Z+" "\n\t" \
00926 "elpm %B0, Z+" "\n\t" \
00927 "elpm %C0, Z+" "\n\t" \
00928 "elpm %D0, Z" "\n\t" \
00929 : "=r" (__result) \
00930 : "r" (__addr32), \
00931 "I" (_SFR_IO_ADDR(RAMPZ)) \
00932 : "r30", "r31" \
00933 ); \
00934 __result; \
00935 }))
00936
00937 #define __ELPM_float_xmega__(addr) \
00938 (__extension__({ \
00939 uint32_t __addr32 = (uint32_t)(addr); \
00940 float __result; \
00941 __asm__ __volatile__ \
00942 ( \
00943 "in __tmp_reg__, %2" "\n\t" \
00944 "out %2, %C1" "\n\t" \
00945 "movw r30, %1" "\n\t" \
00946 "elpm %A0, Z+" "\n\t" \
00947 "elpm %B0, Z+" "\n\t" \
00948 "elpm %C0, Z+" "\n\t" \
00949 "elpm %D0, Z" "\n\t" \
00950 "out %2, __tmp_reg__" \
00951 : "=r" (__result) \
00952 : "r" (__addr32), \
00953 "I" (_SFR_IO_ADDR(RAMPZ)) \
00954 : "r30", "r31" \
00955 ); \
00956 __result; \
00957 }))
00958
00959
00960
00961
00962
00963
00964 #if defined (__AVR_HAVE_RAMPD__)
00965
00966 #define __ELPM(addr) __ELPM_xmega__(addr)
00967 #define __ELPM_word(addr) __ELPM_word_xmega__(addr)
00968 #define __ELPM_dword(addr) __ELPM_dword_xmega__(addr)
00969 #define __ELPM_float(addr) __ELPM_float_xmega__(addr)
00970
00971 #else
00972
00973 #if defined (__AVR_HAVE_LPMX__)
00974
00975 #define __ELPM(addr) __ELPM_enhanced__(addr)
00976 #define __ELPM_word(addr) __ELPM_word_enhanced__(addr)
00977 #define __ELPM_dword(addr) __ELPM_dword_enhanced__(addr)
00978 #define __ELPM_float(addr) __ELPM_float_enhanced__(addr)
00979
00980 #else
00981
00982 #define __ELPM(addr) __ELPM_classic__(addr)
00983 #define __ELPM_word(addr) __ELPM_word_classic__(addr)
00984 #define __ELPM_dword(addr) __ELPM_dword_classic__(addr)
00985 #define __ELPM_float(addr) __ELPM_float_classic__(addr)
00986
00987 #endif
00988
00989 #endif
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999 #define pgm_read_byte_far(address_long) __ELPM((uint32_t)(address_long))
01000
01001
01002
01003
01004
01005
01006
01007
01008 #define pgm_read_word_far(address_long) __ELPM_word((uint32_t)(address_long))
01009
01010
01011
01012
01013
01014
01015
01016
01017 #define pgm_read_dword_far(address_long) __ELPM_dword((uint32_t)(address_long))
01018
01019
01020
01021
01022
01023
01024
01025
01026 #define pgm_read_float_far(address_long) __ELPM_float((uint32_t)(address_long))
01027
01028
01029
01030
01031
01032
01033
01034
01035 #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
01036
01037 #endif
01038
01039
01040
01041
01042
01043
01044
01045
01046 #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
01047
01048
01049
01050
01051
01052
01053
01054
01055 #define pgm_read_word(address_short) pgm_read_word_near(address_short)
01056
01057
01058
01059
01060
01061
01062
01063
01064 #define pgm_read_dword(address_short) pgm_read_dword_near(address_short)
01065
01066
01067
01068
01069
01070
01071
01072
01073 #define pgm_read_float(address_short) pgm_read_float_near(address_short)
01074
01075
01076
01077
01078
01079
01080
01081
01082 #define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 #define pgm_get_far_address(var) \
01118 ({ \
01119 uint_farptr_t tmp; \
01120 \
01121 __asm__ __volatile__( \
01122 \
01123 "ldi %A0, lo8(%1)" "\n\t" \
01124 "ldi %B0, hi8(%1)" "\n\t" \
01125 "ldi %C0, hh8(%1)" "\n\t" \
01126 "clr %D0" "\n\t" \
01127 : \
01128 "=d" (tmp) \
01129 : \
01130 "p" (&(var)) \
01131 ); \
01132 tmp; \
01133 })
01134
01135
01136
01137 extern const void * memchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
01138 extern int memcmp_P(const void *, const void *, size_t) __ATTR_PURE__;
01139 extern void *memccpy_P(void *, const void *, int __val, size_t);
01140 extern void *memcpy_P(void *, const void *, size_t);
01141 extern void *memmem_P(const void *, size_t, const void *, size_t) __ATTR_PURE__;
01142 extern const void * memrchr_P(const void *, int __val, size_t __len) __ATTR_CONST__;
01143 extern char *strcat_P(char *, const char *);
01144 extern const char * strchr_P(const char *, int __val) __ATTR_CONST__;
01145 extern const char * strchrnul_P(const char *, int __val) __ATTR_CONST__;
01146 extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
01147 extern char *strcpy_P(char *, const char *);
01148 extern int strcasecmp_P(const char *, const char *) __ATTR_PURE__;
01149 extern char *strcasestr_P(const char *, const char *) __ATTR_PURE__;
01150 extern size_t strcspn_P(const char *__s, const char * __reject) __ATTR_PURE__;
01151 extern size_t strlcat_P (char *, const char *, size_t );
01152 extern size_t strlcpy_P (char *, const char *, size_t );
01153 extern size_t __strlen_P(const char *) __ATTR_CONST__;
01154 extern size_t strnlen_P(const char *, size_t) __ATTR_CONST__;
01155 extern int strncmp_P(const char *, const char *, size_t) __ATTR_PURE__;
01156 extern int strncasecmp_P(const char *, const char *, size_t) __ATTR_PURE__;
01157 extern char *strncat_P(char *, const char *, size_t);
01158 extern char *strncpy_P(char *, const char *, size_t);
01159 extern char *strpbrk_P(const char *__s, const char * __accept) __ATTR_PURE__;
01160 extern const char * strrchr_P(const char *, int __val) __ATTR_CONST__;
01161 extern char *strsep_P(char **__sp, const char * __delim);
01162 extern size_t strspn_P(const char *__s, const char * __accept) __ATTR_PURE__;
01163 extern char *strstr_P(const char *, const char *) __ATTR_PURE__;
01164 extern char *strtok_P(char *__s, const char * __delim);
01165 extern char *strtok_rP(char *__s, const char * __delim, char **__last);
01166
01167 extern size_t strlen_PF (uint_farptr_t src) __ATTR_CONST__;
01168 extern size_t strnlen_PF (uint_farptr_t src, size_t len) __ATTR_CONST__;
01169 extern void *memcpy_PF (void *dest, uint_farptr_t src, size_t len);
01170 extern char *strcpy_PF (char *dest, uint_farptr_t src);
01171 extern char *strncpy_PF (char *dest, uint_farptr_t src, size_t len);
01172 extern char *strcat_PF (char *dest, uint_farptr_t src);
01173 extern size_t strlcat_PF (char *dst, uint_farptr_t src, size_t siz);
01174 extern char *strncat_PF (char *dest, uint_farptr_t src, size_t len);
01175 extern int strcmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
01176 extern int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
01177 extern int strcasecmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
01178 extern int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n) __ATTR_PURE__;
01179 extern char *strstr_PF (const char *s1, uint_farptr_t s2);
01180 extern size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz);
01181 extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
01182
01183
01184 __attribute__((__always_inline__)) static inline size_t strlen_P(const char * s);
01185 static inline size_t strlen_P(const char *s) {
01186 return __builtin_constant_p(__builtin_strlen(s))
01187 ? __builtin_strlen(s) : __strlen_P(s);
01188 }
01189
01190
01191
01192 #ifdef __cplusplus
01193 }
01194 #endif
01195
01196 #endif