Add UF2 bootloader for USB firmware flashing

Vendored and trimmed from microsoft/uf2-samdx1, adapted to the actual
ATSAMD21G17D (128 KiB flash / 16 KiB RAM), fixing the flash/RAM-size
mismatch that the previously commented-out SAM-BA bootloader target
had (it assumed a 256 KiB SAMD21G18A). Builds as a standalone
PlatformIO environment (bootloader/platformio.ini), no python2/make
dependency. Compiles clean, fits in the 8 KiB bootloader region
(7292/8192 bytes). Not yet flashed/verified on real hardware.
This commit is contained in:
cjjohn 2026-08-03 20:56:58 +02:00
parent ce5db617a1
commit de52b57041
143 changed files with 69119 additions and 0 deletions

View file

@ -0,0 +1,140 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef CDC_ENUMERATE_H
#define CDC_ENUMERATE_H
#define PKT_SIZE 64
#define USB_EP_IN 1
#define USB_EP_OUT 2
#define USB_EP_COMM 3
#define USB_EP_MSC_IN 4
#define USB_EP_MSC_OUT 5
#define USB_EP_HID 6
#define USB_EP_WEB 7
#define MAX_EP 8
#define NVM_USB_PAD_TRANSN_POS 45
#define NVM_USB_PAD_TRANSN_SIZE 5
#define NVM_USB_PAD_TRANSP_POS 50
#define NVM_USB_PAD_TRANSP_SIZE 5
#define NVM_USB_PAD_TRIM_POS 55
#define NVM_USB_PAD_TRIM_SIZE 3
typedef struct _USB_CDC {
// Private members
uint8_t currentConfiguration;
uint8_t currentConnection;
} USB_CDC, *P_USB_CDC;
typedef struct {
uint32_t dwDTERate;
uint8_t bCharFormat;
uint8_t bParityType;
uint8_t bDataBits;
} usb_cdc_line_coding_t;
/**
* \brief Initializes the USB module
*/
void usb_init(void);
/**
* \brief Sends a single byte through USB CDC
*
* \param Data to send
* \return number of data sent
*/
int cdc_putc(int value);
/**
* \brief Reads a single byte through USB CDC
*
* \return Data read through USB
*/
int cdc_getc(void);
/**
* \brief Checks if a character has been received on USB CDC
*
* \return \c 1 if a byte is ready to be read.
*/
bool cdc_is_rx_ready(void);
/**
* \brief Sends buffer on USB CDC
*
* \param data pointer
* \param number of data to send
* \return number of data sent
*/
uint32_t cdc_write_buf(void const *data, uint32_t length);
uint32_t cdc_write_buf_xmd(void const *data, uint32_t length);
/**
* \brief Gets data on USB CDC
*
* \param data pointer
* \param number of data to read
* \return number of data read
*/
uint32_t cdc_read_buf(void *data, uint32_t length);
/**
* \brief Gets specified number of bytes on USB CDC
*
* \param data pointer
* \param number of data to read
* \return number of data read
*/
uint32_t cdc_read_buf_xmd(void *data, uint32_t length);
void reset_ep(uint8_t ep);
void stall_ep(uint8_t ep);
typedef struct {
uint8_t size;
uint8_t ptr;
uint8_t read_job;
uint8_t padding;
uint8_t buf[PKT_SIZE];
} PacketBuffer __attribute__((aligned(4)));
uint32_t USB_Read(void *pData, uint32_t length, uint32_t ep);
uint32_t USB_Write(const void *pData, uint32_t length, uint8_t ep_num);
uint32_t USB_WriteCore(const void *pData, uint32_t length, uint8_t ep_num, bool handoverMode);
void USB_ReadBlocking(void *dst, uint32_t length, uint32_t ep, PacketBuffer *cache);
uint32_t USB_ReadCore(void *pData, uint32_t length, uint32_t ep, PacketBuffer *cache);
bool USB_Ok(void);
#endif // CDC_ENUMERATE_H

150
bootloader/inc/configkeys.h Normal file
View file

@ -0,0 +1,150 @@
#ifndef __CONFIGKEYS_H
#define __CONFIGKEYS_H 1
#define CFG_MAGIC0 0x1e9e10f1
#define CFG_MAGIC1 0x20227a79
#define CFG_PIN_ACCELEROMETER_INT 1
#define CFG_PIN_ACCELEROMETER_SCL 2
#define CFG_PIN_ACCELEROMETER_SDA 3
#define CFG_PIN_BTN_A 4
#define CFG_PIN_BTN_B 5
#define CFG_PIN_BTN_SLIDE 6
#define CFG_PIN_DOTSTAR_CLOCK 7
#define CFG_PIN_DOTSTAR_DATA 8
#define CFG_PIN_FLASH_CS 9
#define CFG_PIN_FLASH_MISO 10
#define CFG_PIN_FLASH_MOSI 11
#define CFG_PIN_FLASH_SCK 12
#define CFG_PIN_LED 13
#define CFG_PIN_LIGHT 14
#define CFG_PIN_MICROPHONE 15
#define CFG_PIN_MIC_CLOCK 16
#define CFG_PIN_MIC_DATA 17
#define CFG_PIN_MISO 18
#define CFG_PIN_MOSI 19
#define CFG_PIN_NEOPIXEL 20
#define CFG_PIN_RX 21
#define CFG_PIN_RXLED 22
#define CFG_PIN_SCK 23
#define CFG_PIN_SCL 24
#define CFG_PIN_SDA 25
#define CFG_PIN_SPEAKER_AMP 26
#define CFG_PIN_TEMPERATURE 27
#define CFG_PIN_TX 28
#define CFG_PIN_TXLED 29
#define CFG_PIN_IR_OUT 30
#define CFG_PIN_IR_IN 31
#define CFG_PIN_DISPLAY_SCK 32
#define CFG_PIN_DISPLAY_MISO 33
#define CFG_PIN_DISPLAY_MOSI 34
#define CFG_PIN_DISPLAY_CS 35
#define CFG_PIN_DISPLAY_DC 36
#define CFG_DISPLAY_WIDTH 37
#define CFG_DISPLAY_HEIGHT 38
#define CFG_DISPLAY_CFG0 39
#define CFG_DISPLAY_CFG1 40
#define CFG_DISPLAY_CFG2 41
#define CFG_DISPLAY_CFG3 42
#define CFG_PIN_DISPLAY_RST 43
#define CFG_PIN_DISPLAY_BL 44
#define CFG_PIN_SERVO_1 45
#define CFG_PIN_SERVO_2 46
#define CFG_PIN_BTN_LEFT 47
#define CFG_PIN_BTN_RIGHT 48
#define CFG_PIN_BTN_UP 49
#define CFG_PIN_BTN_DOWN 50
#define CFG_PIN_BTN_MENU 51
#define CFG_PIN_LED_R 52
#define CFG_PIN_LED_G 53
#define CFG_PIN_LED_B 54
#define CFG_PIN_LED1 55
#define CFG_PIN_LED2 56
#define CFG_PIN_LED3 57
#define CFG_PIN_LED4 58
#define CFG_SPEAKER_VOLUME 59
#define CFG_PIN_JACK_TX 60
#define CFG_PIN_JACK_SENSE 61
#define CFG_PIN_JACK_HPEN 62
#define CFG_PIN_JACK_BZEN 63
#define CFG_PIN_JACK_PWREN 64
#define CFG_PIN_JACK_SND 65
#define CFG_PIN_JACK_BUSLED 66
#define CFG_PIN_JACK_COMMLED 67
#define CFG_PIN_BTNMX_LATCH 66
#define CFG_PIN_BTNMX_CLOCK 67
#define CFG_PIN_BTNMX_DATA 68
#define CFG_PIN_BTN_SOFT_RESET 69
#define CFG_ACCELEROMETER_TYPE 70
#define CFG_DISPLAY_TYPE 78
#define CFG_PIN_A0 100
#define CFG_PIN_A1 101
#define CFG_PIN_A2 102
#define CFG_PIN_A3 103
#define CFG_PIN_A4 104
#define CFG_PIN_A5 105
#define CFG_PIN_A6 106
#define CFG_PIN_A7 107
#define CFG_PIN_A8 108
#define CFG_PIN_A9 109
#define CFG_PIN_A10 110
#define CFG_PIN_A11 111
#define CFG_PIN_A12 112
#define CFG_PIN_A13 113
#define CFG_PIN_A14 114
#define CFG_PIN_A15 115
#define CFG_PIN_D0 150
#define CFG_PIN_D1 151
#define CFG_PIN_D2 152
#define CFG_PIN_D3 153
#define CFG_PIN_D4 154
#define CFG_PIN_D5 155
#define CFG_PIN_D6 156
#define CFG_PIN_D7 157
#define CFG_PIN_D8 158
#define CFG_PIN_D9 159
#define CFG_PIN_D10 160
#define CFG_PIN_D11 161
#define CFG_PIN_D12 162
#define CFG_PIN_D13 163
#define CFG_PIN_D14 164
#define CFG_PIN_D15 165
#define CFG_NUM_NEOPIXELS 200
#define CFG_NUM_DOTSTARS 201
#define CFG_DEFAULT_BUTTON_MODE 202
#define CFG_SWD_ENABLED 203
#define CFG_FLASH_BYTES 204
#define CFG_RAM_BYTES 205
#define CFG_SYSTEM_HEAP_BYTES 206
#define CFG_LOW_MEM_SIMULATION_KB 207
#define CFG_BOOTLOADER_BOARD_ID 208
#define CFG_UF2_FAMILY 209
#define CFG_PINS_PORT_SIZE 210
#define ACCELEROMETER_TYPE_LIS3DH 0x32
#define ACCELEROMETER_TYPE_MMA8453 0x38
#define ACCELEROMETER_TYPE_FXOS8700 0x3c
#define ACCELEROMETER_TYPE_MMA8653 0x3a
#define ACCELEROMETER_TYPE_MSA300 0x4c
#define UF2_FAMILY_ATSAMD21 0x68ed2b88
#define UF2_FAMILY_ATSAMD51 0x55114460
#define UF2_FAMILY_NRF52840 0x1b57745f
#define UF2_FAMILY_STM32F103 0x5ee21072
#define UF2_FAMILY_STM32F401 0x57755a57
#define UF2_FAMILY_ATMEGA32 0x16573617
#define UF2_FAMILY_CYPRESS_FX2 0x5a18069b
#define PINS_PORT_SIZE_PA_16 0x10
#define PINS_PORT_SIZE_PA_32 0x20
#define PINS_PORT_SIZE_P0_16 0x1010
#define PINS_PORT_SIZE_P0_32 0x1020
#define DEFAULT_BUTTON_MODE_ACTIVE_HIGH_PULL_DOWN 0x11
#define DEFAULT_BUTTON_MODE_ACTIVE_HIGH_PULL_UP 0x21
#define DEFAULT_BUTTON_MODE_ACTIVE_HIGH_PULL_NONE 0x31
#define DEFAULT_BUTTON_MODE_ACTIVE_LOW_PULL_DOWN 0x10
#define DEFAULT_BUTTON_MODE_ACTIVE_LOW_PULL_UP 0x20
#define DEFAULT_BUTTON_MODE_ACTIVE_LOW_PULL_NONE 0x30
#endif // __CONFIGKEYS_H

46
bootloader/inc/main.h Normal file
View file

@ -0,0 +1,46 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _MAIN_H_
#define _MAIN_H_
#define CPU_FREQUENCY 48000000
#define FLASH_WAIT_STATES 1
#ifndef BOOT_USART_MODULE
#define BOOT_USART_MODULE SERCOM3
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD1_TX_PAD0
#define BOOT_USART_PAD3 PINMUX_UNUSED
#define BOOT_USART_PAD2 PINMUX_UNUSED
#define BOOT_USART_PAD1 PINMUX_PA23C_SERCOM3_PAD1
#define BOOT_USART_PAD0 PINMUX_PA22C_SERCOM3_PAD0
#endif
#endif // _MAIN_H_

92
bootloader/inc/neopixel.h Normal file
View file

@ -0,0 +1,92 @@
#ifndef DEVICE_NEOPIXEL_H
#define DEVICE_NEOPIXEL_H
#ifdef BOARD_NEOPIXEL_PIN
// The timings are taken from Adafruit's NeoPixel library
static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMask,
const uint8_t *ptr, int numBytes) __attribute__((naked));
static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMask,
const uint8_t *ptr, int numBytes) {
asm volatile(" push {r4, r5, r6, lr};"
" add r3, r2, r3;"
"loopLoad:"
" ldrb r5, [r2, #0];" // r5 := *ptr
" add r2, #1;" // ptr++
" movs r4, #128;" // r4-mask, 0x80
"loopBit:"
" str r1, [r0, #4];" // set
#ifdef SAMD21
" movs r6, #3; d2: sub r6, #1; bne d2;" // delay 3
#endif
#ifdef SAMD51
" movs r6, #3; d2: subs r6, #1; bne d2;" // delay 3
#endif
" tst r4, r5;" // mask&r5
" bne skipclr;"
" str r1, [r0, #0];" // clr
"skipclr:"
#ifdef SAMD21
" movs r6, #6; d0: sub r6, #1; bne d0;" // delay 6
#endif
#ifdef SAMD51
" movs r6, #6; d0: subs r6, #1; bne d0;" // delay 6
#endif
" str r1, [r0, #0];" // clr (possibly again, doesn't matter)
#ifdef SAMD21
" asr r4, r4, #1;" // mask >>= 1
#endif
#ifdef SAMD51
" asrs r4, r4, #1;" // mask >>= 1
#endif
" beq nextbyte;"
" uxtb r4, r4;"
#ifdef SAMD21
" movs r6, #2; d1: sub r6, #1; bne d1;" // delay 2
#endif
#ifdef SAMD51
" movs r6, #2; d1: subs r6, #1; bne d1;" // delay 2
#endif
" b loopBit;"
"nextbyte:"
" cmp r2, r3;"
" bcs stop;"
" b loopLoad;"
"stop:"
" pop {r4, r5, r6, pc};"
"");
}
// this assumes the pin has been configured correctly
static inline void neopixel_send_buffer(const uint8_t *ptr, int numBytes) {
uint8_t portNum = BOARD_NEOPIXEL_PIN / 32;
uint32_t pinMask = 1ul << (BOARD_NEOPIXEL_PIN % 32);
PINOP(BOARD_NEOPIXEL_PIN, DIRSET);
#if (USB_VID == 0x239a) && (USB_PID == 0x0013) // Adafruit Metro M0
// turn off mux too, needed for metro m0
PORT->Group[BOARD_NEOPIXEL_PIN / 32].PINCFG[BOARD_NEOPIXEL_PIN % 32].reg =
(uint8_t)(PORT_PINCFG_INEN);
#endif
PINOP(BOARD_NEOPIXEL_PIN, OUTCLR);
delay(1);
volatile uint32_t *clraddr = &PORT->Group[portNum].OUTCLR.reg;
// equivalent to cpu_irq_is_enabled()
if (__get_PRIMASK() == 0) {
__disable_irq();
neopixel_send_buffer_core(clraddr, pinMask, ptr, numBytes);
__enable_irq();
} else {
neopixel_send_buffer_core(clraddr, pinMask, ptr, numBytes);
}
}
#endif
#endif

View file

@ -0,0 +1,581 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _MRECURSION_H_
#define _MRECURSION_H_
/**
* \defgroup group_sam0_utils_mrecursion Preprocessor - Macro Recursion
*
* \ingroup group_sam0_utils
*
* @{
*/
#include "preprocessor.h"
#define DEC_256 255
#define DEC_255 254
#define DEC_254 253
#define DEC_253 252
#define DEC_252 251
#define DEC_251 250
#define DEC_250 249
#define DEC_249 248
#define DEC_248 247
#define DEC_247 246
#define DEC_246 245
#define DEC_245 244
#define DEC_244 243
#define DEC_243 242
#define DEC_242 241
#define DEC_241 240
#define DEC_240 239
#define DEC_239 238
#define DEC_238 237
#define DEC_237 236
#define DEC_236 235
#define DEC_235 234
#define DEC_234 233
#define DEC_233 232
#define DEC_232 231
#define DEC_231 230
#define DEC_230 229
#define DEC_229 228
#define DEC_228 227
#define DEC_227 226
#define DEC_226 225
#define DEC_225 224
#define DEC_224 223
#define DEC_223 222
#define DEC_222 221
#define DEC_221 220
#define DEC_220 219
#define DEC_219 218
#define DEC_218 217
#define DEC_217 216
#define DEC_216 215
#define DEC_215 214
#define DEC_214 213
#define DEC_213 212
#define DEC_212 211
#define DEC_211 210
#define DEC_210 209
#define DEC_209 208
#define DEC_208 207
#define DEC_207 206
#define DEC_206 205
#define DEC_205 204
#define DEC_204 203
#define DEC_203 202
#define DEC_202 201
#define DEC_201 200
#define DEC_200 199
#define DEC_199 198
#define DEC_198 197
#define DEC_197 196
#define DEC_196 195
#define DEC_195 194
#define DEC_194 193
#define DEC_193 192
#define DEC_192 191
#define DEC_191 190
#define DEC_190 189
#define DEC_189 188
#define DEC_188 187
#define DEC_187 186
#define DEC_186 185
#define DEC_185 184
#define DEC_184 183
#define DEC_183 182
#define DEC_182 181
#define DEC_181 180
#define DEC_180 179
#define DEC_179 178
#define DEC_178 177
#define DEC_177 176
#define DEC_176 175
#define DEC_175 174
#define DEC_174 173
#define DEC_173 172
#define DEC_172 171
#define DEC_171 170
#define DEC_170 169
#define DEC_169 168
#define DEC_168 167
#define DEC_167 166
#define DEC_166 165
#define DEC_165 164
#define DEC_164 163
#define DEC_163 162
#define DEC_162 161
#define DEC_161 160
#define DEC_160 159
#define DEC_159 158
#define DEC_158 157
#define DEC_157 156
#define DEC_156 155
#define DEC_155 154
#define DEC_154 153
#define DEC_153 152
#define DEC_152 151
#define DEC_151 150
#define DEC_150 149
#define DEC_149 148
#define DEC_148 147
#define DEC_147 146
#define DEC_146 145
#define DEC_145 144
#define DEC_144 143
#define DEC_143 142
#define DEC_142 141
#define DEC_141 140
#define DEC_140 139
#define DEC_139 138
#define DEC_138 137
#define DEC_137 136
#define DEC_136 135
#define DEC_135 134
#define DEC_134 133
#define DEC_133 132
#define DEC_132 131
#define DEC_131 130
#define DEC_130 129
#define DEC_129 128
#define DEC_128 127
#define DEC_127 126
#define DEC_126 125
#define DEC_125 124
#define DEC_124 123
#define DEC_123 122
#define DEC_122 121
#define DEC_121 120
#define DEC_120 119
#define DEC_119 118
#define DEC_118 117
#define DEC_117 116
#define DEC_116 115
#define DEC_115 114
#define DEC_114 113
#define DEC_113 112
#define DEC_112 111
#define DEC_111 110
#define DEC_110 109
#define DEC_109 108
#define DEC_108 107
#define DEC_107 106
#define DEC_106 105
#define DEC_105 104
#define DEC_104 103
#define DEC_103 102
#define DEC_102 101
#define DEC_101 100
#define DEC_100 99
#define DEC_99 98
#define DEC_98 97
#define DEC_97 96
#define DEC_96 95
#define DEC_95 94
#define DEC_94 93
#define DEC_93 92
#define DEC_92 91
#define DEC_91 90
#define DEC_90 89
#define DEC_89 88
#define DEC_88 87
#define DEC_87 86
#define DEC_86 85
#define DEC_85 84
#define DEC_84 83
#define DEC_83 82
#define DEC_82 81
#define DEC_81 80
#define DEC_80 79
#define DEC_79 78
#define DEC_78 77
#define DEC_77 76
#define DEC_76 75
#define DEC_75 74
#define DEC_74 73
#define DEC_73 72
#define DEC_72 71
#define DEC_71 70
#define DEC_70 69
#define DEC_69 68
#define DEC_68 67
#define DEC_67 66
#define DEC_66 65
#define DEC_65 64
#define DEC_64 63
#define DEC_63 62
#define DEC_62 61
#define DEC_61 60
#define DEC_60 59
#define DEC_59 58
#define DEC_58 57
#define DEC_57 56
#define DEC_56 55
#define DEC_55 54
#define DEC_54 53
#define DEC_53 52
#define DEC_52 51
#define DEC_51 50
#define DEC_50 49
#define DEC_49 48
#define DEC_48 47
#define DEC_47 46
#define DEC_46 45
#define DEC_45 44
#define DEC_44 43
#define DEC_43 42
#define DEC_42 41
#define DEC_41 40
#define DEC_40 39
#define DEC_39 38
#define DEC_38 37
#define DEC_37 36
#define DEC_36 35
#define DEC_35 34
#define DEC_34 33
#define DEC_33 32
#define DEC_32 31
#define DEC_31 30
#define DEC_30 29
#define DEC_29 28
#define DEC_28 27
#define DEC_27 26
#define DEC_26 25
#define DEC_25 24
#define DEC_24 23
#define DEC_23 22
#define DEC_22 21
#define DEC_21 20
#define DEC_20 19
#define DEC_19 18
#define DEC_18 17
#define DEC_17 16
#define DEC_16 15
#define DEC_15 14
#define DEC_14 13
#define DEC_13 12
#define DEC_12 11
#define DEC_11 10
#define DEC_10 9
#define DEC_9 8
#define DEC_8 7
#define DEC_7 6
#define DEC_6 5
#define DEC_5 4
#define DEC_4 3
#define DEC_3 2
#define DEC_2 1
#define DEC_1 0
#define DEC_(n) DEC_##n
/** Maximal number of repetitions supported by MRECURSION. */
#define MRECURSION_LIMIT 256
/** \brief Macro recursion.
*
* This macro represents a horizontal repetition construct.
*
* \param[in] count The number of repetitious calls to macro. Valid values
* range from 0 to MRECURSION_LIMIT.
* \param[in] macro A binary operation of the form macro(data, n). This macro
* is expanded by MRECURSION with the current repetition number
* and the auxiliary data argument.
* \param[in] data A recursive threshold, building on this to decline by times
* defined with param count.
*
* \return <tt>macro(data-count+1,0) macro(data-count+2,1)...macro(data,count-1)</tt>
*/
#define MRECURSION(count, macro, data) TPASTE2(MRECURSION, count) (macro, data)
#define MRECURSION0( macro, data)
#define MRECURSION1( macro, data) MRECURSION0( macro, DEC_(data)) macro(data, 0)
#define MRECURSION2( macro, data) MRECURSION1( macro, DEC_(data)) macro(data, 1)
#define MRECURSION3( macro, data) MRECURSION2( macro, DEC_(data)) macro(data, 2)
#define MRECURSION4( macro, data) MRECURSION3( macro, DEC_(data)) macro(data, 3)
#define MRECURSION5( macro, data) MRECURSION4( macro, DEC_(data)) macro(data, 4)
#define MRECURSION6( macro, data) MRECURSION5( macro, DEC_(data)) macro(data, 5)
#define MRECURSION7( macro, data) MRECURSION6( macro, DEC_(data)) macro(data, 6)
#define MRECURSION8( macro, data) MRECURSION7( macro, DEC_(data)) macro(data, 7)
#define MRECURSION9( macro, data) MRECURSION8( macro, DEC_(data)) macro(data, 8)
#define MRECURSION10( macro, data) MRECURSION9( macro, DEC_(data)) macro(data, 9)
#define MRECURSION11( macro, data) MRECURSION10( macro, DEC_(data)) macro(data, 10)
#define MRECURSION12( macro, data) MRECURSION11( macro, DEC_(data)) macro(data, 11)
#define MRECURSION13( macro, data) MRECURSION12( macro, DEC_(data)) macro(data, 12)
#define MRECURSION14( macro, data) MRECURSION13( macro, DEC_(data)) macro(data, 13)
#define MRECURSION15( macro, data) MRECURSION14( macro, DEC_(data)) macro(data, 14)
#define MRECURSION16( macro, data) MRECURSION15( macro, DEC_(data)) macro(data, 15)
#define MRECURSION17( macro, data) MRECURSION16( macro, DEC_(data)) macro(data, 16)
#define MRECURSION18( macro, data) MRECURSION17( macro, DEC_(data)) macro(data, 17)
#define MRECURSION19( macro, data) MRECURSION18( macro, DEC_(data)) macro(data, 18)
#define MRECURSION20( macro, data) MRECURSION19( macro, DEC_(data)) macro(data, 19)
#define MRECURSION21( macro, data) MRECURSION20( macro, DEC_(data)) macro(data, 20)
#define MRECURSION22( macro, data) MRECURSION21( macro, DEC_(data)) macro(data, 21)
#define MRECURSION23( macro, data) MRECURSION22( macro, DEC_(data)) macro(data, 22)
#define MRECURSION24( macro, data) MRECURSION23( macro, DEC_(data)) macro(data, 23)
#define MRECURSION25( macro, data) MRECURSION24( macro, DEC_(data)) macro(data, 24)
#define MRECURSION26( macro, data) MRECURSION25( macro, DEC_(data)) macro(data, 25)
#define MRECURSION27( macro, data) MRECURSION26( macro, DEC_(data)) macro(data, 26)
#define MRECURSION28( macro, data) MRECURSION27( macro, DEC_(data)) macro(data, 27)
#define MRECURSION29( macro, data) MRECURSION28( macro, DEC_(data)) macro(data, 28)
#define MRECURSION30( macro, data) MRECURSION29( macro, DEC_(data)) macro(data, 29)
#define MRECURSION31( macro, data) MRECURSION30( macro, DEC_(data)) macro(data, 30)
#define MRECURSION32( macro, data) MRECURSION31( macro, DEC_(data)) macro(data, 31)
#define MRECURSION33( macro, data) MRECURSION32( macro, DEC_(data)) macro(data, 32)
#define MRECURSION34( macro, data) MRECURSION33( macro, DEC_(data)) macro(data, 33)
#define MRECURSION35( macro, data) MRECURSION34( macro, DEC_(data)) macro(data, 34)
#define MRECURSION36( macro, data) MRECURSION35( macro, DEC_(data)) macro(data, 35)
#define MRECURSION37( macro, data) MRECURSION36( macro, DEC_(data)) macro(data, 36)
#define MRECURSION38( macro, data) MRECURSION37( macro, DEC_(data)) macro(data, 37)
#define MRECURSION39( macro, data) MRECURSION38( macro, DEC_(data)) macro(data, 38)
#define MRECURSION40( macro, data) MRECURSION39( macro, DEC_(data)) macro(data, 39)
#define MRECURSION41( macro, data) MRECURSION40( macro, DEC_(data)) macro(data, 40)
#define MRECURSION42( macro, data) MRECURSION41( macro, DEC_(data)) macro(data, 41)
#define MRECURSION43( macro, data) MRECURSION42( macro, DEC_(data)) macro(data, 42)
#define MRECURSION44( macro, data) MRECURSION43( macro, DEC_(data)) macro(data, 43)
#define MRECURSION45( macro, data) MRECURSION44( macro, DEC_(data)) macro(data, 44)
#define MRECURSION46( macro, data) MRECURSION45( macro, DEC_(data)) macro(data, 45)
#define MRECURSION47( macro, data) MRECURSION46( macro, DEC_(data)) macro(data, 46)
#define MRECURSION48( macro, data) MRECURSION47( macro, DEC_(data)) macro(data, 47)
#define MRECURSION49( macro, data) MRECURSION48( macro, DEC_(data)) macro(data, 48)
#define MRECURSION50( macro, data) MRECURSION49( macro, DEC_(data)) macro(data, 49)
#define MRECURSION51( macro, data) MRECURSION50( macro, DEC_(data)) macro(data, 50)
#define MRECURSION52( macro, data) MRECURSION51( macro, DEC_(data)) macro(data, 51)
#define MRECURSION53( macro, data) MRECURSION52( macro, DEC_(data)) macro(data, 52)
#define MRECURSION54( macro, data) MRECURSION53( macro, DEC_(data)) macro(data, 53)
#define MRECURSION55( macro, data) MRECURSION54( macro, DEC_(data)) macro(data, 54)
#define MRECURSION56( macro, data) MRECURSION55( macro, DEC_(data)) macro(data, 55)
#define MRECURSION57( macro, data) MRECURSION56( macro, DEC_(data)) macro(data, 56)
#define MRECURSION58( macro, data) MRECURSION57( macro, DEC_(data)) macro(data, 57)
#define MRECURSION59( macro, data) MRECURSION58( macro, DEC_(data)) macro(data, 58)
#define MRECURSION60( macro, data) MRECURSION59( macro, DEC_(data)) macro(data, 59)
#define MRECURSION61( macro, data) MRECURSION60( macro, DEC_(data)) macro(data, 60)
#define MRECURSION62( macro, data) MRECURSION61( macro, DEC_(data)) macro(data, 61)
#define MRECURSION63( macro, data) MRECURSION62( macro, DEC_(data)) macro(data, 62)
#define MRECURSION64( macro, data) MRECURSION63( macro, DEC_(data)) macro(data, 63)
#define MRECURSION65( macro, data) MRECURSION64( macro, DEC_(data)) macro(data, 64)
#define MRECURSION66( macro, data) MRECURSION65( macro, DEC_(data)) macro(data, 65)
#define MRECURSION67( macro, data) MRECURSION66( macro, DEC_(data)) macro(data, 66)
#define MRECURSION68( macro, data) MRECURSION67( macro, DEC_(data)) macro(data, 67)
#define MRECURSION69( macro, data) MRECURSION68( macro, DEC_(data)) macro(data, 68)
#define MRECURSION70( macro, data) MRECURSION69( macro, DEC_(data)) macro(data, 69)
#define MRECURSION71( macro, data) MRECURSION70( macro, DEC_(data)) macro(data, 70)
#define MRECURSION72( macro, data) MRECURSION71( macro, DEC_(data)) macro(data, 71)
#define MRECURSION73( macro, data) MRECURSION72( macro, DEC_(data)) macro(data, 72)
#define MRECURSION74( macro, data) MRECURSION73( macro, DEC_(data)) macro(data, 73)
#define MRECURSION75( macro, data) MRECURSION74( macro, DEC_(data)) macro(data, 74)
#define MRECURSION76( macro, data) MRECURSION75( macro, DEC_(data)) macro(data, 75)
#define MRECURSION77( macro, data) MRECURSION76( macro, DEC_(data)) macro(data, 76)
#define MRECURSION78( macro, data) MRECURSION77( macro, DEC_(data)) macro(data, 77)
#define MRECURSION79( macro, data) MRECURSION78( macro, DEC_(data)) macro(data, 78)
#define MRECURSION80( macro, data) MRECURSION79( macro, DEC_(data)) macro(data, 79)
#define MRECURSION81( macro, data) MRECURSION80( macro, DEC_(data)) macro(data, 80)
#define MRECURSION82( macro, data) MRECURSION81( macro, DEC_(data)) macro(data, 81)
#define MRECURSION83( macro, data) MRECURSION82( macro, DEC_(data)) macro(data, 82)
#define MRECURSION84( macro, data) MRECURSION83( macro, DEC_(data)) macro(data, 83)
#define MRECURSION85( macro, data) MRECURSION84( macro, DEC_(data)) macro(data, 84)
#define MRECURSION86( macro, data) MRECURSION85( macro, DEC_(data)) macro(data, 85)
#define MRECURSION87( macro, data) MRECURSION86( macro, DEC_(data)) macro(data, 86)
#define MRECURSION88( macro, data) MRECURSION87( macro, DEC_(data)) macro(data, 87)
#define MRECURSION89( macro, data) MRECURSION88( macro, DEC_(data)) macro(data, 88)
#define MRECURSION90( macro, data) MRECURSION89( macro, DEC_(data)) macro(data, 89)
#define MRECURSION91( macro, data) MRECURSION90( macro, DEC_(data)) macro(data, 90)
#define MRECURSION92( macro, data) MRECURSION91( macro, DEC_(data)) macro(data, 91)
#define MRECURSION93( macro, data) MRECURSION92( macro, DEC_(data)) macro(data, 92)
#define MRECURSION94( macro, data) MRECURSION93( macro, DEC_(data)) macro(data, 93)
#define MRECURSION95( macro, data) MRECURSION94( macro, DEC_(data)) macro(data, 94)
#define MRECURSION96( macro, data) MRECURSION95( macro, DEC_(data)) macro(data, 95)
#define MRECURSION97( macro, data) MRECURSION96( macro, DEC_(data)) macro(data, 96)
#define MRECURSION98( macro, data) MRECURSION97( macro, DEC_(data)) macro(data, 97)
#define MRECURSION99( macro, data) MRECURSION98( macro, DEC_(data)) macro(data, 98)
#define MRECURSION100(macro, data) MRECURSION99( macro, DEC_(data)) macro(data, 99)
#define MRECURSION101(macro, data) MRECURSION100( macro, DEC_(data)) macro(data, 100)
#define MRECURSION102(macro, data) MRECURSION101( macro, DEC_(data)) macro(data, 101)
#define MRECURSION103(macro, data) MRECURSION102( macro, DEC_(data)) macro(data, 102)
#define MRECURSION104(macro, data) MRECURSION103( macro, DEC_(data)) macro(data, 103)
#define MRECURSION105(macro, data) MRECURSION104( macro, DEC_(data)) macro(data, 104)
#define MRECURSION106(macro, data) MRECURSION105( macro, DEC_(data)) macro(data, 105)
#define MRECURSION107(macro, data) MRECURSION106( macro, DEC_(data)) macro(data, 106)
#define MRECURSION108(macro, data) MRECURSION107( macro, DEC_(data)) macro(data, 107)
#define MRECURSION109(macro, data) MRECURSION108( macro, DEC_(data)) macro(data, 108)
#define MRECURSION110(macro, data) MRECURSION109( macro, DEC_(data)) macro(data, 109)
#define MRECURSION111(macro, data) MRECURSION110( macro, DEC_(data)) macro(data, 110)
#define MRECURSION112(macro, data) MRECURSION111( macro, DEC_(data)) macro(data, 111)
#define MRECURSION113(macro, data) MRECURSION112( macro, DEC_(data)) macro(data, 112)
#define MRECURSION114(macro, data) MRECURSION113( macro, DEC_(data)) macro(data, 113)
#define MRECURSION115(macro, data) MRECURSION114( macro, DEC_(data)) macro(data, 114)
#define MRECURSION116(macro, data) MRECURSION115( macro, DEC_(data)) macro(data, 115)
#define MRECURSION117(macro, data) MRECURSION116( macro, DEC_(data)) macro(data, 116)
#define MRECURSION118(macro, data) MRECURSION117( macro, DEC_(data)) macro(data, 117)
#define MRECURSION119(macro, data) MRECURSION118( macro, DEC_(data)) macro(data, 118)
#define MRECURSION120(macro, data) MRECURSION119( macro, DEC_(data)) macro(data, 119)
#define MRECURSION121(macro, data) MRECURSION120( macro, DEC_(data)) macro(data, 120)
#define MRECURSION122(macro, data) MRECURSION121( macro, DEC_(data)) macro(data, 121)
#define MRECURSION123(macro, data) MRECURSION122( macro, DEC_(data)) macro(data, 122)
#define MRECURSION124(macro, data) MRECURSION123( macro, DEC_(data)) macro(data, 123)
#define MRECURSION125(macro, data) MRECURSION124( macro, DEC_(data)) macro(data, 124)
#define MRECURSION126(macro, data) MRECURSION125( macro, DEC_(data)) macro(data, 125)
#define MRECURSION127(macro, data) MRECURSION126( macro, DEC_(data)) macro(data, 126)
#define MRECURSION128(macro, data) MRECURSION127( macro, DEC_(data)) macro(data, 127)
#define MRECURSION129(macro, data) MRECURSION128( macro, DEC_(data)) macro(data, 128)
#define MRECURSION130(macro, data) MRECURSION129( macro, DEC_(data)) macro(data, 129)
#define MRECURSION131(macro, data) MRECURSION130( macro, DEC_(data)) macro(data, 130)
#define MRECURSION132(macro, data) MRECURSION131( macro, DEC_(data)) macro(data, 131)
#define MRECURSION133(macro, data) MRECURSION132( macro, DEC_(data)) macro(data, 132)
#define MRECURSION134(macro, data) MRECURSION133( macro, DEC_(data)) macro(data, 133)
#define MRECURSION135(macro, data) MRECURSION134( macro, DEC_(data)) macro(data, 134)
#define MRECURSION136(macro, data) MRECURSION135( macro, DEC_(data)) macro(data, 135)
#define MRECURSION137(macro, data) MRECURSION136( macro, DEC_(data)) macro(data, 136)
#define MRECURSION138(macro, data) MRECURSION137( macro, DEC_(data)) macro(data, 137)
#define MRECURSION139(macro, data) MRECURSION138( macro, DEC_(data)) macro(data, 138)
#define MRECURSION140(macro, data) MRECURSION139( macro, DEC_(data)) macro(data, 139)
#define MRECURSION141(macro, data) MRECURSION140( macro, DEC_(data)) macro(data, 140)
#define MRECURSION142(macro, data) MRECURSION141( macro, DEC_(data)) macro(data, 141)
#define MRECURSION143(macro, data) MRECURSION142( macro, DEC_(data)) macro(data, 142)
#define MRECURSION144(macro, data) MRECURSION143( macro, DEC_(data)) macro(data, 143)
#define MRECURSION145(macro, data) MRECURSION144( macro, DEC_(data)) macro(data, 144)
#define MRECURSION146(macro, data) MRECURSION145( macro, DEC_(data)) macro(data, 145)
#define MRECURSION147(macro, data) MRECURSION146( macro, DEC_(data)) macro(data, 146)
#define MRECURSION148(macro, data) MRECURSION147( macro, DEC_(data)) macro(data, 147)
#define MRECURSION149(macro, data) MRECURSION148( macro, DEC_(data)) macro(data, 148)
#define MRECURSION150(macro, data) MRECURSION149( macro, DEC_(data)) macro(data, 149)
#define MRECURSION151(macro, data) MRECURSION150( macro, DEC_(data)) macro(data, 150)
#define MRECURSION152(macro, data) MRECURSION151( macro, DEC_(data)) macro(data, 151)
#define MRECURSION153(macro, data) MRECURSION152( macro, DEC_(data)) macro(data, 152)
#define MRECURSION154(macro, data) MRECURSION153( macro, DEC_(data)) macro(data, 153)
#define MRECURSION155(macro, data) MRECURSION154( macro, DEC_(data)) macro(data, 154)
#define MRECURSION156(macro, data) MRECURSION155( macro, DEC_(data)) macro(data, 155)
#define MRECURSION157(macro, data) MRECURSION156( macro, DEC_(data)) macro(data, 156)
#define MRECURSION158(macro, data) MRECURSION157( macro, DEC_(data)) macro(data, 157)
#define MRECURSION159(macro, data) MRECURSION158( macro, DEC_(data)) macro(data, 158)
#define MRECURSION160(macro, data) MRECURSION159( macro, DEC_(data)) macro(data, 159)
#define MRECURSION161(macro, data) MRECURSION160( macro, DEC_(data)) macro(data, 160)
#define MRECURSION162(macro, data) MRECURSION161( macro, DEC_(data)) macro(data, 161)
#define MRECURSION163(macro, data) MRECURSION162( macro, DEC_(data)) macro(data, 162)
#define MRECURSION164(macro, data) MRECURSION163( macro, DEC_(data)) macro(data, 163)
#define MRECURSION165(macro, data) MRECURSION164( macro, DEC_(data)) macro(data, 164)
#define MRECURSION166(macro, data) MRECURSION165( macro, DEC_(data)) macro(data, 165)
#define MRECURSION167(macro, data) MRECURSION166( macro, DEC_(data)) macro(data, 166)
#define MRECURSION168(macro, data) MRECURSION167( macro, DEC_(data)) macro(data, 167)
#define MRECURSION169(macro, data) MRECURSION168( macro, DEC_(data)) macro(data, 168)
#define MRECURSION170(macro, data) MRECURSION169( macro, DEC_(data)) macro(data, 169)
#define MRECURSION171(macro, data) MRECURSION170( macro, DEC_(data)) macro(data, 170)
#define MRECURSION172(macro, data) MRECURSION171( macro, DEC_(data)) macro(data, 171)
#define MRECURSION173(macro, data) MRECURSION172( macro, DEC_(data)) macro(data, 172)
#define MRECURSION174(macro, data) MRECURSION173( macro, DEC_(data)) macro(data, 173)
#define MRECURSION175(macro, data) MRECURSION174( macro, DEC_(data)) macro(data, 174)
#define MRECURSION176(macro, data) MRECURSION175( macro, DEC_(data)) macro(data, 175)
#define MRECURSION177(macro, data) MRECURSION176( macro, DEC_(data)) macro(data, 176)
#define MRECURSION178(macro, data) MRECURSION177( macro, DEC_(data)) macro(data, 177)
#define MRECURSION179(macro, data) MRECURSION178( macro, DEC_(data)) macro(data, 178)
#define MRECURSION180(macro, data) MRECURSION179( macro, DEC_(data)) macro(data, 179)
#define MRECURSION181(macro, data) MRECURSION180( macro, DEC_(data)) macro(data, 180)
#define MRECURSION182(macro, data) MRECURSION181( macro, DEC_(data)) macro(data, 181)
#define MRECURSION183(macro, data) MRECURSION182( macro, DEC_(data)) macro(data, 182)
#define MRECURSION184(macro, data) MRECURSION183( macro, DEC_(data)) macro(data, 183)
#define MRECURSION185(macro, data) MRECURSION184( macro, DEC_(data)) macro(data, 184)
#define MRECURSION186(macro, data) MRECURSION185( macro, DEC_(data)) macro(data, 185)
#define MRECURSION187(macro, data) MRECURSION186( macro, DEC_(data)) macro(data, 186)
#define MRECURSION188(macro, data) MRECURSION187( macro, DEC_(data)) macro(data, 187)
#define MRECURSION189(macro, data) MRECURSION188( macro, DEC_(data)) macro(data, 188)
#define MRECURSION190(macro, data) MRECURSION189( macro, DEC_(data)) macro(data, 189)
#define MRECURSION191(macro, data) MRECURSION190( macro, DEC_(data)) macro(data, 190)
#define MRECURSION192(macro, data) MRECURSION191( macro, DEC_(data)) macro(data, 191)
#define MRECURSION193(macro, data) MRECURSION192( macro, DEC_(data)) macro(data, 192)
#define MRECURSION194(macro, data) MRECURSION193( macro, DEC_(data)) macro(data, 193)
#define MRECURSION195(macro, data) MRECURSION194( macro, DEC_(data)) macro(data, 194)
#define MRECURSION196(macro, data) MRECURSION195( macro, DEC_(data)) macro(data, 195)
#define MRECURSION197(macro, data) MRECURSION196( macro, DEC_(data)) macro(data, 196)
#define MRECURSION198(macro, data) MRECURSION197( macro, DEC_(data)) macro(data, 197)
#define MRECURSION199(macro, data) MRECURSION198( macro, DEC_(data)) macro(data, 198)
#define MRECURSION200(macro, data) MRECURSION199( macro, DEC_(data)) macro(data, 199)
#define MRECURSION201(macro, data) MRECURSION200( macro, DEC_(data)) macro(data, 200)
#define MRECURSION202(macro, data) MRECURSION201( macro, DEC_(data)) macro(data, 201)
#define MRECURSION203(macro, data) MRECURSION202( macro, DEC_(data)) macro(data, 202)
#define MRECURSION204(macro, data) MRECURSION203( macro, DEC_(data)) macro(data, 203)
#define MRECURSION205(macro, data) MRECURSION204( macro, DEC_(data)) macro(data, 204)
#define MRECURSION206(macro, data) MRECURSION205( macro, DEC_(data)) macro(data, 205)
#define MRECURSION207(macro, data) MRECURSION206( macro, DEC_(data)) macro(data, 206)
#define MRECURSION208(macro, data) MRECURSION207( macro, DEC_(data)) macro(data, 207)
#define MRECURSION209(macro, data) MRECURSION208( macro, DEC_(data)) macro(data, 208)
#define MRECURSION210(macro, data) MRECURSION209( macro, DEC_(data)) macro(data, 209)
#define MRECURSION211(macro, data) MRECURSION210( macro, DEC_(data)) macro(data, 210)
#define MRECURSION212(macro, data) MRECURSION211( macro, DEC_(data)) macro(data, 211)
#define MRECURSION213(macro, data) MRECURSION212( macro, DEC_(data)) macro(data, 212)
#define MRECURSION214(macro, data) MRECURSION213( macro, DEC_(data)) macro(data, 213)
#define MRECURSION215(macro, data) MRECURSION214( macro, DEC_(data)) macro(data, 214)
#define MRECURSION216(macro, data) MRECURSION215( macro, DEC_(data)) macro(data, 215)
#define MRECURSION217(macro, data) MRECURSION216( macro, DEC_(data)) macro(data, 216)
#define MRECURSION218(macro, data) MRECURSION217( macro, DEC_(data)) macro(data, 217)
#define MRECURSION219(macro, data) MRECURSION218( macro, DEC_(data)) macro(data, 218)
#define MRECURSION220(macro, data) MRECURSION219( macro, DEC_(data)) macro(data, 219)
#define MRECURSION221(macro, data) MRECURSION220( macro, DEC_(data)) macro(data, 220)
#define MRECURSION222(macro, data) MRECURSION221( macro, DEC_(data)) macro(data, 221)
#define MRECURSION223(macro, data) MRECURSION222( macro, DEC_(data)) macro(data, 222)
#define MRECURSION224(macro, data) MRECURSION223( macro, DEC_(data)) macro(data, 223)
#define MRECURSION225(macro, data) MRECURSION224( macro, DEC_(data)) macro(data, 224)
#define MRECURSION226(macro, data) MRECURSION225( macro, DEC_(data)) macro(data, 225)
#define MRECURSION227(macro, data) MRECURSION226( macro, DEC_(data)) macro(data, 226)
#define MRECURSION228(macro, data) MRECURSION227( macro, DEC_(data)) macro(data, 227)
#define MRECURSION229(macro, data) MRECURSION228( macro, DEC_(data)) macro(data, 228)
#define MRECURSION230(macro, data) MRECURSION229( macro, DEC_(data)) macro(data, 229)
#define MRECURSION231(macro, data) MRECURSION230( macro, DEC_(data)) macro(data, 230)
#define MRECURSION232(macro, data) MRECURSION231( macro, DEC_(data)) macro(data, 231)
#define MRECURSION233(macro, data) MRECURSION232( macro, DEC_(data)) macro(data, 232)
#define MRECURSION234(macro, data) MRECURSION233( macro, DEC_(data)) macro(data, 233)
#define MRECURSION235(macro, data) MRECURSION234( macro, DEC_(data)) macro(data, 234)
#define MRECURSION236(macro, data) MRECURSION235( macro, DEC_(data)) macro(data, 235)
#define MRECURSION237(macro, data) MRECURSION236( macro, DEC_(data)) macro(data, 236)
#define MRECURSION238(macro, data) MRECURSION237( macro, DEC_(data)) macro(data, 237)
#define MRECURSION239(macro, data) MRECURSION238( macro, DEC_(data)) macro(data, 238)
#define MRECURSION240(macro, data) MRECURSION239( macro, DEC_(data)) macro(data, 239)
#define MRECURSION241(macro, data) MRECURSION240( macro, DEC_(data)) macro(data, 240)
#define MRECURSION242(macro, data) MRECURSION241( macro, DEC_(data)) macro(data, 241)
#define MRECURSION243(macro, data) MRECURSION242( macro, DEC_(data)) macro(data, 242)
#define MRECURSION244(macro, data) MRECURSION243( macro, DEC_(data)) macro(data, 243)
#define MRECURSION245(macro, data) MRECURSION244( macro, DEC_(data)) macro(data, 244)
#define MRECURSION246(macro, data) MRECURSION245( macro, DEC_(data)) macro(data, 245)
#define MRECURSION247(macro, data) MRECURSION246( macro, DEC_(data)) macro(data, 246)
#define MRECURSION248(macro, data) MRECURSION247( macro, DEC_(data)) macro(data, 247)
#define MRECURSION249(macro, data) MRECURSION248( macro, DEC_(data)) macro(data, 248)
#define MRECURSION250(macro, data) MRECURSION249( macro, DEC_(data)) macro(data, 249)
#define MRECURSION251(macro, data) MRECURSION250( macro, DEC_(data)) macro(data, 250)
#define MRECURSION252(macro, data) MRECURSION251( macro, DEC_(data)) macro(data, 251)
#define MRECURSION253(macro, data) MRECURSION252( macro, DEC_(data)) macro(data, 252)
#define MRECURSION254(macro, data) MRECURSION253( macro, DEC_(data)) macro(data, 253)
#define MRECURSION255(macro, data) MRECURSION254( macro, DEC_(data)) macro(data, 254)
#define MRECURSION256(macro, data) MRECURSION255( macro, DEC_(data)) macro(data, 255)
/** @} */
#endif /* _MRECURSION_H_ */

View file

@ -0,0 +1,321 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _MREPEAT_H_
#define _MREPEAT_H_
/**
* \defgroup group_sam0_utils_mrepeat Preprocessor - Macro Repeat
*
* \ingroup group_sam0_utils
*
* @{
*/
#include "preprocessor.h"
/** Maximal number of repetitions supported by MREPEAT. */
#define MREPEAT_LIMIT 256
/** \brief Macro repeat.
*
* This macro represents a horizontal repetition construct.
*
* \param[in] count The number of repetitious calls to macro. Valid values
* range from 0 to MREPEAT_LIMIT.
* \param[in] macro A binary operation of the form macro(n, data). This macro
* is expanded by MREPEAT with the current repetition number
* and the auxiliary data argument.
* \param[in] data Auxiliary data passed to macro.
*
* \return <tt>macro(0, data) macro(1, data) ... macro(count - 1, data)</tt>
*/
#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count) (macro, data)
#define MREPEAT0( macro, data)
#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data)
#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data)
#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data)
#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data)
#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data)
#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data)
#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data)
#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data)
#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data)
#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data)
#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data)
#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data)
#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data)
#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data)
#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data)
#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data)
#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data)
#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data)
#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data)
#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data)
#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data)
#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data)
#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data)
#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data)
#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data)
#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data)
#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data)
#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data)
#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data)
#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data)
#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data)
#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data)
#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data)
#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data)
#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data)
#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data)
#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data)
#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data)
#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data)
#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data)
#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data)
#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data)
#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data)
#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data)
#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data)
#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data)
#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data)
#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data)
#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data)
#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data)
#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data)
#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data)
#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data)
#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data)
#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data)
#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data)
#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data)
#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data)
#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data)
#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data)
#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data)
#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data)
#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data)
#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data)
#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data)
#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data)
#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data)
#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data)
#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data)
#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data)
#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data)
#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data)
#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data)
#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data)
#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data)
#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data)
#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data)
#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data)
#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data)
#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data)
#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data)
#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data)
#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data)
#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data)
#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data)
#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data)
#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data)
#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data)
#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data)
#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data)
#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data)
#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data)
#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data)
#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data)
#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data)
#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data)
#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data)
#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data)
#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data)
#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data)
#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data)
#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data)
#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data)
#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data)
#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data)
#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data)
#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data)
#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data)
#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data)
#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data)
#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data)
#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data)
#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data)
#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data)
#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data)
#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data)
#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data)
#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data)
#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data)
#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data)
#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data)
#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data)
#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data)
#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data)
#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data)
#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data)
#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data)
#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data)
#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data)
#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data)
#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data)
#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data)
#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data)
#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data)
#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data)
#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data)
#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data)
#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data)
#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data)
#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data)
#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data)
#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data)
#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data)
#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data)
#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data)
#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data)
#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data)
#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data)
#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data)
#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data)
#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data)
#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data)
#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data)
#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data)
#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data)
#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data)
#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data)
#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data)
#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data)
#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data)
#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data)
#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data)
#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data)
#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data)
#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data)
#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data)
#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data)
#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data)
#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data)
#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data)
#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data)
#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data)
#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data)
#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data)
#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data)
#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data)
#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data)
#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data)
#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data)
#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data)
#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data)
#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data)
#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data)
#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data)
#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data)
#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data)
#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data)
#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data)
#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data)
#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data)
#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data)
#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data)
#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data)
#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data)
#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data)
#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data)
#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data)
#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data)
#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data)
#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data)
#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data)
#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data)
#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data)
#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data)
#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data)
#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data)
#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data)
#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data)
#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data)
#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data)
#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data)
#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data)
#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data)
#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data)
#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data)
#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data)
#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data)
#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data)
#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data)
#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data)
#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data)
#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data)
#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data)
#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data)
#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data)
#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data)
#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data)
#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data)
#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data)
#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data)
#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data)
#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data)
#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data)
#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data)
#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data)
#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data)
#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data)
#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data)
#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data)
#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data)
#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data)
#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data)
#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data)
#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data)
#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data)
#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data)
#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data)
#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data)
#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data)
#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data)
#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data)
#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data)
#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data)
#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data)
#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data)
#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data)
/** @} */
#endif /* _MREPEAT_H_ */

View file

@ -0,0 +1,38 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _PREPROCESSOR_H_
#define _PREPROCESSOR_H_
#include "tpaste.h"
#include "stringz.h"
#include "mrepeat.h"
#include "mrecursion.h"
#endif // _PREPROCESSOR_H_

View file

@ -0,0 +1,67 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _STRINGZ_H_
#define _STRINGZ_H_
/**
* \defgroup group_sam0_utils_stringz Preprocessor - Stringize
*
* \ingroup group_sam0_utils
*
* @{
*/
/** \brief Stringize.
*
* Stringize a preprocessing token, this token being allowed to be \#defined.
*
* May be used only within macros with the token passed as an argument if the
* token is \#defined.
*
* For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN)
* and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to
* writing "A0".
*/
#define STRINGZ(x) #x
/** \brief Absolute stringize.
*
* Stringize a preprocessing token, this token being allowed to be \#defined.
*
* No restriction of use if the token is \#defined.
*
* For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is
* equivalent to writing "A0".
*/
#define ASTRINGZ(x) STRINGZ(x)
/** @} */
#endif // _STRINGZ_H_

View file

@ -0,0 +1,85 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _TPASTE_H_
#define _TPASTE_H_
/**
* \defgroup group_sam0_utils_tpaste Preprocessor - Token Paste
*
* \ingroup group_sam0_utils
*
* @{
*/
/** \name Token Paste
*
* Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
*
* May be used only within macros with the tokens passed as arguments if the tokens are \#defined.
*
* For example, writing TPASTE2(U, WIDTH) within a macro \#defined by
* UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is
* equivalent to writing U32.
*
* @{ */
#define TPASTE2( a, b) a##b
#define TPASTE3( a, b, c) a##b##c
#define TPASTE4( a, b, c, d) a##b##c##d
#define TPASTE5( a, b, c, d, e) a##b##c##d##e
#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f
#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g
#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h
#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i
#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j
/** @} */
/** \name Absolute Token Paste
*
* Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
*
* No restriction of use if the tokens are \#defined.
*
* For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined
* as 32 is equivalent to writing U32.
*
* @{ */
#define ATPASTE2( a, b) TPASTE2( a, b)
#define ATPASTE3( a, b, c) TPASTE3( a, b, c)
#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d)
#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e)
#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f)
#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g)
#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h)
#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i)
#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j)
/** @} */
/** @} */
#endif // _TPASTE_H_

View file

@ -0,0 +1,69 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _MONITOR_SAM_BA_H_
#define _MONITOR_SAM_BA_H_
#include <stdint.h>
#define SAM_BA_VERSION "1.1"
/* Selects USART as the communication interface of the monitor */
#define SAM_BA_INTERFACE_USART 1
/* Selects USB as the communication interface of the monitor */
#define SAM_BA_INTERFACE_USBCDC 0
/* Selects USB as the communication interface of the monitor */
#define SIZEBUFMAX 64
/**
* \brief Initialize the monitor
*
*/
void sam_ba_monitor_init(uint8_t com_interface);
/**
* \brief Main function of the SAM-BA Monitor
*
*/
void sam_ba_monitor_run(void);
/**
* \brief
*
*/
void sam_ba_putdata_term(uint8_t *data, uint32_t length);
/**
* \brief
*
*/
void call_applet(uint32_t address);
#endif // _MONITOR_SAM_BA_H_

View file

@ -0,0 +1,107 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef UART_DRIVER_H
#define UART_DRIVER_H
#include "sam.h"
#include <stdbool.h>
#include <stdio.h>
#define PINMUX_UNUSED 0xFFFFFFFF
#define GCLK_ID_SERCOM0_CORE 0x14
/* SERCOM UART available pad settings */
enum uart_pad_settings {
UART_RX_PAD0_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1),
UART_RX_PAD1_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1),
UART_RX_PAD2_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(2),
UART_RX_PAD3_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(3),
UART_RX_PAD1_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(1),
UART_RX_PAD3_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1),
};
/**
* \brief Gets the index of the provided SERCOM instance
*
* \param Pointer to SERCOM instance
* \return Index of the SERCOM module
*/
uint32_t uart_get_sercom_index(Sercom *sercom_instance);
/**
* \brief Initializes the UART
*
* \param Pointer to SERCOM instance
* \param Baud value corresponding to the desired baudrate
* \param SERCOM pad settings
*/
void uart_basic_init(Sercom *sercom, uint16_t baud_val, enum uart_pad_settings pad_conf);
/**
* \brief Disables UART interface
*
* \param Pointer to SERCOM instance
*/
void uart_disable(Sercom *sercom);
/**
* \brief Sends a single byte through UART interface
*
* \param Pointer to SERCOM instance
* \param Data to send
*/
void uart_write_byte(Sercom *sercom, uint8_t data);
/**
* \brief Reads a single character from UART interface
*
* \param Pointer to SERCOM instance
* \return Data byte read
*/
uint8_t uart_read_byte(Sercom *sercom);
/**
* \brief Sends buffer on UART interface
*
* \param Pointer to SERCOM instance
* \param Pointer to data to send
* \param Number of bytes to send
*/
void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length);
/**
* \brief Reads data on UART interface
*
* \param Pointer to SERCOM instance
* \param Pointer to store read data
* \param Number of bytes to read
*/
void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length);
#endif

314
bootloader/inc/uf2.h Normal file
View file

@ -0,0 +1,314 @@
#ifndef UF2_H
#define UF2_H 1
#include <stdint.h>
#include "board_config.h"
#include "sam.h"
#define UF2_DEFINE_HANDOVER 1 // for testing
#include "uf2format.h"
#include "uf2hid.h"
#include "main.h"
#include "cdc_enumerate.h"
#include "sam_ba_monitor.h"
#include "usart_sam_ba.h"
#include <stdio.h>
#include <string.h>
#include "configkeys.h"
#undef DISABLE
#undef ENABLE
// always go for crystalless - smaller and more compatible
#ifndef CRYSTALLESS
#define CRYSTALLESS 1
#endif
#ifndef USB_PID
#define USB_VID 0x03EB // Atmel
#define USB_PID 0x2402 // Generic HID device
#endif
#ifndef INDEX_URL
#define INDEX_URL "https://www.pxt.io/"
#endif
#include "uf2_version.h"
// needs to be more than ~4200 (to force FAT16)
#define NUM_FAT_BLOCKS 16000
// Logging to help debugging
#define USE_LOGS 0
// Check various conditions; best leave on
#define USE_ASSERT 0 // 188 bytes
// Enable reading flash via FAT files; otherwise drive will appear empty
#define USE_FAT 1 // 272 bytes
// Enable index.htm file on the drive
#define USE_INDEX_HTM 1 // 132 bytes
// Enable USB CDC (Communication Device Class; i.e., USB serial) monitor for Arduino style flashing
#define USE_CDC 1 // 1264 bytes (plus terminal, see below)
// Support the UART (real serial port, not USB)
#define USE_UART 0
// Support Human Interface Device (HID) - serial, flashing and debug
#define USE_HID 1 // 788 bytes
// Expose HID via WebUSB
#define USE_WEBUSB 1
// Doesn't yet disable code, just enumeration
#define USE_MSC 1
#ifdef BOARD_SCREEN
#define USE_SCREEN 1
#else
#define USE_SCREEN 0
#endif
// If enabled, bootloader will start on power-on and every reset. A second reset
// will start the app. This only happens if the app says it wants that (see SINGLE_RESET() below).
// If disabled here or by the app, the bootloader will only start with double-click of the reset
// button.
#define USE_SINGLE_RESET 1
// Fine-tuning of features
#define USE_HID_SERIAL 0 // just an example, not really needed; 36 bytes
#define USE_HID_EXT 1 // extended HID commands (read/write mem); 60 bytes
#define USE_HID_HANDOVER 1 // allow HID application->bootloader seamless transition; 56 bytes
#define USE_MSC_HANDOVER 1 // ditto for MSC; 348 bytes
#define USE_MSC_CHECKS 0 // check validity of MSC commands; 460 bytes
#define USE_CDC_TERMINAL 0 // enable ASCII mode on CDC loop (not used by BOSSA); 228 bytes
#define USE_DBG_MSC 0 // output debug info about MSC
#if USE_CDC
#define CDC_VERSION "S"
#else
#define CDC_VERSION ""
#endif
#if USE_LOGS
#define LOGS_VERSION "L"
#else
#define LOGS_VERSION ""
#endif
#if USE_FAT
#define FAT_VERSION "F"
#else
#define FAT_VERSION ""
#endif
#if USE_ASSERT
#define ASSERT_VERSION "A"
#else
#define ASSERT_VERSION ""
#endif
#if USE_HID
#define HID_VERSION "H"
#else
#define HID_VERSION ""
#endif
#if USE_SINGLE_RESET
#define RESET_VERSION "R"
#else
#define RESET_VERSION ""
#endif
#if USE_WEBUSB
#define WEB_VERSION "W"
#else
#define WEB_VERSION ""
#endif
#if USE_MSC_HANDOVER
#define MSC_HANDOVER_VERSION "O"
#else
#define MSC_HANDOVER_VERSION ""
#endif
#define UF2_VERSION \
UF2_VERSION_BASE " " CDC_VERSION LOGS_VERSION FAT_VERSION ASSERT_VERSION HID_VERSION \
WEB_VERSION RESET_VERSION MSC_HANDOVER_VERSION
// End of config
#define USE_MONITOR (USE_CDC || USE_UART)
#ifdef SAMD51
// 51 also runs at 48MHz in bootloader mode, but it's still faster
#define TIMER_STEP 2000
#else
#define TIMER_STEP 1500
#endif
#ifdef BOARD_NEOPIXEL_PIN
#define COLOR_START 0x040000
#define COLOR_USB 0x000400
#define COLOR_UART 0x040400
#define COLOR_LEAVE 0x000000
#else
#define COLOR_START 0x000040
#define COLOR_USB 0x004000
#define COLOR_UART 0x404000
#define COLOR_LEAVE 0x400040
#endif
/*
From CPU config:
#define FLASH_SIZE 0x8000UL
#define FLASH_PAGE_SIZE 64
#define FLASH_NB_OF_PAGES 512
*/
// These two need to be defined as plain decimal numbers, as we're using # on them
#define FLASH_ROW_SIZE 256
#ifndef FLASH_NUM_ROWS
#define FLASH_NUM_ROWS 1024
#endif
#define NOOP \
do { \
} while (0)
#if USE_LOGS
struct LogStore {
int ptr;
char buffer[4096];
};
extern struct LogStore logStoreUF2;
void logmsg(const char *msg);
void logval(const char *lbl, uint32_t v);
void logwritenum(uint32_t n);
void logwrite(const char *msg);
void logreset(void);
#else
#define logmsg(...) NOOP
#define logval(...) NOOP
#define logwritenum(...) NOOP
#define logwrite(...) NOOP
#define logreset() NOOP
#endif
#if USE_DBG_MSC
#define DBG_MSC(x) x
#else
#define DBG_MSC(x) NOOP
#endif
void panic(int code);
#if USE_ASSERT
#define assert(cond) \
if (!(cond)) { \
panic(__LINE__); \
}
#else
#define assert(cond) NOOP
#endif
extern volatile bool b_sam_ba_interface_usart;
void flash_write_row(uint32_t *dst, uint32_t *src);
void flash_erase_to_end(uint32_t *start_address);
void flash_write_words(uint32_t *dst, uint32_t *src, uint32_t n_words);
void copy_words(uint32_t *dst, uint32_t *src, uint32_t n_words);
int writeNum(char *buf, uint32_t n, bool full);
void process_hid(void);
// index of highest LUN
#define MAX_LUN 0
void process_msc(void);
void msc_reset(void);
//! Static block size for all memories
#define UDI_MSC_BLOCK_SIZE 512L
void read_block(uint32_t block_no, uint8_t *data);
#define MAX_BLOCKS (FLASH_SIZE / 256 + 100)
typedef struct {
uint32_t numBlocks;
uint32_t numWritten;
uint8_t writtenMask[MAX_BLOCKS / 8 + 1];
} WriteState;
void write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state);
void padded_memcpy(char *dst, const char *src, int len);
// Last word in RAM
// Unlike for ordinary applications, our link script doesn't place the stack at the bottom
// of the RAM, but instead after all allocated BSS.
// In other words, this word should survive reset.
#ifdef SAMD21
#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))
#endif
#ifdef SAMD51
#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))
#endif
#define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set
#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef
#if USE_SINGLE_RESET
#ifdef SAMD21
#define SINGLE_RESET() (*((uint32_t *)0x20B4) == 0x87eeb07c)
#endif
#ifdef SAMD51
#define SINGLE_RESET() (*((uint32_t *)0x4268) == 0x87eeb07c)
#endif
#endif
void resetIntoApp(void);
void resetIntoBootloader(void);
void system_init(void);
#define LED_TICK led_tick
#define PINOP(pin, OP) (PORT->Group[(pin) / 32].OP.reg = (1 << ((pin) % 32)))
#define PINIP(pin) (((PORT->Group[(pin) / 32].IN.reg) >> ((pin) % 32)) & 0x1)
#define PINCFG(pin) (PORT->Group[(pin) / 32].PINCFG[(pin) % 32].reg)
#define PINMUX(pin) (PORT->Group[(pin) / 32].PMUX[((pin) % 32)/2].reg)
void led_tick(void);
void led_signal(void);
void led_init(void);
void RGBLED_set_color(uint32_t color);
// Not all targets have a LED
#if defined(LED_PIN)
#define LED_MSC_OFF() PINOP(LED_PIN, OUTCLR)
#define LED_MSC_ON() PINOP(LED_PIN, OUTSET)
#define LED_MSC_TGL() PINOP(LED_PIN, OUTTGL)
#else
#define LED_MSC_OFF()
#define LED_MSC_ON()
#define LED_MSC_TGL()
#endif
extern uint32_t timerHigh, resetHorizon;
void timerTick(void);
void delay(uint32_t ms);
void hidHandoverLoop(int ep);
void handoverPrep(void);
#define CONCAT_1(a, b) a##b
#define CONCAT_0(a, b) CONCAT_1(a, b)
#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) }
#ifdef SAMD21
STATIC_ASSERT(FLASH_ROW_SIZE == FLASH_PAGE_SIZE * 4);
STATIC_ASSERT(FLASH_ROW_SIZE == NVMCTRL_ROW_SIZE);
STATIC_ASSERT(FLASH_NUM_ROWS * 4 == FLASH_NB_OF_PAGES);
#endif
extern const char infoUf2File[];
#if USE_SCREEN
void draw_screen(void);
void draw_hf2(void);
void draw_drag(void);
void screen_init(void);
void screen_early_init(void);
#endif
#endif

120
bootloader/inc/uf2format.h Normal file
View file

@ -0,0 +1,120 @@
#ifndef UF2FORMAT_H
#define UF2FORMAT_H 1
#include <stdint.h>
#include <stdbool.h>
// All entries are little endian.
// if you increase that, you will also need to update the linker script file
#ifdef SAMD21
#define APP_START_ADDRESS 0x00002000
#define UF2_FAMILY 0x68ed2b88
#endif
#ifdef SAMD51
#define APP_START_ADDRESS 0x00004000
#define UF2_FAMILY 0x55114460
#endif
#define UF2_MAGIC_START0 0x0A324655UL // "UF2\n"
#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected
#define UF2_MAGIC_END 0x0AB16F30UL // Ditto
// If set, the block is "comment" and should not be flashed to the device
#define UF2_FLAG_NOFLASH 0x00000001
#define UF2_FLAG_FAMILYID_PRESENT 0x00002000
#define UF2_IS_MY_FAMILY(bl) \
(((bl)->flags & UF2_FLAG_FAMILYID_PRESENT) == 0 || (bl)->familyID == UF2_FAMILY)
typedef struct {
// 32 byte header
uint32_t magicStart0;
uint32_t magicStart1;
uint32_t flags;
uint32_t targetAddr;
uint32_t payloadSize;
uint32_t blockNo;
uint32_t numBlocks;
uint32_t familyID;
// raw data;
uint8_t data[476];
// store magic also at the end to limit damage from partial block reads
uint32_t magicEnd;
} UF2_Block;
typedef struct {
uint8_t version;
uint8_t ep_in;
uint8_t ep_out;
uint8_t reserved0;
uint32_t cbw_tag;
uint32_t blocks_remaining;
uint8_t *buffer;
} UF2_HandoverArgs;
typedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);
typedef void (*UF2_HID_Handover_Handler)(int ep);
// this is required to be exactly 16 bytes long by the linker script
typedef struct {
const uint32_t *config_data;
UF2_HID_Handover_Handler handoverHID;
UF2_MSC_Handover_Handler handoverMSC;
const char *info_uf2;
} UF2_BInfo;
#define UF2_BINFO ((UF2_BInfo *)(APP_START_ADDRESS - sizeof(UF2_BInfo)))
static inline bool is_uf2_block(void *data) {
UF2_Block *bl = (UF2_Block *)data;
return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&
bl->magicEnd == UF2_MAGIC_END;
}
static inline bool in_uf2_bootloader_space(const void *addr) {
return 0xb4 <= (uint32_t)addr && (uint32_t)addr < APP_START_ADDRESS;
}
static inline const char *uf2_info(void) {
if (in_uf2_bootloader_space(UF2_BINFO->info_uf2))
return UF2_BINFO->info_uf2;
return "N/A";
}
#ifdef UF2_DEFINE_HANDOVER
static inline void hf2_handover(uint8_t ep) {
const char *board_info = UF2_BINFO->info_uf2;
UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;
if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&
((uint32_t)fn & 1)) {
// Pass control to bootloader; never returns
fn(ep & 0xf);
}
}
// the ep_in/ep_out are without the 0x80 mask
// cbw_tag is in the same bit format as it came
static inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,
uint8_t ep_out, uint32_t cbw_tag) {
if (!is_uf2_block(buffer))
return;
const char *board_info = UF2_BINFO->info_uf2;
UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;
if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&
((uint32_t)fn & 1)) {
UF2_HandoverArgs hand = {
1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,
};
// Pass control to bootloader; never returns
fn(&hand);
}
}
#endif
#endif

107
bootloader/inc/uf2hid.h Normal file
View file

@ -0,0 +1,107 @@
#ifndef UF2_HID_H
#define UF2_HID_H 1
#define HF2_CMD_BININFO 0x0001
// no arguments
#define HF2_MODE_BOOTLOADER 0x01
#define HF2_MODE_USERSPACE 0x02
struct HF2_BININFO_Result {
uint32_t mode;
uint32_t flash_page_size;
uint32_t flash_num_pages;
uint32_t max_message_size;
uint32_t uf2_family;
};
#define HF2_CMD_INFO 0x0002
// no arguments
// results is utf8 character array
#define HF2_CMD_RESET_INTO_APP 0x0003
// no arguments, no result
#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004
// no arguments, no result
#define HF2_CMD_START_FLASH 0x0005
// no arguments, no result
#define HF2_CMD_WRITE_FLASH_PAGE 0x0006
struct HF2_WRITE_FLASH_PAGE_Command {
uint32_t target_addr;
uint32_t data[0];
};
// no result
#define HF2_CMD_CHKSUM_PAGES 0x0007
struct HF2_CHKSUM_PAGES_Command {
uint32_t target_addr;
uint32_t num_pages;
};
struct HF2_CHKSUM_PAGES_Result {
uint16_t chksums[0 /* num_pages */];
};
#define HF2_CMD_READ_WORDS 0x0008
struct HF2_READ_WORDS_Command {
uint32_t target_addr;
uint32_t num_words;
};
struct HF2_READ_WORDS_Result {
uint32_t words[0 /* num_words */];
};
#define HF2_CMD_WRITE_WORDS 0x0009
struct HF2_WRITE_WORDS_Command {
uint32_t target_addr;
uint32_t num_words;
uint32_t words[0 /* num_words */];
};
// no result
#define HF2_CMD_DMESG 0x0010
// no arguments
// results is utf8 character array
typedef struct {
uint32_t command_id;
uint16_t tag;
uint8_t reserved0;
uint8_t reserved1;
union {
struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;
struct HF2_WRITE_WORDS_Command write_words;
struct HF2_READ_WORDS_Command read_words;
struct HF2_CHKSUM_PAGES_Command chksum_pages;
};
} HF2_Command;
typedef struct {
uint16_t tag;
union {
struct {
uint8_t status;
uint8_t status_info;
};
uint16_t status16;
};
union {
struct HF2_BININFO_Result bininfo;
uint8_t data8[0];
uint16_t data16[0];
uint32_t data32[0];
};
} HF2_Response;
#define HF2_FLAG_SERIAL_OUT 0x80
#define HF2_FLAG_SERIAL_ERR 0xC0
#define HF2_FLAG_CMDPKT_LAST 0x40
#define HF2_FLAG_CMDPKT_BODY 0x00
#define HF2_FLAG_MASK 0xC0
#define HF2_SIZE_MASK 63
#define HF2_STATUS_OK 0x00
#define HF2_STATUS_INVALID_CMD 0x01
#endif

View file

@ -0,0 +1,158 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011-2014, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _USART_SAM_BA_H_
#define _USART_SAM_BA_H_
#include "stdbool.h"
#include "stdint.h"
/* USART buffer size (must be a power of two) */
#define USART_BUFFER_SIZE 128
/* Define the default time-out value for USART. */
#define USART_DEFAULT_TIMEOUT 1000
/* Xmodem related defines */
/* CRC16 polynomial */
#define CRC16POLY 0x1021
#define SHARP_CHARACTER '#'
/* X/Ymodem protocol: */
#define SOH 0x01
//#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define ESC 0x1b
#define PKTLEN_128 128
/**
* \brief Open the given USART
*/
void usart_open(void);
/**
* \brief Stops the USART
*/
void usart_close(void);
/**
* \brief Puts a byte on usart line
*
* \param value Value to put
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
int usart_putc(int value);
/**
* \brief Waits and gets a value on usart line
*
* \return value read on usart line
*/
int usart_getc(void);
/**
* \brief Returns true if the SAM-BA Uart received the sharp char
*
* \return Returns true if the SAM-BA Uart received the sharp char
*/
int usart_sharp_received(void);
/**
* \brief This function checks if a character has been received on the usart
* line
*
* \return \c 1 if a byte is ready to be read.
*/
bool usart_is_rx_ready(void);
/**
* \brief Gets a value on usart line
*
* \return value read on usart line
*/
int usart_readc(void);
/**
* \brief Send buffer on usart line
*
* \param data pointer
* \param number of data to send
* \return number of data sent
*/
uint32_t usart_putdata(void const *data, uint32_t length); // Send given data (polling)
/**
* \brief Gets data from usart line
*
* \param data pointer
* \param number of data to get
* \return value read on usart line
*/
uint32_t usart_getdata(void *data, uint32_t length); // Get data from comm. device
/**
* \brief Send buffer on usart line using Xmodem protocol
*
* \param data pointer
* \param number of data to send
* \return number of data sent
*/
uint32_t
usart_putdata_xmd(void const *data,
uint32_t length); // Send given data (polling) using xmodem (if necessary)
/**
* \brief Gets data from usart line using Xmodem protocol
*
* \param data pointer
* \param number of data to get
* \return value read on usart line
*/
uint32_t
usart_getdata_xmd(void *data,
uint32_t length); // Get data from comm. device using xmodem (if necessary)
/**
* \brief Gets data from usart line using Xmodem protocol
*
* \param data pointer
* \param number of data to get
* \return value read on usart line
*/
uint16_t add_crc(uint8_t ch, unsigned short crc0);
uint8_t getPacket(uint8_t *pData, uint8_t sno);
#endif // _USART_SAM_BA_H_