From c0964e8f038cf05b636664b526996b6f7711e269 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 13 Feb 2016 13:43:57 +0000 Subject: [PATCH 1/5] Update SPI.h - Add transfer_out An alternative "output only" transfer that doesn't destroy the source buffer with the bytes returned from the slave device. Some code simplifications and const enforcement of input variables Tested in ATMEGA328p (UNO) * no speed changes noticed (comparing the the original function) * writing/reading to an SPI RAM returns the correct values --- hardware/arduino/avr/libraries/SPI/SPI.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hardware/arduino/avr/libraries/SPI/SPI.h b/hardware/arduino/avr/libraries/SPI/SPI.h index 5206a091843..a4ced430f58 100644 --- a/hardware/arduino/avr/libraries/SPI/SPI.h +++ b/hardware/arduino/avr/libraries/SPI/SPI.h @@ -255,6 +255,21 @@ 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 + * by Pedro Ribeiro pamribeirox@gmail.com + */ + inline static void transfer_out(const void *buf, size_t count) { + if (count == 0) return; + uint8_t *p = (uint8_t *)buf; + while (count-- > 0) { + SPDR = *p++; + while (!(SPSR & _BV(SPIF))) ; + } + } // 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) { From ab231017de1d16a66822b77cb4e00fc10870b5c5 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Mon, 15 Feb 2016 12:29:29 +0000 Subject: [PATCH 2/5] Update SPI.h - Optimization of transfer_out 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" --- hardware/arduino/avr/libraries/SPI/SPI.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hardware/arduino/avr/libraries/SPI/SPI.h b/hardware/arduino/avr/libraries/SPI/SPI.h index a4ced430f58..384d43d6c06 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 @@ -260,15 +261,19 @@ class SPIClass { * contents of the source buffer with the bytes returned from the * slave device. * Some code simplifications and const enforcement - * by Pedro Ribeiro pamribeirox@gmail.com - */ + * 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; uint8_t *p = (uint8_t *)buf; - while (count-- > 0) { - SPDR = *p++; - while (!(SPSR & _BV(SPIF))) ; + 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 From 7223c48fa87e8c489b4a61f1251ab6f4567ef3af Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Mon, 15 Feb 2016 14:12:46 +0000 Subject: [PATCH 3/5] Update SPI.h - keep pointer to const Near cosmetic change, in the cast, keep the pointer to const values --- hardware/arduino/avr/libraries/SPI/SPI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/arduino/avr/libraries/SPI/SPI.h b/hardware/arduino/avr/libraries/SPI/SPI.h index 384d43d6c06..a339fd34330 100644 --- a/hardware/arduino/avr/libraries/SPI/SPI.h +++ b/hardware/arduino/avr/libraries/SPI/SPI.h @@ -266,7 +266,7 @@ class SPIClass { */ inline static void transfer_out(const void *buf, size_t count) { if (count == 0) return; - uint8_t *p = (uint8_t *)buf; + const uint8_t *p = (uint8_t *)buf; SPDR = *p; while (--count > 0) { uint8_t out = *(p++ + 1); // ugly but somehow results in a speedup! From 8026e56640318d6d07a036e796bea94cc9a65f12 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Mon, 15 Feb 2016 16:01:15 +0000 Subject: [PATCH 4/5] Update SPI.h - avoid double calls Avoid double calls in several methods by changing them to inline --- hardware/arduino/sam/libraries/SPI/SPI.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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(); From 361bd0ae79f061114a18368f5d109c4f65877bfb Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Mon, 15 Feb 2016 16:43:13 +0000 Subject: [PATCH 5/5] Update platform.h disable bossac debug When verbose output is enabled, bossac was run in debug mode, changed to only extra info (-i) --- hardware/arduino/sam/platform.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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