Skip to content

Commit 5f36ae4

Browse files
committed
Add MKR Motor Carrier variant
IMPORTANT: lto build is needed to fit both production bootloader and production firmware in 16KB; at the moment 7-2017q4 toolchain is unable to produce a proper build, so use the system gcc toolchain (on Arch Linux) Marking the vector section as used allows us to use lto also on c files. Necessary to compile the bootloader safely (we could also add a checksum strategy)
1 parent 95d08de commit 5f36ae4

File tree

19 files changed

+1375
-35
lines changed

19 files changed

+1375
-35
lines changed

boards.txt

+52
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ menu.clock=Clock Source
1919
menu.usb=USB Config
2020
menu.serial=Serial Config
2121
menu.bootloader=Bootloader Size
22+
menu.lto=Link time optimization
23+
menu.pinmap=Pinmap
2224

2325

2426
# MattairTech Xeno
@@ -748,6 +750,10 @@ d11d14as.menu.serial.one_uart=ONE_UART_ONE_WIRE_ONE_SPI
748750
d11d14as.menu.serial.one_uart.build.serialcom_uart=ONE_UART
749751
d11d14as.menu.serial.one_uart.build.serialcom_wire=ONE_WIRE
750752
d11d14as.menu.serial.one_uart.build.serialcom_spi=ONE_SPI
753+
d11d14as.menu.serial.one_uart_no_spi=ONE_UART_ONE_WIRE_NO_SPI
754+
d11d14as.menu.serial.one_uart_no_spi.build.serialcom_uart=ONE_UART
755+
d11d14as.menu.serial.one_uart_no_spi.build.serialcom_wire=ONE_WIRE
756+
d11d14as.menu.serial.one_uart_no_spi.build.serialcom_spi=NO_SPI
751757
d11d14as.menu.serial.no_uart=NO_UART_ONE_WIRE_ONE_SPI
752758
d11d14as.menu.serial.no_uart.build.serialcom_uart=NO_UART
753759
d11d14as.menu.serial.no_uart.build.serialcom_wire=ONE_WIRE
@@ -775,6 +781,52 @@ d11d14as.menu.usb.none=USB_DISABLED
775781
d11d14as.menu.usb.none.build.usbcom=USB_DISABLED
776782
d11d14as.menu.usb.none.build.pid=0x0856
777783

784+
# MKR Motor Shield
785+
mkrmotorshield.name=MKR Motor Shield
786+
mkrmotorshield.vid.0=0x2341
787+
mkrmotorshield.pid.0=0x1337
788+
mkrmotorshield.build.mcu=cortex-m0plus
789+
mkrmotorshield.build.f_cpu=48000000L
790+
mkrmotorshield.build.usb_product="MKRMOTOR"
791+
mkrmotorshield.build.usb_manufacturer="Arduino LLC"
792+
mkrmotorshield.build.board=SAMD_ZERO
793+
mkrmotorshield.build.core=arduino
794+
mkrmotorshield.build.variant=MKRMotorShield
795+
mkrmotorshield.build.variant_system_lib=
796+
mkrmotorshield.build.vid=0x2341
797+
mkrmotorshield.build.pid=0x1337
798+
mkrmotorshield.upload.protocol=sam-ba
799+
mkrmotorshield.bootloader.tool=arduino:openocd
800+
mkrmotorshield.build.clockconfig=CLOCKCONFIG_INTERNAL
801+
mkrmotorshield.build.extra_flags=-D__SAMD11D14AS__ {build.usb_flags} {build.pinmap} {build.lto}
802+
mkrmotorshield.build.ldscript=flash_16KB.ld
803+
mkrmotorshield.build.openocdscript=openocd_scripts/SAMD11D14AS.cfg
804+
mkrmotorshield.bootloader.file=zero/binaries/sam_ba_Generic_D11D14AS_SAMD11D14AS.bin
805+
mkrmotorshield.menu.bootloader.4kb=4KB bootloader
806+
mkrmotorshield.menu.bootloader.4kb.build.bootloader_size=__4KB_BOOTLOADER__
807+
mkrmotorshield.menu.bootloader.4kb.build.ldscript_path=linker_scripts/gcc/4KB_Bootloader
808+
mkrmotorshield.menu.bootloader.4kb.upload.maximum_size=12288
809+
mkrmotorshield.menu.bootloader.0kb=No bootloader
810+
mkrmotorshield.menu.bootloader.0kb.build.bootloader_size=__NO_BOOTLOADER__
811+
mkrmotorshield.menu.bootloader.0kb.build.ldscript_path=linker_scripts/gcc/No_Bootloader
812+
mkrmotorshield.menu.bootloader.0kb.upload.maximum_size=16384
813+
mkrmotorshield.menu.pinmap.complete=Complete
814+
mkrmotorshield.menu.pinmap.complete.build.pinmap=
815+
mkrmotorshield.menu.pinmap.minimal=Minimal (bootloader)
816+
mkrmotorshield.menu.pinmap.minimal.build.pinmap=-DPIN_MAP_SUPER_COMPACT
817+
mkrmotorshield.menu.lto.enabled=Enabled
818+
mkrmotorshield.menu.lto.enabled.build.lto=-flto
819+
mkrmotorshield.menu.lto.disabled=Disabled
820+
mkrmotorshield.menu.lto.disabled.build.lto=
821+
mkrmotorshield.upload.tool=arduino:openocd
822+
mkrmotorshield.upload.use_1200bps_touch=false
823+
mkrmotorshield.upload.wait_for_upload_port=false
824+
mkrmotorshield.upload.native_usb=false
825+
mkrmotorshield.build.serialcom_uart=NO_UART
826+
mkrmotorshield.build.serialcom_wire=ONE_WIRE
827+
mkrmotorshield.build.serialcom_spi=NO_SPI
828+
mkrmotorshield.serialcom_spi=NO_SPI
829+
mkrmotorshield.build.usbcom=USB_DISABLED
778830

779831
# MattairTech Core for Arduino/Genuino Zero (Autodetect Port)
780832
arduino_zero.name=Arduino/Genuino Zero (Autodetect Port)

cores/arduino/RingBuffer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
// using a ring buffer (I think), in which head is the index of the location
2626
// to which to write the next incoming character and tail is the index of the
2727
// location from which to read.
28-
#define SERIAL_BUFFER_SIZE 64
28+
#define SERIAL_BUFFER_SIZE 68
2929

3030
class RingBuffer
3131
{

cores/arduino/WVariant.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern "C" {
3030
/* Definitions and types for pins */
3131
typedef enum _EAnalogChannel
3232
{
33-
No_ADC_Channel=-1,
33+
No_ADC_Channel=0xFF,
3434
ADC_Channel0=0,
3535
ADC_Channel1=1,
3636
ADC_Channel2=2,
@@ -59,7 +59,7 @@ typedef enum _EAnalogChannel
5959
// RESERVED (1 bit, used for negative) | Timer Number (3 bits: 0-7) | Timer Type (1 bit: 0=TCC, 1=TC) | Timer Channel (3 bits: 0-7)
6060
typedef enum _ETCChannel
6161
{
62-
NOT_ON_TIMER=-1,
62+
NOT_ON_TIMER=0xFF,
6363
TCC0_CH0 = (0<<4)|(0<<3)|(0),
6464
TCC0_CH1 = (0<<4)|(0<<3)|(1),
6565
TCC0_CH2 = (0<<4)|(0<<3)|(2),
@@ -111,12 +111,12 @@ extern const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM] ;
111111
// RESERVED (1 bit, used for negative) | GCLK (3 bits: 0-7) | CCL (4 bits: 2 for CCL number, 2 for pin)
112112
typedef enum _EGCLK_CCL
113113
{
114-
GCLK_CCL_NONE=-1,
114+
GCLK_CCL_NONE=0xFF,
115115
} EGCLK_CCL ;
116116

117117
typedef enum _EPortType
118118
{
119-
NOT_A_PORT=-1,
119+
NOT_A_PORT=0xFF,
120120
PORTA=0,
121121
PORTB=1,
122122
PORTC=2,
@@ -142,7 +142,7 @@ typedef enum
142142
EXTERNAL_INT_15,
143143
EXTERNAL_INT_NMI,
144144
EXTERNAL_NUM_INTERRUPTS,
145-
NOT_AN_INTERRUPT = -1,
145+
NOT_AN_INTERRUPT = 0xFF,
146146
EXTERNAL_INT_NONE = NOT_AN_INTERRUPT,
147147
} EExt_Interrupts ;
148148

@@ -154,7 +154,7 @@ typedef enum
154154
#define INPUT_PULLDOWN (0x3)
155155
typedef enum _EPioType
156156
{
157-
PIO_NOT_A_PIN=-1, /* Not under control of a peripheral. */
157+
PIO_NOT_A_PIN=0xFF, /* Not under control of a peripheral. */
158158

159159
PIO_INPUT=INPUT, /* The pin is controlled by PORT and is an input. */
160160
PIO_OUTPUT=OUTPUT, /* The pin is controlled by PORT and is an output. */
@@ -219,7 +219,7 @@ typedef enum _EPioType
219219
//EIC REF ADC AC PTC DAC SERCOM SERCOM_ALT TC/TCC TCC COM AC/GCLK CCL
220220
typedef enum _EPioPeripheral
221221
{
222-
PER_PORT=-1, /* The pin is controlled by PORT. */
222+
PER_PORT=0xFF, /* The pin is controlled by PORT. */
223223
PER_EXTINT=0, /* The pin is controlled by the associated signal of peripheral A. */
224224
PER_ANALOG=1, /* The pin is controlled by the associated signal of peripheral B. */
225225
PER_SERCOM=2, /* The pin is controlled by the associated signal of peripheral C. */

cores/arduino/cortex_handlers.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ extern uint32_t __bss_end__;
9494
extern uint32_t __StackTop;
9595

9696
/* Exception Table */
97-
__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
97+
__attribute__ ((used,section(".isr_vector"))) const DeviceVectors exception_table =
9898
{
9999
/* Configure Initial Stack Pointer, using linker-generated symbols */
100100
(void*) (&__StackTop),

cores/arduino/wiring_analog.c

+21-9
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ static void syncTC_16(Tc* TCx) {
9696
#endif
9797
}
9898

99+
// Wait for synchronization of registers between the clock domains
100+
static __inline__ void syncTC_8(Tc* TCx) __attribute__((always_inline, unused));
101+
static void syncTC_8(Tc* TCx) {
102+
while (TCx->COUNT8.STATUS.bit.SYNCBUSY);
103+
}
104+
99105
// Wait for synchronization of registers between the clock domains
100106
static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
101107
static void syncTCC(Tcc* TCCx) {
@@ -275,12 +281,15 @@ uint32_t analogRead( uint32_t pin )
275281
return mapResolution(valueRead, _ADCResolution, _readResolution);
276282
}
277283

284+
void analogWrite(uint32_t pin, uint32_t value) {
285+
analogWritePeriod(pin, value, 0xFFFF);
286+
}
278287

279288
// Right now, PWM output only works on the pins with
280289
// hardware support. These are defined in the appropriate
281290
// pins_*.c file. For the rest of the pins, we default
282291
// to digital output.
283-
void analogWrite(uint32_t pin, uint32_t value)
292+
void analogWritePeriod(uint32_t pin, uint32_t value, uint32_t period)
284293
{
285294
if ( pinPeripheral(pin, PIO_ANALOG_DAC) == RET_STATUS_OK )
286295
{
@@ -370,12 +379,13 @@ void analogWrite(uint32_t pin, uint32_t value)
370379
// Set PORT
371380
if ( TCx )
372381
{
382+
373383
// -- Configure TC
374384
// Disable TCx
375385
TCx->COUNT16.CTRLA.bit.ENABLE = 0;
376386
syncTC_16(TCx);
377387
// Set Timer counter Mode to 16 bits, normal PWM
378-
TCx->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
388+
TCx->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCSYNC_RESYNC;
379389
syncTC_16(TCx);
380390
// Set TCx as normal PWM
381391
#if (SAMD)
@@ -395,14 +405,16 @@ void analogWrite(uint32_t pin, uint32_t value)
395405
// Disable TCCx
396406
TCCx->CTRLA.bit.ENABLE = 0;
397407
syncTCC(TCCx);
408+
TCCx->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV16;
409+
syncTCC(TCCx);
398410
// Set TCCx as normal PWM
399411
TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
400412
syncTCC(TCCx);
401413
// Set the initial value
402414
TCCx->CC[Channelx].reg = (uint32_t)value;
403415
syncTCC(TCCx);
404416
// Set PER to maximum counter value (resolution : 0xFFFF)
405-
TCCx->PER.reg = 0xFFFF;
417+
TCCx->PER.reg = (uint16_t)period;
406418
syncTCC(TCCx);
407419
// Enable TCCx
408420
TCCx->CTRLA.bit.ENABLE = 1;
@@ -421,13 +433,13 @@ void analogWrite(uint32_t pin, uint32_t value)
421433
#if (SAMD)
422434
TCCx->CTRLBSET.bit.LUPD = 1;
423435
syncTCC(TCCx);
424-
TCCx->CCB[Channelx].reg = (uint32_t) value;
425-
syncTCC(TCCx);
426-
TCCx->CTRLBCLR.bit.LUPD = 1;
427-
// LUPD caused endless spinning in syncTCC() on SAML (and probably SAMC). Note that CCBUF writes are already
428-
// atomic. The LUPD bit is intended for updating several registers at once, which analogWrite() does not do.
436+
TCCx->CCB[Channelx].reg = (uint32_t) value;
437+
syncTCC(TCCx);
438+
TCCx->CTRLBCLR.bit.LUPD = 1;
439+
// LUPD caused endless spinning in syncTCC() on SAML (and probably SAMC). Note that CCBUF writes are already
440+
// atomic. The LUPD bit is intended for updating several registers at once, which analogWrite() does not do.
429441
#elif (SAML21 || SAMC21)
430-
TCCx->CCBUF[Channelx].reg = (uint32_t) value;
442+
TCCx->CCBUF[Channelx].reg = (uint32_t) value;
431443
#endif
432444
syncTCC(TCCx);
433445
}

cores/arduino/wiring_analog.h

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ extern void analogReference( eAnalogReference ulMode ) ;
9595
*/
9696
extern void analogWrite( uint32_t ulPin, uint32_t ulValue ) ;
9797

98+
extern void analogWritePeriod(uint32_t pin, uint32_t value, uint32_t period) ;
99+
98100
/*
99101
* \brief Reads the value from the specified analog pin.
100102
*

cores/arduino/wiring_private.c

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ int pinPeripheral( uint32_t ulPin, uint32_t ulPeripheral )
140140
uint8_t pinNum = g_APinDescription[ulPin].ulPin;
141141
uint8_t pinCfg = PORT_PINCFG_INEN; // INEN should be enabled for both input and output (but not analog)
142142

143+
#if !defined PIN_MAP_SUPER_COMPACT
143144
// Disable DAC, if analogWrite() used previously the DAC is enabled
144145
// Note that on the L21, the DAC output would interfere with other peripherals if left enabled, even if the anaolog peripheral is not selected
145146
if ((pinAttribute & PIN_ATTR_DAC) && !((1UL << ulPeripheral) & PIN_ATTR_DAC))
@@ -179,6 +180,7 @@ int pinPeripheral( uint32_t ulPin, uint32_t ulPeripheral )
179180
}
180181
#endif
181182
}
183+
#endif
182184

183185
noInterrupts(); // Avoid possible invalid interim pin state
184186

libraries/SPI/SPI.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ int SPIClass::beginSlave()
7171
init();
7272

7373
// PIO init
74-
pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
75-
pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
76-
pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
77-
pinPeripheral(_uc_pinSS, g_APinDescription[_uc_pinSS].ulPinType);
74+
pinPeripheral(_uc_pinMiso, PIO_SERCOM);
75+
pinPeripheral(_uc_pinSCK, PIO_SERCOM);
76+
pinPeripheral(_uc_pinMosi, PIO_SERCOM);
77+
pinPeripheral(_uc_pinSS, PIO_SERCOM);
7878

7979
config(SPI_SLAVE_OPERATION, DEFAULT_SPI_SETTINGS);
8080

libraries/Wire/Wire.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ class TwoWire : public Stream
5656
void onReceive(void(*)(int));
5757
void onRequest(void(*)(void));
5858

59-
inline size_t write(unsigned long n) { return write((uint8_t)n); }
60-
inline size_t write(long n) { return write((uint8_t)n); }
61-
inline size_t write(unsigned int n) { return write((uint8_t)n); }
62-
inline size_t write(int n) { return write((uint8_t)n); }
59+
inline size_t write(uint16_t n) { return write((const uint8_t *)&n, sizeof(uint16_t)); }
60+
inline size_t write(unsigned long n) { return write((const uint8_t *)&n, sizeof(unsigned long)); }
61+
inline size_t write(long n) { return write((const uint8_t *)&n, sizeof(long)); }
62+
inline size_t write(unsigned int n) { return write((const uint8_t *)&n, sizeof(unsigned int)); }
63+
inline size_t write(int n) { return write((const uint8_t *)&n, sizeof(int)); }
6364
using Print::write;
6465

6566
void onService(void);

platform.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ compiler.warning_flags.more=-Wall
3232
compiler.warning_flags.all=-Wall -Wextra
3333

3434
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
35+
#compiler.path=/bin/
3536
compiler.c.cmd=arm-none-eabi-gcc
3637
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD
3738
compiler.c.elf.cmd=arm-none-eabi-gcc
@@ -58,11 +59,11 @@ compiler.readelf.cmd=arm-none-eabi-readelf
5859
build.extra_flags=
5960

6061
# These can be overridden in platform.local.txt
61-
compiler.c.extra_flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.0.0-mattairtech-2.path}/CMSIS/Device/ATMEL/" -D{build.clockconfig} -D{build.usbcom} -D{build.serialcom_uart} -D{build.serialcom_wire} -D{build.serialcom_spi} -D{build.bootloader_size}
62+
compiler.c.extra_flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.0.0-mattairtech-1.path}/CMSIS/Device/ATMEL/" -D{build.clockconfig} -D{build.usbcom} -D{build.serialcom_uart} -D{build.serialcom_wire} -D{build.serialcom_spi} -D{build.bootloader_size}
6263
compiler.c.elf.extra_flags=
6364
#compiler.c.elf.extra_flags=-v
64-
compiler.cpp.extra_flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.0.0-mattairtech-2.path}/CMSIS/Device/ATMEL/" -D{build.clockconfig} -D{build.usbcom} -D{build.serialcom_uart} -D{build.serialcom_wire} -D{build.serialcom_spi} -D{build.bootloader_size}
65-
compiler.S.extra_flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.0.0-mattairtech-2.path}/CMSIS/Device/ATMEL/" -D{build.clockconfig} -D{build.usbcom} -D{build.serialcom_uart} -D{build.serialcom_wire} -D{build.serialcom_spi} -D{build.bootloader_size}
65+
compiler.cpp.extra_flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.0.0-mattairtech-1.path}/CMSIS/Device/ATMEL/" -D{build.clockconfig} -D{build.usbcom} -D{build.serialcom_uart} -D{build.serialcom_wire} -D{build.serialcom_spi} -D{build.bootloader_size}
66+
compiler.S.extra_flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.0.0-mattairtech-1.path}/CMSIS/Device/ATMEL/" -D{build.clockconfig} -D{build.usbcom} -D{build.serialcom_uart} -D{build.serialcom_wire} -D{build.serialcom_spi} -D{build.bootloader_size}
6667
compiler.ar.extra_flags=
6768
compiler.elf2hex.extra_flags=
6869

variants/Generic_D11D14AS/variant.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,20 @@ SERCOM sercom0( SERCOM0 ) ;
9696
SERCOM sercom1( SERCOM1 ) ;
9797
SERCOM sercom2( SERCOM2 ) ;
9898

99-
#if defined(ONE_UART) || defined(TWO_UART)
100-
Uart Serial1( SERCOM_INSTANCE_SERIAL1, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ;
99+
#if defined(TWO_UART)
100+
Uart Serial2( SERCOM_INSTANCE_SERIAL1, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ;
101101

102102
void SERCOM1_Handler()
103103
{
104-
Serial1.IrqHandler();
104+
Serial2.IrqHandler();
105105
}
106106
#endif
107107

108-
#if defined(TWO_UART)
109-
Uart Serial2( SERCOM_INSTANCE_SERIAL2, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ) ;
108+
#if defined(ONE_UART) || defined(TWO_UART)
109+
Uart Serial1( SERCOM_INSTANCE_SERIAL2, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ) ;
110110

111111
void SERCOM0_Handler()
112112
{
113-
Serial2.IrqHandler();
113+
Serial1.IrqHandler();
114114
}
115115
#endif

0 commit comments

Comments
 (0)