diff --git a/hardware/arduino/avr/libraries/SPI/SPI.h b/hardware/arduino/avr/libraries/SPI/SPI.h index 5206a091843..a339fd34330 100644 --- a/hardware/arduino/avr/libraries/SPI/SPI.h +++ b/hardware/arduino/avr/libraries/SPI/SPI.h @@ -3,6 +3,7 @@ * Copyright (c) 2014 by Paul Stoffregen (Transaction API) * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) + * Copyright (c) 2016 by Pedro M. Ribeiro (transfer_out) * SPI Master library for arduino. * * This file is free software; you can redistribute it and/or modify @@ -255,6 +256,25 @@ class SPIClass { while (!(SPSR & _BV(SPIF))) ; *p = SPDR; } + /* + * An alternative "output only" transfer that doesn't destroy the + * contents of the source buffer with the bytes returned from the + * slave device. + * Some code simplifications and const enforcement + * Revision with speedup of about 25% in atmega328p tests + * NOTE: I can't explain that "*(p++ + 1);" being speedier than "*++p" + */ + inline static void transfer_out(const void *buf, size_t count) { + if (count == 0) return; + const uint8_t *p = (uint8_t *)buf; + SPDR = *p; + while (--count > 0) { + uint8_t out = *(p++ + 1); // ugly but somehow results in a speedup! + while (!(SPSR & _BV(SPIF))) ; // last SPI transfer is over? + SPDR = out; + } + while (!(SPSR & _BV(SPIF))) ; // last SPI transfer is over? + } // After performing a group of transfers and releasing the chip select // signal, this function allows others to access the SPI bus inline static void endTransaction(void) { diff --git a/hardware/arduino/sam/libraries/SPI/SPI.h b/hardware/arduino/sam/libraries/SPI/SPI.h index ef5b5141a52..b8168ef5354 100644 --- a/hardware/arduino/sam/libraries/SPI/SPI.h +++ b/hardware/arduino/sam/libraries/SPI/SPI.h @@ -85,13 +85,13 @@ class SPIClass { uint16_t transfer16(byte _pin, uint16_t _data, SPITransferMode _mode = SPI_LAST); void transfer(byte _pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST); // Transfer functions on default pin BOARD_SPI_DEFAULT_SS - byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); } - uint16_t transfer16(uint16_t _data, SPITransferMode _mode = SPI_LAST) { return transfer16(BOARD_SPI_DEFAULT_SS, _data, _mode); } - void transfer(void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST) { transfer(BOARD_SPI_DEFAULT_SS, _buf, _count, _mode); } + inline byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); } + inline uint16_t transfer16(uint16_t _data, SPITransferMode _mode = SPI_LAST) { return transfer16(BOARD_SPI_DEFAULT_SS, _data, _mode); } + inline void transfer(void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST) { transfer(BOARD_SPI_DEFAULT_SS, _buf, _count, _mode); } // Transaction Functions void usingInterrupt(uint8_t interruptNumber); - void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } + inline void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } void beginTransaction(uint8_t pin, SPISettings settings); void endTransaction(void); @@ -112,9 +112,9 @@ class SPIClass { void setClockDivider(uint8_t _pin, uint8_t); // These methods sets the same parameters but on default pin BOARD_SPI_DEFAULT_SS - void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); }; - void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); }; - void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); }; + inline void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); }; + inline void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); }; + inline void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); }; private: void init(); diff --git a/hardware/arduino/sam/platform.txt b/hardware/arduino/sam/platform.txt index 9a7f52d0a7f..e8062501f85 100644 --- a/hardware/arduino/sam/platform.txt +++ b/hardware/arduino/sam/platform.txt @@ -97,7 +97,8 @@ tools.bossac.path={runtime.tools.bossac.path} tools.bossac.cmd=bossac tools.bossac.cmd.windows=bossac.exe -tools.bossac.upload.params.verbose=-i -d +#tools.bossac.upload.params.verbose=-i -d +tools.bossac.upload.params.verbose=-i tools.bossac.upload.params.quiet= tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -e -w -v -b "{build.path}/{build.project_name}.bin" -R