From 3cd7251ac131322373287f6d892c7b26b1b01973 Mon Sep 17 00:00:00 2001 From: RFduino Date: Mon, 6 Jan 2014 12:18:25 -0700 Subject: [PATCH 01/52] added getDeviceId() --- CHANGELOG | 4 ++++ .../examples/DeviceInfo/DeviceInfo.ino | 11 +++++++++++ variants/RFduino/variant.cpp | 15 +++++++++++++++ variants/RFduino/variant.h | 5 +++++ 4 files changed, 35 insertions(+) create mode 100644 libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino mode change 100755 => 100644 variants/RFduino/variant.cpp mode change 100755 => 100644 variants/RFduino/variant.h diff --git a/CHANGELOG b/CHANGELOG index b8b7d64..896da6f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 1.6 + - Added getDeviceId() to return the unique id for each device + (see DeviceInfo sketch) + v 1.5.1 - Added support for OSX (contributed by nitsky) - RFDLoader now supports 32-bit and 64-bit osx snow leopard through mavericks diff --git a/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino b/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino new file mode 100644 index 0000000..c3c9aa2 --- /dev/null +++ b/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino @@ -0,0 +1,11 @@ +void setup() { + Serial.begin(57600); + + Serial.println("The device id is:"); + uint64_t id = getDeviceId(); + Serial.println(getDeviceIdLow(), HEX); + Serial.println(getDeviceIdHigh(), HEX); +} + +void loop() { +} diff --git a/variants/RFduino/variant.cpp b/variants/RFduino/variant.cpp old mode 100755 new mode 100644 index 430bd04..1e3f3bb --- a/variants/RFduino/variant.cpp +++ b/variants/RFduino/variant.cpp @@ -260,6 +260,21 @@ uint8_t UART0_RX() return uc_data; } +uint32_t getDeviceIdLow() +{ + return NRF_FICR->DEVICEID[0]; +} + +uint32_t getDeviceIdHigh() +{ + return NRF_FICR->DEVICEID[1]; +} + +uint64_t getDeviceId() +{ + return ((uint64_t)getDeviceIdHigh() << 32) | getDeviceIdLow(); +} + #ifdef __cplusplus } #endif diff --git a/variants/RFduino/variant.h b/variants/RFduino/variant.h old mode 100755 new mode 100644 index f87866d..343e9f3 --- a/variants/RFduino/variant.h +++ b/variants/RFduino/variant.h @@ -166,6 +166,11 @@ uint8_t UART0_RX(); #include "Memory.h" +// unique id for each unit +uint32_t getDeviceIdLow(); +uint32_t getDeviceIdHigh(); +uint64_t getDeviceId(); + #ifdef __cplusplus } #endif From 569f5a9394455a5501be4191e4c28e2124d4a0a8 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 7 Jan 2014 12:11:33 -0700 Subject: [PATCH 02/52] fixes for pinWakeCallback, incorrect return types for rfduino_ calls, and max sketch size --- CHANGELOG | 6 ++++++ boards.txt | 4 ++-- variants/RFduino/libRFduino.a | Bin 8018 -> 8504 bytes variants/RFduino/libRFduino.h | 10 ++++++---- .../RFduino/linker_scripts/gcc/RFduino.ld | 2 +- 5 files changed, 15 insertions(+), 7 deletions(-) mode change 100755 => 100644 boards.txt mode change 100755 => 100644 variants/RFduino/libRFduino.a mode change 100755 => 100644 variants/RFduino/libRFduino.h mode change 100755 => 100644 variants/RFduino/linker_scripts/gcc/RFduino.ld diff --git a/CHANGELOG b/CHANGELOG index 896da6f..fd6f3c4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ CHANGELOG +v 1.6.1 + - Fixed issue with not being able to call RFduinoBLE.end() / + RFduino_systemReset() from pinWakeCallback + - corrected return types from uint32_t to void for rfduino_ functions + - Corrected maximum sketch size. The last 4 flash pages are reserved, + v 1.6 - Added getDeviceId() to return the unique id for each device (see DeviceInfo sketch) diff --git a/boards.txt b/boards.txt old mode 100755 new mode 100644 index 8161997..c3df3fc --- a/boards.txt +++ b/boards.txt @@ -18,5 +18,5 @@ RFduino.upload.tool=RFDLoader RFduino.upload.protocol= # sizer will not run if this is not defined -# 132KB -RFduino.upload.maximum_size=135168 +# 128KB +RFduino.upload.maximum_size=131072 diff --git a/variants/RFduino/libRFduino.a b/variants/RFduino/libRFduino.a old mode 100755 new mode 100644 index 035c65c3ed3d64918869a4336b98588f4cc2cef9..7270b1e689839d552fe8bb70ee2f411619668402 GIT binary patch literal 8504 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 literal 8018 zcmbtZeQaCR6+h3zrY2C?Km#>nlEgp z9|DP#Rim&@OMz`k166_kfiyN1MkFLwD0GuxlbBto6bREi24h1T%ETlJ>&VV|Uw-c< z>8kB0*XN#le)rsSzfbOSZi*zM@y*to9C~VQX>Z-IVM9x6yTj2Ws0|Y zG!z?*^!CRR$@|ngVsT$0rIc%Xp>>#gg|au&-`^XF9#CD}+Y{)F^+%2<1)iQQaw~n> zqGY5mG1L)FCl1D-KhZ0<(l|sjxY(>UH#N1jwK*I&f3tbLGHVZR>DkJ098R7@9MnQy z0x;6N0+?DwRtqiA1nxf!chz93#k3YvGp1WHc`$h~bz-_Q^{TtdcNe@9g!-n;8P_xJ zOQso=%6+BrO7A7_a_>rCNxaft=C=x!;i@>)+cL|0;D(Z1$#zG)KF-~EQP}9QWTNr$ zE~qtTU0C)L;T3Ovm}|4NTK!e=)1JT1yy`Y!8{o_auAINH6~Z8hZZbbSqAvUbC&b3eZJ#|ywB)=KTNr=KcRX?_{s!- zhnya3%8k0th&|-cm#;sO+9;l~`M|wAT<$a4cZbXUoU1at!e8dw7k|_I)n#z*3qS3i zfo$-&iNBl)7W-{p$Yp{>h`TdP9u#)xf4K%r)+)-gVCM}aNY2#f6;S$*6bIy~(39o>^F1rC>O8(~22LJTEioZt0wojdL zxAR*3y)sVz-r$$`8h=InsMlg|&gGol;IUD?Ro%ygIw6boE;t`C)OoXk3V+U98Fyhl z8`d-6J}CFw;|^h^rq(jKRyLT!8bva$Q07aK7YnwqwflAVsB02R3w{$QaG1rl(SCjf z&fDDFRa_GqlK03g_IFLsjHzlL?X*YEZS-_xU4BztVYVv%uwZ`N;h*!ajywF|S{3KU zzaqg?Zm{am_C|H!J$B z@mQCgoif^s?05M0`bsMfbUbn{Xg6eo-H&>>>D@iMx6>@&?l+88#V?feV^9y72XnBF z%W@6(zsI?DdEO~^*z4@0wtXEi#+~fBZM&a4^+hntdkZVPFv;CK&3k>FezNi$uIO*s zz6fMpqwc#5kHIejue<2C14kUzmSjiW&pKyJoZ~H+4&NELwfoWVczC04)csg|#sq7> z%+MZg5m#SjwpDYgK(6UEvTq!_P;MGCo-$1u#`%fT%I|k@6BC|~rzbpyER2tNa?@*k zm)w)$+4ctVY``tHT%L7xkGg$fY#UFL>TRQLkKE$3F3t%zT!Qz)rvu*$PvDxG#NGF= zOsUv=T|(r)lix?*Dvd4hfDG*3iKJg_nl^-&ii@ zily^_@>c=RoG!2T7Dw&wp^;=XmOSFCVf*tKU%aNYJMC|GLVzJx0^uHeeJa^A*OaFyI@V*>|`sUrjFNH6kq zQsQwXmyR7yLt|eg9f8K)R0Fy(YbR6QDc#KT6}vH}NG67oiS!Ys z%5F_)p*Au+bSRb#NfAb92ty226B!;3#SX>>)1gC=1bV2rHLQsR(DTCX#2<{?->sbW%Ck7W-1jpl`XvbyGA~-jL3nK0WCWVwf zRU>YRQiyyO7X}^Z&6tWX5sv0{Gh^=~EL(v|A;sP;j6IuOs!#UtUrNhi=#@^j1A14DcDgOP8v9}HFH6e!lE61ex_dCYkM<{p7wumYAe#_W9jP`7(Cwmn# zj{N&4W3LuBBDJfKVsDnQH>T+?ohgccRahUP>iH5x`Iur%#*tW#<=XXkM&sWq8AtwY zV(fi@@ko@12ajH_=`#f@u7ln3Vn=X6#)-doL-* zWE_cU#@;O2Q|8w#pY?Mv@Mcsgm37q8-e;sZIGV^b@fOf9!w101a2K3|C!Yg zkEev*egU-U@HmJX;=#<|&EV7FaUeCsQcvD>BVJU-O3a54Umnu+^^H9j(3*luQzL3EeG58{Q8xd(0MK^n%c)XeQ z{aq&FY5hq=H+Pwx-JE&i@#fRxD@1&&3Za`ZPdrpH_$m=!t3v4J%M%Z)82l;`e^`ak&6Xz~su_H> zh_6v0baUm2$D2p*zf;7&t3sS=jxs#%K0V$o;-6Gev^(>}@E34`Jpm%C5@leO$>$Ga@&ss*m7IHE|vbUDO*E9Hf_)Le_ zp7=Cg4Gg{kIJxhVeQo4H_;n0^9hAs;0o&nFuO%KDwIbHP2`CPyDkm_NV&vT<%PT~A z83;PL1op}@c~Xk|Df$Cw2vQVae@v8D!D?BS{H=yIS)LX3PS~os)5zc3W&KN{-VK9{{y|w!F;OY5 z*D*#vA@x5Vzrv?=uzcOecDVX;LrF~iXKR@7wLgK?=D6xJ& zDEa-Vk>0#8Fw&nF`Vt58LZnaqau(9QNL}L{Y9W>S`lKkCHz!@O=A}tH3iQ5&FE5d3 zeBsZW+7E(CH%I!hHv>cYKB$jP1Bw3rM5?V-`(03aSyaLF2Bm#h0=iEO-2e{|zYSoN z_#SD`8Saqws$r)TM^ZWME8-N5SW$40+$GC+1uOC<(ns)P6Y*YvZN#GhyJQ|D-Ung~ zWsLzwCn)0;wSqWaovp~pF12U1OaCvaGKL;2soV^b|A-Uoqf<3jxIpL2JNB{l Date: Mon, 3 Feb 2014 16:25:38 -0700 Subject: [PATCH 03/52] RFduino to RFduino --- CHANGELOG | 7 + RFDLoader32 | Bin 0 -> 24712 bytes boards.txt | 2 +- cores/arduino/UARTClass.h | 3 - cores/arduino/WInterrupts.c | 57 +---- cores/arduino/WInterrupts.h | 2 +- cores/arduino/avr/pgmspace.h | 44 ++++ cores/arduino/syscalls.c | 2 +- .../AdvertisementPeriodic.ino | 2 +- libraries/RFduinoGZLL/RFduinoGZLL.cpp | 105 ++++++++++ libraries/RFduinoGZLL/RFduinoGZLL.h | 115 ++++++++++ .../01.DeviceToHost/Device0/Device0.ino | 71 +++++++ .../examples/01.DeviceToHost/Host/Host.ino | 44 ++++ .../02.HostToDevice/Device0/Device0.ino | 44 ++++ .../examples/02.HostToDevice/Host/Host.ino | 74 +++++++ .../03.DeviceToDevice/Device0/Device0.ino | 72 +++++++ .../03.DeviceToDevice/Device1/Device1.ino | 42 ++++ .../examples/03.DeviceToDevice/Host/Host.ino | 33 +++ .../examples/04.RSSI/Device0/Device0.ino | 49 +++++ .../examples/04.RSSI/Device1/Device1.ino | 49 +++++ .../examples/04.RSSI/Device2/Device2.ino | 50 +++++ .../examples/04.RSSI/Host/Host.ino | 101 +++++++++ .../examples/05.WithBLE/Device0/Device0.ino | 72 +++++++ .../examples/05.WithBLE/Host/Host.ino | 33 +++ libraries/RFduinoGZLL/keywords.txt | 34 +++ platform.txt | 2 +- source/libRFduinoGZLL/build.bat | 57 +++++ source/libRFduinoGZLL/libRFduinoGZLL.c | 150 +++++++++++++ source/libRFduinoGZLL/libRFduinoGZLL.h | 78 +++++++ system/RFduino/build_gcc/mk.bat | 2 +- system/RFduino/chip.h | 2 + system/RFduino/include/nrf51.h | 90 -------- system/RFduino/include/startup_nrf51822.h | 55 +++++ system/RFduino/include/system_nrf51.h | 22 ++ system/RFduino/source/startup_nrf51822.c | 197 ++++++++++++++---- system/RFduino/source/system_nrf51.c | 2 +- variants/RFduino/libRFduinoGZLL.a | Bin 0 -> 60314 bytes variants/RFduino/libRFduinoGZLL.h | 78 +++++++ variants/RFduino/libRFduinoSystem.a | Bin 5238 -> 6154 bytes variants/RFduino/libRFduinoSystem.a.txt | 7 +- 40 files changed, 1649 insertions(+), 200 deletions(-) create mode 100644 RFDLoader32 mode change 100755 => 100644 cores/arduino/UARTClass.h mode change 100755 => 100644 cores/arduino/WInterrupts.c mode change 100755 => 100644 cores/arduino/WInterrupts.h create mode 100644 cores/arduino/avr/pgmspace.h mode change 100755 => 100644 cores/arduino/syscalls.c mode change 100755 => 100644 libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino create mode 100644 libraries/RFduinoGZLL/RFduinoGZLL.cpp create mode 100644 libraries/RFduinoGZLL/RFduinoGZLL.h create mode 100644 libraries/RFduinoGZLL/examples/01.DeviceToHost/Device0/Device0.ino create mode 100644 libraries/RFduinoGZLL/examples/01.DeviceToHost/Host/Host.ino create mode 100644 libraries/RFduinoGZLL/examples/02.HostToDevice/Device0/Device0.ino create mode 100644 libraries/RFduinoGZLL/examples/02.HostToDevice/Host/Host.ino create mode 100644 libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device0/Device0.ino create mode 100644 libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device1/Device1.ino create mode 100644 libraries/RFduinoGZLL/examples/03.DeviceToDevice/Host/Host.ino create mode 100644 libraries/RFduinoGZLL/examples/04.RSSI/Device0/Device0.ino create mode 100644 libraries/RFduinoGZLL/examples/04.RSSI/Device1/Device1.ino create mode 100644 libraries/RFduinoGZLL/examples/04.RSSI/Device2/Device2.ino create mode 100644 libraries/RFduinoGZLL/examples/04.RSSI/Host/Host.ino create mode 100644 libraries/RFduinoGZLL/examples/05.WithBLE/Device0/Device0.ino create mode 100644 libraries/RFduinoGZLL/examples/05.WithBLE/Host/Host.ino create mode 100644 libraries/RFduinoGZLL/keywords.txt mode change 100755 => 100644 platform.txt create mode 100644 source/libRFduinoGZLL/build.bat create mode 100644 source/libRFduinoGZLL/libRFduinoGZLL.c create mode 100644 source/libRFduinoGZLL/libRFduinoGZLL.h mode change 100755 => 100644 system/RFduino/build_gcc/mk.bat mode change 100755 => 100644 system/RFduino/chip.h mode change 100755 => 100644 system/RFduino/include/nrf51.h create mode 100644 system/RFduino/include/startup_nrf51822.h create mode 100644 system/RFduino/include/system_nrf51.h mode change 100755 => 100644 system/RFduino/source/startup_nrf51822.c mode change 100755 => 100644 system/RFduino/source/system_nrf51.c create mode 100644 variants/RFduino/libRFduinoGZLL.a create mode 100644 variants/RFduino/libRFduinoGZLL.h mode change 100755 => 100644 variants/RFduino/libRFduinoSystem.a mode change 100755 => 100644 variants/RFduino/libRFduinoSystem.a.txt diff --git a/CHANGELOG b/CHANGELOG index fd6f3c4..b44fd45 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,12 @@ CHANGELOG +v 1.7 + - Added RFduino to RFduino wireless communication support + - Added pgmspace.h / PROGMEM support + - Added __RFduino__ constant + - Provided a 32-bit RFDLoader for 32-bit OSX support + - Cleaned up startup code and dependencies + v 1.6.1 - Fixed issue with not being able to call RFduinoBLE.end() / RFduino_systemReset() from pinWakeCallback diff --git a/RFDLoader32 b/RFDLoader32 new file mode 100644 index 0000000000000000000000000000000000000000..bd41c1625108471528b1e9d607de2894a76900b0 GIT binary patch literal 24712 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 mQtk=IYzF-iYZnL`$n9Uwz7L?a;TyBl8` - typedef void Uart; class UARTClass : public HardwareSerial diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c old mode 100755 new mode 100644 index 095b3d0..6ee0946 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.c @@ -44,69 +44,16 @@ #include "WInterrupts.h" -static callback_t callbacks[32]; - -// -15 Reset_Handler -// -14 NMI_Handler -// -13 HardFault_Handler -// -12 reserved -// -11 reserved -// -10 reserved -// -9 reserved -// -8 reserved -// -7 reserved -// -6 reserved -// -5 SVC_Handler -// -4 DebugMonitor_Handler -// -3 reserved -// -2 PendSV_Handler -// -1 SysTick_Handler - -// configurable interrupts -void POWER_CLOCK_IRQHandler() { callbacks[POWER_CLOCK_IRQn](); } // 0 Power Clock -void RADIO_IRQHandler() { callbacks[RADIO_IRQn](); } // 1 Radio -void UART0_IRQHandler() { callbacks[UART0_IRQn](); } // 2 UART 0 -void SPI0_TWI0_IRQHandler() { callbacks[SPI0_TWI0_IRQn](); } // 3 SPI0 and TWI0 -void SPI1_TWI1_IRQHandler() { callbacks[SPI1_TWI1_IRQn](); } // 4 SPI1 and TWI1 -// reserved // 5 reserved -void GPIOTE_IRQHandler() { callbacks[GPIOTE_IRQn](); } // 6 General Purpose IO Tasks and Events -void ADC_IRQHandler() { callbacks[ADC_IRQn](); } // 7 Analog to Digital Converter -void TIMER0_IRQHandler() { callbacks[TIMER0_IRQn](); } // 8 Timer 0 -void TIMER1_IRQHandler() { callbacks[TIMER1_IRQn](); } // 9 Timer 1 -void TIMER2_IRQHandler() { callbacks[TIMER2_IRQn](); } // 10 Timer 2 -void RTC0_IRQHandler() { callbacks[RTC0_IRQn](); } // 11 Real Time Clock 0 -void TEMP_IRQHandler() { callbacks[TEMP_IRQn](); } // 12 Temperature -void RNG_IRQHandler() { callbacks[RNG_IRQn](); } // 13 Random Number Generator -void ECB_IRQHandler() { callbacks[ECB_IRQn](); } // 14 ECB -void CCM_AAR_IRQHandler() { callbacks[CCM_AAR_IRQn](); } // 15 CCM AAR -void WDT_IRQHandler() { callbacks[WDT_IRQn](); } // 16 Watchdog Timer -void RTC1_IRQHandler() { callbacks[RTC1_IRQn](); } // 17 Real Time Clock 1 -void QDEC_IRQHandler() { callbacks[QDEC_IRQn](); } // 18 QDEC -void WUCOMP_IRQHandler() { callbacks[WUCOMP_COMP_IRQn](); } // 19 WUCOMP -//the blestack uses these (multiply defined) -//void SWI0_IRQHandler() { callbacks[SWI0_IRQn](); } // 20 Software Interrupt 0 -//void SWI1_IRQHandler() { callbacks[SWI1_IRQn](); } // 21 Software Interrupt 0 -//void SWI2_IRQHandler() { callbacks[SWI2_IRQn](); } // 22 Software Interrupt 0 -//void SWI3_IRQHandler() { callbacks[SWI3_IRQn](); } // 23 Software Interrupt 0 -//void SWI4_IRQHandler() { callbacks[SWI4_IRQn](); } // 24 Software Interrupt 0 -//void SWI5_IRQHandler() { callbacks[SWI5_IRQn](); } // 25 Software Interrupt 0 -// reserved // 26 reserved -// reserved // 27 reserved -// reserved // 28 reserved -// reserved // 29 reserved -// reserved // 30 reserved -// reserved // 31 reserved - void attachInterrupt(uint8_t IRQn, callback_t callback) { - callbacks[IRQn] = callback; + dynamic_handlers[IRQn] = callback; rfduino_nvic_enableirq(IRQn); } void detachInterrupt(uint8_t IRQn) { rfduino_nvic_disableirq(IRQn); - callbacks[IRQn] = NULL; + dynamic_handlers[IRQn] = NULL; } void attachPinInterrupt(uint32_t pin, pin_callback_t callback, uint32_t mode) diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h old mode 100755 new mode 100644 index 7f74087..8d599a5 --- a/cores/arduino/WInterrupts.h +++ b/cores/arduino/WInterrupts.h @@ -51,7 +51,7 @@ extern "C" { #endif -typedef void (*callback_t)(void); +typedef dynamic_handler_t callback_t; void attachInterrupt(uint8_t IRQn, callback_t callback); void detachInterrupt(uint8_t IRQn); diff --git a/cores/arduino/avr/pgmspace.h b/cores/arduino/avr/pgmspace.h new file mode 100644 index 0000000..9b344c9 --- /dev/null +++ b/cores/arduino/avr/pgmspace.h @@ -0,0 +1,44 @@ +#ifndef __PGMSPACE_H_ +#define __PGMSPACE_H_ 1 + +#include + +#define PROGMEM +#define PGM_P const char * +#define PSTR(str) (str) + +#define _SFR_BYTE(n) (n) + +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef int8_t prog_int8_t; +typedef uint8_t prog_uint8_t; +typedef int16_t prog_int16_t; +typedef uint16_t prog_uint16_t; +typedef int32_t prog_int32_t; +typedef uint32_t prog_uint32_t; + +#define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#define strcat_P(dest, src) strcat((dest), (src)) +#define strcmp_P(a, b) strcmp((a), (b)) +#define strstr_P(a, b) strstr((a), (b)) +#define strlen_P(a) strlen((a)) +#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) + +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) + +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_dword_near(addr) pgm_read_dword(addr) +#define pgm_read_float_near(addr) pgm_read_float(addr) +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) + +#endif diff --git a/cores/arduino/syscalls.c b/cores/arduino/syscalls.c old mode 100755 new mode 100644 index fb0cee9..32a63fd --- a/cores/arduino/syscalls.c +++ b/cores/arduino/syscalls.c @@ -58,7 +58,7 @@ #include #include -#include "nrf51.h" +#include #if defined ( __GNUC__ ) /* GCC CS3 */ #include #include diff --git a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino old mode 100755 new mode 100644 index f0f4b97..2a0624b --- a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino @@ -55,7 +55,7 @@ void loop() digitalWrite(led, LOW); // button used to wake up the RFduino (when button 1 is pressed, the RFduino will restart advertising) - pinMode(button, INPUT_PULLUP); + pinMode(button, INPUT); RFduino_pinWake(5, HIGH); // wait indefinitely in ultra low power and wake up on button 1 press diff --git a/libraries/RFduinoGZLL/RFduinoGZLL.cpp b/libraries/RFduinoGZLL/RFduinoGZLL.cpp new file mode 100644 index 0000000..9056a56 --- /dev/null +++ b/libraries/RFduinoGZLL/RFduinoGZLL.cpp @@ -0,0 +1,105 @@ +/* + RFduinoGZLL.cpp + + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* +The Gazell protocol is a wireless communication protocol that is used +to setup a robust wireless link between a single host and up to eight +devices in a star network topology. + +The Host in a Gazell network is always listening, and it is the Device +that always initiates a communication. + +Each packet that a Device sends is required to be acknowledged by the +Host. Gazell auotmatically handle packet retransmission if necessary. + +It is possible for the Host to send data to the Device by piggybacking +data to an acknowledgement (ACK) packet. Therefore a Host has to wait +for a packet from a Device before it can send any data to it. + +Gazell utilizes channel hopping functionality that gives a high date +rate and reliable wireless link. + +Gazell requires no connection packets to setup a link, and devices can +enter and exit from the network at any time. +*/ + +#include "Arduino.h" +#include "RFduinoGZLL.h" + +RFduinoGZLLClass::RFduinoGZLLClass() +{ + txPowerLevel = +4; +} + +int RFduinoGZLLClass::begin(device_t device) +{ + RFduinoGZLL_tx_power_level = txPowerLevel; + + return RFduinoGZLL_begin(device); +} + +void RFduinoGZLLClass::end() +{ + RFduinoGZLL_end(); +} + +bool RFduinoGZLLClass::sendToHost(const char *data, int len) +{ + return RFduinoGZLL_send_to_host(data, len); +} + +bool RFduinoGZLLClass::sendToDevice(device_t device, const char *data, int len) +{ + return RFduinoGZLL_send_to_device(device, data, len); +} + +bool RFduinoGZLLClass::sendToHost(const char *data) +{ + return sendToHost(data, strlen(data)); +} + +bool RFduinoGZLLClass::sendToDevice(device_t device, const char *data) +{ + return sendToDevice(device, data, strlen(data)); +} + +bool RFduinoGZLLClass::sendToHost(String &data) +{ + char buf[32]; + data.toCharArray(buf, sizeof(buf)); + return sendToHost(buf); +} + +bool RFduinoGZLLClass::sendToDevice(device_t device, String &data) +{ + char buf[32]; + data.toCharArray(buf, sizeof(buf)); + return sendToDevice(device, buf); +} + +RFduinoGZLLClass RFduinoGZLL; diff --git a/libraries/RFduinoGZLL/RFduinoGZLL.h b/libraries/RFduinoGZLL/RFduinoGZLL.h new file mode 100644 index 0000000..c2a8ada --- /dev/null +++ b/libraries/RFduinoGZLL/RFduinoGZLL.h @@ -0,0 +1,115 @@ +/* + RFduinoGZLL.h + + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + Copyright (c) 2012, Nordic Semiconductor. All Rights Reserved. + + Gazell is the property of Nordic Semiconductor ASA. + Terms and conditions of the usage are described in detail in NORDIC + SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. +*/ + +/* +The Gazell protocol is a wireless communication protocol that is used +to setup a robust wireless link between a single host and up to eight +devices in a star network topology. + +The Host in a Gazell network is always listening, and it is the Device +that always initiates a communication. + +Each packet that a Device sends is required to be acknowledged by the +Host. Gazell auotmatically handle packet retransmission if necessary. + +It is possible for the Host to send data to the Device by piggybacking +data to an acknowledgement (ACK) packet. Therefore a Host has to wait +for a packet from a Device before it can send any data to it. + +Gazell utilizes channel hopping functionality that gives a high date +rate and reliable wireless link. + +Gazell requires no connection packets to setup a link, and devices can +enter and exit from the network at any time. +*/ + +#ifndef _RFDUINOGZLL_H_ +#define _RFDUINOGZLL_H_ + +#include +#include + +#include "WString.h" + +// needed for enum and callback support +#include "libRFduinoGZLL.h" + +class RFduinoGZLLClass +{ +public: + // -20 dBm to +4 dBm - default +4 dBm + int txPowerLevel; + +public: + RFduinoGZLLClass(); + + int begin(device_t device); + void end(); + + // max length is 32 bytes + bool sendToHost(const char *data, int len); + bool sendToDevice(device_t device, const char *data, int len); + + bool sendToHost(char data) { return sendToHost((const char *)&data, sizeof(char)); } + bool sendToHost(unsigned char data) { return sendToHost((const char *)&data, sizeof(unsigned char)); } + bool sendToHost(int data) { return sendToHost((const char *)&data, sizeof(int)); } + bool sendToHost(unsigned int data) { return sendToHost((const char *)&data, sizeof(unsigned int)); } + bool sendToHost(long data) { return sendToHost((const char *)&data, sizeof(long)); } + bool sendToHost(unsigned long data) { return sendToHost((const char *)&data, sizeof(unsigned long)); } + bool sendToHost(float data) { return sendToHost((const char *)&data, sizeof(float)); } + bool sendToHost(double data) { return sendToHost((const char *)&data, sizeof(double)); } + bool sendToHost(char *data) { return sendToHost((const char *)data); } + bool sendToHost(const char *data); + bool sendToHost(String &data); + bool sendToHost(const __FlashStringHelper *data) { return sendToHost(reinterpret_cast(data)); } + + bool sendToDevice(device_t device, char data) { return sendToDevice(device, (const char *)&data, sizeof(char)); } + bool sendToDevice(device_t device, unsigned char data) { return sendToDevice(device, (const char *)&data, sizeof(unsigned char)); } + bool sendToDevice(device_t device, int data) { return sendToDevice(device, (const char *)&data, sizeof(int)); } + bool sendToDevice(device_t device, unsigned int data) { return sendToDevice(device, (const char *)&data, sizeof(unsigned int)); } + bool sendToDevice(device_t device, long data) { return sendToDevice(device, (const char *)&data, sizeof(long)); } + bool sendToDevice(device_t device, unsigned long data) { return sendToDevice(device, (const char *)&data, sizeof(unsigned long)); } + bool sendToDevice(device_t device, float data) { return sendToDevice(device, (const char *)&data, sizeof(float)); } + bool sendToDevice(device_t device, double data) { return sendToDevice(device, (const char *)&data, sizeof(double)); } + bool sendToDevice(device_t device, char *data) { return sendToDevice(device, (const char *)data); } + bool sendToDevice(device_t device, const char *data); + bool sendToDevice(device_t device, String &data); + bool sendToDevice(device_t device, const __FlashStringHelper *data) { return sendToDevice(device, reinterpret_cast(data)); } +}; + +extern RFduinoGZLLClass RFduinoGZLL; + +#endif diff --git a/libraries/RFduinoGZLL/examples/01.DeviceToHost/Device0/Device0.ino b/libraries/RFduinoGZLL/examples/01.DeviceToHost/Device0/Device0.ino new file mode 100644 index 0000000..0992297 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/01.DeviceToHost/Device0/Device0.ino @@ -0,0 +1,71 @@ +/* +This sketch demonstrates how to send data from a Device +to a Host in a Gazell network. + +When Button A on the Device is pressed and released, +the green led on the host will toggle. +*/ + +#include + +device_t role = DEVICE0; + +// pin for Button A on the RGB Shield +int button_a = 5; + +// debounce time (in ms) +int debounce_time = 10; + +// maximum debounce timeout (in ms) +int debounce_timeout = 100; + +// starting state is off +char state = 0; + +void setup() +{ + pinMode(button_a, INPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +int debounce(int button, int state) +{ + int start = millis(); + int debounce_start = start; + + while (millis() - start < debounce_timeout) + if (digitalRead(button) == state) + { + if (millis() - debounce_start >= debounce_time) + return 1; + } + else + debounce_start = millis(); + + return 0; +} + +int delay_until_button(int button, int state) +{ + while (! debounce(button, state)) + ; +} + +void loop() +{ + delay_until_button(button_a, HIGH); + + // toggle state + state = ! state; + + // send state to Host + RFduinoGZLL.sendToHost(state); + + delay_until_button(button_a, LOW); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ +} diff --git a/libraries/RFduinoGZLL/examples/01.DeviceToHost/Host/Host.ino b/libraries/RFduinoGZLL/examples/01.DeviceToHost/Host/Host.ino new file mode 100644 index 0000000..e597fa2 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/01.DeviceToHost/Host/Host.ino @@ -0,0 +1,44 @@ +/* +This sketch demonstrates how to send data from a Device +to a Host in a Gazell network. + +The host and upto 3 devices should have the RGB shield +attached. When Button A on a Device is pressed, the +associated led on the Host will toggle. Device1 is +associated with the Red led, Device2 with the Green led +and Device3 with the Blue led. + +The Green led on the Device will blink to indicate +that an acknowledgement from the Host was received. +*/ + +#include + +device_t role = HOST; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + char state = data[0]; + + // this test is not needed for a single device + if (device == DEVICE0) + digitalWrite(green_led, state); + + // no data to piggyback on the acknowledgement sent back to the Device + // RFduinoGZLL.sendToDevice(device, "OK"); +} diff --git a/libraries/RFduinoGZLL/examples/02.HostToDevice/Device0/Device0.ino b/libraries/RFduinoGZLL/examples/02.HostToDevice/Device0/Device0.ino new file mode 100644 index 0000000..efdd768 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/02.HostToDevice/Device0/Device0.ino @@ -0,0 +1,44 @@ +/* +This sketch demonstrates how to send data from a Host +to a Device in a Gazell network. + +Button A on the Host is used to toggle the Green led +on the Device. + +Since the Device must initiate communication, the +device "polls" the Host evey 200ms. +*/ + +#include + +device_t role = DEVICE0; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ + delay(200); + + // request the state from the Host (send a 0 byte payload) + RFduinoGZLL.sendToHost(NULL, 0); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // ignore acknowledgement without payload + if (len > 0) + { + // update the Green led with the current state on the Host + int state = data[0]; + digitalWrite(green_led, state); + } +} diff --git a/libraries/RFduinoGZLL/examples/02.HostToDevice/Host/Host.ino b/libraries/RFduinoGZLL/examples/02.HostToDevice/Host/Host.ino new file mode 100644 index 0000000..4d25252 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/02.HostToDevice/Host/Host.ino @@ -0,0 +1,74 @@ +/* +This sketch demonstrates how to send data from a Host +to a Device in a Gazell network. + +Button A on the Host is used to toggle the Green led +on the Device. + +Since the Device must initiate communication, the +device "polls" the Host evey 200ms. +*/ + +#include + +device_t role = HOST; + +// pin for Button A on the RGB Shield +int button_a = 5; + +// debounce time (in ms) +int debounce_time = 10; + +// maximum debounce timeout (in ms) +int debounce_timeout = 100; + +// starting state is off +char state = 0; + +void setup() +{ + pinMode(button_a, INPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +int debounce(int button, int state) +{ + int start = millis(); + int debounce_start = start; + + while (millis() - start < debounce_timeout) + if (digitalRead(button) == state) + { + if (millis() - debounce_start >= debounce_time) + return 1; + } + else + debounce_start = millis(); + + return 0; +} + +int delay_until_button(int button, int state) +{ + while (! debounce(button, state)) + ; +} + +void loop() +{ + delay_until_button(button_a, HIGH); + + // toggle state + state = ! state; + + delay_until_button(button_a, LOW); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // piggyback the current Host Button A state on the acknowledgement sent + // back to the Device + RFduinoGZLL.sendToDevice(device, state); +} diff --git a/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device0/Device0.ino b/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device0/Device0.ino new file mode 100644 index 0000000..ee001b3 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device0/Device0.ino @@ -0,0 +1,72 @@ +/* +This sketch demonstrates how to send data from a Device +to another Device (using the Host as an intermediary) +in a Gazell network. + +When Button A on Device0 is pressed and released, +the green led on Device1 will toggle. +*/ + +#include + +device_t role = DEVICE0; + +// pin for Button A on the RGB Shield +int button_a = 5; + +// debounce time (in ms) +int debounce_time = 10; + +// maximum debounce timeout (in ms) +int debounce_timeout = 100; + +// starting state is off +char state = 0; + +void setup() +{ + pinMode(button_a, INPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +int debounce(int button, int state) +{ + int start = millis(); + int debounce_start = start; + + while (millis() - start < debounce_timeout) + if (digitalRead(button) == state) + { + if (millis() - debounce_start >= debounce_time) + return 1; + } + else + debounce_start = millis(); + + return 0; +} + +int delay_until_button(int button, int state) +{ + while (! debounce(button, state)) + ; +} + +void loop() +{ + delay_until_button(button_a, HIGH); + + // toggle state + state = ! state; + + // send state to Host + RFduinoGZLL.sendToHost(state); + + delay_until_button(button_a, LOW); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ +} diff --git a/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device1/Device1.ino b/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device1/Device1.ino new file mode 100644 index 0000000..f54976b --- /dev/null +++ b/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Device1/Device1.ino @@ -0,0 +1,42 @@ +/* +This sketch demonstrates how to send data from a Device +to another Device (using the Host as an intermediary) +in a Gazell network. + +When Button A on Device0 is pressed and released, +the green led on Device1 will toggle. +*/ + +#include + +device_t role = DEVICE1; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ + delay(200); + + // request the state from the Host (send a 0 byte payload) + RFduinoGZLL.sendToHost(NULL, 0); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // ignore acknowledgement without payload + if (len > 0) + { + // update the Green led with the current state relayed by the Host + char state = data[0]; + digitalWrite(green_led, state); + } +} diff --git a/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Host/Host.ino b/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Host/Host.ino new file mode 100644 index 0000000..01c5f17 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/03.DeviceToDevice/Host/Host.ino @@ -0,0 +1,33 @@ +/* +This sketch demonstrates how to send data from a Device +to another Device (using the Host as an intermediary) +in a Gazell network. + +When Button A on Device0 is pressed and released, +the green led on Device1 will toggle. +*/ + +#include + +device_t role = HOST; + +// the last known state from DEVICE0 (default to off) +char state = 0; + +void setup() +{ + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + if (device == DEVICE0) // get the current state from DEVICE0 + state = data[0]; + else if (device == DEVICE1) // relay the last known state to DEVICE1 + RFduinoGZLL.sendToDevice(device, state); +} diff --git a/libraries/RFduinoGZLL/examples/04.RSSI/Device0/Device0.ino b/libraries/RFduinoGZLL/examples/04.RSSI/Device0/Device0.ino new file mode 100644 index 0000000..ca758ad --- /dev/null +++ b/libraries/RFduinoGZLL/examples/04.RSSI/Device0/Device0.ino @@ -0,0 +1,49 @@ +/* +This sketch demonstrates how to coordinate data +between 3 devices in a Gazell network. + +The host collects RSSI samples from the Devices, +and determines which device has the strongest +average RSSI (ie: the Device that is closest +to the Host). The Green led is set on the +closest Device. + +Since the Device must initiate communication, the +device "polls" the Host evey 200ms. +*/ + +#include + +device_t role = DEVICE0; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + RFduinoGZLL.txPowerLevel = 0; + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ + delay(200); + + // request the state from the Host (send a 0 byte payload) + RFduinoGZLL.sendToHost(NULL, 0); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // ignore acknowledgement without payload + if (len > 0) + { + // set the Green led if this device is the closest device + device_t closest_device = (device_t)data[0]; + digitalWrite(green_led, (role == closest_device)); + } +} diff --git a/libraries/RFduinoGZLL/examples/04.RSSI/Device1/Device1.ino b/libraries/RFduinoGZLL/examples/04.RSSI/Device1/Device1.ino new file mode 100644 index 0000000..6eba2df --- /dev/null +++ b/libraries/RFduinoGZLL/examples/04.RSSI/Device1/Device1.ino @@ -0,0 +1,49 @@ +/* +This sketch demonstrates how to coordinate data +between 3 devices in a Gazell network. + +The host collects RSSI samples from the Devices, +and determines which device has the strongest +average RSSI (ie: the Device that is closest +to the Host). The Green led is set on the +closest Device. + +Since the Device must initiate communication, the +device "polls" the Host evey 200ms. +*/ + +#include + +device_t role = DEVICE1; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + RFduinoGZLL.txPowerLevel = 0; + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ + delay(200); + + // request the state from the Host (send a 0 byte payload) + RFduinoGZLL.sendToHost(NULL, 0); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // ignore acknowledgement without payload + if (len > 0) + { + // set the Green led if this device is the closest device + device_t closest_device = (device_t)data[0]; + digitalWrite(green_led, (role == closest_device)); + } +} diff --git a/libraries/RFduinoGZLL/examples/04.RSSI/Device2/Device2.ino b/libraries/RFduinoGZLL/examples/04.RSSI/Device2/Device2.ino new file mode 100644 index 0000000..c7069fe --- /dev/null +++ b/libraries/RFduinoGZLL/examples/04.RSSI/Device2/Device2.ino @@ -0,0 +1,50 @@ +/* +This sketch demonstrates how to coordinate data +between 3 devices in a Gazell network. + +The host collects RSSI samples from the Devices, +and determines which device has the strongest +average RSSI (ie: the Device that is closest +to the Host). The Green led is set on the +closest Device. + +Since the Device must initiate communication, the +device "polls" the Host evey 200ms. +*/ + +#include + +// Gazell Role Assignment +device_t role = DEVICE2; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + RFduinoGZLL.txPowerLevel = 0; + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ + delay(200); + + // request the state from the Host (send a 0 byte payload) + RFduinoGZLL.sendToHost(NULL, 0); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // ignore acknowledgement without payload + if (len > 0) + { + // set the Green led if this device is the closest device + device_t closest_device = (device_t)data[0]; + digitalWrite(green_led, (role == closest_device)); + } +} diff --git a/libraries/RFduinoGZLL/examples/04.RSSI/Host/Host.ino b/libraries/RFduinoGZLL/examples/04.RSSI/Host/Host.ino new file mode 100644 index 0000000..7a157f1 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/04.RSSI/Host/Host.ino @@ -0,0 +1,101 @@ +/* +This sketch demonstrates how to coordinate data +between 3 devices in a Gazell network. + +The host collects RSSI samples from the Devices, +and determines which device has the strongest +average RSSI (ie: the Device that is closest +to the Host). The Green led is set on the +closest Device. + +Since the Device must initiate communication, the +device "polls" the Host evey 200ms. +*/ + +#define MAX_DEVICES 3 + +#include + +// RSSI total and count for each device for averaging +int rssi_total[MAX_DEVICES]; +int rssi_count[MAX_DEVICES]; + +// device with the maximum RSSI +char closest_device = 0; + +// collect samples flag +int collect_samples = 0; + +void setup() +{ + // write the Device and RSSI values to the Serial Monitor + Serial.begin(57600); + + // start the GZLL stack + RFduinoGZLL.begin(HOST); +} + +void loop() +{ + int i; + + // reset the RSSI averaging for each device + for (i = 0; i < MAX_DEVICES; i++) + { + rssi_total[i] = 0; + rssi_count[i] = 0; + } + + // start collecting RSSI samples + collect_samples = 1; + + // wait one second + delay(1000); + + // stop collecting RSSI samples + collect_samples = 0; + + // calculate the RSSI avarages for each device + int average[MAX_DEVICES]; + + for (i = 0; i < MAX_DEVICES; i++) + { + // no samples received, set to the lowest RSSI + // (also prevents divide by zero) + if (rssi_count[i] == 0) + average[i] = -128; + else + average[i] = rssi_total[i] / rssi_count[i]; + + // printf increases the sketch size more than Serial.println, but + // this is an easy way to concatenate data onto a single line + // (note: the newline is required with printf!) + printf("average RSSI for device %d is %d\n", i, average[i]); + } + Serial.println(""); + + // find the device with the maximum RSSI value + int closest = 0; + for (i = 1; i < MAX_DEVICES; i++) + if (average[i] > average[closest]) + closest = i; + + closest_device = closest; +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + // ignore device if outside range + if (device > MAX_DEVICES) + return; + + // if collecting samples, update the RSSI total and count + if (collect_samples) + { + rssi_total[device] += rssi; + rssi_count[device]++; + } + + // piggyback max_device on the acknowledgement sent back to the requesting Device + RFduinoGZLL.sendToDevice(device, closest_device); +} diff --git a/libraries/RFduinoGZLL/examples/05.WithBLE/Device0/Device0.ino b/libraries/RFduinoGZLL/examples/05.WithBLE/Device0/Device0.ino new file mode 100644 index 0000000..9d6508a --- /dev/null +++ b/libraries/RFduinoGZLL/examples/05.WithBLE/Device0/Device0.ino @@ -0,0 +1,72 @@ +/* +This sketch demonstrates how to use Bluetooth Low Energy +and Gazell in the same sketch. + +This sketch accepts a connection from the LedButton iPhone App. +When the button on the iPhone app is pressed, the green led on +the Host will toggle. +*/ + +#include +#include + +device_t role = DEVICE0; + +char led = 0; + +int state = 0; + +void setup() +{ + Serial.begin(57600); + Serial.println("start"); +} + +void loop() +{ + switch (state) + { + case 0: + RFduinoBLE.begin(); + state = 1; + break; + + case 1: + // waiting for a BLE button press + break; + + case 2: + // this disconnects us from the iPhone App + // (we get a warning on the iPhone App because we are + // not detecting this condition correctly in the App) + RFduinoBLE.end(); + state = 3; + break; + + case 3: + RFduinoGZLL.begin(role); + RFduinoGZLL.sendToHost(led); + state = 4; + break; + + case 4: + // waiting for GZLL acknowledgement from Host + break; + + case 5: + RFduinoGZLL.end(); + state = 0; + break; + } +} + +void RFduinoBLE_onReceive(char *data, int len) +{ + led = ! led; + state = 2; +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + state = 5; +} diff --git a/libraries/RFduinoGZLL/examples/05.WithBLE/Host/Host.ino b/libraries/RFduinoGZLL/examples/05.WithBLE/Host/Host.ino new file mode 100644 index 0000000..08a3730 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/05.WithBLE/Host/Host.ino @@ -0,0 +1,33 @@ +/* +This sketch demonstrates how to use Bluetooth Low Energy +and Gazell in the same sketch. + +This sketch accepts a connection from the LedButton iPhone App. +When the button on the iPhone app is pressed, the green led on +the Host will toggle. +*/ + +#include + +device_t role = HOST; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + char state = data[0]; + digitalWrite(green_led, state); +} diff --git a/libraries/RFduinoGZLL/keywords.txt b/libraries/RFduinoGZLL/keywords.txt new file mode 100644 index 0000000..513769d --- /dev/null +++ b/libraries/RFduinoGZLL/keywords.txt @@ -0,0 +1,34 @@ +####################################### +# Syntax Coloring Map SPI +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +RFduinoGZLL KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +txPowerLevel KEYWORD2 + +begin KEYWORD2 +end KEYWORD2 +sendToHost KEYWORD2 +sendToDevice KEYWORD2 + +RFduinoBLE_onReceive KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +DEVICE0 LITERAL1 +DEVICE1 LITERAL1 +DEVICE2 LITERAL1 +DEVICE3 LITERAL1 +DEVICE4 LITERAL1 +DEVICE5 LITERAL1 +DEVICE6 LITERAL1 +DEVICE7 LITERAL1 +HOST LITERAL1 diff --git a/platform.txt b/platform.txt old mode 100755 new mode 100644 index aa86b55..5f74ad0 --- a/platform.txt +++ b/platform.txt @@ -40,7 +40,7 @@ recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -m recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} {build.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.variant.path}/libRFduino.a" "{build.variant.path}/libRFduinoBLE.a" "{build.path}/{archive_file}" -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} {build.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.variant.path}/libRFduino.a" "{build.variant.path}/libRFduinoBLE.a" "{build.variant.path}/libRFduinoGZLL.a" "{build.path}/{archive_file}" -Wl,--end-group ## Create eeprom recipe.objcopy.eep.pattern= diff --git a/source/libRFduinoGZLL/build.bat b/source/libRFduinoGZLL/build.bat new file mode 100644 index 0000000..be34939 --- /dev/null +++ b/source/libRFduinoGZLL/build.bat @@ -0,0 +1,57 @@ +@echo off + +set arduino=C:\arduino-1.5.5 +set nordic="C:\Nordic Semiconductor\nRF51 SDK_v4.2.0.25053\Nordic\nrf51822" + +if not exist %nordic% ( +echo Error: The Nordic SDK is required to build libRFduinoGZLL. +goto end +) + +if not exist _build\nul mkdir _build +if exist _build\* del /q _build\* + +set tools=%arduino%\hardware\tools\g++_arm_none_eabi +set RFduino=%arduino%\hardware\arduino\RFduino + +set gcc=%tools%\bin\arm-none-eabi-gcc +set ar=%tools%\bin\arm-none-eabi-ar + +set includes=-I%nordic%\Include +set includes=%includes% -I%nordic%\Include\gzll +set includes=%includes% -I%nordic%\Include\gcc + +rem set cflags=--param max-inline-insns-single=500 +set cflags=-Os -w -mcpu=cortex-m0 -mthumb -DNRF51 -DBOARD_PCA10001 -ffunction-sections -fdata-sections -nostdlib -fno-rtti -fno-exceptions --param max-inline-insns-single=500 -Dprintf=iprintf %includes% + +echo compiling... + +echo libRFduinoGZLL.c +%gcc% %cflags% -c -o _build\libRFduinoGZLL.o libRFduinoGZLL.c + +echo creating library... + +set objs=_build\libRFduinoGZLL.o + +cd _build +%ar% -x %nordic%\lib\gzll\gcc\gzll_gcc.a +cd .. +set objs=%objs% _build\nrf_assert_internal.o +set objs=%objs% _build\nrf_channel_manager.o +set objs=%objs% _build\nrf_fifo.o +set objs=%objs% _build\nrf_flywheel.o +set objs=%objs% _build\nrf_gzll.o +set objs=%objs% _build\nrf_impala.o +set objs=%objs% _build\nrf_link_core.o +set objs=%objs% _build\nrf_notification_manager.o +set objs=%objs% _build\nrf_packet_manager.o +set objs=%objs% _build\nrf_state_machine.o + +for %%f in (%objs%) do %ar% rcs _build/libRFduinoGZLL.a %%f + +echo copying libray and header to variants... +copy _build\libRFduinoGZLL.a %RFduino%\variants\RFduino\libRFduinoGZLL.a +copy libRFduinoGZLL.h %RFduino%\variants\RFduino\libRFduinoGZLL.h + +:end +pause diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.c b/source/libRFduinoGZLL/libRFduinoGZLL.c new file mode 100644 index 0000000..90f1108 --- /dev/null +++ b/source/libRFduinoGZLL/libRFduinoGZLL.c @@ -0,0 +1,150 @@ +/* + libRFduinoGZLL.c + + Copyright (c) 2014 RF Digital Corporation. All Rights Reserved. + + The information contained herein is property of RF Digital + Corporation and is free for use on any product or in any + application containing an RF Digital Module. + + NO WARRANTY of ANY KIND is provided. This heading must NOT be + removed from the file. +*/ + +/* +The Gazell protocol is a wireless communication protocol that is used +to setup a robust wireless link between a single host and up to eight +devices in a star network topology. + +The Host in a Gazell network is always listening, and it is the Device +that always initiates a communication. + +Each packet that a Device sends is required to be acknowledged by the +Host. Gazell auotmatically handle packet retransmission if necessary. + +It is possible for the Host to send data to the Device by piggybacking +data to an acknowledgement (ACK) packet. Therefore a Host has to wait +for a packet from a Device before it can send any data to it. + +Gazell utilizes channel hopping functionality that gives a high date +rate and reliable wireless link. + +Gazell requires no connection packets to setup a link, and devices can +enter and exit from the network at any time. +*/ + +#include + +#include "nrf_gzll.h" + +#include "libRFduinoGZLL.h" + +// -20 dBm to +4 dBm = default +4 dBm +int RFduinoGZLL_tx_power_level = 4; + +static device_t _device; + +// 0 = success +// 1 = init failed +// 2 = set tx_power failed +// 3 = enabled failed +int RFduinoGZLL_begin(device_t device) +{ + _device = device; + + if (! nrf_gzll_init(device == HOST ? NRF_GZLL_MODE_HOST : NRF_GZLL_MODE_DEVICE)) + return 1; + + nrf_gzll_tx_power_t tx_power; + if (RFduinoGZLL_tx_power_level <= -20) + tx_power = NRF_GZLL_TX_POWER_N20_DBM; + else if (RFduinoGZLL_tx_power_level <= -16) + tx_power = NRF_GZLL_TX_POWER_N16_DBM; + else if (RFduinoGZLL_tx_power_level <= -12) + tx_power = NRF_GZLL_TX_POWER_N12_DBM; + else if (RFduinoGZLL_tx_power_level <= -16) + tx_power = NRF_GZLL_TX_POWER_N16_DBM; + else if (RFduinoGZLL_tx_power_level <= -8) + tx_power = NRF_GZLL_TX_POWER_N8_DBM; + else if (RFduinoGZLL_tx_power_level <= -4) + tx_power = NRF_GZLL_TX_POWER_N4_DBM; + else if (RFduinoGZLL_tx_power_level <= 0) + tx_power = NRF_GZLL_TX_POWER_0_DBM; + else + tx_power = NRF_GZLL_TX_POWER_4_DBM; + + if (! nrf_gzll_set_tx_power(tx_power)) + return 2; + + if (! nrf_gzll_enable()) + return 3; + + return 0; +} + +bool RFduinoGZLL_send_to_host(const char *data, int len) +{ + if (_device == HOST) + return false; + + // a zero byte load is valid, but data must be non-null + if (!data && !len) + data = &_device; + + return nrf_gzll_add_packet_to_tx_fifo(_device, data, len); +} + +bool RFduinoGZLL_send_to_device(device_t device, const char *data, int len) +{ + if (_device != HOST) + return false; + + return nrf_gzll_add_packet_to_tx_fifo(device, data, len); +} + +void RFduinoGZLL_end(void) +{ + nrf_gzll_disable(); + + while (nrf_gzll_is_enabled()) + ; + + NVIC_DisableIRQ(RADIO_IRQn); + NVIC_DisableIRQ(TIMER2_IRQn); +} + +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) +{ + char payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + int length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + + if (! nrf_gzll_fetch_packet_from_rx_fifo(pipe, payload, &length)) + return; + + if (RFduinoGZLL_onReceive) + RFduinoGZLL_onReceive(pipe, rx_info.rssi, payload, length); +} + +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ + char payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + int length = 0; + + if (tx_info.payload_received_in_ack) + { + length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + if (! nrf_gzll_fetch_packet_from_rx_fifo(pipe, payload, &length)) + return; + } + + if (RFduinoGZLL_onReceive) + RFduinoGZLL_onReceive(HOST, tx_info.rssi, payload, length); +} + +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ +} + +void nrf_gzll_disabled() +{ +} diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.h b/source/libRFduinoGZLL/libRFduinoGZLL.h new file mode 100644 index 0000000..2e54887 --- /dev/null +++ b/source/libRFduinoGZLL/libRFduinoGZLL.h @@ -0,0 +1,78 @@ +/* + libRFduinoGZLL.h + + Copyright (c) 2014 RF Digital Corporation. All Rights Reserved. + + The information contained herein is property of RF Digital + Corporation and is free for use on any product or in any + application containing an RF Digital Module. + + NO WARRANTY of ANY KIND is provided. This heading must NOT be + removed from the file. +*/ + +/* +The Gazell protocol is a wireless communication protocol that is used +to setup a robust wireless link between a single host and up to eight +devices in a star network topology. + +The Host in a Gazell network is always listening, and it is the Device +that always initiates a communication. + +Each packet that a Device sends is required to be acknowledged by the +Host. Gazell auotmatically handle packet retransmission if necessary. + +It is possible for the Host to send data to the Device by piggybacking +data to an acknowledgement (ACK) packet. Therefore a Host has to wait +for a packet from a Device before it can send any data to it. + +Gazell utilizes channel hopping functionality that gives a high date +rate and reliable wireless link. + +Gazell requires no connection packets to setup a link, and devices can +enter and exit from the network at any time. +*/ + +#ifndef _LIBRFDUINOGZLL_H_ +#define _LIBRFDUINOGZLL_H_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum +{ + DEVICE0, + DEVICE1, + DEVICE2, + DEVICE3, + DEVICE4, + DEVICE5, + DEVICE6, + DEVICE7, + HOST +} device_t; + +// -20 dBm to +4 dBm - default +4 dBm +extern int RFduinoGZLL_tx_power_level; + +extern void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) __attribute__((weak)); + +// 0 = success +// 1 = init failed +// 2 = set tx_power failed +// 3 = enabled failed +int RFduinoGZLL_begin(device_t device); + +void RFduinoGZLL_end(void); + +// max length is 32 (NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH) +bool RFduinoGZLL_send_to_host(const char *data, int len); + +bool RFduinoGZLL_send_to_device(device_t device, const char *data, int len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/system/RFduino/build_gcc/mk.bat b/system/RFduino/build_gcc/mk.bat old mode 100755 new mode 100644 index 91b3fd8..e470257 --- a/system/RFduino/build_gcc/mk.bat +++ b/system/RFduino/build_gcc/mk.bat @@ -1,2 +1,2 @@ -c:\arduino-1.5.2\hardware\tools\g++_arm_none_eabi\bin\cs-make +..\..\..\..\..\tools\g++_arm_none_eabi\bin\cs-make pause diff --git a/system/RFduino/chip.h b/system/RFduino/chip.h old mode 100755 new mode 100644 index 2d9f31e..c5fe298 --- a/system/RFduino/chip.h +++ b/system/RFduino/chip.h @@ -48,6 +48,8 @@ /* * Core and peripherals registers definitions */ +#include "include/startup_nrf51822.h" +#include "include/system_nrf51.h" #include "include/nrf51.h" #include "include/nrf51_bitfields.h" diff --git a/system/RFduino/include/nrf51.h b/system/RFduino/include/nrf51.h old mode 100755 new mode 100644 index c5df713..042db70 --- a/system/RFduino/include/nrf51.h +++ b/system/RFduino/include/nrf51.h @@ -69,96 +69,6 @@ typedef enum { SWI5_IRQn = 25 /*!< 25 SWI5 */ } IRQn_Type; -typedef struct _DeviceVectors -{ - /* Stack pointer */ - void* pvStack; - - /* Cortex-M handlers */ - void* pfnReset_Handler; - void* pfnNMI_Handler; - void* pfnHardFault_Handler; - void* pfnReserved1_Handler; - void* pfnReserved2_Handler; - void* pfnReserved3_Handler; - void* pfnReserved4_Handler; - void* pfnReserved5_Handler; - void* pfnReserved6_Handler; - void* pfnReserved7_Handler; - void* pfnSVC_Handler; - void* pfnReserved8_Handler; - void* pfnReserved9_Handler; - void* pfnPendSV_Handler; - void* pfnSysTick_Handler; - - /* Configurable interrupts */ - void* pfnPOWER_CLOCK_IRQHandler; /* 0 Power Clock */ - void* pfnRADIO_IRQHandler; /* 1 Radio Controller*/ - void* pfnUART0_IRQHandler; /* 2 UART0 Controller */ - void* pfnSPI0_TWI0_IRQHandler; /* 3 SPI0 & TWI0 Controller*/ - void* pfnSPI1_TWI1_IRQHandler; /* 4 SPI1 & TWI1 Controller*/ - void* pfnReserved10_IRQHandler; /* 5 Reserved */ - void* pfnGPIOTE_IRQHandler; /* 6 GPIO */ - void* pfnADC_IRQHandler; /* 7 ADC Controller */ - void* pfnTIMER0_IRQHandler; /* 8 Timer Counter 0 */ - void* pfnTIMER1_IRQHandler; /* 9 Timer Counter 1 */ - void* pfnTIMER2_IRQHandler; /* 10 Timer Counter 2 */ - void* pfnRTC0_IRQHandler; /* 11 Real Time Clock Controller 0 */ - void* pfnTEMP_IRQHandler; /* 12 Temperature */ - void* pfnRNG_IRQHandler; /* 13 Random Number Generator */ - void* pfnECB_IRQHandler; /* 14 ECB */ - void* pfnCCM_AAR_IRQHandler; /* 15 CCM_AAR */ - void* pfnWDT_IRQHandler; /* 16 Watchdog Timer */ - void* pfnRTC1_IRQHandler; /* 17 Real Time Clock Controller 1 */ - void* pfnQDEC_IRQHandler; /* 18 QDEC */ - void* pfnWUCOMP_IRQHandler; /* 19 WUCOMP */ - void* pfnSWI0_IRQHandler; /* 20 Software Interrupt 0 */ - void* pfnSWI1_IRQHandler; /* 21 Software Interrupt 1 */ - void* pfnSWI2_IRQHandler; /* 22 Software Interrupt 2 */ - void* pfnSWI3_IRQHandler; /* 23 Software Interrupt 3 */ - void* pfnSWI4_IRQHandler; /* 24 Software Interrupt 4 */ - void* pfnSWI5_IRQHandler; /* 25 Software Interrupt 5 */ - void* pfnReserved11_IRQHandler; /* 26 Reserved */ - void* pfnReserved12_IRQHandler; /* 27 Reserved */ - void* pfnReserved13_IRQHandler; /* 28 Reserved */ - void* pfnReserved14_IRQHandler; /* 29 Reserved */ - void* pfnReserved15_IRQHandler; /* 30 Reserved */ - void* pfnReserved16_IRQHandler; /* 31 Reserved */ -} DeviceVectors; - -/* Cortex-M3 core handlers */ -void NMI_Handler ( void ); -void HardFault_Handler ( void ); -void SVC_Handler ( void ); -void PendSV_Handler ( void ); -void SysTick_Handler ( void ); - -/* Peripherals handlers */ -void POWER_CLOCK_IRQHandler ( void ); -void RADIO_IRQHandler ( void ); -void UART0_IRQHandler ( void ); -void SPI0_TWI0_IRQHandler ( void ); -void SPI1_TWI1_IRQHandler ( void ); -void GPIOTE_IRQHandler ( void ); -void ADC_IRQHandler ( void ); -void TIMER0_IRQHandler ( void ); -void TIMER1_IRQHandler ( void ); -void TIMER2_IRQHandler ( void ); -void RTC0_IRQHandler ( void ); -void TEMP_IRQHandler ( void ); -void RNG_IRQHandler ( void ); -void ECB_IRQHandler ( void ); -void CCM_AAR_IRQHandler ( void ); -void WDT_IRQHandler ( void ); -void RTC1_IRQHandler ( void ); -void QDEC_IRQHandler ( void ); -void WUCOMP_IRQHandler ( void ); -void SWI0_IRQHandler ( void ); -void SWI1_IRQHandler ( void ); -void SWI2_IRQHandler ( void ); -void SWI3_IRQHandler ( void ); -void SWI4_IRQHandler ( void ); -void SWI5_IRQHandler ( void ); /** @addtogroup Configuration_of_CMSIS * @{ diff --git a/system/RFduino/include/startup_nrf51822.h b/system/RFduino/include/startup_nrf51822.h new file mode 100644 index 0000000..d4dcb28 --- /dev/null +++ b/system/RFduino/include/startup_nrf51822.h @@ -0,0 +1,55 @@ +#ifndef __STARTUP_NRF51822_H +#define __STARTUP_NRF51822_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DYNAMIC_HANDLERS + +/* Cortex-M0 core handlers */ +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* peripheral handlers */ +void POWER_CLOCK_IRQHandler ( void ); +void RADIO_IRQHandler ( void ); +void UART0_IRQHandler ( void ); +void SPI0_TWI0_IRQHandler ( void ); +void SPI1_TWI1_IRQHandler ( void ); +void GPIOTE_IRQHandler ( void ); +void ADC_IRQHandler ( void ); +void TIMER0_IRQHandler ( void ); +void TIMER1_IRQHandler ( void ); +void TIMER2_IRQHandler ( void ); +void RTC0_IRQHandler ( void ); +void TEMP_IRQHandler ( void ); +void RNG_IRQHandler ( void ); +void ECB_IRQHandler ( void ); +void CCM_AAR_IRQHandler ( void ); +void WDT_IRQHandler ( void ); +void RTC1_IRQHandler ( void ); +void QDEC_IRQHandler ( void ); +void WUCOMP_IRQHandler ( void ); +void SWI0_IRQHandler ( void ); +void SWI1_IRQHandler ( void ); +void SWI2_IRQHandler ( void ); +void SWI3_IRQHandler ( void ); +void SWI4_IRQHandler ( void ); +void SWI5_IRQHandler ( void ); + +#ifdef DYNAMIC_HANDLERS + +typedef void (*dynamic_handler_t)(void); +extern dynamic_handler_t *dynamic_handlers/*[32]*/; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/system/RFduino/include/system_nrf51.h b/system/RFduino/include/system_nrf51.h new file mode 100644 index 0000000..5fead02 --- /dev/null +++ b/system/RFduino/include/system_nrf51.h @@ -0,0 +1,22 @@ +#ifndef __SYSTEM_NRF51_H +#define __SYSTEM_NRF51_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define __XTAL (16000000UL) /* Oscillator frequency */ + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +extern void SystemInit (void); + +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/system/RFduino/source/startup_nrf51822.c b/system/RFduino/source/startup_nrf51822.c old mode 100755 new mode 100644 index e342990..ff34d14 --- a/system/RFduino/source/startup_nrf51822.c +++ b/system/RFduino/source/startup_nrf51822.c @@ -25,6 +25,8 @@ */ #include "nrf51.h" +#include "startup_nrf51822.h" +#include "system_nrf51.h" /* Initialize segments */ extern uint32_t _sfixed; @@ -37,52 +39,110 @@ extern uint32_t _ezero; extern uint32_t _sstack; extern uint32_t _estack; +/* C library initialization */ +void __libc_init_array(void); + /** \cond DOXYGEN_SHOULD_SKIP_THIS */ int main(void); /** \endcond */ -void Reset_Handler(void); -void __libc_init_array(void); -/* Default empty handler */ -void Dummy_Handler(void); +void Reset_Handler(void); +void Default_Handler(void); /* Cortex-M0 core handlers */ -void NMI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SVC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void NMI_Handler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SVC_Handler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void PendSV_Handler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SysTick_Handler ( void ) __attribute__ ((weak, alias("Default_Handler"))); /* Peripherals handlers */ -void POWER_CLOCK_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void RADIO_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void UART0_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SPI0_TWI0_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SPI1_TWI1_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void GPIOTE_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void ADC_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void TIMER0_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void TIMER1_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void TIMER2_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void RTC0_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void TEMP_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void RNG_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void ECB_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void CCM_AAR_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void WDT_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void RTC1_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void QDEC_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void WUCOMP_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SWI0_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SWI1_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SWI2_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SWI3_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SWI4_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); -void SWI5_IRQHandler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); - -/* Exception Table */ +void POWER_CLOCK_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void RADIO_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void UART0_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SPI0_TWI0_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SPI1_TWI1_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void GPIOTE_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void ADC_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER0_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER1_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void TIMER2_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void RTC0_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void TEMP_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void RNG_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void ECB_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void CCM_AAR_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void WDT_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void RTC1_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void QDEC_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void WUCOMP_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SWI0_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SWI1_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SWI2_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SWI3_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SWI4_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); +void SWI5_IRQHandler ( void ) __attribute__ ((weak, alias("Default_Handler"))); + +typedef struct +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M0 core handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReserved1_Handler; + void* pfnReserved2_Handler; + void* pfnReserved3_Handler; + void* pfnReserved4_Handler; + void* pfnReserved5_Handler; + void* pfnReserved6_Handler; + void* pfnReserved7_Handler; + void* pfnSVC_Handler; + void* pfnReserved8_Handler; + void* pfnReserved9_Handler; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Configurable interrupts */ + void* pfnPOWER_CLOCK_IRQHandler; /* 0 Power Clock */ + void* pfnRADIO_IRQHandler; /* 1 Radio Controller*/ + void* pfnUART0_IRQHandler; /* 2 UART0 Controller */ + void* pfnSPI0_TWI0_IRQHandler; /* 3 SPI0 & TWI0 Controller*/ + void* pfnSPI1_TWI1_IRQHandler; /* 4 SPI1 & TWI1 Controller*/ + void* pfnReserved10_IRQHandler; /* 5 Reserved */ + void* pfnGPIOTE_IRQHandler; /* 6 GPIO */ + void* pfnADC_IRQHandler; /* 7 ADC Controller */ + void* pfnTIMER0_IRQHandler; /* 8 Timer Counter 0 */ + void* pfnTIMER1_IRQHandler; /* 9 Timer Counter 1 */ + void* pfnTIMER2_IRQHandler; /* 10 Timer Counter 2 */ + void* pfnRTC0_IRQHandler; /* 11 Real Time Clock Controller 0 */ + void* pfnTEMP_IRQHandler; /* 12 Temperature */ + void* pfnRNG_IRQHandler; /* 13 Random Number Generator */ + void* pfnECB_IRQHandler; /* 14 ECB */ + void* pfnCCM_AAR_IRQHandler; /* 15 CCM_AAR */ + void* pfnWDT_IRQHandler; /* 16 Watchdog Timer */ + void* pfnRTC1_IRQHandler; /* 17 Real Time Clock Controller 1 */ + void* pfnQDEC_IRQHandler; /* 18 QDEC */ + void* pfnWUCOMP_IRQHandler; /* 19 WUCOMP */ + void* pfnSWI0_IRQHandler; /* 20 Software Interrupt 0 */ + void* pfnSWI1_IRQHandler; /* 21 Software Interrupt 1 */ + void* pfnSWI2_IRQHandler; /* 22 Software Interrupt 2 */ + void* pfnSWI3_IRQHandler; /* 23 Software Interrupt 3 */ + void* pfnSWI4_IRQHandler; /* 24 Software Interrupt 4 */ + void* pfnSWI5_IRQHandler; /* 25 Software Interrupt 5 */ + void* pfnReserved11_IRQHandler; /* 26 Reserved */ + void* pfnReserved12_IRQHandler; /* 27 Reserved */ + void* pfnReserved13_IRQHandler; /* 28 Reserved */ + void* pfnReserved14_IRQHandler; /* 29 Reserved */ + void* pfnReserved15_IRQHandler; /* 30 Reserved */ + void* pfnReserved16_IRQHandler; /* 31 Reserved */ +} vector_table_t; + +/* Vector Table */ __attribute__ ((section(".vectors"))) -const DeviceVectors exception_table = { +const vector_table_t vector_table = { /* Configure Initial Stack Pointer, using linker-generated symbols */ (void*) (&_estack), (void*) Reset_Handler, @@ -103,10 +163,10 @@ const DeviceVectors exception_table = { /* Configurable interrupts */ (void*) POWER_CLOCK_IRQHandler, /* 0 Power Clock */ - (void*) RADIO_IRQHandler, /* 1 Radio Controller*/ + (void*) RADIO_IRQHandler, /* 1 Radio Controller */ (void*) UART0_IRQHandler, /* 2 UART0 Controller */ - (void*) SPI0_TWI0_IRQHandler, /* 3 SPI0 & TWI0 Controller*/ - (void*) SPI1_TWI1_IRQHandler, /* 4 SPI1 & TWI1 Controller*/ + (void*) SPI0_TWI0_IRQHandler, /* 3 SPI0 & TWI0 Controller */ + (void*) SPI1_TWI1_IRQHandler, /* 4 SPI1 & TWI1 Controller */ (void*) (0UL), /* 5 Reserved */ (void*) GPIOTE_IRQHandler, /* 6 GPIO */ (void*) ADC_IRQHandler, /* 7 ADC Controller */ @@ -172,11 +232,62 @@ void Reset_Handler(void) while (1); } +#ifdef DYNAMIC_HANDLERS + +void Default_Dynamic_Handler(void); + +/* exception number mirrors vector table */ +dynamic_handler_t exception_handlers[48] = +{ + 0, /* No Exception - Executing Thread */ + Default_Dynamic_Handler, /* Reset */ + Default_Dynamic_Handler, /* NMI */ + Default_Dynamic_Handler, /* Hard Fault */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + Default_Dynamic_Handler, /* SVC */ + 0, /* Reserved */ + 0, /* Reserved */ + Default_Dynamic_Handler, /* PendSV */ + Default_Dynamic_Handler /* SysTick */ +}; + +/* interrupt number: negative for non-configuable interrupts, positive for configurable interrupts */ +dynamic_handler_t *dynamic_handlers = &exception_handlers[16]; + +/** + * \brief Default interrupt handler for unused IRQs. + */ +void Default_Handler(void) +{ + // call the dynamic exception handler registered for the exception number of the the active vector + // field of the interrupt control and state register of the system control block + exception_handlers[SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk](); +} + +/** + * \brief Default dynamic interrupt handler for unused IRQs. + */ +void Default_Dynamic_Handler(void) +{ + while (1) + ; +} + +#else + /** * \brief Default interrupt handler for unused IRQs. */ -void Dummy_Handler(void) +void Default_Handler(void) { - while (1) { - } + while (1) + ; } + +#endif diff --git a/system/RFduino/source/system_nrf51.c b/system/RFduino/source/system_nrf51.c old mode 100755 new mode 100644 index 68a01e5..78ca0ac --- a/system/RFduino/source/system_nrf51.c +++ b/system/RFduino/source/system_nrf51.c @@ -25,7 +25,7 @@ device. /*lint ++flb "Enter library region" */ -#define __SYSTEM_CLOCK (16000000UL) +#define __SYSTEM_CLOCK (__XTAL) #define FLASH_RESET_VALUE (0xFFFFFFFF) diff --git a/variants/RFduino/libRFduinoGZLL.a b/variants/RFduino/libRFduinoGZLL.a new file mode 100644 index 0000000000000000000000000000000000000000..80e3f6b4e346e312574b61ba8dd5db964fcc7d5a GIT binary patch literal 60314 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 diff --git a/variants/RFduino/libRFduinoSystem.a.txt b/variants/RFduino/libRFduinoSystem.a.txt old mode 100755 new mode 100644 index 23a60d6..5b194ec --- a/variants/RFduino/libRFduinoSystem.a.txt +++ b/variants/RFduino/libRFduinoSystem.a.txt @@ -2,7 +2,8 @@ startup_nrf51822.o: 00000000 W ADC_IRQHandler 00000000 W CCM_AAR_IRQHandler -00000000 T Dummy_Handler +00000000 T Default_Dynamic_Handler +00000000 T Default_Handler 00000000 W ECB_IRQHandler 00000000 W GPIOTE_IRQHandler 00000000 W HardFault_Handler @@ -40,8 +41,10 @@ startup_nrf51822.o: U _ezero U _srelocate U _szero -00000000 R exception_table +00000000 D dynamic_handlers +00000000 D exception_handlers U main +00000000 R vector_table system_nrf51.o: 00000000 D SystemCoreClock From 13c28aaa97446c2f41c85b7f738fd8547f7dd0b8 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 18 Feb 2014 10:13:01 -0700 Subject: [PATCH 04/52] Fix for the UART stops receiving bytes after some time with BLE enabled --- CHANGELOG | 3 ++ cores/arduino/UARTClass.cpp | 9 +++- libraries/RFduinoBLE/RFduinoBLE.cpp | 14 ++++++ variants/RFduino/libRFduino.h | 2 + variants/RFduino/variant.cpp | 74 ++++++++++++++++++++++------- variants/RFduino/variant.h | 14 +++++- 6 files changed, 95 insertions(+), 21 deletions(-) mode change 100755 => 100644 cores/arduino/UARTClass.cpp mode change 100755 => 100644 libraries/RFduinoBLE/RFduinoBLE.cpp diff --git a/CHANGELOG b/CHANGELOG index b44fd45..71941ea 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ CHANGELOG +v 1.7.1 + - Fix for the UART stops receiving bytes after some time with BLE enabled + v 1.7 - Added RFduino to RFduino wireless communication support - Added pgmspace.h / PROGMEM support diff --git a/cores/arduino/UARTClass.cpp b/cores/arduino/UARTClass.cpp old mode 100755 new mode 100644 index d243fcc..7a2ee71 --- a/cores/arduino/UARTClass.cpp +++ b/cores/arduino/UARTClass.cpp @@ -118,9 +118,14 @@ void UARTClass::IrqHandler( void ) // did we receive data if (UART0_RXReady()) { - _rx_buffer->store_char(UART0_RXData()); + UART0_RXReset(); - UART0_RXReset( true ); + uint8_t ch = UART0_RXData(); + + if (UART0_RXErrorReset()) + return; + + _rx_buffer->store_char(ch); if (serialEvent) serialEvent(); diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp old mode 100755 new mode 100644 index f3ee3f7..0a63b4f --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -39,6 +39,20 @@ RFduinoBLEClass::RFduinoBLEClass() int RFduinoBLEClass::begin() { + if (UART0_State != UART0_State_NotStarted && UART0_BaudRate() > 9600) + { + const char *error = "BLE + UART > 9600 baud not permitted due to critical BLE timing requirements"; + + // attempt to notify user of error condition + const char *p = error; + while (*p) + UART0_TX(*p++); + + // don't continue + while (1) + ; + } + RFduinoBLE_device_name = deviceName; RFduinoBLE_advertisement_data = advertisementData; RFduinoBLE_advertisement_interval = advertisementInterval; diff --git a/variants/RFduino/libRFduino.h b/variants/RFduino/libRFduino.h index 3156ae0..1239f36 100644 --- a/variants/RFduino/libRFduino.h +++ b/variants/RFduino/libRFduino.h @@ -19,6 +19,8 @@ extern "C" { #define HIGH 1 #define DISABLE 5 +extern int RFduinoBLE_enabled; + // pass the pin number so you can use the same interrupt handler for all pins // return 0 to reset wake_detect bit (and not exit RFduino_ULPDelay) // return 1 to leave wake_detect bit alone (and exit RFduino_ULPDelay) diff --git a/variants/RFduino/variant.cpp b/variants/RFduino/variant.cpp index 1e3f3bb..1aa48c7 100644 --- a/variants/RFduino/variant.cpp +++ b/variants/RFduino/variant.cpp @@ -103,15 +103,32 @@ void init( void ) // NRF_UART0->EVENTS_TXDRDY is initialized to 0 at power up // we cannot test this event until after one byte has been transmitted -enum UART0_States -{ - UART0_State_NotStarted, - UART0_State_BeforeFirstTX, - UART0_State_AfterFirstTX -}; - UART0_States UART0_State = UART0_State_NotStarted; +int UART0_BaudRate() +{ + switch ((NRF_UART0->BAUDRATE & UART_BAUDRATE_BAUDRATE_Msk) >> UART_BAUDRATE_BAUDRATE_Pos) + { + case UART_BAUDRATE_BAUDRATE_Baud1200: return 1200; + case UART_BAUDRATE_BAUDRATE_Baud2400: return 2400; + case UART_BAUDRATE_BAUDRATE_Baud4800: return 4800; + case UART_BAUDRATE_BAUDRATE_Baud9600: return 9600; + case UART_BAUDRATE_BAUDRATE_Baud14400: return 14400; + case UART_BAUDRATE_BAUDRATE_Baud19200: return 19200; + case UART_BAUDRATE_BAUDRATE_Baud28800: return 28800; + case UART_BAUDRATE_BAUDRATE_Baud38400: return 38400; + case UART_BAUDRATE_BAUDRATE_Baud57600: return 57600; + case UART_BAUDRATE_BAUDRATE_Baud76800: return 76800; + case UART_BAUDRATE_BAUDRATE_Baud115200: return 115200; + case UART_BAUDRATE_BAUDRATE_Baud230400: return 230400; + case UART_BAUDRATE_BAUDRATE_Baud250000: return 250000; + case UART_BAUDRATE_BAUDRATE_Baud460800: return 460800; + case UART_BAUDRATE_BAUDRATE_Baud921600: return 921600; + case UART_BAUDRATE_BAUDRATE_Baud1M: return 1000000; + } + return 0; +} + void UART0_Start( int dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) { // must STOP before restarting @@ -165,6 +182,20 @@ void UART0_Start( int dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) attachInterrupt(UART0_IRQn, UART0_Interrupt); UART0_State = UART0_State_BeforeFirstTX; + + if (RFduinoBLE_enabled && dwBaudRate > 9600) + { + const char *error = "BLE + UART > 9600 baud not permitted due to critical BLE timing requirements"; + + // attempt to notify user of error condition + const char *p = error; + while (*p) + UART0_TX(*p++); + + // don't continue + while (1) + ; + } } void UART0_Stop() @@ -213,15 +244,17 @@ void UART0_TX( const uint8_t uc_data ) // UART0_RXData declared inline in variant.h -void UART0_RXReset( int isr ) +void UART0_RXReset() { - // errors - - // UART0_RXReset() should only be called after a byte is received (no need to check UART0_State) + NRF_UART0->EVENTS_RXDRDY = 0; +} +int UART0_RXErrorReset() +{ if (NRF_UART0->ERRORSRC & UART_ERRORSRC_OVERRUN_Msk) { NRF_UART0->ERRORSRC = (UART_ERRORSRC_OVERRUN_Clear << UART_ERRORSRC_OVERRUN_Pos); + return true; } /* else if (NRF_UART0->ERRORSRC & UART_ERRORSRC_PARITY_Msk) @@ -232,6 +265,7 @@ void UART0_RXReset( int isr ) else if (NRF_UART0->ERRORSRC & UART_ERRORSRC_FRAMING_Msk) { NRF_UART0->ERRORSRC = (UART_ERRORSRC_FRAMING_Clear << UART_ERRORSRC_FRAMING_Pos); + return true; } /* else if (NRF_UART0->ERRORSRC & UART_ERRORSRC_BREAK_Msk) @@ -239,8 +273,8 @@ void UART0_RXReset( int isr ) NRF_UART0->ERRORSRC = (UART_ERRORSRC_BREAK_Clear << UART_ERRORSRC_BREAK_Pos); } */ - else - NRF_UART0->EVENTS_RXDRDY = 0; + + return false; } uint8_t UART0_RX() @@ -249,13 +283,17 @@ uint8_t UART0_RX() // if you call UART0_RX(), you expect UART0 to be Started (no need to check UART0_State) - // byte available - while (! UART0_RXReady()) - ; + do + { + // byte available + while (! UART0_RXReady()) + ; + + UART0_RXReset(); - uc_data = UART0_RXData(); + uc_data = UART0_RXData(); - UART0_RXReset( false ); + } while (UART0_RXErrorReset()); return uc_data; } diff --git a/variants/RFduino/variant.h b/variants/RFduino/variant.h index 343e9f3..3a2cd54 100644 --- a/variants/RFduino/variant.h +++ b/variants/RFduino/variant.h @@ -133,6 +133,17 @@ extern uint8_t Pin_Occupied_for_PWM[PINS_COUNT]; // Determines if particular pin #define UART_DEFAULT_RX_PIN 0 #define UART_DEFAULT_TX_PIN 1 +typedef enum +{ + UART0_State_NotStarted, + UART0_State_BeforeFirstTX, + UART0_State_AfterFirstTX +} UART0_States; + +extern UART0_States UART0_State; + +int UART0_BaudRate(); + void UART0_Start( int dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ); void UART0_Stop(); void UART0_FlushTX(); @@ -150,7 +161,8 @@ static uint8_t __INLINE UART0_RXData() return NRF_UART0->RXD; } -void UART0_RXReset( int isr ); +void UART0_RXReset(); +int UART0_RXErrorReset(); uint8_t UART0_RX(); /* From a23c6517f25152331366112969b4e512e2fb088c Mon Sep 17 00:00:00 2001 From: RFduino Date: Wed, 12 Mar 2014 15:51:13 -0600 Subject: [PATCH 05/52] PPI channel and wire speed enhancement --- CHANGELOG | 4 ++ cores/arduino/wiring_analog.c | 51 ++++++++++++++----------- cores/arduino/wiring_analog.h | 1 + libraries/RFduinoBLE/RFduinoBLE.cpp | 2 + libraries/RFduinoGZLL/RFduinoGZLL.cpp | 2 + libraries/Wire/Wire.cpp | 29 ++++++++++---- libraries/Wire/Wire.h | 5 +++ source/libRFduinoGZLL/libRFduinoGZLL.c | 6 +++ variants/RFduino/libRFduino.a | Bin 8504 -> 8952 bytes variants/RFduino/libRFduino.h | 3 ++ variants/RFduino/libRFduinoGZLL.a | Bin 60314 -> 60386 bytes 11 files changed, 72 insertions(+), 31 deletions(-) mode change 100755 => 100644 cores/arduino/wiring_analog.c mode change 100755 => 100644 cores/arduino/wiring_analog.h mode change 100755 => 100644 libraries/Wire/Wire.h diff --git a/CHANGELOG b/CHANGELOG index 71941ea..9ae7240 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 1.7.2 + - Enhancement to PPI channel selection to eliminate potential conflicts + - Added the ability to select I2C speed to Wire Library (100, 250 or 400 kbps) + v 1.7.1 - Fix for the UART stops receiving bytes after some time with BLE enabled diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c old mode 100755 new mode 100644 index 2ccc52e..1aa0585 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -120,30 +120,35 @@ uint32_t analogRead(uint32_t ulPin) return ulValue; } +int find_free_PPI_channel(int exclude_channel) +{ + // For BLE / NonBLE, find first free PPI Channel in the range 0-7. Note the channels 8-15 is occupied by SoftDevice. Maximum 4 PPI pairs. + // For GZLL only, find first free PPI Channel in the range 3-8. Note the channels 0-2 and TIMER2 are used by Gazell. Maximum 3 PPI pairs. + // For GZLL and BLE, find first free PPI Channel in the range 3-7. Maximum 2 PPI pairs. + int start = 0; + int end = 8; + + int i; + + if (RFduinoGZLL_used) + start = 3; + + if (! RFduinoBLE_used) + end = 16; + + for (i = start; i < end; i++) + if (! (NRF_PPI->CHEN & (1 << i))) + if (i != exclude_channel) + return i; + + return 255; +} + void turn_On_PPI_to_GPIO_for_PWM(uint32_t ulPin, uint32_t gpiote_channel, NRF_TIMER_Type* Timer, uint32_t CC_channel) { - uint32_t i; - uint8_t chan_0 = 255; - uint8_t chan_1 = 255; - // Initialize Programmable Peripheral Interconnect - // Find first free PPI Channel in the range 0-7. Note the channels 8-15 is occupied by SoftDevice - for (i = 0; i < 8; i++) - { - if (!(NRF_PPI->CHEN & (1 << i))) - { - chan_0 = i; - // Find second free PPI Channel in the range 0-7. Note the channels 8-15 is occupied by SoftDevice - for (i = (chan_0 + 1); i < 8; i++) - { - if (!(NRF_PPI->CHEN & (1 << i))) - { - chan_1 = i; - break; - } - } - break; - } - } + // Initialize Programmable Peripheral Interconnect + int chan_0 = find_free_PPI_channel(255); + int chan_1 = find_free_PPI_channel(chan_1); if ((chan_0 != 255) && (chan_1 != 255)) { @@ -383,7 +388,7 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) { else { // All channels of Timer1 is occupied, need to use Timer2 - if (Timer2_Compare_Unit_Occupied_by_Pin[0] == 255) + if (!RFduinoGZLL_used && Timer2_Compare_Unit_Occupied_by_Pin[0] == 255) { // Timer2 is not used: need to initialize it diff --git a/cores/arduino/wiring_analog.h b/cores/arduino/wiring_analog.h old mode 100755 new mode 100644 index b854cd8..ca87c63 --- a/cores/arduino/wiring_analog.h +++ b/cores/arduino/wiring_analog.h @@ -102,6 +102,7 @@ extern void analogReadResolution(int res); */ extern void analogWriteResolution(int res); +extern int find_free_PPI_channel(int exclude_channel); extern void turn_Off_GPIOTE_PPI_from_GPIO(uint32_t ulPin); #ifdef __cplusplus diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index 0a63b4f..d16a2e8 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -31,6 +31,8 @@ volatile int& RFduinoBLEClass::radioActive = RFduinoBLE_radioActive; RFduinoBLEClass::RFduinoBLEClass() { + ::RFduinoBLE_used = 1; + deviceName = "RFduino"; advertisementData = "sketch"; advertisementInterval = 80; diff --git a/libraries/RFduinoGZLL/RFduinoGZLL.cpp b/libraries/RFduinoGZLL/RFduinoGZLL.cpp index 9056a56..9642aa2 100644 --- a/libraries/RFduinoGZLL/RFduinoGZLL.cpp +++ b/libraries/RFduinoGZLL/RFduinoGZLL.cpp @@ -53,6 +53,8 @@ enter and exit from the network at any time. RFduinoGZLLClass::RFduinoGZLLClass() { + ::RFduinoGZLL_used = 1; + txPowerLevel = +4; } diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 6618bad..0c396b8 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -110,8 +110,9 @@ static inline bool TWI_STATUS_DNACK(uint32_t status) { TwoWire::TwoWire(NRF_TWI_Type *_twi) : twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0), - txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status( - UNINITIALIZED) { + txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), + status(UNINITIALIZED), speed(100) +{ // Empty } @@ -182,8 +183,19 @@ bool TwoWire::twi_master_init(void) twi->EVENTS_TXDSENT = 0; twi->PSELSCL = SCL_pin_number; twi->PSELSDA = SDA_pin_number; - twi->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos; - rfduino_ppi_channel_unassign(7); + + uint32_t freq TWI_FREQUENCY_FREQUENCY_K100;; + if (speed == 250) + freq = TWI_FREQUENCY_FREQUENCY_K250; + else if (speed == 400) + freq = TWI_FREQUENCY_FREQUENCY_K400; + twi->FREQUENCY = freq; + + PPI_channel = find_free_PPI_channel(255); + + // reserve the PPI channel + rfduino_ppi_channel_assign(PPI_channel, 0, 0); + twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; return twi_master_clear_bus(); @@ -202,11 +214,11 @@ uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t iss if ((data_length == 1) && (issue_stop_condition == 1)) { - rfduino_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_STOP); + rfduino_ppi_channel_assign(PPI_channel, &twi->EVENTS_BB, &twi->TASKS_STOP); } else { - rfduino_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_SUSPEND); + rfduino_ppi_channel_assign(PPI_channel, &twi->EVENTS_BB, &twi->TASKS_SUSPEND); } twi->TASKS_STARTRX = 1; while(true) @@ -230,7 +242,7 @@ uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t iss { if (issue_stop_condition == 1) { - rfduino_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_STOP); + rfduino_ppi_channel_assign(PPI_channel, &twi->EVENTS_BB, &twi->TASKS_STOP); } } @@ -249,7 +261,8 @@ uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t iss twi->EVENTS_STOPPED = 0; } - rfduino_ppi_channel_unassign(7); + // unassign the PPI channel (but keep it reserved) + rfduino_ppi_channel_assign(PPI_channel, 0, 0); return bytes_received; } diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h old mode 100755 new mode 100644 index 4c0929a..d8c9bb7 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -61,6 +61,8 @@ class TwoWire : public Stream { public: + int speed; // 100, 250 or 400 kbps + TwoWire(NRF_TWI_Type *twi); void begin(); void beginOnPins(uint8_t clock_pin, uint8_t data_pin); @@ -103,6 +105,9 @@ class TwoWire : public Stream { uint8_t SDA_pin_number; uint8_t SCL_pin_number; + // PPI channel + uint8_t PPI_channel; + // RX Buffer uint8_t rxBuffer[BUFFER_LENGTH]; uint8_t rxBufferIndex; diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.c b/source/libRFduinoGZLL/libRFduinoGZLL.c index 90f1108..8ce6c37 100644 --- a/source/libRFduinoGZLL/libRFduinoGZLL.c +++ b/source/libRFduinoGZLL/libRFduinoGZLL.c @@ -39,6 +39,8 @@ enter and exit from the network at any time. #include "libRFduinoGZLL.h" +extern int RFduinoGZLL_enabled; + // -20 dBm to +4 dBm = default +4 dBm int RFduinoGZLL_tx_power_level = 4; @@ -79,6 +81,8 @@ int RFduinoGZLL_begin(device_t device) if (! nrf_gzll_enable()) return 3; + RFduinoGZLL_enabled = 1; + return 0; } @@ -111,6 +115,8 @@ void RFduinoGZLL_end(void) NVIC_DisableIRQ(RADIO_IRQn); NVIC_DisableIRQ(TIMER2_IRQn); + + RFduinoGZLL_enabled = 0; } void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) diff --git a/variants/RFduino/libRFduino.a b/variants/RFduino/libRFduino.a index 7270b1e689839d552fe8bb70ee2f411619668402..6c45ed5d8917a5f917f4a019a4d2dfb89045ce1b 100644 GIT binary patch delta 1298 zcmb`HO-NKx6vzMXjgs%pWHZj#*c;KC1{#_3>CBixCe498A^GJ}E6psFV;o(py9*+x=jJ8CiTW|C(@VbH0 zn36`cBAz|0KQ&5Jk0ocn`;W$Lt{P{7Q?5Dv*#XxB-Eh|ejZ`NgjV&o7NmQoj6j6Jg zrinU<+$#2is4q`l?vyb^6jHJKME8iQ6n!R|&1bfHQpPJHp<+`+OZnIbqP6^cJ1bH~ z8Kv1Z$BB}8dQCJ$lvGu=c@rAsQE!7*rEHV3oywk3c2wCZWgjU!N7gHwd_L`s-0y49 z7G>JkrhSr6eD%#UbRXL32)KHhW(iH+wL#NCbA7A^fI5dPuiTn-RaTeEq$M_g%mw)! zO&+)E<)kIFFLK%n$`wl(KiA{Z6Yyv1)=Mc37m))I6vrc|(Ciddo#KVVf#`4f#JT)- zO4KM`I2?%arZ$EHE!jk1RNJ?x+fMG{K@iJDybIroI1Fd*Q0)BO*}3X>`oAy#_6)93 z1HBiRU_A-kWbFrTu?_;0tY_`RXFso(mG8dkvoDd}lVkq|@8$R~(7`$abh2IssFl(_ z)=~Px=lJ1@Y!-eGmErQHuzw4Bk31o2Gvsx#w;b3(%FXBzrU#(@FgF48$D#ahnXd!y zS!rj>?59nwuu|t$R$Ba5R=QSqNzHNKAv10AF)QUiW2O8V(gS=7v+ST3Ye>x-0J&gJ X054fBU?Jz2g95!? delta 1024 zcmbu7O-K}B7{~uJCc49J?z*lk&T69@<)L!Kb$9Ip#L~?}wunIxnWRFNsreBd3_U~$ z6$!5$BZIyU7RFvY6clvmQqe^^2$N*lu9MimStPg{(M_j!e+v0y#|0FpuPQ{CzI_s*xh!lV|ZdUH56SshTAa8QRN8grNQ zJ3iI!&#Fa#MQ+u9SNF|T0d=fMs4FEI-!iS(u~piWyloF=e9vjzEGy5`-sJ5CZH;C- zxvEgcS5XaAICh$5)7*ZKX)QF%$puO?zTSN9C~Y*~?>=po=8pNDww$*EVa`WOJEL3= zr}TmX^&q@OkGg1d(e9$hfi|upk*(TAwTJJkY9O*pyPxdaz zs07w^s@F8tP!v^{1I4*md2wOjofqCfYO2PJt8UW@eEBPS#*Aw})HSm{P^!5JxB96W z_tkol7PW3hRaq>Un~#lZB`e;HQW(Ov+}`R}`mZ}M&Dc3UdKQ=x9s*{BM}P~$9$;2@ z*ga^8%Yh5!4j5(bk?WnFM}PZn$)5mPg@eF;;Ypy&BZq`xoB}upj3M=@CK}=}GQ45A zH%ISO<+Yop8TCtaBe0p2$@mE)1aN*BJmi=ce+tAiNv} zK`R3uYAF%VQgILBp%4fn>OrJn!4^#|y;=~_Tk32~LX9+_Vutt4>^CzzyKkA@g*D~V znlkTiizgHD*g*Vl@SO1kp!fQpp??tIZ!qitXoS(|kbHEeWibBxV%hfq`@?7!Y(dOu zy1RehfcOT`42BFAKmU$b9RMvrxW34C9AJNldByIk-5bn%-AW=B$EA?Yvbg1a;4_~! zX{*yYZ5>vpO=-`hZNUlPc_tgl~@r9~cZngt>a7WeH1|AB8SsqW4{)$&f zKgL^uu%(LuTMah!)uuNfAOhpc5v&eBj1S|-{6PU9P{ zSr_RpK4a)SHil=8yki^#!8`Q7%fT($1Zoj#-k;(mW1$N4frrou?Z73eij1GC#&sHZ zLI-53JXhgPm}$tLYv8vV_!0xr*W+N;scV-mU!6i`?#7X$8%7V+Gev+_0C4mH9G2V< zpjLS$PMppJ98rKVX=4Br(ozp($;$jWX=&08X{p|cSd#CRSYn|1jB*~W1S%RIdF^5$ z^ibK;EG}`eciB;M2xtHE12saennM(d TUTd9{UUt_Xc$CHb+lKWA=M!Q= delta 1444 zcmaEKoq5)E<_Xg529{=)rk2JNm3-^77#Os)NW&)I7#PUGPKOv6&~ZJw0Eq9SL^oVd zbIVF5F)-l9_4p*|AXksqb(A|`^Ew6we7GJYd3YHnK6#9Rfeu(5Zpo8Z3=FvO<_XN4 zVz7KOd4Z%jqtRp=XD!Br$&V!$3Nd>zDPK-+P`=G@Ih|uK%R`0-ljlh}F-lE-C?(9S z@j!I)cPU39wg>;e|NGCN!FYi|f#CtO0>|FXVbUDTj0%(E<@^~fCa;&%2C^F!g(tt0 z6JQPCVPFuL%q*|WdWC_3K>{ppCocfB&|hAi^$k!=11#1D6f2lKA1Efm2#hYU*gbgx z)&`({jme*Z`a6K)jFTTm2v62i5Mb<>Y_Fis+5;5R28-1J#kNoGS5Rkr1=7zr`GUI= zrw2O&g8?(h+IW3=)(S2LhNY9`Jpw1kC|+ZfnQW}o&zLj$u+n3obC)Y?+XD45NC2@A z0}lfahyw)zKw2Bf2MK8au@D0vgA0^j0_F=agiYQbCofoqrmJhSzX}iI Date: Tue, 8 Apr 2014 15:24:03 -0600 Subject: [PATCH 06/52] iBeacon Support --- CHANGELOG | 3 ++ libraries/RFduinoBLE/RFduinoBLE.cpp | 10 +++++ libraries/RFduinoBLE/RFduinoBLE.h | 5 +++ .../RFduinoBLE/examples/iBeacon/iBeacon.ino | 35 +++++++++++++++ .../iBeaconSettings/iBeaconSettings.ino | 41 ++++++++++++++++++ variants/RFduino/libRFduinoBLE.a | Bin 37024 -> 37940 bytes variants/RFduino/libRFduinoBLE.h | 12 +++++ 7 files changed, 106 insertions(+) mode change 100755 => 100644 libraries/RFduinoBLE/RFduinoBLE.h create mode 100644 libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino create mode 100644 libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino mode change 100755 => 100644 variants/RFduino/libRFduinoBLE.a mode change 100755 => 100644 variants/RFduino/libRFduinoBLE.h diff --git a/CHANGELOG b/CHANGELOG index 9ae7240..f7cd25d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ CHANGELOG +v 1.8 + - iBeacon Enhancement + v 1.7.2 - Enhancement to PPI channel selection to eliminate potential conflicts - Added the ability to select I2C speed to Wire Library (100, 250 or 400 kbps) diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index d16a2e8..018e591 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -35,6 +35,12 @@ RFduinoBLEClass::RFduinoBLEClass() deviceName = "RFduino"; advertisementData = "sketch"; + iBeacon = false; + // iBeacon Proximity UUID + uint8_t uuid[16] = {0xE2, 0xC5, 0x6D, 0xB5, 0xDF, 0xFB, 0x48, 0xD2, 0xB0, 0x60, 0xD0, 0xF5, 0xA7, 0x10, 0x96, 0xE0}; + memcpy(iBeaconUUID, uuid, sizeof(iBeaconUUID)); + iBeaconMajor = 0; + iBeaconMinor = 0; advertisementInterval = 80; txPowerLevel = +4; } @@ -57,6 +63,10 @@ int RFduinoBLEClass::begin() RFduinoBLE_device_name = deviceName; RFduinoBLE_advertisement_data = advertisementData; + RFduinoBLE_ibeacon = iBeacon; + memcpy(RFduinoBLE_ibeacon_uuid, iBeaconUUID, sizeof(RFduinoBLE_ibeacon_uuid)); + RFduinoBLE_ibeacon_major = iBeaconMajor; + RFduinoBLE_ibeacon_minor = iBeaconMinor; RFduinoBLE_advertisement_interval = advertisementInterval; RFduinoBLE_tx_power_level = txPowerLevel; diff --git a/libraries/RFduinoBLE/RFduinoBLE.h b/libraries/RFduinoBLE/RFduinoBLE.h old mode 100755 new mode 100644 index 07f5a4b..ee8c23b --- a/libraries/RFduinoBLE/RFduinoBLE.h +++ b/libraries/RFduinoBLE/RFduinoBLE.h @@ -42,6 +42,11 @@ class RFduinoBLEClass // default "sketch" const char *advertisementData; + bool iBeacon; + uint8_t iBeaconUUID[16]; + unsigned short iBeaconMajor; + unsigned short iBeaconMinor; + // in ms (converted to 0.625ms units) - range 20ms to 10.24s - default 80ms int advertisementInterval; diff --git a/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino b/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino new file mode 100644 index 0000000..7301b51 --- /dev/null +++ b/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino @@ -0,0 +1,35 @@ +/* +The sketch demonstrates iBecaon from an RFduino +*/ + +#include + +// pin 3 on the RGB shield is the green led +int led = 3; + +void setup() { + // led used to indicate that iBeacon has started + pinMode(led, OUTPUT); + + // do iBeacon advertising + RFduinoBLE.iBeacon = true; + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} diff --git a/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino b/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino new file mode 100644 index 0000000..2a2f6d6 --- /dev/null +++ b/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino @@ -0,0 +1,41 @@ +/* +The sketch demonstrates iBecaon from an RFduino +*/ + +#include + +// pin 3 on the RGB shield is the green led +int led = 3; + +void setup() { + // led used to indicate that iBeacon has started + pinMode(led, OUTPUT); + + // do iBeacon advertising + RFduinoBLE.iBeacon = true; + + // override the default iBeacon settings + uint8_t uuid[16] = {0xE2, 0xC5, 0x6D, 0xB5, 0xDF, 0xFB, 0x48, 0xD2, 0xB0, 0x60, 0xD0, 0xF5, 0xA7, 0x10, 0x96, 0xE0}; + memcpy(RFduinoBLE.iBeaconUUID, uuid, sizeof(RFduinoBLE.iBeaconUUID)); + RFduinoBLE.iBeaconMajor = 1234; + RFduinoBLE.iBeaconMinor = 5678; + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a old mode 100755 new mode 100644 index 90f240222e373b5f599667e28fff746c1784d081..a981d6ec22eb6f03aa467b01fd1896457dcfdca6 GIT binary patch delta 3557 zcmcIne{2)?6@PcOAvVph1V4 zcg#wW(amNyy?lu|6bc4dcfjksWyRiM+kzT+VHGs7?Un=FS$5OHxDVLg1-~!eY|=>W zmSQ^>Hl=Q#e@5m+m!e8nE$=8V&1_bVhfTtrkNHW{QakD1jlWUyhI@Q}|N}8nJwj*oXlOVM#ihvtJ%og!`n2QEiwodkCHY;&c8zE zts0@oBc03k9BwXu*>nbcjTy7_Kyr)hn2vWgsl8#l*cl+F%`$kZCZ-h^UuAQ)kB&bk z3+}23T}qEXfOAfdMWi~lTsp0WL@l`_B{}IO^`vsMPjG`rFX+AuOL>mM@@oq)O&0}? zheW|$&4}g=7wK^I>GxuO`P)gKx-5QD321Y!mrtqF80CG*iq`-y92w60>@<`>d$*n0RCBmJ@6F<-l{vBeh* zu51Kf-{`1sF2?+enb6)dcX3?EdsQ{_jz>2{+ctJ~cC7aWS2nYq#WijJ8bOboh{pOK zk0xWgVu{gzpNn30_S51ovWv&2(pNq;#aZLk07Y1NkR7s*Sd%E(HR;dxE~|=Cg(ig^ zUDjvkET2PZ3Z;O?{T8JRN*6S#rKHO`AprDf($Nx$yUboLk*wEHH-YOAWV0pJmXHPW zu&;?gPfVTGFmHIy6log=9q7ximJ|Tgl=Sb_Q!{vWp5Zhxr`R= zGp{3~pHJwBV~=Re9G{otMe9c~-!F);VJ`M3$mC}2L8eHn)Q0J((nh>!5F@gkUCy#f zgUQyj9~o`tWzDF{jrJ5W-CDFrfe$epYsHQX75IE*jyY1mOd?aNMLTg9M(@>yf;{A- z_v#!nxxG?zdgaIYWqb9m5kZ?Y-oAZnr3O=R#dnPq;!9x1D_e2Dx<>_C}R+*1ND zh0|Y&1_SI554p`QfZ_Dd%RV;o-8}noFjBS!|1*gBVoc@y@n z`TBd|K_d>2_8i=s=VgMLf;cr0G3*y;_BHwT?C&m#T}jy4>MDD~Cc}~r3=Zzgx1^7V zoMD1`xWP6JS6AlOw*m%@D5dP_;qquc>&uBi4fPjP>jwu~T%xIIV`=t5LlZO<$c^b2 zt6Dhj5}S2Dmg>L-$_{$#Hx|fWD3Hesr0CQmG1x_R8k}yx-3DXA?pb|u)&b^fOY8?m#*Ym=a1M#6hD53qw&~q|Ih#=qN4-b zvL|BxN!ozq{Bg-*5og+4eU`IsOYVilKw@-&+4&{xL*a@4&leSYg_BYM^r2}R0HA$F zNNwTQ>$A7vff^xsQ2#mNcNqF1y=k_Ex;^>1$v>eVVtg-PqxCoeLex{!Y{LNe5RT}_ zwk?Ik{iH|&tR<|}6WNvkY$16kK%8(Fz~h9NXdfYd+f5MSkK+r37-yPr6yW=WXm<&b z-wkk?um#{}gb{!YA==|dD~LQMzCsFge3uXtzE6l9xJ9^*y(w-_?Zq!?lx&DN1+ZZa zS{az;7|CA-I6;W=Im1pX!>*?#Jw>$@1Kc+3{z8b&FT!m^ypM1{fI@fxU^n4Gfa8cM zQp}J73;3ZyyhVtP?+_w?gK!MscZAri4+y^m@FzlCXdd@7**6lZ01p~+8zJ_y2ay(f z3*mMwgb){{pNACi3N8dG@E3K6upKKT#N%Z@A@)lp+z4=lFa$73xC!7{!p{MGjqvk$ z;1aF@_$FZoz!^f^F*Ag?U>6A20lZ515baD1W;>*B9om94C}9@+h6bX>7m07gkN-wB zW&bfqPcK&&<^7wGjs%Y1ldt*Pr+1ha8XnAHDNi41{qCYXMbBsVt;kc{-q%;0r$|l& Giv9`L!taX! delta 2725 zcma)8eQZ-z6hH61cC3YcvBJK(?X8cFnX9NK=bhb*JW=3 zsMT%+c=|%TR&NAQsu$Llz<<_VV*vkFhpPaFt5~XO3v1v4tSK!uX5_!+1+dxJeU16B zR>ziV0}GV7GR~c)b=b?xM0Ve|Jo9=o&I~|XAwvn2fsI|#zRFdyh9t)AV7HQfP5FtJ zMfop@{ji`s5<+>~uf`aE(&Q{&!A)}F zrKx^z-jJdE+NaqTZju+jo9gxEcJz7;tB*RlNkKd}#Yu*dCZ`Yq*t@W8&y{h~T%3DaD$va^hN|U&vqb|KGvnt(`>5{?? z?2F_j5n*CutxxtDH)V|+hHwQTM7 zY+IEiS;8)_a3Ze*iX0}6dB6BLQ$JR>Q&%=6~T8rj6XCC|lM2@}P&1+v}Dvh+_B z80BXu5hikL(`NlaG>(SPj(J$KeuZmp837mva2#u5$xT@3b^##y4DZbjPPi_xc+k)GJR@TR5vB6XiyO(Nkbo+yCgZ^-^KiEA0)|P<*tGjWd z-?_=-ac{6ztST!9Yk#lY%w;XBv{qn2OM8g@l~Tw$(`sTT)116+2oDYIPCNS}qgNM2 zmM*it#WlJ^$g*YjC9;uO&y36(-6%4AI>ywbx^)jiII?ZOPl1DM}tDNiOGAWer0`r&tMm7(t!| zKAW(jqs&jwi!hD?&$!aeCF7`23pMryRFbLJHCL53WvEgig<`6OMnv__yx4cqk7ErO zTSu#k9%}4qR1ETr^8P{b$%-8nii$zyLT%z%@F}At(WRN4vgIX(a7*Yl ztf0O>wmEyhz~AQBk9lvfgW+^GVoZ-z&@8afL^xO`KdXNNnBj&>WHf_Q@lQg|p`KU- zC{Cm}RD3-o6ah-+#VbjL^-4ekI&#dMFQqgq7N2Z!=S#YfV$ra^{4DMUJKL9^QJN5# zvSN+Z6jXA!eP1hlKC%w8q!!Ew_~-H6^Y}XorzOb1?KAoqx4^~6co9r1oW_+wvkY~% zZ1A-0=3aJRo07zy}q3YkYI*abu7_wZj_#^lkVy zCja#SD+n=;oe=Gm34J@jBEpyBcD)XT)nwSp-ZW=LIsoto`c8mBLJYf$5Z{}_gqZ;E z5n`*8gk1oi6QbXFM1C84X~dOM|F^J2fz_R^dBe0q+M3{6++D0G$J3sfe^lg zXP?jw@FyW%(s)k!b+|l)E?gcSBEaMAkxm9ojDc_iz6b~%IC8>Gm?1)1XF^PT1z{b4 zgYX$;KkbaKH|-lL6i>yLP`h8*;nrRoeg~E--%bw3yR%|1lyojk{F;hQl^)A7uGRN*7@Ff2Yi6I|~ diff --git a/variants/RFduino/libRFduinoBLE.h b/variants/RFduino/libRFduinoBLE.h old mode 100755 new mode 100644 index ed71e81..0b00341 --- a/variants/RFduino/libRFduinoBLE.h +++ b/variants/RFduino/libRFduinoBLE.h @@ -25,6 +25,18 @@ extern const char *RFduinoBLE_advertisement_data; // in ms (converted to 0.625ms units) - range 20ms to 10.24s - default 80ms extern int RFduinoBLE_advertisement_interval; +// default false (false = regular advertising, true = ibeacon advertising) +extern bool RFduinoBLE_ibeacon; + +// default iBeacon Proximity UUID +extern uint8_t RFduinoBLE_ibeacon_uuid[16]; + +// default 0 +extern unsigned short RFduinoBLE_ibeacon_major; + +// default 0 +extern unsigned short RFduinoBLE_ibeacon_minor; + // -20 dBm to +4 dBm - default +4 dBm extern int8_t RFduinoBLE_tx_power_level; From 7e118f1e8750b9447c7a256fd4b1e18dee6f3d2c Mon Sep 17 00:00:00 2001 From: RFduino Date: Fri, 11 Apr 2014 15:37:28 -0600 Subject: [PATCH 07/52] Fix for ADC and SPI Cleanup --- CHANGELOG | 4 ++++ cores/arduino/wiring_analog.c | 11 +++++++-- libraries/SPI/SPI.cpp | 42 +++++++++-------------------------- libraries/SPI/SPI.h | 8 +++---- 4 files changed, 27 insertions(+), 38 deletions(-) mode change 100755 => 100644 libraries/SPI/SPI.cpp mode change 100755 => 100644 libraries/SPI/SPI.h diff --git a/CHANGELOG b/CHANGELOG index f7cd25d..08d9d9b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 1.8.1 + - Fixed conflict between Analog to Digital Conversion and UART + - Cleaned up SPI library + v 1.8 - iBeacon Enhancement diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 1aa0585..aa708a3 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -97,11 +97,18 @@ uint32_t analogRead(uint32_t ulPin) if ((ulPin > 0) && (ulPin < PINS_COUNT)) // Only pins 1-6 is avaliable for using as ADC inputs { pselValue = (1 << (ulPin + 1)); // Calculate PSEL value - NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos)| // 10bit ADC resolution + if (analog_reference == ADC_CONFIG_REFSEL_External) + NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos)| // 10bit ADC resolution (adc_input_selection << ADC_CONFIG_INPSEL_Pos)| // DEFAULT: Analog input specified by PSEL with 1/3 prescaling used as input for the conversion - (analog_reference << ADC_CONFIG_REFSEL_Pos)| // DEFAULT: Use supply voltage with 1/3 prescaling as reference for conversion. Only usable when supply voltage is between 2.5V and 3.6V + (ADC_CONFIG_REFSEL_External << ADC_CONFIG_REFSEL_Pos)| (pselValue << ADC_CONFIG_PSEL_Pos)| // Select ADC input (external_reference << ADC_CONFIG_EXTREFSEL_Pos); // DEFAULT: Use analog reference 0 as reference if selected external reference + else + NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos)| // 10bit ADC resolution + (adc_input_selection << ADC_CONFIG_INPSEL_Pos)| // DEFAULT: Analog input specified by PSEL with 1/3 prescaling used as input for the conversion + (analog_reference << ADC_CONFIG_REFSEL_Pos)| // DEFAULT: Use supply voltage with 1/3 prescaling as reference for conversion. Only usable when supply voltage is between 2.5V and 3.6V + (pselValue << ADC_CONFIG_PSEL_Pos)| // Select ADC input + (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); NRF_ADC->INTENCLR = 0xFFFFFFFF; NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos); // Enable ADC NRF_ADC->TASKS_START = 1; // Start A-D conversion diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp old mode 100755 new mode 100644 index d3f221b..2a2529b --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -65,39 +65,21 @@ void SPIClass::begin() void SPIClass::end() { - spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); + spi->ENABLE &= ~(SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); } void SPIClass::setBitOrder(BitOrder _bitOrder) { if (_bitOrder == MSBFIRST) - spi->CONFIG |= (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos); + spi->CONFIG &= ~(SPI_CONFIG_ORDER_LsbFirst << SPI_CONFIG_ORDER_Pos); else - spi->CONFIG |= (SPI_CONFIG_ORDER_LsbFirst << SPI_CONFIG_ORDER_Pos); + spi->CONFIG |= (SPI_CONFIG_ORDER_LsbFirst << SPI_CONFIG_ORDER_Pos); } void SPIClass::setDataMode(uint8_t _dataMode) { - if (_dataMode == SPI_MODE0) - { - setCPOL(0); - setCPHA(0); - } - else if (_dataMode == SPI_MODE1) - { - setCPOL(0); - setCPHA(1); - } - else if (_dataMode == SPI_MODE2) - { - setCPOL(1); - setCPHA(0); - } - else if (_dataMode == SPI_MODE3) - { - setCPOL(1); - setCPHA(1); - } + setCPOL((_dataMode & 0x02) >> 1); + setCPHA(_dataMode & 0x01); } void SPIClass::setCPOL(bool _activeLow) @@ -105,7 +87,7 @@ void SPIClass::setCPOL(bool _activeLow) if (_activeLow) spi->CONFIG |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos); else - spi->CONFIG |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos); + spi->CONFIG &= ~(SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos); } void SPIClass::setCPHA(bool _trailing) @@ -113,7 +95,7 @@ void SPIClass::setCPHA(bool _trailing) if (_trailing) spi->CONFIG |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); else - spi->CONFIG |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos); + spi->CONFIG &= ~(SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); } void SPIClass::setFrequency(int _speedKbps) @@ -136,21 +118,17 @@ void SPIClass::setFrequency(int _speedKbps) void SPIClass::setClockDivider(uint8_t _divider) { - } byte SPIClass::transfer(uint8_t _data) { -// Serial.println(_data); spi->TXD = _data; - while (spi->EVENTS_READY == 0) - ; + while (spi->EVENTS_READY == 0) + ; + spi->EVENTS_READY = 0; _data = spi->RXD; -// Serial.println(_data); - - spi->EVENTS_READY = 0; return _data; } diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h old mode 100755 new mode 100644 index b46fd98..c18b671 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -40,10 +40,10 @@ #include "variant.h" #include -#define SPI_MODE0 0x02 -#define SPI_MODE1 0x00 -#define SPI_MODE2 0x03 -#define SPI_MODE3 0x01 +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x01 +#define SPI_MODE2 0x02 +#define SPI_MODE3 0x03 class SPIClass { public: From aa96a4ae513266bde896b6e546178ee306c25193 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 29 Apr 2014 07:06:35 -0600 Subject: [PATCH 08/52] iBeacon power measurement support --- CHANGELOG | 4 ++++ cores/arduino/wiring_analog.c | 2 +- libraries/RFduinoBLE/RFduinoBLE.cpp | 2 ++ libraries/RFduinoBLE/RFduinoBLE.h | 2 ++ .../iBeaconSettings/iBeaconSettings.ino | 1 + variants/RFduino/libRFduinoBLE.a | Bin 37940 -> 38110 bytes variants/RFduino/libRFduinoBLE.h | 3 +++ 7 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 08d9d9b..3f82008 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 1.8.2 + - Added support for modifying the iBeacon measured power level at 1 meter + - Fix for analogWrite and RFduinoGZLL (thanks tolson) + v 1.8.1 - Fixed conflict between Analog to Digital Conversion and UART - Cleaned up SPI library diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index aa708a3..f3084d1 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -155,7 +155,7 @@ void turn_On_PPI_to_GPIO_for_PWM(uint32_t ulPin, uint32_t gpiote_channel, NRF_TI { // Initialize Programmable Peripheral Interconnect int chan_0 = find_free_PPI_channel(255); - int chan_1 = find_free_PPI_channel(chan_1); + int chan_1 = find_free_PPI_channel(chan_0); if ((chan_0 != 255) && (chan_1 != 255)) { diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index 018e591..7b5e069 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -41,6 +41,7 @@ RFduinoBLEClass::RFduinoBLEClass() memcpy(iBeaconUUID, uuid, sizeof(iBeaconUUID)); iBeaconMajor = 0; iBeaconMinor = 0; + iBeaconMeasuredPower = 0xC5; advertisementInterval = 80; txPowerLevel = +4; } @@ -67,6 +68,7 @@ int RFduinoBLEClass::begin() memcpy(RFduinoBLE_ibeacon_uuid, iBeaconUUID, sizeof(RFduinoBLE_ibeacon_uuid)); RFduinoBLE_ibeacon_major = iBeaconMajor; RFduinoBLE_ibeacon_minor = iBeaconMinor; + RFduinoBLE_ibeacon_measured_power = iBeaconMeasuredPower; RFduinoBLE_advertisement_interval = advertisementInterval; RFduinoBLE_tx_power_level = txPowerLevel; diff --git a/libraries/RFduinoBLE/RFduinoBLE.h b/libraries/RFduinoBLE/RFduinoBLE.h index ee8c23b..75746a4 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.h +++ b/libraries/RFduinoBLE/RFduinoBLE.h @@ -46,6 +46,8 @@ class RFduinoBLEClass uint8_t iBeaconUUID[16]; unsigned short iBeaconMajor; unsigned short iBeaconMinor; + // default 2's complement iBeacon Power Measurement at 1 meter (default is 0xC5 = -59dBm) + unsigned char iBeaconMeasuredPower; // in ms (converted to 0.625ms units) - range 20ms to 10.24s - default 80ms int advertisementInterval; diff --git a/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino b/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino index 2a2f6d6..c47c0c1 100644 --- a/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino +++ b/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino @@ -19,6 +19,7 @@ void setup() { memcpy(RFduinoBLE.iBeaconUUID, uuid, sizeof(RFduinoBLE.iBeaconUUID)); RFduinoBLE.iBeaconMajor = 1234; RFduinoBLE.iBeaconMinor = 5678; + RFduinoBLE.iBeaconMeasuredPower = 0xC6; // start the BLE stack RFduinoBLE.begin(); diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a index a981d6ec22eb6f03aa467b01fd1896457dcfdca6..a8f0d11918d60edf8027c3fe1c8150d8e218f3f9 100644 GIT binary patch delta 2163 zcmbtVeQZ-z6hF6p9eW)eEp69r-PYF@Xkl9^UB@<=!q9zo!3_rv5w_xHh6FY?7!a|H z50eS}v2dc0paBdbhK~RRL!vVy!2~1Gq7r6;I#Cnq?nSERx7LaMszm2@#r+EaHkf)MI|gJxk|Dt zfjplm^y1(I8d5(KU*fIQ1zE$+T3DsVY7KQ(~ZQjQ7PI%Ix5EdnkLXd}Y_XnxxO%T8GN}(59cAK2x1@!|qeV zuwGwo{hX?vIF68h2H(-!l_i=u|D70Le>1@`gTwk}@oBU$EmbRm_*Z%+E=k{xKcts? zE0;I5EM8VsRk_p`EG`LxZ%t2+Z+%O+t+%Bs+#O!u1HQKKrmzoh2#aCjSK7^Cq6?>; z*T_FR08(j}V*Jz8DUXt7RJD!MtK|ozWvbd0(kx2S(qwiEKUVn6SYtNIImG)_tFYN2 z>T##pBi9pmS>?_XSB^J`lbis}Dkm%s(Sc5jM}CpG0jj$g8;SGdM&d^4QjJQR3 z#o`gq(9?FnY7{kSvU+gHl8Fsgqx^tO0J14RII)DZ)*0g8x3Lcvjw_lC>$t1hIoR=8EiVQPe zwOGn-)4ELiCWqusR6ztcQX=8JB${y6$uWQxHrsRqu@s;y$$q56NcpUkyOd_GgkOYQ z^6}{a=P1B@ykc{tG})=e66V!+N1HR-G{T63*}M7m+1H6{(KGf_!juffsD*sEgM%9# zcqrFsSdrMjfmQ^*m-{r{&s7#aZtsUX6A871aY74$afN1DD2i6+l?ibTcRDVa{BVoajO2NkMchL_5zGDZUOj%aR-MaBzr%u@C4;BKnD?;W%!oI(L_Jv9@a|f z17V~C`4HoC0BxtMbF7OA%e68PU;(R|^vsMbQnBZH6)B?!Kzj FzX9y(`$_-+ delta 2259 zcmbVNeQZ-z6hH5^uk3YWbnRNYwOe0X*h)LPc63|EfFQDsZc8jMpg@#O!3+>Ao1hY9 z4e&=5GgH{EvuVBZCnay`yg2&dWQ8O3ZtvCL94%he5HSTiNl zb0bSEwP?fPP=KA0Jf`b1c8JY|IC!7|=CD7c{$epAw%@<|*ZqRiM>GIzr><{6lh#G1 zaHp;Vd}3NqGKA4qioGfF416#g)7ojxzr@MWoisEL9nt%iU-GpN!BFh|R&U1#$@0W3 zo(FiIYMcvcimJldg0!>4o>X{rW~{FpcRrw$w+rsIi%bckYwh6Cq-_x!FO589R3dsH#B2~>h?~zFEQOcoCv$v>vDOsH_e={z>IO7 zyE)#5McR79F2(L(RGR2^#|8I?3HKhy@Q*#U9f#unL}l;C-2uJ}HSDTvmK!5JUUmb! zFPj}@4_a1s`=bM&){TzpP`XM}Ci&oiIP>y^rX7wutoQg2g!5XjC5 z6LT|wE65ma9c^WI^f7f=p`^hMw@oW&eZ@OXPxklwTUK_hTePCJwPl$8SviiDfmJZ{=b7{3aj=m)33$dY6hZL5uULG5r6x-{{b@FSegY7n3jkI?d2nbv{C3b6* zg|(XvVpL+$O%~(VSw`+C&`pfD%?9ran2v7~hR#6MqLTg7q>wJ2iQO<8q!`v#K(&?V zF(Ey<4wWRv+?HzTrCjaiMqH<4x##Z3l_*6TJF}4wSJ=o#i}9IB0k28qHt(I}PGO!> zp69K9tnh}9qnipt;F97E&pnEE{y8M_ny*D-uKCN^@N6`^DGkoI7=K1D{^B|Bm(pOM zO7|Pqa$Cb{0m4T@fBH5}+cWnt0$MD=TQjwc*)Ie~O zU8kO?Y!ZYq_PgU)NiAH&)=232CHUT+P#i%&l+l);P}UM~LtWM;C;=yQW$jFqPc3uK z7w~gkdZzbeUW6@3AbckKyfX8HE4^=@S9_WRc$>x zvaFqicyS~NO#tr^V$@;6et{! Date: Fri, 16 May 2014 08:12:48 -0600 Subject: [PATCH 09/52] i2c enhancements, uart tx buffer --- CHANGELOG | 7 + cores/arduino/Arduino.h | 1 + cores/arduino/RingBuffer.h | 4 +- cores/arduino/UARTClass.cpp | 45 +++++- cores/arduino/UARTClass.h | 8 +- cores/arduino/WString.h | 1 + libraries/RFduinoBLE/RFduinoBLE.cpp | 29 ++-- .../AdvertisementContinuous.ino | 2 +- .../AdvertisementInterval.ino | 2 +- .../AdvertisementPeriodic.ino | 2 +- .../examples/ColorWheel/ColorWheel.ino | 2 +- .../examples/LedButton/LedButton.ino | 2 +- .../examples/PowerLevel/PowerLevel.ino | 2 +- .../examples/Temperature/Temperature.ino | 2 +- .../TimingCrtitical/TimingCrtitical.ino | 2 +- libraries/Wire/Wire.cpp | 138 ++++++++++++++++-- libraries/Wire/Wire.h | 2 + variants/RFduino/variant.cpp | 67 +++++---- variants/RFduino/variant.h | 11 ++ 19 files changed, 264 insertions(+), 65 deletions(-) mode change 100755 => 100644 cores/arduino/Arduino.h mode change 100755 => 100644 cores/arduino/RingBuffer.h mode change 100755 => 100644 cores/arduino/WString.h mode change 100755 => 100644 libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/LedButton/LedButton.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/Temperature/Temperature.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino diff --git a/CHANGELOG b/CHANGELOG index 3f82008..d7f78b1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,12 @@ CHANGELOG +v 1.9 + - i2c enhancements + - UART TX buffering + - Changed examples comment to indicate that Advertisement length and + deviceName length must be <= 15 bytes + - Added header to WString.h to so F() always available + v 1.8.2 - Added support for modifying the iBeacon measured power level at 1 meter - Fix for analogWrite and RFduinoGZLL (thanks tolson) diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h old mode 100755 new mode 100644 index e06dac0..f12facb --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -47,6 +47,7 @@ #include #include +#include #include #include diff --git a/cores/arduino/RingBuffer.h b/cores/arduino/RingBuffer.h old mode 100755 new mode 100644 index 3db184a..4dbbc98 --- a/cores/arduino/RingBuffer.h +++ b/cores/arduino/RingBuffer.h @@ -57,8 +57,8 @@ class RingBuffer { public: uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; - int _iHead ; - int _iTail ; + volatile int _iHead ; + volatile int _iTail ; public: RingBuffer( void ) ; diff --git a/cores/arduino/UARTClass.cpp b/cores/arduino/UARTClass.cpp index 7a2ee71..c044587 100644 --- a/cores/arduino/UARTClass.cpp +++ b/cores/arduino/UARTClass.cpp @@ -51,9 +51,10 @@ // Constructors -UARTClass::UARTClass( RingBuffer* pRx_buffer ) +UARTClass::UARTClass( RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) { _rx_buffer = pRx_buffer ; + _tx_buffer = pTx_buffer ; } // Public Methods @@ -65,6 +66,7 @@ void UARTClass::begin( const uint32_t dwBaudRate ) void UARTClass::begin( const uint32_t dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) { + transmitting = false; UART0_Start( dwBaudRate, rx_pin, tx_pin ); } @@ -103,18 +105,55 @@ int UARTClass::read( void ) void UARTClass::flush( void ) { - UART0_FlushTX(); + // Wait for any outstanding data to be sent + while (_tx_buffer->_iTail != _tx_buffer->_iHead) + ; + + UART0_FlushTX(); +} + +void UARTClass::tx( void ) +{ + if ( _tx_buffer->_iHead == _tx_buffer->_iTail ) + { + transmitting = false; + return; + } + + transmitting = true; + + uint8_t uc = _tx_buffer->_aucBuffer[_tx_buffer->_iTail] ; + _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE ; + + UART0_TXD(uc); } size_t UARTClass::write( const uint8_t uc_data ) { - UART0_TX( uc_data ); + // silently discard data if Serial.begin() hasn't been called + if (UART0_State == UART0_State_NotStarted) + return 1; + + // Wait if tx_buffer space is not available + while ((_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE == _tx_buffer->_iTail) + ; + + _tx_buffer->store_char(uc_data); + + if (! transmitting) + tx(); return 1; } void UARTClass::IrqHandler( void ) { + if (UART0_TXReady()) + { + UART0_TXReset(); + tx(); + } + // did we receive data if (UART0_RXReady()) { diff --git a/cores/arduino/UARTClass.h b/cores/arduino/UARTClass.h index 10c33d4..cea57e0 100644 --- a/cores/arduino/UARTClass.h +++ b/cores/arduino/UARTClass.h @@ -54,13 +54,15 @@ typedef void Uart; class UARTClass : public HardwareSerial { protected: - RingBuffer *_rx_buffer ; + RingBuffer *_rx_buffer, *_tx_buffer ; + bool transmitting; + void tx( void ); public: - UARTClass( RingBuffer* pRx_buffer ) ; + UARTClass( RingBuffer* pRx_buffer, RingBuffer* pTx_Buffer ) ; void begin( const uint32_t dwBaudRate ) ; - void begin( const uint32_t dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) ; + void begin( const uint32_t dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) ; void end( void ) ; int available( void ) ; int peek( void ) ; diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h old mode 100755 new mode 100644 index 0ac2039..3227527 --- a/cores/arduino/WString.h +++ b/cores/arduino/WString.h @@ -52,6 +52,7 @@ #include #include #include +#include // When compiling programs with this class, the following gcc parameters // dramatically increase performance and memory (RAM) efficiency, typically diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index 7b5e069..2337c9a 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -48,18 +48,25 @@ RFduinoBLEClass::RFduinoBLEClass() int RFduinoBLEClass::begin() { - if (UART0_State != UART0_State_NotStarted && UART0_BaudRate() > 9600) - { - const char *error = "BLE + UART > 9600 baud not permitted due to critical BLE timing requirements"; - - // attempt to notify user of error condition - const char *p = error; - while (*p) - UART0_TX(*p++); + // declared in variant.h + extern bool override_uart_limit; - // don't continue - while (1) - ; + if (! override_uart_limit) + { + if (UART0_State != UART0_State_NotStarted && UART0_BaudRate() > 9600) + { + const char *error = "BLE + UART > 9600 baud not permitted due to critical BLE timing requirements.\r\n" + "To override, add: override_uart_limit = true; to the top of setup() in your sketch."; + + // attempt to notify user of error condition + const char *p = error; + while (*p) + UART0_TX(*p++); + + // don't continue + while (1) + ; + } } RFduinoBLE_device_name = deviceName; diff --git a/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino b/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino old mode 100755 new mode 100644 index 380c123..1a3d55b --- a/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino @@ -13,7 +13,7 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes + // (the deviceName length plus the advertisement length must be <= 15 bytes RFduinoBLE.advertisementData = "data"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino b/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino old mode 100755 new mode 100644 index afc02ea..9a5ae5c --- a/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino @@ -18,7 +18,7 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes) + // (the deviceName length plus the advertisement length must be <= 15 bytes) // (a leading hypen causes the iphone to use instanteous rssi instead of n sample averaging) RFduinoBLE.advertisementData = "-data"; diff --git a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino index 2a0624b..ceee532 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino @@ -21,7 +21,7 @@ int duration = SECONDS(5); void advertise(const char *data, uint32_t ms) { // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes + // (the deviceName length plus the advertisement length must be <= 15 bytes RFduinoBLE.advertisementData = data; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino b/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino old mode 100755 new mode 100644 index ddf02a0..3736bf8 --- a/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino +++ b/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino @@ -23,7 +23,7 @@ void setup() { pinMode(led3, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes + // (the deviceName length plus the advertisement length must be <= 15 bytes RFduinoBLE.advertisementData = "rgb"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/LedButton/LedButton.ino b/libraries/RFduinoBLE/examples/LedButton/LedButton.ino old mode 100755 new mode 100644 index 59dd97c..b424884 --- a/libraries/RFduinoBLE/examples/LedButton/LedButton.ino +++ b/libraries/RFduinoBLE/examples/LedButton/LedButton.ino @@ -33,7 +33,7 @@ void setup() { pinMode(button, INPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes + // (the deviceName length plus the advertisement length must be <= 15 bytes RFduinoBLE.advertisementData = "ledbtn"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino b/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino old mode 100755 new mode 100644 index dc25209..2ade7a6 --- a/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino +++ b/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino @@ -13,7 +13,7 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes + // (the deviceName length plus the advertisement length must be <= 15 bytes RFduinoBLE.advertisementData = "data"; // set the transmit power level in dBm (-20 dBm to +4 dBm) diff --git a/libraries/RFduinoBLE/examples/Temperature/Temperature.ino b/libraries/RFduinoBLE/examples/Temperature/Temperature.ino old mode 100755 new mode 100644 index 765ceb0..f7173e3 --- a/libraries/RFduinoBLE/examples/Temperature/Temperature.ino +++ b/libraries/RFduinoBLE/examples/Temperature/Temperature.ino @@ -10,7 +10,7 @@ It is suppose to be used with the rfduinoTemperature iPhone application. void setup() { // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes) + // (the deviceName length plus the advertisement length must be <= 15 bytes) RFduinoBLE.advertisementData = "temp"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino b/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino old mode 100755 new mode 100644 index c69595d..03cb64e --- a/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino +++ b/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino @@ -16,7 +16,7 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 18 bytes + // (the deviceName length plus the advertisement length must be <= 15 bytes RFduinoBLE.advertisementData = "data"; // start the BLE stack diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 0c396b8..f3e88cb 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -111,7 +111,7 @@ static inline bool TWI_STATUS_DNACK(uint32_t status) { TwoWire::TwoWire(NRF_TWI_Type *_twi) : twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0), txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), - status(UNINITIALIZED), speed(100) + status(UNINITIALIZED), speed(100), PPI_channel(255) { // Empty } @@ -125,11 +125,30 @@ TwoWire::TwoWire(NRF_TWI_Type *_twi) : */ bool TwoWire::twi_master_clear_bus(void) { + uint32_t twi_state; bool bus_clear; + // Save and disable TWI hardware so software can take control over the pins. + twi_state = twi->ENABLE; + twi->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + + NRF_GPIO->PIN_CNF[SCL_pin_number] = + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) + | (GPIO_PIN_CNF_DRIVE_H0D1 << GPIO_PIN_CNF_DRIVE_Pos) + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) + | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + NRF_GPIO->PIN_CNF[SDA_pin_number] = + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) + | (GPIO_PIN_CNF_DRIVE_H0D1 << GPIO_PIN_CNF_DRIVE_Pos) + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) + | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_GPIO->OUTSET = (1UL << SDA_pin_number); - NRF_GPIO->OUTSET = (1UL << SCL_pin_number); - TWI_DELAY(); + NRF_GPIO->OUTSET = (1UL << SCL_pin_number); + TWI_DELAY(); if (((NRF_GPIO->IN >> SDA_pin_number) & 0x1UL) && ((NRF_GPIO->IN >> SCL_pin_number) & 0x1UL)) { @@ -156,9 +175,27 @@ bool TwoWire::twi_master_clear_bus(void) } } + twi->ENABLE = twi_state; + return bus_clear; } +// TWI module lock-up (PAN 56) +void TwoWire::twi_peripheral_recovery(void) +{ + twi->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + + *(uint32_t *)((uint32_t)twi + 0xFFC) = 0; + + delayMicroseconds(5); + + *(uint32_t *)((uint32_t)twi + 0xFFC) = 1; + + twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; + + twi_master_init(); +} + bool TwoWire::twi_master_init(void) { /* To secure correct signal levels on the pins used by the TWI @@ -167,14 +204,14 @@ bool TwoWire::twi_master_init(void) */ NRF_GPIO->PIN_CNF[SCL_pin_number] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) - | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) + | (GPIO_PIN_CNF_DRIVE_H0D1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); NRF_GPIO->PIN_CNF[SDA_pin_number] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) - | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) + | (GPIO_PIN_CNF_DRIVE_H0D1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); @@ -191,14 +228,21 @@ bool TwoWire::twi_master_init(void) freq = TWI_FREQUENCY_FREQUENCY_K400; twi->FREQUENCY = freq; - PPI_channel = find_free_PPI_channel(255); + if (PPI_channel == 255) + { + PPI_channel = find_free_PPI_channel(255); + if (PPI_channel == 255) + Serial.println("no free PPI channels for twi"); + } // reserve the PPI channel rfduino_ppi_channel_assign(PPI_channel, 0, 0); twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; - return twi_master_clear_bus(); + twi_master_clear_bus(); + + return true; } uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t issue_stop_condition) @@ -229,8 +273,43 @@ uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t iss if(timeout == 0) { - /* timeout before receiving event*/ - return bytes_received; + // unassign the PPI channel (but keep it reserved) + rfduino_ppi_channel_assign(PPI_channel, 0, 0); + + // NACK received after sending the address + if (twi->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) + { + twi->ERRORSRC |= TWI_ERRORSRC_ANACK_Clear << TWI_ERRORSRC_ANACK_Pos; + + twi->EVENTS_STOPPED = 0; + twi->TASKS_STOP = 1; + /* wait until stop sequence is sent and clear the EVENTS_STOPPED */ + while (twi->EVENTS_STOPPED == 0) + { + } + + return 0; + } + + // NACK received after sending a data-byte + if (twi->ERRORSRC & TWI_ERRORSRC_DNACK_Msk) + { + twi->ERRORSRC |= TWI_ERRORSRC_DNACK_Clear << TWI_ERRORSRC_DNACK_Pos; + + twi->EVENTS_STOPPED = 0; + twi->TASKS_STOP = 1; + /* wait until stop sequence is sent and clear the EVENTS_STOPPED */ + while (twi->EVENTS_STOPPED == 0) + { + } + + return 0; + } + + // TWI module lock-up (PAN 56) + twi_peripheral_recovery(); + + return 0; } twi->EVENTS_RXDREADY = 0; @@ -249,6 +328,9 @@ uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t iss if (data_length == 0) break; + // TWI module lock-up (PAN 56) + delayMicroseconds(20); + twi->TASKS_RESUME = 1; } @@ -287,7 +369,39 @@ uint8_t TwoWire::twi_master_write(uint8_t *data, uint8_t data_length, uint8_t is if (timeout == 0) { - /* timeout before receiving event*/ + // NACK received after sending the address + if (twi->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) + { + twi->ERRORSRC |= TWI_ERRORSRC_ANACK_Clear << TWI_ERRORSRC_ANACK_Pos; + + twi->EVENTS_STOPPED = 0; + twi->TASKS_STOP = 1; + /* wait until stop sequence is sent and clear the EVENTS_STOPPED */ + while (twi->EVENTS_STOPPED == 0) + { + } + + return 2; + } + + // NACK received after sending a data-byte + if (twi->ERRORSRC & TWI_ERRORSRC_DNACK_Msk) + { + twi->ERRORSRC |= TWI_ERRORSRC_DNACK_Clear << TWI_ERRORSRC_DNACK_Pos; + + twi->EVENTS_STOPPED = 0; + twi->TASKS_STOP = 1; + /* wait until stop sequence is sent and clear the EVENTS_STOPPED */ + while (twi->EVENTS_STOPPED == 0) + { + } + + return 3; + } + + // TWI module lock-up (PAN 56) + twi_peripheral_recovery(); + return 4; } @@ -353,7 +467,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop if(quantity > BUFFER_LENGTH) quantity = BUFFER_LENGTH; - if (quantity > 0 && twi_master_clear_bus()) + if (quantity > 0) { twi->ADDRESS = address; readed = twi_master_read(rxBuffer, quantity, sendStop); @@ -405,7 +519,7 @@ void TwoWire::beginTransmission(int address) { // uint8_t TwoWire::endTransmission(uint8_t sendStop) { uint8_t ret = 4; - if (txBufferLength > 0 && twi_master_clear_bus()) + if (txBufferLength > 0) { twi->ADDRESS = txAddress; // transmit buffer (blocking) diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index d8c9bb7..a20ebfd 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -95,6 +95,8 @@ class TwoWire : public Stream { void onService(void); + void twi_peripheral_recovery(void); + private: bool twi_master_clear_bus(void); bool twi_master_init(void); diff --git a/variants/RFduino/variant.cpp b/variants/RFduino/variant.cpp index 1aa48c7..a7ed6cd 100644 --- a/variants/RFduino/variant.cpp +++ b/variants/RFduino/variant.cpp @@ -50,9 +50,9 @@ * UART objects */ -RingBuffer rxBuffer; +RingBuffer rxBuffer, txBuffer; -UARTClass Serial( &rxBuffer ); +UARTClass Serial( &rxBuffer, &txBuffer ); // IT handlers void UART0_Interrupt() @@ -64,6 +64,8 @@ void UART0_Interrupt() extern "C" { #endif +bool override_uart_limit = false; + /* * Pins descriptions */ @@ -173,28 +175,35 @@ void UART0_Start( int dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) NRF_UART0->BAUDRATE = (dw << UART_BAUDRATE_BAUDRATE_Pos); NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->TASKS_STARTRX = 1; NRF_UART0->EVENTS_RXDRDY = 0; + NRF_UART0->EVENTS_TXDRDY = 0; - NRF_UART0->INTENSET |= (UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos ); - - attachInterrupt(UART0_IRQn, UART0_Interrupt); + NRF_UART0->INTENSET |= (UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos ) + | (UART_INTENSET_TXDRDY_Enabled << UART_INTENSET_TXDRDY_Pos ); UART0_State = UART0_State_BeforeFirstTX; - if (RFduinoBLE_enabled && dwBaudRate > 9600) - { - const char *error = "BLE + UART > 9600 baud not permitted due to critical BLE timing requirements"; + attachInterrupt(UART0_IRQn, UART0_Interrupt); - // attempt to notify user of error condition - const char *p = error; - while (*p) - UART0_TX(*p++); + NRF_UART0->TASKS_STARTTX = 1; + NRF_UART0->TASKS_STARTRX = 1; - // don't continue - while (1) - ; + if (! override_uart_limit) + { + if (RFduinoBLE_enabled && dwBaudRate > 9600) + { + const char *error = "BLE + UART > 9600 baud not recommended due to critical BLE timing requirements.\r\n" + "To override, add: override_uart_limit = true; to the top of setup() in your sketch."; + + // attempt to notify user of error condition + const char *p = error; + while (*p) + UART0_TX(*p++); + + // don't continue + while (1) + ; + } } } @@ -203,12 +212,12 @@ void UART0_Stop() if (UART0_State == UART0_State_NotStarted) return; + // Wait for any outstanding data to be sent + Serial.flush(); + // Disable UART interrupt in NVIC detachInterrupt(UART0_IRQn); - // Wait for any outstanding data to be sent - UART0_FlushTX(); - NRF_UART0->TASKS_STOPTX = 1; NRF_UART0->TASKS_STOPRX = 1; @@ -219,20 +228,21 @@ void UART0_FlushTX() { if (UART0_State == UART0_State_AfterFirstTX) { - // wait for transmission to complete - while (! NRF_UART0->EVENTS_TXDRDY) + // wait for last transmission to complete + while (! UART0_TXReady()) ; } } +// delegate to serial for syscalls/write and error messages void UART0_TX( const uint8_t uc_data ) { - // if UART0 is not started, then setting TXD is ignored and UART0_FlushTX is already protected - - UART0_FlushTX(); + Serial.write( uc_data ); +} +void UART0_TXD( const uint8_t uc_data ) +{ // tx byte - NRF_UART0->EVENTS_TXDRDY = 0; NRF_UART0->TXD = uc_data; // don't change start if not started @@ -249,6 +259,11 @@ void UART0_RXReset() NRF_UART0->EVENTS_RXDRDY = 0; } +void UART0_TXReset() +{ + NRF_UART0->EVENTS_TXDRDY = 0; +} + int UART0_RXErrorReset() { if (NRF_UART0->ERRORSRC & UART_ERRORSRC_OVERRUN_Msk) diff --git a/variants/RFduino/variant.h b/variants/RFduino/variant.h index 3a2cd54..d1853a3 100644 --- a/variants/RFduino/variant.h +++ b/variants/RFduino/variant.h @@ -148,6 +148,7 @@ void UART0_Start( int dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ); void UART0_Stop(); void UART0_FlushTX(); void UART0_TX( const uint8_t uc_data ); +void UART0_TXD( const uint8_t uc_data ); __attribute__(( always_inline )) static int __INLINE UART0_RXReady() @@ -155,6 +156,12 @@ static int __INLINE UART0_RXReady() return NRF_UART0->EVENTS_RXDRDY; } +__attribute__(( always_inline )) +static int __INLINE UART0_TXReady() +{ + return NRF_UART0->EVENTS_TXDRDY; +} + __attribute__(( always_inline )) static uint8_t __INLINE UART0_RXData() { @@ -165,6 +172,8 @@ void UART0_RXReset(); int UART0_RXErrorReset(); uint8_t UART0_RX(); +void UART0_TXReset(); + /* * PWM */ @@ -183,6 +192,8 @@ uint32_t getDeviceIdLow(); uint32_t getDeviceIdHigh(); uint64_t getDeviceId(); +extern bool override_uart_limit; + #ifdef __cplusplus } #endif From a13fc6fd20b87482750103620655be947d33852f Mon Sep 17 00:00:00 2001 From: RFduino Date: Mon, 26 May 2014 14:28:27 -0600 Subject: [PATCH 10/52] 128-bit custom uuid, raw advertisement access --- CHANGELOG | 6 + iPhone Apps/rfduino/RFduino.h | 3 + iPhone Apps/rfduino/RFduino.m | 29 ++++- iPhone Apps/rfduino/RfduinoManager.m | 2 +- .../AppViewController.m | 5 + .../rfduinoColorWheel/AppViewController.m | 5 + .../rfduinoLedButton/AppViewController.m | 5 + .../rfduinoServo/AppViewController.m | 5 + .../rfduinoTemperature/AppViewController.m | 5 + libraries/RFduinoBLE/RFduinoBLE.cpp | 2 + libraries/RFduinoBLE/RFduinoBLE.h | 3 + .../AdvertisementContinuous.ino | 4 +- .../AdvertisementInterval.ino | 5 +- .../AdvertisementPeriodic.ino | 4 +- .../AdvertisementRaw/AdvertisementRaw.ino | 67 +++++++++++ .../AdvertisementRawMaxDeviceName.ino | 81 +++++++++++++ .../AdvertisementRawScanResponse.ino | 106 ++++++++++++++++++ .../AdvertisementRawiBeacon.ino | 86 ++++++++++++++ .../examples/ColorWheel/ColorWheel.ino | 4 +- .../examples/CustomUUID/CustomUUID.ino | 76 +++++++++++++ .../examples/LedButton/LedButton.ino | 4 +- .../examples/PowerLevel/PowerLevel.ino | 4 +- .../examples/Temperature/Temperature.ino | 4 +- .../TimingCrtitical/TimingCrtitical.ino | 4 +- libraries/RFduinoBLE/keywords.txt | 15 +++ variants/RFduino/libRFduinoBLE.a | Bin 38110 -> 40036 bytes variants/RFduino/libRFduinoBLE.h | 21 +++- 27 files changed, 537 insertions(+), 18 deletions(-) mode change 100755 => 100644 iPhone Apps/rfduino/RFduino.h mode change 100755 => 100644 iPhone Apps/rfduino/RFduino.m mode change 100755 => 100644 iPhone Apps/rfduino/RfduinoManager.m mode change 100755 => 100644 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m mode change 100755 => 100644 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m mode change 100755 => 100644 iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m mode change 100755 => 100644 iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.m mode change 100755 => 100644 iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.m create mode 100644 libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino create mode 100644 libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino create mode 100644 libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino create mode 100644 libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino create mode 100644 libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino mode change 100755 => 100644 libraries/RFduinoBLE/keywords.txt diff --git a/CHANGELOG b/CHANGELOG index d7f78b1..b8905d8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ CHANGELOG +v 2.0 + - 128-bit custom UUID enhancement + - raw advertisement packet access + - RFduinoBLE.begin() now truncates (instead of failing) if the advertisement + packet length is exceeded. No more counting deviceName/advertisementData. + v 1.9 - i2c enhancements - UART TX buffering diff --git a/iPhone Apps/rfduino/RFduino.h b/iPhone Apps/rfduino/RFduino.h old mode 100755 new mode 100644 index 5f54ef8..4d102c6 --- a/iPhone Apps/rfduino/RFduino.h +++ b/iPhone Apps/rfduino/RFduino.h @@ -41,6 +41,9 @@ uint8_t dataByte(NSData *data); int dataInt(NSData *data); float dataFloat(NSData *data); +// default NULL (NULL = previous fixed RFduino uuid) +extern NSString *customUUID; + @interface RFduino : NSObject { } diff --git a/iPhone Apps/rfduino/RFduino.m b/iPhone Apps/rfduino/RFduino.m old mode 100755 new mode 100644 index 0f340cf..789db01 --- a/iPhone Apps/rfduino/RFduino.m +++ b/iPhone Apps/rfduino/RFduino.m @@ -30,6 +30,9 @@ static const int max_data = 12; +// default NULL (NULL = previous fixed RFduino uuid) +NSString *customUUID = NULL; + static CBUUID *service_uuid; static CBUUID *send_uuid; static CBUUID *receive_uuid; @@ -61,6 +64,17 @@ float dataFloat(NSData *data) return (sizeof(float) <= len ? *(float*)p : 0); } +// increment the 16-bit uuid inside a 128-bit uuid +static void incrementUuid16(CBUUID *uuid, unsigned char amount) +{ + NSData *data = uuid.data; + unsigned char *bytes = (unsigned char *)[data bytes]; + unsigned char result = bytes[3] + amount; + if (result < bytes[3]) + bytes[2]++; + bytes[3] += amount; +} + @interface RFduino() { CBCharacteristic *send_characteristic; @@ -97,11 +111,16 @@ - (void)connected { NSLog(@"rfduino connected"); - service_uuid = [CBUUID UUIDWithString:@"2220"]; - send_uuid = [CBUUID UUIDWithString:@"2222"]; - receive_uuid = [CBUUID UUIDWithString:@"2221"]; - disconnect_uuid = [CBUUID UUIDWithString:@"2223"]; - + service_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2220")]; + receive_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2221")]; + if (customUUID) + incrementUuid16(receive_uuid, 1); + send_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2222")]; + if (customUUID) + incrementUuid16(send_uuid, 2); + disconnect_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2223")]; + if (customUUID) + incrementUuid16(disconnect_uuid, 3); peripheral.delegate = self; [peripheral discoverServices:[NSArray arrayWithObject:service_uuid]]; diff --git a/iPhone Apps/rfduino/RfduinoManager.m b/iPhone Apps/rfduino/RfduinoManager.m old mode 100755 new mode 100644 index 69aa481..dec6846 --- a/iPhone Apps/rfduino/RfduinoManager.m +++ b/iPhone Apps/rfduino/RfduinoManager.m @@ -63,7 +63,7 @@ - (id)init self = [super init]; if (self) { - service_uuid = [CBUUID UUIDWithString:@"2220"]; + service_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2220")]; rfduinos = [[NSMutableArray alloc] init]; diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m old mode 100755 new mode 100644 index 3138677..e9e81be --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m +++ b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m @@ -55,6 +55,11 @@ @implementation AppViewController @synthesize rfduino; ++ (void)load +{ + // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; +} + - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m old mode 100755 new mode 100644 index dd77555..9db6f15 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m +++ b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m @@ -33,6 +33,11 @@ @implementation AppViewController @synthesize rfduino; ++ (void)load +{ + // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; +} + - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m old mode 100755 new mode 100644 index 2a2365c..3b2b420 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m +++ b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m @@ -32,6 +32,11 @@ @implementation AppViewController @synthesize rfduino; ++ (void)load +{ + // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; +} + - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; diff --git a/iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.m b/iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.m old mode 100755 new mode 100644 index fa2418b..420efc9 --- a/iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.m +++ b/iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.m @@ -32,6 +32,11 @@ @implementation AppViewController @synthesize rfduino; ++ (void)load +{ + // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; +} + - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; diff --git a/iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.m b/iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.m old mode 100755 new mode 100644 index 4834060..665504e --- a/iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.m +++ b/iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.m @@ -32,6 +32,11 @@ @implementation AppViewController @synthesize rfduino; ++ (void)load +{ + // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; +} + - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index 2337c9a..d0b406d 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -33,6 +33,7 @@ RFduinoBLEClass::RFduinoBLEClass() { ::RFduinoBLE_used = 1; + customUUID = ""; deviceName = "RFduino"; advertisementData = "sketch"; iBeacon = false; @@ -69,6 +70,7 @@ int RFduinoBLEClass::begin() } } + RFduinoBLE_custom_uuid = customUUID; RFduinoBLE_device_name = deviceName; RFduinoBLE_advertisement_data = advertisementData; RFduinoBLE_ibeacon = iBeacon; diff --git a/libraries/RFduinoBLE/RFduinoBLE.h b/libraries/RFduinoBLE/RFduinoBLE.h index 75746a4..031ca7a 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.h +++ b/libraries/RFduinoBLE/RFduinoBLE.h @@ -36,6 +36,9 @@ class RFduinoBLEClass { public: + // default "" (previous fixed RFduino uuid) + const char *customUUID; + // default "RFduino" const char *deviceName; diff --git a/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino b/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino index 1a3d55b..6286e3f 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino @@ -13,7 +13,9 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "data"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino b/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino index 9a5ae5c..066b5ff 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino @@ -18,8 +18,9 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes) - // (a leading hypen causes the iphone to use instanteous rssi instead of n sample averaging) + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "-data"; // change the advertisement interval diff --git a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino index ceee532..f27e248 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino @@ -21,7 +21,9 @@ int duration = SECONDS(5); void advertise(const char *data, uint32_t ms) { // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = data; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino b/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino new file mode 100644 index 0000000..8578b69 --- /dev/null +++ b/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino @@ -0,0 +1,67 @@ +/* +Demonstrates advanced raw access to the advertisement and scan response packets. + +This example only applies if you have a specific need for raw access to the advertisement +packet. This is for advanced use only, as the RFduino will not advertise is the packet +is invalid. +*/ + +#include + +// the advertisement packet is composed of a series of variable length blocks, that can appear in any order. +// each block starts with a length byte, followed by a type byte, followed by the data. +// the payload cannot exceed 31 bytes. + +uint8_t advdata[] = +{ + 0x05, // length + 0x09, // complete local name type + 0x41, // 'A' + 0x42, // 'B' + 0x43, // 'C' + 0x44, // 'D' + + 0x02, // length + 0x01, // flags type + 0x06, // le general discovery mode | br edr not supported + + 0x02, // length + 0x0A, // tx power level + 0x04, // +4dBm + + // if this variable block is not included, the RFduino iPhone apps won't see the device + 0x03, // length + 0x03, // 16 bit service uuid (complete) + 0x20, // uuid low + 0x22, // uuid hi +}; + +// pin 3 on the RGB shield is the green led +int led = 3; + +void setup() { + // led used to indicate that the RFduino is advertising + pinMode(led, OUTPUT); + + RFduinoBLE_advdata = advdata; + RFduinoBLE_advdata_len = sizeof(advdata); + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino b/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino new file mode 100644 index 0000000..4054b31 --- /dev/null +++ b/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino @@ -0,0 +1,81 @@ +/* +Demonstrates advanced raw access to the advertisement and scan response packets. + +This example only applies if you have a specific need for raw access to the advertisement +packet. This is for advanced use only, as the RFduino will not advertise is the packet +is invalid. +*/ + +#include + +// the advertisement packet is composed of a series of variable length blocks, that can appear in any order. +// each block starts with a length byte, followed by a type byte, followed by the data. +// the payload cannot exceed 31 bytes. + +// Note: since the RFduino UUID is missing from the advertisement packet, the RFduino iPhone apps will not +// be able to see this advertisement. + +uint8_t advdata[] = +{ + 30, // length + 0x09, // complete local name type + 0x41, // 'A' + 0x42, // 'B' + 0x43, // 'C' + 0x44, // 'D' + 0x45, // 'E' + 0x46, // 'F' + 0x47, // 'G' + 0x48, // 'H' + 0x49, // 'I' + 0x4A, // 'J' + 0x4B, // 'K' + 0x4C, // 'L' + 0x4D, // 'M' + 0x4E, // 'N' + 0x4F, // 'O' + 0x50, // 'P' + 0x51, // 'Q' + 0x52, // 'R' + 0x53, // 'S' + 0x54, // 'T' + 0x55, // 'U' + 0x56, // 'V' + 0x57, // 'W' + 0x58, // 'X' + 0x59, // 'Y' + 0x5A, // 'Z' + 0x30, // '1' + 0x31, // '2' + 0x32, // '3' +}; + +// pin 3 on the RGB shield is the green led +int led = 3; + +void setup() { + // led used to indicate that the RFduino is advertising + pinMode(led, OUTPUT); + + RFduinoBLE_advdata = advdata; + RFduinoBLE_advdata_len = sizeof(advdata); + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} \ No newline at end of file diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino b/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino new file mode 100644 index 0000000..ea08949 --- /dev/null +++ b/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino @@ -0,0 +1,106 @@ +/* +Demonstrates advanced raw access to the advertisement and scan response packets. + +This example only applies if you have a specific need for raw access to the advertisement +packet. This is for advanced use only, as the RFduino will not advertise is the packet +is invalid. + +Note: +This advertisement packet uses a custom 128 bit UUID. +If you use a customUUID, the iPhone apps must also +be updated to discover RFduino's advertising with the +custom UUID. + +The iPhone application source code in this distribution +has been enhanced to discover RFduino's with customUUIDs, +by declaring the UUID in the +Load method of the +AppViewController.m. Without modification, the iPhone +apps continue to operate as before. + +The RFduino AppStore apps will continue to only discover +RFduino's that advertise using the previous fixed RFduino +UUID. +*/ + +#include + +// the advertisement packet is composed of a series of variable length blocks, that can appear in any order. +// each block starts with a length byte, followed by a type byte, followed by the data. +// the payload cannot exceed 31 bytes. + +uint8_t advdata[] = +{ + 0x05, // length + 0x09, // complete local name type + 0x41, // 'A' + 0x42, // 'B' + 0x43, // 'C' + 0x44, // 'D' + + 0x02, // length + 0x01, // flags type + 0x06, // le general discovery mode | br edr not supported + + 0x02, // length + 0x0A, // tx power level + 0x04, // +4dBm +}; + +uint8_t srdata[] = +{ + 0x11, // length + 0x07, // 128 bit service uuid (complete) + + // 128 bit uuid + // equivalent to RFduinoBLE.customUUID = "c97433f0-be8f-4dc8-b6f0-5343e6100eb4" + // little endian + 0xB4, + 0x0E, + 0x10, + 0xE6, + 0x43, + 0x53, + 0xF0, + 0xB6, + 0xC8, + 0x4D, + 0x8F, + 0xBE, + 0xF0, + 0x33, + 0x74, + 0xC9, +}; + +// pin 3 on the RGB shield is the green led +int led = 3; + +void setup() { + // led used to indicate that the RFduino is advertising + pinMode(led, OUTPUT); + + RFduinoBLE_advdata = advdata; + RFduinoBLE_advdata_len = sizeof(advdata); + + RFduinoBLE_srdata = srdata; + RFduinoBLE_srdata_len = sizeof(srdata); + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino b/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino new file mode 100644 index 0000000..7191e4d --- /dev/null +++ b/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino @@ -0,0 +1,86 @@ +/* +Demonstrates advanced raw access to the advertisement and scan response packets. + +This example only applies if you have a specific need for raw access to the advertisement +packet. This is for advanced use only, as the RFduino will not advertise is the packet +is invalid. +*/ + +#include + +// the advertisement packet is composed of a series of variable length blocks, that can appear in any order. +// each block starts with a length byte, followed by a type byte, followed by the data. +// the payload cannot exceed 31 bytes. + +uint8_t advdata[] = +{ + 0x02, // length + 0x01, // flags type + 0x04, // br edr not supported + + 0x1A, // length + 0xFF, // manufacturer data type + + // apple company identifier + 0x4C, + 0x00, + + 0x02, // apple manufacturer data type (0x02 = iBeacon) + 0x15, // length + + // 128-bit iBeacon uuid (little endian) + 0xE2, + 0xC5, + 0x6D, + 0xB5, + 0xDF, + 0xFB, + 0x48, + 0xD2, + 0xB0, + 0x60, + 0xD0, + 0xF5, + 0xA7, + 0x10, + 0x96, + 0xE0, + + 0x00, // iBeacon Major Hi + 0x00, // iBeacon Major Low + + 0x00, // iBeacon Minor Hi + 0x00, // iBeacon Minor Low + + 0xC5, // iBeacon Measured Power +}; + +// pin 3 on the RGB shield is the green led +int led = 3; + +void setup() { + // led used to indicate that the RFduino is advertising + pinMode(led, OUTPUT); + + RFduinoBLE_advdata = advdata; + RFduinoBLE_advdata_len = sizeof(advdata); + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} diff --git a/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino b/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino index 3736bf8..7d5a2e6 100644 --- a/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino +++ b/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino @@ -23,7 +23,9 @@ void setup() { pinMode(led3, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "rgb"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino b/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino new file mode 100644 index 0000000..3fe7d4b --- /dev/null +++ b/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino @@ -0,0 +1,76 @@ +/* +The sketch demonstrates how to use a different UUID for +the RFduino service and characteristics. + +This example only applies if you have a specific +need to use a custom 128 bit uuid. + +Note: +If you use a customUUID, the iPhone apps must also +be updated to discover RFduino's advertising with the +custom UUID. + +The iPhone application source code in this distribution +has been enhanced to discover RFduino's with customUUIDs, +by declaring the UUID in the +Load method of the +AppViewController.m. Without modification, the iPhone +apps continue to operate as before. + +The RFduino AppStore apps will continue to only discover +RFduino's that advertise using the previous fixed RFduino +UUID. +*/ + +#include + +// pin 3 on the RGB shield is the green led +// (shows when the RFduino is advertising or not) +int advertisement_led = 3; + +// pin 2 on the RGB shield is the red led +// (goes on when the RFduino has a connection from the iPhone, and goes off on disconnect) +int connection_led = 2; + +void setup() { + // led used to indicate that the RFduino is advertising + pinMode(advertisement_led, OUTPUT); + + // led used to indicate that the RFduino is connected + pinMode(connection_led, OUTPUT); + + // 128 bit base uuid + // (generated with http://www.uuidgenerator.net) + RFduinoBLE.customUUID = "c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; + + // this must match the customUUID in the iPhone app declared + // in +Load method of AppViewController.m + + // start the BLE stack + RFduinoBLE.begin(); +} + +void loop() { + // switch to lower power mode + RFduino_ULPDelay(INFINITE); +} + +void RFduinoBLE_onAdvertisement(bool start) +{ + // turn the green led on if we start advertisement, and turn it + // off if we stop advertisement + + if (start) + digitalWrite(advertisement_led, HIGH); + else + digitalWrite(advertisement_led, LOW); +} + +void RFduinoBLE_onConnect() +{ + digitalWrite(connection_led, HIGH); +} + +void RFduinoBLE_onDisconnect() +{ + digitalWrite(connection_led, LOW); +} diff --git a/libraries/RFduinoBLE/examples/LedButton/LedButton.ino b/libraries/RFduinoBLE/examples/LedButton/LedButton.ino index b424884..0db570f 100644 --- a/libraries/RFduinoBLE/examples/LedButton/LedButton.ino +++ b/libraries/RFduinoBLE/examples/LedButton/LedButton.ino @@ -33,7 +33,9 @@ void setup() { pinMode(button, INPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "ledbtn"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino b/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino index 2ade7a6..44b66fe 100644 --- a/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino +++ b/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino @@ -13,7 +13,9 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "data"; // set the transmit power level in dBm (-20 dBm to +4 dBm) diff --git a/libraries/RFduinoBLE/examples/Temperature/Temperature.ino b/libraries/RFduinoBLE/examples/Temperature/Temperature.ino index f7173e3..b9fbf14 100644 --- a/libraries/RFduinoBLE/examples/Temperature/Temperature.ino +++ b/libraries/RFduinoBLE/examples/Temperature/Temperature.ino @@ -10,7 +10,9 @@ It is suppose to be used with the rfduinoTemperature iPhone application. void setup() { // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes) + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "temp"; // start the BLE stack diff --git a/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino b/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino index 03cb64e..1fe3684 100644 --- a/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino +++ b/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino @@ -16,7 +16,9 @@ void setup() { pinMode(led, OUTPUT); // this is the data we want to appear in the advertisement - // (the deviceName length plus the advertisement length must be <= 15 bytes + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) RFduinoBLE.advertisementData = "data"; // start the BLE stack diff --git a/libraries/RFduinoBLE/keywords.txt b/libraries/RFduinoBLE/keywords.txt old mode 100755 new mode 100644 index 5057b9b..f8cef93 --- a/libraries/RFduinoBLE/keywords.txt +++ b/libraries/RFduinoBLE/keywords.txt @@ -11,14 +11,24 @@ RFduinoBLE KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### +customUUID KEYWORD2 deviceName KEYWORD2 advertisementData KEYWORD2 +iBeacon KEYWORD2 +iBeaconUUID KEYWORD2 +iBeaconMajor KEYWORD2 +iBeaconMinor KEYWORD2 +iBeaconMeasuredPower KEYWORD2 advertisementInterval KEYWORD2 txPowerLevel KEYWORD2 +radioActive KEYWORD2 begin KEYWORD2 end KEYWORD2 send KEYWORD2 +sendByte KEYWORD2 +sendInt KEYWORD2 +sendFloat KEYWORD2 RFduinoBLE_onAdvertisement KEYWORD2 RFduinoBLE_onRssi KEYWORD2 @@ -26,6 +36,11 @@ RFduinoBLE_onConnect KEYWORD2 RFduinoBLE_onDisconnect KEYQORD2 RFduinoBLE_onReceive KEYWORD2 +RFduinoBLE_advdata KEYWORD2 +RFduinoBLE_advdata_len KEYWORD2 +RFduinoBLE_srdata KEYWORD2 +RFduinoBLE_srdata_len KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a index a8f0d11918d60edf8027c3fe1c8150d8e218f3f9..c2e3bff6f15df4bca769b5f7011993aab81f9e54 100644 GIT binary patch delta 7516 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 18) // 2 = tx_power_level invalid (< -20 || > +4) // 3 = advertisement_interval invalid (< 20ms || > 10.24s) + +// Now always returns 0 (success) and does a best effort to accomodate the users request. +// This means that it is no longer necessary to check the return value, and being off +// by one byte doesn't stop the device from advertising. +// on advertisement packet overflow, it will truncate the advertisement data first down +// to a single byte, then it will truncate the device name. if the tx_power_level is +// outside the limits, its modified to the boundary level value. the same boundary logic +// is also applied to the advertisement_interval. int RFduinoBLE_begin(void); void RFduinoBLE_end(void); bool RFduinoBLE_send(const char *data, uint8_t len); -// void RFduinoBLE_wait_for_event(void); - #ifdef __cplusplus } #endif From 753395ffce1582778d75b7546d0990ade8044064 Mon Sep 17 00:00:00 2001 From: RFduino Date: Thu, 29 May 2014 16:47:39 -0600 Subject: [PATCH 11/52] RFduinoGZLL enhancements --- CHANGELOG | 4 ++++ source/libRFduinoGZLL/build.bat | 2 ++ source/libRFduinoGZLL/libRFduinoGZLL.c | 4 ++++ source/libRFduinoGZLL/libRFduinoGZLL.h | 1 + variants/RFduino/libRFduinoGZLL.a | Bin 60386 -> 60466 bytes variants/RFduino/libRFduinoGZLL.h | 1 + 6 files changed, 12 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index b8905d8..592fee8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 2.0.1 + - RFduinoGZLL enhancement for channel selection policy + - allow build.bat "run as administrator" + v 2.0 - 128-bit custom UUID enhancement - raw advertisement packet access diff --git a/source/libRFduinoGZLL/build.bat b/source/libRFduinoGZLL/build.bat index be34939..babb9b5 100644 --- a/source/libRFduinoGZLL/build.bat +++ b/source/libRFduinoGZLL/build.bat @@ -8,6 +8,8 @@ echo Error: The Nordic SDK is required to build libRFduinoGZLL. goto end ) +cd %arduino%\hardware\arduino\RFduino\source\libRFduinoGZLL + if not exist _build\nul mkdir _build if exist _build\* del /q _build\* diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.c b/source/libRFduinoGZLL/libRFduinoGZLL.c index 8ce6c37..7f6f2f5 100644 --- a/source/libRFduinoGZLL/libRFduinoGZLL.c +++ b/source/libRFduinoGZLL/libRFduinoGZLL.c @@ -50,6 +50,7 @@ static device_t _device; // 1 = init failed // 2 = set tx_power failed // 3 = enabled failed +// 4 = set channel selection policy failed int RFduinoGZLL_begin(device_t device) { _device = device; @@ -78,6 +79,9 @@ int RFduinoGZLL_begin(device_t device) if (! nrf_gzll_set_tx_power(tx_power)) return 2; + if (! nrf_gzll_set_device_channel_selection_policy(NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT)) + return 4; + if (! nrf_gzll_enable()) return 3; diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.h b/source/libRFduinoGZLL/libRFduinoGZLL.h index 2e54887..9a4325a 100644 --- a/source/libRFduinoGZLL/libRFduinoGZLL.h +++ b/source/libRFduinoGZLL/libRFduinoGZLL.h @@ -62,6 +62,7 @@ extern void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len // 1 = init failed // 2 = set tx_power failed // 3 = enabled failed +// 4 = set channel selection policy failed int RFduinoGZLL_begin(device_t device); void RFduinoGZLL_end(void); diff --git a/variants/RFduino/libRFduinoGZLL.a b/variants/RFduino/libRFduinoGZLL.a index 21e0ad1f5ede4c9dcb3f3603110d1895f545d38f..956c1ef0fb469b9375450b2f130c36f65536a937 100644 GIT binary patch delta 1340 zcmaEKoq5v@<_VIVCI*Hk2F8ZwCKHu>>eZPT7_<(NhE4kz7|6lSQ49=dxE@^q%=g*F zz(5~dPkW0>wHO$1;(C0NbdamZ=`t!=zQv7!0S~SROCGUfU_i&G;usick2MgMJZ)lN zz>POgU}hIXWSz+iBqbOvCl{J(GB!+pEcusFe)2;pVP>NTQj@<+IjRXfU{v`3{oj8E z4aSQs3Y-sMY-R=K2Q1!T|73LJYk2TAiVGcK4MFXzv=WAb_+d13N@Ao*glzq~)= zkID1pwHbRRH!2EGz9%oh%E8OPU@`f#yfW(wMg|7P$qyrhC+jH)Fs_(vub|Gl1}LTt z7OMk_U7y^qpw7kx%-bc5lP|a{ab~bHFa$6&Fi1>}*OzDA!NtJvY_hyZ;N}>`G)BgT z&4-nO8G%-btC$P!1{wqd0zk&;&HgIO7$`t*tqX{KFZD0cc Do!dm; delta 1310 zcmdmVgZa^Q<_VIV#+F7F#zuygMiZ5M>eV(eFlZH#hE44l7|6lSTnr3oxE@^q%=gJ+ zV4x4Kr@cibw-^|3;(C0NbdamZ=`t!=zWEyi10GxtmOT89fdL(#;$vW-J=Q>2^3;fd z0XN<}ftg(lk##07kd$CFoP5w!ld)v-W68gaGLs)l2{UUy5TE>A%2A5*!T<07{xfJW zUSw8ae!$|*s3euZpun;BfZOIcX&z?Ah{@S<{)`2acLT|e$=ve(j0+}51IZ1OSIcWN zHcY-QugrRYhk?Oh@_!&}4kH5t<7C4~;mKAC0!(ulCoAj|6O9H5G9bVLAV(Xls0*m* zG~?ue2sO5UK*18AdJiSm7d$}+~uc4{h<6V)oMVu0pz0mG#PNHa+@FjRnOIR=Ir5UtI?pl@iQfD8=bWeYHX z#5NnLFJwjuGqKH|wAON=2#IgrZ@PvTMM!LOm$M@$n$RnsKn*mZsM5c72%*ghTi){{ YxL^n59bsfc6Y4v~Dvc(z>1hKS0OVOp-v9sr diff --git a/variants/RFduino/libRFduinoGZLL.h b/variants/RFduino/libRFduinoGZLL.h index 2e54887..9a4325a 100644 --- a/variants/RFduino/libRFduinoGZLL.h +++ b/variants/RFduino/libRFduinoGZLL.h @@ -62,6 +62,7 @@ extern void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len // 1 = init failed // 2 = set tx_power failed // 3 = enabled failed +// 4 = set channel selection policy failed int RFduinoGZLL_begin(device_t device); void RFduinoGZLL_end(void); From e029f27ec837dbbf34d6e50678adec0569dabb26 Mon Sep 17 00:00:00 2001 From: RFduino Date: Fri, 30 May 2014 17:06:33 -0600 Subject: [PATCH 12/52] connection interval update --- CHANGELOG | 4 + libraries/RFduinoBLE/RFduinoBLE.cpp | 10 ++ libraries/RFduinoBLE/RFduinoBLE.h | 6 + .../AdvertisementContinuous.ino | 26 +++ .../AdvertisementInterval.ino | 26 +++ .../AdvertisementPeriodic.ino | 26 +++ .../AdvertisementRaw/AdvertisementRaw.ino | 26 +++ .../AdvertisementRawMaxDeviceName.ino | 26 +++ .../AdvertisementRawScanResponse.ino | 26 +++ .../AdvertisementRawiBeacon.ino | 26 +++ .../examples/ColorWheel/ColorWheel.ino | 26 +++ .../examples/Connection/Connection.ino | 26 +++ .../examples/CustomUUID/CustomUUID.ino | 26 +++ .../examples/LedButton/LedButton.ino | 26 +++ .../LedButtonConnInterval.ino | 161 ++++++++++++++++++ .../examples/PowerLevel/PowerLevel.ino | 26 +++ .../examples/Proximity/Proximity.ino | 26 +++ .../ProximityAveraged/ProximityAveraged.ino | 26 +++ libraries/RFduinoBLE/examples/Servo/Servo.ino | 2 +- .../examples/Temperature/Temperature.ino | 26 +++ .../RFduinoBLE/examples/Template/Template.ino | 26 +++ .../TimingCrtitical/TimingCrtitical.ino | 26 +++ .../RFduinoBLE/examples/iBeacon/iBeacon.ino | 26 +++ .../iBeaconSettings/iBeaconSettings.ino | 26 +++ .../examples/DeviceInfo/DeviceInfo.ino | 26 +++ .../examples/PinWake/PinWake.ino | 26 +++ .../RGBShieldChangingColors.ino | 26 +++ variants/RFduino/libRFduinoBLE.a | Bin 40036 -> 41540 bytes variants/RFduino/libRFduinoBLE.h | 6 + 29 files changed, 760 insertions(+), 1 deletion(-) mode change 100755 => 100644 libraries/RFduinoBLE/examples/Connection/Connection.ino create mode 100644 libraries/RFduinoBLE/examples/LedButtonConnInterval/LedButtonConnInterval.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/Proximity/Proximity.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/ProximityAveraged/ProximityAveraged.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/Servo/Servo.ino mode change 100755 => 100644 libraries/RFduinoBLE/examples/Template/Template.ino mode change 100755 => 100644 libraries/RFduinoNonBLE/examples/PinWake/PinWake.ino mode change 100755 => 100644 libraries/RFduinoNonBLE/examples/RGBShieldChangingColors/RGBShieldChangingColors.ino diff --git a/CHANGELOG b/CHANGELOG index 592fee8..5f5c2b9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 2.0.2 + - Added connection interval update support + - Added missing copyright notices to sketches + v 2.0.1 - RFduinoGZLL enhancement for channel selection policy - allow build.bat "run as administrator" diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index d0b406d..6c8495c 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -114,4 +114,14 @@ bool RFduinoBLEClass::sendFloat(float data) return RFduinoBLE_send((char*)&data, sizeof(float)); } +void RFduinoBLEClass::updateConnInterval(int min_conn_interval_ms, int max_conn_interval_ms) +{ + RFduinoBLE_update_conn_interval(min_conn_interval_ms, max_conn_interval_ms); +} + +int RFduinoBLEClass::getConnInterval(void) +{ + return RFduinoBLE_get_conn_interval(); +} + RFduinoBLEClass RFduinoBLE; diff --git a/libraries/RFduinoBLE/RFduinoBLE.h b/libraries/RFduinoBLE/RFduinoBLE.h index 031ca7a..500c3dd 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.h +++ b/libraries/RFduinoBLE/RFduinoBLE.h @@ -73,6 +73,12 @@ class RFduinoBLEClass bool sendByte(uint8_t data); bool sendInt(int data); bool sendFloat(float data); + + // request central role use a different connection interval in the given range + // the central role may reject the request (or even pick a value outside the range) + void updateConnInterval(int min_conn_interval_ms, int max_conn_interval_ms); + + int getConnInterval(void); }; extern RFduinoBLEClass RFduinoBLE; diff --git a/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino b/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino index 6286e3f..dc34b2c 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementContinuous/AdvertisementContinuous.ino @@ -3,6 +3,32 @@ The sketch demonstrates how to do continuous Bluetooth Low Energy 4 Advertisement with the RFduino. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino b/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino index 066b5ff..a158ea2 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementInterval/AdvertisementInterval.ino @@ -5,6 +5,32 @@ Advertisement transmission interval. Faster iterval = higher power consumption = lower connection latency */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino index f27e248..2f9a0ee 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementPeriodic/AdvertisementPeriodic.ino @@ -7,6 +7,32 @@ can be woken up by pressing Button 1, at which time the device will advertise again. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino b/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino index 8578b69..6366062 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino @@ -6,6 +6,32 @@ packet. This is for advanced use only, as the RFduino will not advertise is the is invalid. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // the advertisement packet is composed of a series of variable length blocks, that can appear in any order. diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino b/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino index 4054b31..0ab03f3 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino @@ -6,6 +6,32 @@ packet. This is for advanced use only, as the RFduino will not advertise is the is invalid. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // the advertisement packet is composed of a series of variable length blocks, that can appear in any order. diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino b/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino index ea08949..ed51575 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino @@ -22,6 +22,32 @@ RFduino's that advertise using the previous fixed RFduino UUID. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // the advertisement packet is composed of a series of variable length blocks, that can appear in any order. diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino b/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino index 7191e4d..9969e31 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino @@ -6,6 +6,32 @@ packet. This is for advanced use only, as the RFduino will not advertise is the is invalid. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // the advertisement packet is composed of a series of variable length blocks, that can appear in any order. diff --git a/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino b/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino index 7d5a2e6..6fbea18 100644 --- a/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino +++ b/libraries/RFduinoBLE/examples/ColorWheel/ColorWheel.ino @@ -7,6 +7,32 @@ This sketch is supposed to be used with the rfduinoColorWheel iPhone application. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 2 on the RGB shield is the red led diff --git a/libraries/RFduinoBLE/examples/Connection/Connection.ino b/libraries/RFduinoBLE/examples/Connection/Connection.ino old mode 100755 new mode 100644 index ed2eb00..c9c89d6 --- a/libraries/RFduinoBLE/examples/Connection/Connection.ino +++ b/libraries/RFduinoBLE/examples/Connection/Connection.ino @@ -3,6 +3,32 @@ The sketch demonstrates how to detect a Bluetooth Low Energy 4 connection with the RFduino. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino b/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino index 3fe7d4b..a19d0d6 100644 --- a/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino +++ b/libraries/RFduinoBLE/examples/CustomUUID/CustomUUID.ino @@ -21,6 +21,32 @@ RFduino's that advertise using the previous fixed RFduino UUID. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/LedButton/LedButton.ino b/libraries/RFduinoBLE/examples/LedButton/LedButton.ino index 0db570f..fd14044 100644 --- a/libraries/RFduinoBLE/examples/LedButton/LedButton.ino +++ b/libraries/RFduinoBLE/examples/LedButton/LedButton.ino @@ -8,6 +8,32 @@ The button on the iPhone can be used to turn the green led on or off. The button state of button 1 is transmitted to the iPhone and shown in the application. */ + +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ #include diff --git a/libraries/RFduinoBLE/examples/LedButtonConnInterval/LedButtonConnInterval.ino b/libraries/RFduinoBLE/examples/LedButtonConnInterval/LedButtonConnInterval.ino new file mode 100644 index 0000000..b891a20 --- /dev/null +++ b/libraries/RFduinoBLE/examples/LedButtonConnInterval/LedButtonConnInterval.ino @@ -0,0 +1,161 @@ +/* +This RFduino sketch demonstrates a full bi-directional Bluetooth Low +Energy 4 connection between an iPhone application and an RFduino. +This sketch also demonstrates how to select a slower connection +interval, which will slow down the response rate, but also drastically +reduce the power consumption of the RFduino. + +This sketch works with the rfduinoLedButton iPhone application. + +The button on the iPhone can be used to turn the green led on or off. +The button state of button 1 is transmitted to the iPhone and shown in +the application. +*/ + +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include + +// pin 3 on the RGB shield is the red led +// (can be turned on/off from the iPhone app) +int led = 3; + +// pin 5 on the RGB shield is button 1 +// (button press will be shown on the iPhone app) +int button = 5; + +// debounce time (in ms) +int debounce_time = 10; + +// maximum debounce timeout (in ms) +int debounce_timeout = 100; + +void setup() { + Serial.begin(9600); + + // led turned on/off from the iPhone app + pinMode(led, OUTPUT); + + // button press will be shown on the iPhone app) + pinMode(button, INPUT); + + // this is the data we want to appear in the advertisement + // (if the deviceName and advertisementData are too long to fix into the 31 byte + // ble advertisement packet, then the advertisementData is truncated first down to + // a single byte, then it will truncate the deviceName) + RFduinoBLE.advertisementData = "ledbtn"; + + // start the BLE stack + RFduinoBLE.begin(); +} + +int debounce(int state) +{ + int start = millis(); + int debounce_start = start; + + while (millis() - start < debounce_timeout) + if (digitalRead(button) == state) + { + if (millis() - debounce_start >= debounce_time) + return 1; + } + else + debounce_start = millis(); + + return 0; +} + +int delay_until_button(int state) +{ + // set button edge to wake up on + if (state) + RFduino_pinWake(button, HIGH); + else + RFduino_pinWake(button, LOW); + + do + // switch to lower power mode until a button edge wakes us up + RFduino_ULPDelay(INFINITE); + while (! debounce(state)); + + // if multiple buttons were configured, this is how you would determine what woke you up + if (RFduino_pinWoke(button)) + { + // execute code here + RFduino_resetPinWake(button); + } +} + +void loop() { + delay_until_button(HIGH); + RFduinoBLE.send(1); + + delay_until_button(LOW); + RFduinoBLE.send(0); + + // uncomment here to update the connection interval after the first button press + // RFduinoBLE_update_conn_interval(900,1000); + + // display the connection interval the iPhone actually selected after a button press + int connInterval = RFduinoBLE.getConnInterval(); + Serial.println(connInterval); +} + +void RFduinoBLE_onConnect() +{ + // request central role use a different connection interval in the given range + // the central role may reject the request (or even pick a value outside the range) + // we will request something in the 900ms to 1100ms range + // the actual rate the iPhone uses is 1098ms + // the best way to get the connection interval you are after is trail and error + // if the iPhone rejects the request, the connection interval will be the default (25ms) + RFduinoBLE.updateConnInterval(900, 1100); + + // note: you cannot use delay()/RFduinoBLE.getConnInterval() here to determine which + // connection interval the iPhone selected - getConnInterval() must be called from + // either loop() or onReceive() +} + +void RFduinoBLE_onDisconnect() +{ + // don't leave the led on if they disconnect + digitalWrite(led, LOW); +} + +void RFduinoBLE_onReceive(char *data, int len) +{ + // display the connection interval the iPhone actually selected after a button press + int connInterval = RFduinoBLE.getConnInterval(); + Serial.println(connInterval); + + // if the first byte is 0x01 / on / true + if (data[0]) + digitalWrite(led, HIGH); + else + digitalWrite(led, LOW); +} diff --git a/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino b/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino index 44b66fe..4359dcb 100644 --- a/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino +++ b/libraries/RFduinoBLE/examples/PowerLevel/PowerLevel.ino @@ -3,6 +3,32 @@ The sketch demonstrates how to control the Bluetooth Low Energy 4 transmission power of the RFduino. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/Proximity/Proximity.ino b/libraries/RFduinoBLE/examples/Proximity/Proximity.ino old mode 100755 new mode 100644 index fd379bd..d37d5c6 --- a/libraries/RFduinoBLE/examples/Proximity/Proximity.ino +++ b/libraries/RFduinoBLE/examples/Proximity/Proximity.ino @@ -13,6 +13,32 @@ the third zone, both leds are on (yellow). In the forth and closest zone led2 is on (red). */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB sheild is the green led diff --git a/libraries/RFduinoBLE/examples/ProximityAveraged/ProximityAveraged.ino b/libraries/RFduinoBLE/examples/ProximityAveraged/ProximityAveraged.ino old mode 100755 new mode 100644 index 2a5e4c1..c766a4d --- a/libraries/RFduinoBLE/examples/ProximityAveraged/ProximityAveraged.ino +++ b/libraries/RFduinoBLE/examples/ProximityAveraged/ProximityAveraged.ino @@ -12,6 +12,32 @@ both leds are off. In the second zone (closer), led1 is on (green). In the third zone, both leds are on (yellow). In the forth and closest zone led2 is on (red). */ + +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ #include diff --git a/libraries/RFduinoBLE/examples/Servo/Servo.ino b/libraries/RFduinoBLE/examples/Servo/Servo.ino old mode 100755 new mode 100644 index f3b742b..9aed9b0 --- a/libraries/RFduinoBLE/examples/Servo/Servo.ino +++ b/libraries/RFduinoBLE/examples/Servo/Servo.ino @@ -1 +1 @@ -/* The sketch accepts a Bluetooth Low Energy 4 connection from an iPhone and accepts commands from the iPhone to run upto 4 standard servos. This sketch is suppose to work with the rfduinoServo application. It receives two bytes from the iPhone. The first byte contains the servos to set (bit1 = servo a, bit2 = servo b, etc), and the value is the number of degrees (0-180) to position the servo too. */ #include #include Servo s1; Servo s2; Servo s3; Servo s4; void setup() { s1.attach(2); s2.attach(3); s3.attach(4); s4.attach(5); RFduinoBLE.advertisementInterval = 675; RFduinoBLE.advertisementData = "-servo"; RFduinoBLE.begin(); } void loop() { // RFduino_ULPDelay(INFINITE); } void RFduinoBLE_onReceive(char *data, int len){ int servo = data[0]; int degree = data[1]; if (bitRead(servo, 1)) s1.write(degree); if (bitRead(servo, 2)) s2.write(degree); if (bitRead(servo, 3)) s3.write(degree); if (bitRead(servo, 4)) s4.write(degree); } \ No newline at end of file +/* The sketch accepts a Bluetooth Low Energy 4 connection from an iPhone and accepts commands from the iPhone to run upto 4 standard servos. This sketch is suppose to work with the rfduinoServo application. It receives two bytes from the iPhone. The first byte contains the servos to set (bit1 = servo a, bit2 = servo b, etc), and the value is the number of degrees (0-180) to position the servo too. */ /* Copyright (c) 2014 OpenSourceRF.com. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include Servo s1; Servo s2; Servo s3; Servo s4; void setup() { s1.attach(2); s2.attach(3); s3.attach(4); s4.attach(5); RFduinoBLE.advertisementInterval = 675; RFduinoBLE.advertisementData = "-servo"; RFduinoBLE.begin(); } void loop() { // RFduino_ULPDelay(INFINITE); } void RFduinoBLE_onReceive(char *data, int len){ int servo = data[0]; int degree = data[1]; if (bitRead(servo, 1)) s1.write(degree); if (bitRead(servo, 2)) s2.write(degree); if (bitRead(servo, 3)) s3.write(degree); if (bitRead(servo, 4)) s4.write(degree); } \ No newline at end of file diff --git a/libraries/RFduinoBLE/examples/Temperature/Temperature.ino b/libraries/RFduinoBLE/examples/Temperature/Temperature.ino index b9fbf14..9bf95d0 100644 --- a/libraries/RFduinoBLE/examples/Temperature/Temperature.ino +++ b/libraries/RFduinoBLE/examples/Temperature/Temperature.ino @@ -6,6 +6,32 @@ updates once a second. It is suppose to be used with the rfduinoTemperature iPhone application. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include void setup() { diff --git a/libraries/RFduinoBLE/examples/Template/Template.ino b/libraries/RFduinoBLE/examples/Template/Template.ino old mode 100755 new mode 100644 index 98ebf72..2cd731c --- a/libraries/RFduinoBLE/examples/Template/Template.ino +++ b/libraries/RFduinoBLE/examples/Template/Template.ino @@ -3,6 +3,32 @@ The sketch is an empty template for Bluetooth Low Energy 4. Simply remove what you dont need, and fill in the rest. */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include void setup() diff --git a/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino b/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino index 1fe3684..ce5533d 100644 --- a/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino +++ b/libraries/RFduinoBLE/examples/TimingCrtitical/TimingCrtitical.ino @@ -2,6 +2,32 @@ The sketch demonstrates how to integrate timing critical code with Bluetooth Low Energy 4. */ + +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ #include diff --git a/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino b/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino index 7301b51..d85084d 100644 --- a/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino +++ b/libraries/RFduinoBLE/examples/iBeacon/iBeacon.ino @@ -2,6 +2,32 @@ The sketch demonstrates iBecaon from an RFduino */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino b/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino index c47c0c1..14ef272 100644 --- a/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino +++ b/libraries/RFduinoBLE/examples/iBeaconSettings/iBeaconSettings.ino @@ -2,6 +2,32 @@ The sketch demonstrates iBecaon from an RFduino */ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + #include // pin 3 on the RGB shield is the green led diff --git a/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino b/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino index c3c9aa2..3dff3d9 100644 --- a/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino +++ b/libraries/RFduinoNonBLE/examples/DeviceInfo/DeviceInfo.ino @@ -1,3 +1,29 @@ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + void setup() { Serial.begin(57600); diff --git a/libraries/RFduinoNonBLE/examples/PinWake/PinWake.ino b/libraries/RFduinoNonBLE/examples/PinWake/PinWake.ino old mode 100755 new mode 100644 index 5108c4e..4f76be2 --- a/libraries/RFduinoNonBLE/examples/PinWake/PinWake.ino +++ b/libraries/RFduinoNonBLE/examples/PinWake/PinWake.ino @@ -1,3 +1,29 @@ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + int myPinCallback(uint32_t ulPin) { digitalWrite(4, HIGH); diff --git a/libraries/RFduinoNonBLE/examples/RGBShieldChangingColors/RGBShieldChangingColors.ino b/libraries/RFduinoNonBLE/examples/RGBShieldChangingColors/RGBShieldChangingColors.ino old mode 100755 new mode 100644 index 99ae5dc..ba16890 --- a/libraries/RFduinoNonBLE/examples/RGBShieldChangingColors/RGBShieldChangingColors.ino +++ b/libraries/RFduinoNonBLE/examples/RGBShieldChangingColors/RGBShieldChangingColors.ino @@ -1,3 +1,29 @@ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + int led_red = 2; int led_green = 3; int led_blue = 4; diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a index c2e3bff6f15df4bca769b5f7011993aab81f9e54..e1033af66f436211d110e851578dc7348095e4cd 100644 GIT binary patch delta 6761 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 diff --git a/variants/RFduino/libRFduinoBLE.h b/variants/RFduino/libRFduinoBLE.h index 9207577..e206050 100644 --- a/variants/RFduino/libRFduinoBLE.h +++ b/variants/RFduino/libRFduinoBLE.h @@ -77,6 +77,12 @@ void RFduinoBLE_end(void); bool RFduinoBLE_send(const char *data, uint8_t len); +// request central role use a different connection interval in the given range +// the central role may reject the request (or even pick a value outside the range) +void RFduinoBLE_update_conn_interval(int min_conn_interval_ms, int max_conn_interval_ms); + +int RFduinoBLE_get_conn_interval(void); + #ifdef __cplusplus } #endif From cfe1a448524f2dafc25f62cccd900484925bba8a Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 20 Jun 2014 12:23:58 -0700 Subject: [PATCH 13/52] Serial.printf() support --- CHANGELOG | 4 + cores/arduino/Print.cpp | 76 ++++++++++++++++++- cores/arduino/Print.h | 5 +- cores/arduino/UARTClass.cpp | 4 +- cores/arduino/UARTClass.h | 2 +- cores/arduino/WString.h | 2 + .../RFduinoNonBLE/examples/Printf/Printf.ino | 49 ++++++++++++ variants/RFduino/variant.cpp | 21 +++-- 8 files changed, 149 insertions(+), 14 deletions(-) mode change 100755 => 100644 cores/arduino/Print.cpp mode change 100755 => 100644 cores/arduino/Print.h create mode 100644 libraries/RFduinoNonBLE/examples/Printf/Printf.ino diff --git a/CHANGELOG b/CHANGELOG index 5f5c2b9..02dee47 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 2.0.3 + - Added printf() support to Serial (see RFduinoNonBLE/Printf sketch) + - Fixed issue with Serial.flush()/Serial.end() when switching TX/RX pins + v 2.0.2 - Added connection interval update support - Added missing copyright notices to sketches diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp old mode 100755 new mode 100644 index d554fa2..f3749fe --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. + Copyright (c) 2014 OpenSourceRF.com. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -47,6 +47,7 @@ #include #include +#include #include #include #include "Arduino.h" @@ -285,3 +286,76 @@ size_t Print::printFloat(double number, uint8_t digits) return n; } + +size_t Print::printf(const char *format, ...) +{ + va_list vl; + size_t n = 0; + + va_start(vl, format); + + while (*format) + { + if (*format == '%') + { + format++; + + char ch = *format; + if (! ch) + break; + else if (ch == '%') + n += print(*format); + else if (ch == 'b') + { + unsigned u = va_arg(vl, unsigned); + n += print(u, BIN); + } + else if (ch == 'c') + { + int ch = va_arg(vl, int); + n += print((char)ch); + } + else if (ch == 'd') + { + int i = va_arg(vl, int); + n += print(i); + } + else if (ch == 'u') + { + unsigned u = va_arg(vl, unsigned); + n += print(u); + } + else if (ch == 'x') + { + unsigned x = va_arg(vl, unsigned); + n += print(x, HEX); + } + else if (ch == 's') + { + char *s = va_arg(vl, char *); + n += print(s); + } + else if (ch == 'f') + { + double d = va_arg(vl, double); + long l = d; + n += print(l); + n += print('.'); + d *= 100; + l = d; + if (l < 1) + l = -l; + l %= 100; + n += print(l); + } + } + else + n += print(*format); + + format++; + } + + va_end(vl); + + return n; +} diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h old mode 100755 new mode 100644 index 9f12a33..539d7f6 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. + Copyright (c) 2014 OpenSourceRF.com. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -102,6 +102,9 @@ class Print size_t println(double, int = 2); size_t println(const Printable&); size_t println(void); + + // supports c,d,u,x,s,f,b + size_t printf(const char *, ...); }; #endif diff --git a/cores/arduino/UARTClass.cpp b/cores/arduino/UARTClass.cpp index c044587..ea73f64 100644 --- a/cores/arduino/UARTClass.cpp +++ b/cores/arduino/UARTClass.cpp @@ -106,10 +106,8 @@ int UARTClass::read( void ) void UARTClass::flush( void ) { // Wait for any outstanding data to be sent - while (_tx_buffer->_iTail != _tx_buffer->_iHead) + while (transmitting) ; - - UART0_FlushTX(); } void UARTClass::tx( void ) diff --git a/cores/arduino/UARTClass.h b/cores/arduino/UARTClass.h index cea57e0..43ce0ea 100644 --- a/cores/arduino/UARTClass.h +++ b/cores/arduino/UARTClass.h @@ -55,7 +55,7 @@ class UARTClass : public HardwareSerial { protected: RingBuffer *_rx_buffer, *_tx_buffer ; - bool transmitting; + volatile bool transmitting; void tx( void ); public: diff --git a/cores/arduino/WString.h b/cores/arduino/WString.h index 3227527..44117fb 100644 --- a/cores/arduino/WString.h +++ b/cores/arduino/WString.h @@ -195,6 +195,8 @@ class String // parsing/conversion long toInt(void) const; + + const char *cstr() const { return buffer; } protected: char *buffer; // the actual char array diff --git a/libraries/RFduinoNonBLE/examples/Printf/Printf.ino b/libraries/RFduinoNonBLE/examples/Printf/Printf.ino new file mode 100644 index 0000000..44d269e --- /dev/null +++ b/libraries/RFduinoNonBLE/examples/Printf/Printf.ino @@ -0,0 +1,49 @@ +/* + Copyright (c) 2014 OpenSourceRF.com. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* +The sketch demonstrates various Serial.printf() calls. +*/ + +void setup() { + char ch = 'A'; + int i = -123; + double d = -123.456; + + Serial.begin(57600); + + Serial.printf("Hello World!\n"); + Serial.printf("ch = %c\n", ch); + Serial.printf("i = %d, unsigned = %u, hex = %x, binary = %b\n", i, i, i, i); + Serial.printf("d = %f\n", d); + Serial.printf("string1 = %s, string2 = %s\n", "hi", F("hi")); + + // this works, but has been commented out for testing due to String impact on code size + // Serial.printf("string3 = %s\n", String("hi").cstr()); +} + +void loop() { +} diff --git a/variants/RFduino/variant.cpp b/variants/RFduino/variant.cpp index a7ed6cd..347df77 100644 --- a/variants/RFduino/variant.cpp +++ b/variants/RFduino/variant.cpp @@ -215,23 +215,28 @@ void UART0_Stop() // Wait for any outstanding data to be sent Serial.flush(); + NRF_UART0->TASKS_STOPTX = 1; + NRF_UART0->TASKS_STOPRX = 1; + + NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); + // Disable UART interrupt in NVIC detachInterrupt(UART0_IRQn); - NRF_UART0->TASKS_STOPTX = 1; - NRF_UART0->TASKS_STOPRX = 1; + // Disconnect high drive tx pin + int tx_pin = NRF_UART0->PSELTXD; + NRF_GPIO->PIN_CNF[tx_pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) + | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); UART0_State = UART0_State_NotStarted; } void UART0_FlushTX() { - if (UART0_State == UART0_State_AfterFirstTX) - { - // wait for last transmission to complete - while (! UART0_TXReady()) - ; - } + Serial.flush(); } // delegate to serial for syscalls/write and error messages From 4b2f351ac5f2c5a8a72c3a10fef539ef3d140f67 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 15 Jul 2014 17:57:45 -0600 Subject: [PATCH 14/52] fixes for arduino 1.5.7 --- size | 8 -- size.bat | 8 -- system/RFduino/build_gcc/Makefile | 75 ------------ system/RFduino/build_gcc/RFduino.mk | 183 ---------------------------- system/RFduino/build_gcc/debug.mk | 51 -------- system/RFduino/build_gcc/gcc.mk | 90 -------------- system/RFduino/build_gcc/mk.bat | 2 - system/RFduino/build_gcc/release.mk | 51 -------- system/RFduino/source/build.bat | 46 +++++++ 9 files changed, 46 insertions(+), 468 deletions(-) delete mode 100755 size delete mode 100755 size.bat delete mode 100755 system/RFduino/build_gcc/Makefile delete mode 100755 system/RFduino/build_gcc/RFduino.mk delete mode 100755 system/RFduino/build_gcc/debug.mk delete mode 100755 system/RFduino/build_gcc/gcc.mk delete mode 100644 system/RFduino/build_gcc/mk.bat delete mode 100755 system/RFduino/build_gcc/release.mk create mode 100644 system/RFduino/source/build.bat diff --git a/size b/size deleted file mode 100755 index 886b6ed..0000000 --- a/size +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -size=0 -while read i j k; do - if [ "$i" == ".text" ] || [ "$i" == ".ARM.exidx" ] || [ "$i" == ".relocate" ] ; then - size=$((size+j)) - fi -done < <($@) -echo size=$size diff --git a/size.bat b/size.bat deleted file mode 100755 index b08ba9e..0000000 --- a/size.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -set size=0 -for /f "skip=2 tokens=1,2" %%i in ('%*') do ( -if "%%i"==".text" set /a size = size + %%j -if "%%i"==".ARM.exidx" set /a size = size + %%j -if "%%i"==".relocate" set /a size = size + %%j -) -echo size=%size% diff --git a/system/RFduino/build_gcc/Makefile b/system/RFduino/build_gcc/Makefile deleted file mode 100755 index b897de0..0000000 --- a/system/RFduino/build_gcc/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright (c) 2013 OpenSourceRF.com. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# -# Copyright (c) 2011 Arduino. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Makefile for compiling libchip - -SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables --no-print-directory - -#------------------------------------------------------------------------------- -# Rules -#------------------------------------------------------------------------------- - -all: libRFduinoSystem.a - -.PHONY: libRFduinoSystem.a -libRFduinoSystem.a: - @echo ------------------------------------------------------------------------------- - @echo --- Making $@ - @$(MAKE) $(SUBMAKE_OPTIONS) -f RFduino.mk - -.PHONY: libRFduinoSystem_dbg.a -libRFduinoSystem_dbg.a: - @echo ------------------------------------------------------------------------------- - @echo --- Making $@ - @echo --- - @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f RFduino.mk - @echo ------------------------------------------------------------------------------- - -.PHONY: clean -clean: - @echo ------------------------------------------------------------------------------- - @echo --- Cleaning RFduino release and debug - @$(MAKE) $(SUBMAKE_OPTIONS) -f RFduino.mk $@ - @$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f RFduino.mk $@ - @echo ------------------------------------------------------------------------------- diff --git a/system/RFduino/build_gcc/RFduino.mk b/system/RFduino/build_gcc/RFduino.mk deleted file mode 100755 index 4538fbb..0000000 --- a/system/RFduino/build_gcc/RFduino.mk +++ /dev/null @@ -1,183 +0,0 @@ -# -# Copyright (c) 2013 OpenSourceRF.com. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# -# Copyright (c) 2011 Arduino. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Makefile for compiling libchip -.SUFFIXES: .o .a .c .s -SUB_MAKEFILES=debug.mk gcc.mk release.mk win.mk nrf51.mk - -LIBNAME=libRFduinoSystem -TOOLCHAIN=gcc - -ifeq ($(OS),Windows_NT) -DEV_NUL=NUL -else -DEV_NUL=/dev/null -endif - -# referenced in gcc.mk -CHIP=RFduino - -#------------------------------------------------------------------------------- -# Path -#------------------------------------------------------------------------------- - -# Output directories -OUTPUT_BIN = ../../../variants/RFduino - -# Libraries -PROJECT_BASE_PATH = .. -CMSIS_ROOT_PATH = $(PROJECT_BASE_PATH)/../CMSIS - -CMSIS_ARM_PATH=$(CMSIS_ROOT_PATH)/CMSIS/Include - -#------------------------------------------------------------------------------- -# Files -#------------------------------------------------------------------------------- - -vpath %.h $(PROJECT_BASE_PATH)/include $(CMSIS_ARM_PATH) -vpath %.c $(PROJECT_BASE_PATH)/source $(CMSIS_ARM_PATH) - -VPATH+=$(PROJECT_BASE_PATH)/source -VPATH+=$(CMSIS_ARM_PATH) - -INCLUDES = -I$(PROJECT_BASE_PATH) -INCLUDES += -I$(PROJECT_BASE_PATH)/include -INCLUDES += -I$(CMSIS_ARM_PATH) - -#------------------------------------------------------------------------------- -ifdef DEBUG -include debug.mk -else -include release.mk -endif - -#------------------------------------------------------------------------------- -# Tools -#------------------------------------------------------------------------------- - -include $(TOOLCHAIN).mk - -#------------------------------------------------------------------------------- -ifdef DEBUG -OUTPUT_OBJ=debug -OUTPUT_LIB=$(LIBNAME)_dbg.a -else -OUTPUT_OBJ=release -OUTPUT_LIB=$(LIBNAME).a -endif - -OUTPUT_PATH=$(OUTPUT_OBJ) - -#------------------------------------------------------------------------------- -# C source files and objects -#------------------------------------------------------------------------------- -C_SRC=$(wildcard $(PROJECT_BASE_PATH)/source/*.c) - -C_OBJ_TEMP=$(patsubst %.c, %.o, $(notdir $(C_SRC))) - -# during development, remove some files -C_OBJ_FILTER= - -C_OBJ=$(filter-out $(C_OBJ_FILTER), $(C_OBJ_TEMP)) - -#------------------------------------------------------------------------------- -# Assembler source files and objects -#------------------------------------------------------------------------------- -A_SRC=$(wildcard $(PROJECT_BASE_PATH)/source/*.s) - -A_OBJ_TEMP=$(patsubst %.s, %.o, $(notdir $(A_SRC))) - -# during development, remove some files -A_OBJ_FILTER= - -A_OBJ=$(filter-out $(A_OBJ_FILTER), $(A_OBJ_TEMP)) - -#------------------------------------------------------------------------------- -# Rules -#------------------------------------------------------------------------------- -all: libRFduino - -libRFduino: create_output $(OUTPUT_LIB) - -.PHONY: create_output -create_output: - @echo ------------------------------------------------------------------------------- - @echo --- Preparing libRFduino files $(OUTPUT_PATH) to $(OUTPUT_BIN) - @echo ------------------------- - @echo *C_SRC=$(C_SRC) - @echo ------------------------- - @echo *C_OBJ=$(C_OBJ) - @echo ------------------------- - @echo *OUTPUT_PATH=$(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) - @echo ------------------------- - @echo *A_SRC=$(A_SRC) - @echo ------------------------- - -# -@mkdir $(subst /,$(SEP),$(OUTPUT_BIN)) 1>$(DEV_NUL) 2>&1 - -@$(RM) $(OUTPUT_PATH) - -@mkdir $(OUTPUT_PATH) - @echo ------------------------------------------------------------------------------- - -$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c -# @"$(CC)" -v -c $(CFLAGS) -Wa,aln=$(subst .o,.s,$@) $< -o $@ - @"$(CC)" -c $(CFLAGS) $< -o $@ - -$(addprefix $(OUTPUT_PATH)/,$(A_OBJ)): $(OUTPUT_PATH)/%.o: %.s - @"$(AS)" -c $(ASFLAGS) $< -o $@ - -$(OUTPUT_LIB): $(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(A_OBJ)) - @"$(AR)" -r "$(OUTPUT_BIN)/$@" $^ - @"$(NM)" "$(OUTPUT_BIN)/$@" > "$(OUTPUT_BIN)/$@.txt" - -.PHONY: clean -clean: - @echo ------------------------------------------------------------------------------- - @echo --- Cleaning libRFduino files $(OUTPUT_PATH) $(subst /,$(SEP),$(OUTPUT_BIN)/$(OUTPUT_LIB)) - -@$(RM) $(OUTPUT_PATH) 1>$(DEV_NUL) 2>&1 - -@$(RM) $(subst /,$(SEP),$(OUTPUT_BIN)/$(OUTPUT_LIB)) 1>$(DEV_NUL) 2>&1 - -@$(RM) $(subst /,$(SEP),$(OUTPUT_BIN)/$(OUTPUT_LIB)).txt 1>$(DEV_NUL) 2>&1 - @echo ------------------------------------------------------------------------------- - -# dependencies -$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: $(PROJECT_BASE_PATH)/chip.h $(wildcard $(PROJECT_BASE_PATH)/include/*.h) $(wildcard $(CMSIS_BASE_PATH)/*.h) diff --git a/system/RFduino/build_gcc/debug.mk b/system/RFduino/build_gcc/debug.mk deleted file mode 100755 index f876003..0000000 --- a/system/RFduino/build_gcc/debug.mk +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2013 OpenSourceRF.com. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# -# Copyright (c) 2011 Arduino. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Optimization level -# -O1 Optimize -# -O2 Optimize even more -# -O3 Optimize yet more -# -O0 Reduce compilation time and make debugging produce the expected results -# -Os Optimize for size -OPTIMIZATION = -g -O0 -DDEBUG diff --git a/system/RFduino/build_gcc/gcc.mk b/system/RFduino/build_gcc/gcc.mk deleted file mode 100755 index f915ce1..0000000 --- a/system/RFduino/build_gcc/gcc.mk +++ /dev/null @@ -1,90 +0,0 @@ -# -# Copyright (c) 2013 OpenSourceRF.com. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# -# Copyright (c) 2011 Arduino. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Tool suffix when cross-compiling -#CROSS_COMPILE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi- -CROSS_COMPILE = ../../../../../tools/g++_arm_none_eabi/bin/arm-none-eabi- - -# Compilation tools -AR = $(CROSS_COMPILE)ar -CC = $(CROSS_COMPILE)gcc -AS = $(CROSS_COMPILE)as -NM = $(CROSS_COMPILE)nm -ifeq ($(OS),Windows_NT) -RM=cs-rm -Rf -#RM=del /s /f -else -RM=rm -Rf -endif - -SEP=/ - -# --------------------------------------------------------------------------------------- -# C Flags - -CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses -CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings -CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes -CFLAGS += -Wmissing-prototypes -Wmissing-declarations -CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -CFLAGS += -Wunreachable-code -CFLAGS += -Wcast-align -#CFLAGS += -Wmissing-noreturn -#CFLAGS += -Wconversion - -# To reduce application size use only integer printf function. -CFLAGS += -Dprintf=iprintf - -CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m0 -mthumb -mlong-calls -ffunction-sections -fdata-sections -std=c99 -CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) - - -# --------------------------------------------------------------------------------------- -# ASM Flags - -ASFLAGS = -mcpu=cortex-m0 -mthumb -Wall -a -g $(INCLUDES) diff --git a/system/RFduino/build_gcc/mk.bat b/system/RFduino/build_gcc/mk.bat deleted file mode 100644 index e470257..0000000 --- a/system/RFduino/build_gcc/mk.bat +++ /dev/null @@ -1,2 +0,0 @@ -..\..\..\..\..\tools\g++_arm_none_eabi\bin\cs-make -pause diff --git a/system/RFduino/build_gcc/release.mk b/system/RFduino/build_gcc/release.mk deleted file mode 100755 index f14bd81..0000000 --- a/system/RFduino/build_gcc/release.mk +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2013 OpenSourceRF.com. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# -# Copyright (c) 2011 Arduino. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Optimization level -# -O1 Optimize -# -O2 Optimize even more -# -O3 Optimize yet more -# -O0 Reduce compilation time and make debugging produce the expected results -# -Os Optimize for size -OPTIMIZATION = -Os diff --git a/system/RFduino/source/build.bat b/system/RFduino/source/build.bat new file mode 100644 index 0000000..4faeae9 --- /dev/null +++ b/system/RFduino/source/build.bat @@ -0,0 +1,46 @@ +@echo off + +set arduino=C:\arduino-1.5.7 + +cd %arduino%\hardware\arduino\RFduino\system\RFduino\source + +if not exist _build\nul mkdir _build +if exist _build\* del /q _build\* + +set tools=%arduino%\hardware\tools\gcc-arm-none-eabi-4.8.3-2014q1 +set RFduino=%arduino%\hardware\arduino\RFduino + +set gcc=%tools%\bin\arm-none-eabi-gcc +set ar=%tools%\bin\arm-none-eabi-ar +set nm=%tools%\bin\arm-none-eabi-nm + +set includes=-I../include +set includes=%includes% -I../../CMSIS/CMSIS/Include + +set cflags=-Os -w -mcpu=cortex-m0 -mthumb -DNRF51 -DBOARD_PCA10001 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fno-builtin %includes% + +echo compiling... + +echo startup_nrf51822.c +%gcc% %cflags% -c -o _build\startup_nrf51822.o startup_nrf51822.c + +echo system_nrf51.c +%gcc% %cflags% -c -o _build\system_nrf51.o system_nrf51.c + +echo creating library... + +set objs=_build\startup_nrf51822.o +set objs=%objs% _build\system_nrf51.o + +set output=libRFduinoSystem.a + +for %%f in (%objs%) do %ar% rcs _build\%output% %%f + +%nm% _build\%output% >_build\%output%.txt + +echo copying libray and txt to variants... +copy _build\%output% %RFduino%\variants\RFduino\%output% +copy _build\%output%.txt %RFduino%\variants\RFduino\%output%.txt + +:end +pause From 9aba776bc4526fe82208fc661fff79c12542c0cb Mon Sep 17 00:00:00 2001 From: RFduino Date: Fri, 18 Jul 2014 20:41:28 -0600 Subject: [PATCH 15/52] fixes for arduino 1.5.7 #2 --- CHANGELOG | 6 +++++ platform.txt | 19 ++++++++-------- source/libRFduinoGZLL/build.bat | 7 +++--- variants/RFduino/libRFduino.a | Bin 8952 -> 9036 bytes variants/RFduino/libRFduinoBLE.a | Bin 41540 -> 41176 bytes variants/RFduino/libRFduinoGZLL.a | Bin 60466 -> 60526 bytes variants/RFduino/libRFduinoSystem.a | Bin 6154 -> 6286 bytes variants/RFduino/libRFduinoSystem.a.txt | 28 ++++++++++++------------ 8 files changed, 32 insertions(+), 28 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 02dee47..5a1ad03 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ CHANGELOG +v 2.1 + - Fixes required to support Arduino 1.5.7 + (NOTE: Arduino 1.5.7 or higher is now required for RFduino 2.1 or above). + - Updated gcc compiler now generates smaller code sizes + - Sketch size information now includes RAM usage. + v 2.0.3 - Added printf() support to Serial (see RFduinoNonBLE/Printf sketch) - Fixed issue with Serial.flush()/Serial.end() when switching TX/RX pins diff --git a/platform.txt b/platform.txt index 5f74ad0..c4f2aa6 100644 --- a/platform.txt +++ b/platform.txt @@ -3,14 +3,15 @@ # ------------------------- name=RFduino Boards -compiler.path={runtime.ide.path}/hardware/tools/g++_arm_none_eabi/bin/ +compiler.path={runtime.ide.path}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/ compiler.c.cmd=arm-none-eabi-gcc -compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -Dprintf=iprintf +compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-builtin compiler.c.elf.cmd=arm-none-eabi-g++ -compiler.c.elf.flags=-Os -Wl,--gc-sections +# -u _printf_float +compiler.c.elf.flags=-Wl,--gc-sections --specs=nano.specs compiler.S.flags=-c -g -assembler-with-cpp compiler.cpp.cmd=arm-none-eabi-g++ -compiler.cpp.flags=-c -g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf +compiler.cpp.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fno-builtin compiler.ar.cmd=arm-none-eabi-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arm-none-eabi-objcopy @@ -19,9 +20,6 @@ compiler.elf2hex.flags=-O ihex compiler.elf2hex.cmd=arm-none-eabi-objcopy compiler.ldflags= compiler.size.cmd=arm-none-eabi-size -size.script.path={runtime.ide.path}/hardware/arduino/RFduino -size.script.cmd=size -size.script.cmd.windows=size.bat compiler.define=-DARDUINO= # this can be overriden in boards.txt @@ -40,7 +38,7 @@ recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -m recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} {build.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.variant.path}/libRFduino.a" "{build.variant.path}/libRFduinoBLE.a" "{build.variant.path}/libRFduinoGZLL.a" "{build.path}/{archive_file}" -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} {build.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" -Wl,--cref -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group "{build.path}/syscalls.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.variant.path}/libRFduino.a" "{build.variant.path}/libRFduinoBLE.a" "{build.variant.path}/libRFduinoGZLL.a" "{build.path}/{archive_file}" -Wl,--end-group ## Create eeprom recipe.objcopy.eep.pattern= @@ -49,8 +47,9 @@ recipe.objcopy.eep.pattern= recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" ## Compute size -recipe.size.pattern="{size.script.path}/{size.script.cmd}" "{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=size=(.*) +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" +recipe.size.regex=^(?:\.text|\.ARM.exidx|\.relocate)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.relocate|\.bss)\s+([0-9]+).* # RFduino Uploader tools # ---------------------- diff --git a/source/libRFduinoGZLL/build.bat b/source/libRFduinoGZLL/build.bat index babb9b5..db87d65 100644 --- a/source/libRFduinoGZLL/build.bat +++ b/source/libRFduinoGZLL/build.bat @@ -1,6 +1,6 @@ @echo off -set arduino=C:\arduino-1.5.5 +set arduino=C:\arduino-1.5.7 set nordic="C:\Nordic Semiconductor\nRF51 SDK_v4.2.0.25053\Nordic\nrf51822" if not exist %nordic% ( @@ -13,7 +13,7 @@ cd %arduino%\hardware\arduino\RFduino\source\libRFduinoGZLL if not exist _build\nul mkdir _build if exist _build\* del /q _build\* -set tools=%arduino%\hardware\tools\g++_arm_none_eabi +set tools=%arduino%\hardware\tools\gcc-arm-none-eabi-4.8.3-2014q1 set RFduino=%arduino%\hardware\arduino\RFduino set gcc=%tools%\bin\arm-none-eabi-gcc @@ -23,8 +23,7 @@ set includes=-I%nordic%\Include set includes=%includes% -I%nordic%\Include\gzll set includes=%includes% -I%nordic%\Include\gcc -rem set cflags=--param max-inline-insns-single=500 -set cflags=-Os -w -mcpu=cortex-m0 -mthumb -DNRF51 -DBOARD_PCA10001 -ffunction-sections -fdata-sections -nostdlib -fno-rtti -fno-exceptions --param max-inline-insns-single=500 -Dprintf=iprintf %includes% +set cflags=-Os -w -mcpu=cortex-m0 -mthumb -DNRF51 -DBOARD_PCA10001 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fno-builtin %includes% echo compiling... diff --git a/variants/RFduino/libRFduino.a b/variants/RFduino/libRFduino.a index 6c45ed5d8917a5f917f4a019a4d2dfb89045ce1b..56613e5c783166c0574b3ea788cdaae46f69ca4f 100644 GIT binary patch literal 9036 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 P5&tsfIKHn?j^+LjndEJl literal 8952 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 RbSFpU-B=QTkV+i?e*n-fDfa*X diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a index e1033af66f436211d110e851578dc7348095e4cd..a3e08ae2be6decf8af1ae326d031c6e111915c6b 100644 GIT binary patch literal 41176 zcmd_T3w&JFc`v$VMlX+KTMs`*^4M(6*q{fjM$O^6NTNU|h*Wb_zI zvNHx!1SW}qG(1dGV@N`4k{CjXtHeDCNm`OLza~x3?F=NRhLB`TXiP)eIw2<^k6Z5l zzxG~xue~+G{BHT(+r#MQ!j`xEaDt~T7zw5Dy~Z>;r@2 zNX4N+S82FYnyb8q_6+u+Sb9bV`z8*K4-S};bm=w+s=;_pLf`(}go6i%T-j(z(q*_6 zWO{X~R))HF|G|mLv5_7re$Virs-rzf2AzY4CWY=jG&x3#%v>yB%-SPhN(?im{$7#ZC+?oEg7PYX(Dq;CT4ZlVX7Fm9@4 zb4(nb=;@oB9M47bgdP|i9)u#Uh)u~oeFFpIJ*dNO;s+8#lY_%U6O*$^b`IN$SdxYY zCT4TH6zS3Q*gM=ek?83k?{8X%<};FHMo~Z0{{v&=13e!YhZ36Sp5ZZMz1KI{w-41| zyl+Bhm7X~{#|QfcG?|i-d7$~BYK`{|42|{l^-m6=pJE+D88&&#&}14Nn;hCZ)ZZuj zQkglcy+e_EV4CGxw@!KW2AKt{c*v5GvC)RH)uxYL>6GW}=t&6<5AAXKZ}`~b;ClBs z*wom#jxjeiHMN)u^agLcva7@A^I}!$f)tB^mJaBeob4dB{rr@TZ1*b&(N>H=xW|Y*tl8L#s7Rd z9Il$Gm2!lXa|!IG^owD8PkQCFVakwy*JrD3x-U`{-w~^tqEw|3?W?kj;-We<9qKeG z%hSI&_vm3!Q<+(auuG)o71;%_m!=C0<2rH`XN|k|-1TR7mBe434)+$vLok&vRlTKJ zx>Wk!3>TgDBQ#|eeT{r7=cF!hpFjQOPG7X5cPjF1{&T(GJhihoV4U7c>gnyxiHek{ z7nzpcFKnwx&~K(|CT=7{(%zCdwe|Yg&P|cjGc!fWhsB~g-}8$ikz^z#E}n_`(jO21 zdPb}|30wa1f1N34c`fv6=m#?w)t5hi(Z(Olh?-#fNG$((->RCbW$>S$^k<)`DoTo| zsPm zCj-gD@knY}qB871N}6xQPct9f_D9=GBY$*tU2iD*!Op@bTY3i&XKQa!#HT0PE1uKeqz;tZ)b+OgjJrR=IfcUE;EFv`ATLazC0l=o0lGr*MuumHz7SY z#h0ZR=Yj10_==Qhs85e|(F1Y@D^(&5Uxj(!NODk$>;=XMNG=k#l{Q#j8@Ht}wmubH}G@JB3l62u+ne&~&t>v-SZ| zE7G;$i%**QEz%p$t?ycd7)3RG(1KQl604Gfy{pFQUKB5vErs@m_=-r?)bW&YhtKf0 zpREqIl~f1Yjq1DGk0%QwFC+gn+uK&>h5oT{$qeIoLm{Aa}*#&q}m&Yiu!XmM{vcz1&BPt^V{eWKcL zd`EP57i<;Abg!@a{@&vWQTK;*k)0MH{vbq~DYregYZF=@TK4+W`QegqQ6$k}=IZ|N z{LG5@{*GmdimB!CWr>~g@6o9+?9WX_vNf{*S{$#i^ZKTa5NZwcZee_Z?YqCDd#b?b zZ5Pp_Qw!q9V&aF7il8jFn>x-+6~~7j5t&!6|{{5C`PxYq%*Jn#Vp2eC6a8-Nz z2BYSx?e8_N9UB{-F!qj(8=H1)Gp-!jGdO_xkhJ&fgwl#`^lEQ8CeC2tIe2aZc10i3fugbR~Pc%#%9+~Xh13Woy;)Jpx z;G}4f^W26#6BD9=9u3>C+uGi<^Dw4$BRd8;3pKqb2IPEpUtbbavP0%VWlk!lnd3PE z$|YB_Z@drlWw~mZE!$o`s`Iaq*gyAeXf{DLEIoIXP!9 zbsNUVSif2Mn;Mz~t9gT_s9J1sP41;>OJmtaJmIuOySgNJy_CBuoHi4uncTmYZO@Q<{HBZ>$j}cz~l>9ZZ98cgiBzGU@pXmO}AO`hTx~b z9EgNyhlj3T7uS}!S}j{ zZ(t6-DnzQso0x-doriCD4!&zVe91ZZhCO_fbMSrC!y=aE+mCi1nxEP_$`{mLWn zNzgF2v_Z)`?~&IEVc!N<8_W_IC2t`rHdyU6o`i$>p+Lzi2A?bcYE8a2FtR-@*oX~`f`>3zy0FAI5Wn{6;FVU)ZVJ@Q&nxHX_FQ1Z@r1+ez z#V|_V8Hfb#IaHO7Jm^l9z-$>ZCx~M?CT- z=ivKL4n8E!24(-OC*HZ_odDlFJ2c7y`N#CP!8E|A{QFyvycG0Pae>XYpYiB-Gx+e| z1{LOK9(m+bc}r$xFNXqp{@nsTz28uLjUK*x=8)G7KD~TDItO1O2Oqp_Q1;t$@O9f< zPFX*ggOB~K0wwP=IrtQfyvqKK9DFKo$*1fugHO*trdP?(nryGT(~O zt|_mPfdThH-T~7p|B^;i20j!qo3;cW7U)gN0Zbl384UPrXa-+3!YWXF#41gsJ;uSM zScpwPhhdl|)(fUVm-kq;5H~rQA7USkG65}8{@>w$+2%r?){PV=!AUpheO`|?R4}Va6(#0Qigu@mM7f7vj)Ms^ewMr+bR7byjqdzgBswhq8p*#%)=$F@r1w;eZ;2=T z60yq)&pDzWbk=XqhfFZ}DOPQDfffU@J^|*RXGsA%+8%Y z&h#7zKr=Vp(Ue>P%)H$66*9i8-2riC=0HFg9)3geciAk4ZKEY1A|C#ThrZH7Un%8H z+gvMc8!Z9Mblm!0Ecu;Wx!A++l!O_+R`NScwT>0GfT;7(F=^8vfP)~GhXWWqGzf@G zJ@iX8D&=41p)T>z`9A&HBf^6B9UCI}i}>avZP)#Jj}|^rgzo z|8n$q|7ht?Mg!(&np^e(c3U*Z(MpedwdQ8{%^vrSnw#?eNOP0_KDg;cdztv<8^__` z*h@qAfA_e*=W(C+xaVn81jcuX$Ng@&nM5=FRifMF4vPT~f70XrpvQfW6}}g^9R1lN z9y;g!3aHO%kNY1y?&m!2mp$%RJ?`Io+)J5p7BId#xS3uW=I50j_dd(L3-of7!XeAe zk+dBB=ZE1|KzX0^xIbs{p9HNOE6eYC=x03cf42BnO8$$5Ki`yY>Q^U1mYc!K#5z&u zqSuN|F8Zb7S{Hqd71=q&}Q+~6UvD~OOkbjx@uFJhayllCd)-v=ze{h9gD;Bci z08IThipyN?2C>=YMtgT(@aPvSC&jEYrIiC>t^*~Hzj+{|dCopW(unqMH4lk2fBWD_ z^V7E2<&lv_a<l={jRH+W22jgCRpb5XCBxw(lYA?noHdsJ9lpV|L@u; zl{IgR<+`w?DJlzclf29I7Vnz&^vE;do}uOeq3i<#Lx&tk^TDB;^}IEYv3d|-<{8Qrlg!ngN=>G@e`;iZrBm}F3xPtfr+@B;~igXiWfI*K}1a4VBulnKQZUL^#2&$_XzQE;*Sc!xo+@}agIa$apVs%^6?d5 z|DPiL#MpG>9M?aF^b=o?^b;S0-o!k!#T?N85XzN!0DFhT*CJnt8!&Gt9>Td3F_uUn z;v?8MAV$6##K_N;#K_+o;yZ-6l=wRAK@y`ftRdcqdP2Md`9wU3IX`i~5L<{32+>8n z3-yP15Au;1^=}t3%JoKKY<5C@5yTR>3z+F;eY4B)5vzV8-`Y$PyhHZB)@No)zlQQZT|8Y@pP%loFHD!#S7z>+_GNw18)Dx) zQjz`c^xxj~NUSJRguAaL>7uaF_?>%rm#iTBjk}M>0-5RQ3VG8^-Ffvz&!1+Tlj3tX^=(Y; z?-=g=dGDotPxc+1xMjLJ>}xrCyYFNm;*xzpM0XxIdf1d&(Ov}Ur7*ro-cvG$1J&V0 zkw&S1;B$FLeNQZkj`yy)ee(7%+`gvoOVeLjUK?(fRBC?=+B^CbL6dA>hseZ!s213CV$0}%rEbmA3q)|Py3&&4VPN?YG0fF^i*`p7d?>_4}Z4zC%xzI zF>j*hhik%xb{ucKf%g3lyvL|5&amE6D+teJ#z}kzgYV4DFU|&VHBDZDw1bk|pTLF1 zethJDuT6&f`8`T5E_``*5MM^jzAi}-i9@(stxM)rtDZynJch#T8+)mNp?&yV$MMi7 zvD!i^H-ntV=O*bB;Q#bRsQ*g$pz_S2N&e;7O5hlY>51I$qPrC)7axXo7vB|g@L||> z@wLst_k@RU^BjC%_wZ5QT>AaU!^b(p3K#_{y)VE+KlSRGZ|++zhCffYD7y&e-(mE8 z8HSrO6(}8Eg@-QhM#u}nkMc@jl)O?1)8%~$v?-;O#Rnuxz@*EYggnkqD39|FB~L$B zg14M=4bWnN((e+FygUdoz(aYZFiPH5@ZrC`L(hFmOx0{4jb;b_fRt2(`4E69sSV^I zU|K~!8{Q2*&XW}=E3uXhq7{kH!h>`3RWQ_#dNNORc_CzOixL8wW`)ZE-T&=4PhRMV zhAmId0T~DNN3#To*+z$Z1+z$ZmMBQNc{lo~* z`s}Ya+e{FJzRrqgJ8=cp$H4x}(4S&`X>EnQwe@B5I{S@;3w;~9((G#N_2pvJMt%c2 z1TzA2Eez+{C7&t?x2CW)aKHZnanyI;s&LEnCt|HHj3*u!*M#y<=E?QaP)GjBiY6iL zqNX{M==kQX{)g^~8JRt?J)1VBc8J}fyF(Y%RlO)KEyx@XZ%F!D0>{MhAIzk$6%P$} zY)DnCxf{~V8M&w_%WOzRQ@)kYg*GOAYrl1_#3;%N3c~Zli^8Hlkof|> ztlX5Y&W?2~S-(6wjSw5H?*>Kss1^ zNp**fdVtr$hQ(B3{8HT-5st@`m6s1vCRJ~ZEJ(c~!e&%Nc@%tYrXomLB zKbEbWE;RCM#hFiKuj#xubWP{q%=~FgoH>@gemcKSoOv)Czxr=Ne>3ydj?SyUdZjq? z(d^c%zl`03r(^!~{W0SNZ!7a)A!q3bY z$=%cSp~_@l^St2hWF+~U{bF@Zdc)yp>i+Pt@ONf5g-VQzYTy6j?r@;FI;nE<4OtGC zPya0BZz)UuV8$$qr%@Kc^p_KbhN#_~ekH^;<MOCj=l#b^E_q*j%S}J7WZZ#f=DUh*i7dAb(9_>om3(HVJa~Q5NHVs0 zh)vYaPuIBO@;~fr`N53;=s%tlhR7Bg<{I_3*WP&JgBWDEPCbA6=&6y8QS1&BtSwwu z60T3SB#*_4(?_OpEh$rItjr!ko%mgPS?c=2-+X^bmb*29^a)VUX9}{BaBZq3W!BV% z*=DS?gO4+oj?AN};1bQ`9u1|{!X@X_V%f;`S0DK7}4V-IOH!6e!W0^Xl?WYU$++Ug@_8!YGgPHNv$ZuWlQ0~`Qt?})Q|beH0W#6TZ@JGTlgtZ@|0U)-T%MBniNw{na@mDt~<@{ zHB^Dv?BX{kiYjfn)}%cy{tK^3$1VQHfc>)OE9tq{n0HzHYzuE?jd|SSXI=NB20sBe z&)7_0jdmc{n$w|DAJzm10@(TZ3&$y`TraT9*%r74bWPm7YdE{(_T0(Ar^fpDVz0+$ zk1YDi%VFa=Tn#dWYpZu#_<9R(Ksk{984GuiA5~@tG1g>zEWFw}DN}FlTp#6|j?DkBv~RBW2&$XthK{Tzs`qPyUEe)Yd|mL@$GT~BvK-4f4)X|?eJ#hKSX;Yx& zDYwG9|JyOv>3MACo{EY2lJ6=5GlzBh?6HUY;M9?2T#nLMZMhjwIpkdltbq9-`)=(? zFWG&oX7E;Dp0h5N$$Egkadnf`HJKgMh3^S8@)b`WtG@j@5bIu6o&70 z6`d{$m&u;2=xglP3XMN5tjLJkvh=(yzTSCTvFe*D>YTR~Z#KpAj#u@v&%-@}%o2k( z^n5v>;&gGmxNE3m*>pjZkuXo^^YNAxE{>#oste?cGWl^Mu`F@ys((3GF-r#DpIL^L zX<_=l{nfS79L2$H&z17^6}(^QEK#)^t?F$S z`;=9q&A#pG83^>uHE%vT3>SJ;(c$#IuP9%%7?GEGC;AhE0|!x#dk>EGtA{a|O!eq# zt_MuapnDGP-HWGTxRBNZn%?iQ_b%9HD^Pv=CU~%)Q{z=D?78@Md-&#B1FLf*C9e(P z*oP`m@p4|MkAIsnu(035wK<$#Ipg1_VAu8I*s=vifztJ1c@8;k-a@2l|8<=qK+9D^y3W1y1vGuU-`--EjbMuC#|Q+Vj|z6c=({3s7yy)BQz zsHfRIn|BPA40zjRQ~4J8E(IU{+h0ii0rnULSwI@iM*Pv^<@{Tf6h%ha5Y3}@*v+3W-@kGAIdgP?-yOU83-|!GOq(fR zwNf(-*XVBkLcy~o%4Zw)%a&>K@-NSU-Td>!P4Hi1v*Dj zc~}R1o>?c)jothe;?FICW_;W^bAaCg>kvS0d|vaQcHe|y`D}qHM|tob3*BwfT|Da? znfFLYuaR`*U#{s7zBRHo3)EZzPR}d>KH40>njdIBvu6d|G{`Yrn|^Afo;@n-J|fqX z;j>ck*4}HL{YIO2hQZdsd&Vn?kyQ=E=qFge{qW@Y;;+ViX5!^$p8HWKo9V7H`x)+0 z7;pzKHTy#HyTXI0!n3r=hoB-@Z-%2B#_tCo6RN)3;lZxGw}Dx|x$R;8b>94KY&Cr@ zydLcCeAaHE1E0Ap>Xe&RWB?G zuef6H=F!5U@0V_0nfM>#$@lu24p#2({m#t1?0oqA5I&2-2P;>u@wE*1{$R$}m}q|K zoWJw(WJMC^Lvuj#^nAQ;dqb?EwQs66JFRdR)=btI9 zpO;>Qw}>0h{_)umaPsVq`fcftoPB!w^Ie~h8+f&ur5tPg^76t+)LcnM`}f{*%MT0x zb>Y9xh|A`uZzw9L&pY$!&L4=(bp^Fce)woSAY%w+eQW;=ukU^$R`J54+y7m>R=F#I z8`+KRO$Ao2{9ESB?@L6kX@3au><+PPs}sH^k=b&V_K$7jYtK(4?z`$HtSd$4U1xnK zeUUTSyRgpmwJgm{%h#WSavgkK_OB0rZ8YDzK#@$2!9>_4TU`R78(-O01}hQhn2?z_sD6*a|~_s4ILy8k%q zJ1HXmWF!$wzI5;Z1WjbVpM7uq;Y23;=hMIEZG^NiI7Uf?udv5-%Mfpi)&s|@+>v*gr6S?gxw;ji=e*^I*1X+i*vHq5!?8kzN#yPHn~8(V^+?riiSW0emBHM>aZLlelT`D+7Tj zO8$kLvzt20Q}@LVp}*{Ie-HU(?PrRG;S2j^NO6fVwSId`>Qk}c3kf6DzBb-f9SWIJ zed~>>^XHo4k?CcqJB1l{sKwb!t^O{sVsoZ0j@~m#Ij>4N(YP6#s9Brwt^egYQi@+l zL~m&iZwXg-H9q5tW0@64QN|Z7??it;Rp0ySfQa6-cWJgfZuVe-6=j+7c%F>qk=V~5 ztG|8T7D|#Ss_|ufYkqMqfbod8cHSDSKfSoC$mkmtwb9H-$D-(~Q|0l3wX7%IO=iz7 zYL;Z`rz45}y(RIN29~7~k)7?uozFr0u9mLm=-)@bNmGs&#H)I{WQ}{bR)$Io?pqZZ z%W!L`D4oyOq?7rbrlIc6IHdRk;Zp3r6-IW4%hSQF^HTR<)Dtx&=|pwBy>RPyLpR<$ zQ26q~yi8>{ChKz~TpCvWFl8i9FXoHh(W9}V7b>UwzbMvJ?oBM{`h;k>hBOiN9e4=ua0laoUJ>yk#O|8(Qiy_6V(apyP5-XWIwQ#Wi6t` z$+6Dl){10t@&s}zkQwgc4C7t0KNU5L)I^#)n5|7xan>QwAtrXFK#eKMNZwT&ZgLn`pd7i0ThOspDg-xUu$ z{{G6EaF^_>zKHtmi;Bn%vHg2r9q8KTTXShL-W5$1)PLjo@@yIMmodb)cE&?fMJaXL z?8|A)Io8E8KJ*|%8FBH_?8el)I(;o05o39Z<7wdGqp{`}S!=H7^sRd?WbdLNvnoFR5SI*GbdwTPZt}jZB3)`rQ1SN30u?W(t)ga#JA?>QrC*iqOL?V zl3KcTXZv?U1$9L)`l`3agi+bMYwz;|zUBmK0@KU!B|lRZ$FCzKF^SC<8cXH(F8bRY z?wX)nKhn3ym8U3+ms)*VRa(?8O)rR-Ojo5!q7TN(p9@a0Pe=XBqBdlY#(w`oqI!3G zVOL-1AMV{PHt%5VTo4Vp>Ny2(u=~l8bn7+|sZELd#Y4}{+!LGkEK;)a+V(YDODgNG zSUG)X?3YY^baz%9TixYrO+=1h*03b}-`agGmEmjJKU>)sY7P73uLqpi&D(+}uKE42 zZ{zO=o}2mSbKUJ23uIqYpE9=lHa4b=t@ZLv{lJRGOft1x{_a9xMO}tD7g%v|rYc^5 z-l{SlO4g^o5S#aW!brB864RF`qYV7F=)N*!L3Chvk$@EHhQy{XU@w~ z5K)nRi~ZU=ch8zPrTCo0(CFT=+%J#I`^@%l<;=cm<)X{&Z+kD>`fA<&H5~2RA?rtP z_7340ar{Qs0A7H%gIP4^2YLo48-^yv`x+WGCa%{^t$CF~4#MV#Zq zEVUN4em<#3{WQ@W(YRDsKT>3!BJg^=by}c~0myEa917knlm4-TeEXWupO5r7TFW06 zvV4ceZ^8@X8XJE5s7Gb38B~6-Hr}wVrE#s2H8f!_>=EVA{&<-HE~N*D!79``VHd1=Vw zem&(C!zg(_hh3M){rU&tr$EVj1s=M*S0Jw&ew4=@V!!5=S2I zz$tkbdF1g;voPoilzz)R@}?nArI$O*N*>Q-@ZYX4y^zPZ5fmtS>pk)wg*@KbWO})y ztmM7lBkvTB3wTbWK*`(fk#`E4#V5f;dEAdz^6v7;TU01SLJ70@==_jJ-mY4w{_*@v z$>Uq<_;088R>*6l01K3UpYzC@hCHY!^}|&#Ti%Nvc~3%Kn+d&48|+gf_DO>E1n@yNTe2I0;S(d_{~$Ez^_Bzmw;IwxDsc} zV|~;0yAylW*MhD<$!qh-J5}eTw;IeUz5MP-mv;v8cz&Qj$=mCZ_if0V0u%L%!YFwU zfDcK;Igkl2qjAH_24(+r4n8efsS^WzD+gbzEzOLV&L8C9%O#KRro0vXm;f(du6ACQ zgD+RSd?&>#PvtH3S9ZRW;^iwLg9VDOCkJ1ye3{I_r({s1vh%G%Z@jtE`*04vT~)1!v7W+1}TMMpP|e9c|?e# znun4HHW%prZ^s!ob#Wk1j!BGzdgeOgcJt@swM8@SCjaa+Za05{xXQ&}0G9(i<972q z-$rxp#53-3;2Z5A=;SrvnYTOqJaG_ore`yZA9RLy+MC{UvpkAD;fuvbtne#k_+lB} zXv2;hdYTmCZ1@6-p*C>#ig)A2cJnvdZ)2PJ)9B%ElE0@zPm1N+-tO@FNJ;t49(uEQ+S11? zuV#<@77u@m_w$Zf^CjH$dTFG zk0Z`*rM2^@N6Sq|JCI75n4li!RwLe2R{1)HB@Hi ztS6ZDI_%_^d5GYmF%~VfwIlChv1+2d5APy6yTz>9E|UJtii=z@(KPQOA496rtI)*EV5x$KW{P;vr-o=x1 zPS6edw_D#C-ikL!N&lc3j&IU-(tVpbucw=R6V4pvJlWqN#GP>acM16xt$#n>YNh*z z|CjRiS@QZUc~?8~xEcxGZru$84q5R?{gB=VNI!z_9EstcAqLZrh=b-EwtQ2TdzbWI zK@7eP7M9;lqLb{T8~pMuT4d7ebVKd}^r^&+7UrH2!*3@BANOeJK1PgqP7-4Y^jE}) z@7tD}zyC)0@~zqT;!O#-nP2j)S(L}?bfY}vTeB!v4BWEZ+4r-2i-=K<@~v5vt9%0% z;pH2!2+vs>?_9Evr#`!gk*+<&C_ns{_?U%de%&s_H|Rz>Ub6f-CNRJ2hz-;SU_bP2 zBSt)YlZSe4A%-4Z#L%moc)yu{OxG^DQBQ6pMtSxUqnuYT9_ZOk4EfZPa&IJt++JeH z9Uz8WEY(GDrBz>{2dt9L^in?SE#=Dki*&bI^ec!FUdr#X3v zcn8WEIC!@Z*ApYMJBT6oW5meBzqZ^jTkc;Hqn)IXKGHvC;YWz!|2^VTlru2%h4qT* z{R1)5%SkiSkw=Vl7ZD>pCB#sE5i#vkL+a$=aR;|$%^LFx?pydKZz>P*YTp-!F;{vQ?%pnlFYNSJH=cf| zd#d_7;{Cfy!s4>urvI$EXxn#0qC2!3zc*j=`}FiK|H?<(r@QfM^y2s~QTMxaBk$~F zeQkNzGT}FT^TQ>$ZzAgb@|E4!&&}%$#(mWfb(e)1=GZP#^SgBZmQ}rC<>u~(c8S_Q zq|NX67@l$(Ap;F5T{?v5>ZHum)L)B`j7+tM>)UaYM&5Nms2COy;U z>u&S4{QO+w*ZAg)`J4B`DEiv#rwhUh!;8aW;Il&s79 zBwixoO|Q~yXQCA^F+Dp|)bxO$ylT9ibC)nRFKB-Xw=(k$k!89mk2jIclo$2l*40%$ z+#g9^W!=4cXWs9S7x53_SEYMC(8q^cU^-{Rjd>r$<@tR#C2mlrDX4rMUR=DY> zK!xdnht78^+`0JB?PJ&0fztWr{ETBY^MLZGKZaMAyl3F%xU4|Mdkh|Wyc|=4iV0Yy z<3ZT(IpfFIMl5Ju^zerr+HKh8P2L06#UmBC+^ zw+r$x#7lYHbyo6LgAf1h`ph{7`4p)1Zu9W10ii@O0jqfVCaxZDLdzHCql)(c`1E?; z26@y&fwJ>_oc2bGK)wTt379k*&c)D%l8W?~;L~@<$U|V-Ra>L`CGdSx5#d%=Vvuae zLRkX=+5T%`m=5L>)2hp3rtp4&0?n$tB-Z`kj&mf|IS2BjZj6I^<~m1m^XJPpL;lT@ zKVP%}JMDM&xsp44fqZY%311+?v+prM)mGERH+9|Ni#+_S84mDV$<43VFy?=;ht3x5 z0MCWo;oUBt`?!4;N_{?Ri(m_Mfag4Je*UVN{BB%KnaS_95l$VeOIL-jwvreP+#i zu(3F6#)21Y<*!5GIeqmmuF2z`_t=s3Xj3J}Q=j8FzS_*j<7v)kJf3nEqrC*B=`Sxu zI_$Y7FAI<_+*@E9;`fy7i}*W4ELr>ah)`G|y3rwBObquSi#}!H2IAG`eG~GrPEp?K zmdgztF7&-*bJN;plfO53p?7e5&5qOlUXrJld^_b5m>QU^Fh!^H<36J*)!i0K2IR{n z_$`mCobNqaPnX2=!;6g)d_5x9IW-G1iw$$tA!>?XH+=({fMI@fV7;sI&Rhq0J}|al z%9Q@?!+7PadvJ6BKjr6oq(oA84o-HD4~=2Ueb{-v#B3$5-%#t{yU%>v(w>&%o8P7$ z2;9;)IxvhEsofLr93sqn$mTUy*ApYAm#b;M4G&)Z?>HCdc&tFpFZRHLeW4m9*(c}X zyVb+jHV5Bh9=^?R8!!r#>__3DkED(09N0f|^kP3jK4R{J>G}=8?Tqb?u1~{Xm)C~C zHSnW6jw?!D7Iw;2^QK2E8ju8~-)nGr`KX5iWiNz<_C||9c?T2|FljWLmm$uiBJnJ| zNjWSYI;pSHjc)E68x&xHvJ$H@Bxx6>NqqCN9QKP~m=5MA^F)`IK)?Pi_$g5Glv`ol z|LvF~axLLN9&T5d`9eK&%@N)F`Sv?sCjaa?p_~80ca7Zqg@S8MrrDH_OwxdJMmK+v zI1D<+KNDC}9N_ONxcP&Ue~rz;8tDLkSAp^zD3QN)MmP2GxmG(Y&-vnRiiNiGR?)GUPP%O?CB6XV;z8)DQ~Q$sql2 zC{(|?zR8FY^9v!)79zjo|GsSs2%+q`$Aq{bVc5-Y3!&^serN!P`bI{EN4nzOL%joiBcgkBv~OgrYiMLgS5NoA!1nH*onmx&$5?OQ?*5*>E+e>q zc*u&dxvh6s|Ilzt=XqUyL%l+CUfDO+)iXRa)YU&U);F@ddq58y>>rvra95(Yd#rEf z@WJln%z>i=-Mjm`2EbsbXOEtwlx1{RqHC;wuy1(Rm>xDt*$2BucF4@=A=~?|>>tuS z%#s-D9z-gAj-c+|-6*{N(Z0dHp|LLHq1%n<*)=*gJlM5sSHGjEG@g1=)A{M4{oDJx zk*6$P)A*avuEFlBhDWkRKy}Oz(APb>YoxEYD=~Zxnuk`sPT{iE@mSJ`g+kcf=cs+e zW$C!sWh=1J5jW8Akp;Vbpifm<7i+M~XgEUm?;q+Pb9kWbGQ4lM;cbe7_=bCQWOvs{ zUt$<9!ARc@wCSGV-ag5IA>E@r{rz2I!(F?^cC0ac$MA}%w*gHZsmZc1QW=$@$o|mS zXjfmduV>d-pSbw4_J*$Z%@=Jn-#Lo2eR!yMaOlbrRM9BjmagvJ-jOc6K{5?1@S1r4 zSl>YZ=-BiiGhTo1==3ngM->{7(XQUUfj)@gNY*MQD=kN)tZ_#7jCOU8jg54nO^>+v zIbx4yL%8Z;$3XXJysKxVr+ziw?ZE^KiV_BxjHPYSNKit*bGuDrOL^Tsb49RAsue+CZSnsYwBjV8TSpSaxp6)UB zlCoG=x`!g?z%df$rSA_vE4-ltn?(3#gdK|IL=VSB?SG^To;ucMa1`PXLNpgl z=0^i@^3I7GX&UJonBRPe^jO=mw#4KOM~j0y+ggIfQ^AhXcx8%zKb)$<-$U~6i>d0& z1!8xgBD!1L-6CH8j3B3y=p307J`c9lq(ZU`ilT*2es)#@`?38`LP5)|Rd37CcojS+J4uM2#<<*Pbs^$cu_vZ`u>0zsmbBy*8(k z$s8%ss*Tl>M#f9l9iH&l#*R0192SSSeyOcKdf#|us!s9|lFte}d(z~%98b}7O*A-e zlN-<=319x+`HM~_Ve5)VYH&_X>^Ig3R`EG}Q>ec|3{dAKrhPqY%T zJyT+lC-d3hYZIad&()rcXTdWQM;5#q_+jA0#KPM07Z$ENfv}?V=iB$T1p(Y zPD~UeyqRN_1ql%mOTFn&w?9`|l=uwZqC=OKH+Wto|68OhXQ}7q9Jt0IZP`-KO9+X5 zs^gx>-1uS7LA2(wm?u*6&=oDdgb($Z>SzVW*4PcPy$R+~)a0apTfI+QE6W{e?e~TD zv~LRUiK@_lMd+vuUHOnVIVWkX6Fnw9{vW|-6WzjXks${8@;#lUA=-fxElA`vk^f$sek*n61 zB`%6C{A#?dHnpj}B>agw=Ip}g;>W7SMRldO%3s#H^M=moWULDBg5f@LLwj^hxGH&M zS7)R#bz0;JDXS-Pf9e~No$Jp`+#mbr?V+HkHp)m${aNM?NS4ZcBb+DGTiLPv$lT;+ z@=F~|tO*;)Dzp>ICDPu=+(#p*hx-#d+rH80Im7qW`(tau52k8No^w!_%a5?$SM2?H zwDnf6fmr!HEYajA!eWNbr zzo0)Lu3*xO9*1!YWZzr{&?eXwD^@y(=N>gB7Na}+#(Lu7op-(m+)uwZIQftNvGLiX zvGi}hQu6ss4*aTM#fH|_wV|4ehj)$i^o{HZZK$mcbz+hfYN)HPySjdP{hBpPLQN~0 zR@94g8vyU_>)zfkJT-XCZM|^wmh-kQKfg}o73H5_=qb%9_ssL0<_mZ#Je8i)bC!9; ziqSoTW8K?9$3_eqS5ISo$uY4)&dpbB9~~7d=&@q7SI(`k>`q_;yW3a+able{6m#Q| zEJ1RamgpYo#xhB+1E5@s0at$!BXL`~jqoe(p z&1RL{3>!|^(X^#=-%vLub6JCW`$x5~>5K9eBYgu#X0k2M&1}BgBHd=dc{vsWLzpCw zxR(Al$eu6CHGS5A>8ty!u&hh@tVp>8w?owOvVZ7GRo+%9a8itkc^Aqp(apC+MjIJs zb6k-*R&oly^+|Uu~}kl@fZvS(f(CaH&I$vES}EA|1{ARPHtyR3$@-- zWBKpSkQsSehRhYegr9fmmadjd+S<o=t zcW}fCF1@gR7c0))eEtfqcl)M4rpq}H5gC#qTkbABZ$f=(yN7 zDWmv3;^No4)My9fR}HK9{m|s6`n4GNy{{2zMs1IJ&H`I_PiKiC7%bfu(*^+TftB9AW!xDpDupi1V747`Pj!Rey4*G{T07$ z;HOoG^}O~JahCw6%SV1nCM07$U+3Z%n*sN^EI4G%GV1vWGhMDlXvi;YJj%b6iS|1# z`ECGC@gPt=|4&!CHv*^Xo;Z~!whcYM#L=ycdM-f(9XAeKwsx?>g*z|+RqS zxE(IsUBJQ1GV1xdEVxY;%8qkq7F@Re`GG7rl@{5m=VMuLst$-#&p!oDFTa`c@e|-bAUq?CzSsWfooI_P=%X|XW%UJN8lDBt}+To zs`A9JjTj6@ z-8q8!vQ3U0is88g&@VT-tw((klAes-OsFQyl_W6yx8T_>jOMJcypD#Y@ zz@yMLFtc-(?>vd` zv>?unK_6yrPW)*S&v~L@IJ2{j4>L0-zCz-Y7KAf5+xW2a=ETdLI1AvzOv)L)K&&$J z%Q=}B;mq$MD+Xs?w(()+zRb{!EwrXS(<;afM@&sTm&*Nm!n? z!6Z*JK8zU7aD4<}c`S2lYh3s>dN9&I+Z7H~EzS7ET37g5*&glp&FCLq)7rBZ z9sJMHop66Z+zWXrGS|YT=wF{O-ITu+GlB0r!b=6$U&L>f;q&DB7LU^KoyoJ_HDeyJ zz~x@za<6u|Tj3^u<_W#8h{4UVn0Bss>z(Ud_?uns11|TM;U>QWl3#`R9^5)Vu6uO% zf4JPIp)47n?|3Qt$1|<6HP=U)I|R&!H8;y+#O2~y%7iyIyB>&1hn z+u&a-{>BmBD1Pb)UnYL*2wx(K%_*W0f0a1hbQ|)azjmL3EgBOuoh7;ajk6fdbNcy_ z7HI8B^W;eLx6X_-KW(#Lo)&3A_U5^HPNaotCq&bIaW(|c>8CmKI8FiFd+mer2+!PRpMEBl?IcRe*MCJ()HoS)C`3xZ&y^}zqN__D zTXyv~^jgoogS!T7M??R|)VV43P^TYFX=fYL6;Boa-roM*8qZx|s)G6%q%p~Qs-=bh zA5u_d{hBJOXpy$Qqn7gU(7C!2s?=;_8Hy<<|LqjFd!EW=#7q`EgjxEltcy{LCYN;g}ij=07vY}R|mxja*_6_zV_6QKA z%!yZoM|kq})nw7%>{C}_md{>27%Qy!uN6>0D7Y_NAUic zv0v^-IA?$Un}ld49T%d56#kn{f9iJ8zn65MvFYT;l05}C`GBSH-Xa7b!h0*U@JT-{ z#Aivd5#j~)-)78D{Ky35ru;$D+l@J$ci7k;XMXA!5B@m}zr&bg`R_FRiRXTqf4?aw zmU^4$2D5FXNHk9RIU)B{n9j%OZZ_oeV`+Og-Qe>W>F168d*U*1d%u7=6X|)_Unhn9 zZ;%52CMnYW4JqQiP0CDSP^a8Eq}|y6Bt^LtlcHQoNKqc;q%0g5Z;O#X(gM?6Y|;{w zmYXzSQe;ua3z>A0No!0xAJiWfSRH~M6qq#`^!KEP47r$3o(=gA3vmW1+-;3)FpE+HmN_m4=i#q}2H7r_@5?nfb?L;58lc9`zlP0DpQ+i9Bg z6GA*sI)Zv2y$Je)r1zjcNOz+?Nbf~`kY0)UAiWIrL5ii}Z%9%8Z<7u{UzKz{GL5+} z>mi2}^-w^H@-HT3eUPHQ1EiOuJ(6CG_k;8*v`f-UaE?YANBbk~!+S$IhVmu70{JBE z6=FRo^Sg-@<+_a&<U*I2?0V3RO^vHV(wtlmy2hCAT6)l@ zVYh7u^qcR2y$|*Q*au-Z!@fCr)6t!6d5!tOid6X$&kN9*OqHBJ)RwpUb?5{(1lLK8 zT2WIr^{=-SMGv*iNqZj^)zD83Q-AE|;}6CnDQE*GeinQE7DM|s|0uQ5n9q0KLA^q6 zx^7)zt>^gh315bBE?aYKqTs1FC#h5W^xiw7UpN|!=Lf~IW$FI5p|-Q?H>~#D5lJqu z6;qz3P*Q4&F3yoLb3LA>Urf+1M{4fow$kl6v?}5G;OARjo0|Pl>$To%tGs2c*QU;v za_2%@Hz)mzj3?qtB%`gVb;+`aZ%JG`zIH)T%Frh!LZn~Hd}m?~^zNw7IR|=oCDrpD z^SADuXh>A~=Y;pezewtNdLJ!o9ZiU8ZzLEF1)q?5qa|<^wMG(sv44s!?%vV;cYp$68-Cak)j0k1nZ>KrH_;! zDX%WPb2PTtitQ~F zW_v3dpIe)o-c*~PE~%}Ux@8<%#K4TBQ z>%pfx{XP7+CmRZ%$nC<{9@F(D$s)cx>5N0AtFGPn0*A~Ts&Q&wuP+g7M6$R4N_?bb zd&s%1@!^{>vCbZ(trGrZl_>6*dtmd}h+vuwV*SOCB~3N{5{E8c8aIw%G-tvVz@7}Z z3>bI1Iq*|PrMnRxI*xOPY&Zlw!&A zXD9yT=g&@jzUT%sn}5DyEh*2Ro%jNgbl_#nx8m^p*@-U{`y6<^rLunfF1%md1^iZv zBi}IF@I2YczgS=zE#>FC=G9J08H?w`PW)`if0NaK_=ecVhZgR{mq`3Z3&NIV8=m*- z#)tFT2jRi;jKP*7f8PRChOxh=9H4an*ya8QxEY`CdMV_8-4%{$tPJP7%k!1_1e+#A zs!!&7gmbr88>y`gSoaw12*@%zJHqX8+2PF*+4RuI;zhl}9Afo>RUeDZ4J!L{^ReLp z`E|7(LGEa2yF2>kk&e@bWeq(%w7IXR49I*5Y2RhZYM>Db0aC5=wFi}zFaSZu11}3-(w>w+;Tk(`YqF+I->MnggPc&PYOKS zrFW^B-ZC>iypn8xUbvY#bKmaN)@k_2*DvS{jh_uTg>%Y@m;<< zymyNIxk0Rb&h*?a&NwHtGyb@ECXf@(kzXA3x8*!^TD_2KGEsB(RDatKuk#+--*V=Z zSm~MahDAn%BT4Upionf*h4@OYICN$P-;4oQ9NxUm(98Z=K|u;#al#(>%KQ9_Z}^{ z`?R1poD*CS6rVTZ=S_uzXJf@!Yx?*kQbfuUzT{0ubAq#j^Max_lpb!If7XJ?cyOJ$ zdgID0{7MhL6U$An9Y56KePLaypju=Kt9Q1|Z>&l#O>PYy-QsC@cH(jTeJ)U&xF6W6 zbZxS#R=oVZ4Ee2*DDl8aCf*9nO?Vp%{TC%_6ZegarB&(s z@dcxp`X`|82tE^7xJ0~sPsY<=#Pi5_$0urltqa^Mzp{($S(;?puOi-@bY-$O8AR%T zmho2qN~YyEDLK?8A~%a#Kfmv+^H%4D8-wC=Mj46pS2K}YjIcnRuR7lm_N7eZRwFD_ zS6)5O5q3xB{;Nc7BwdrdVZp+s9mg-euwwiN6`L=-bK>hQ;`k>sxl6?HPh>tke*T5u z4t#s!n{AyJe)GKDFXS#Ad!ggPzibgxqZ#0)5}7-I9?bM-es+~uxg@=APfgN`k~$PD zMT=SZlBcn8i>J;LIW}=c3!jdm4Azb}2E28ZiDMI`{tqW=5?@F86{r6)E|#>V>jKQz zI#rEj$S__zp(OulTLx#5N_Ex~6eN~_sko}E~l2#h}-@HP}A zo}Cc>jftg+%g3JxR3y9&h5pOo+Jo=EumANs?_Bq5V=p5yc_+S~zN)RiO++>{wAGg- ziW0{DL}6y{IKS`Ri#9MXU6s5%f8O(RGnfEQiEvKleuR~$3o{M)_Ig8OMbfjbDp_N+ zOGs9VFQf~-0PCer|NBr`9)u-AdoSKd1@+W#?}^1KURT975|v=FVQH&(rW@|QO6 z_jP3l#yAX%*1C5Mp4FNJkC@vT<|+^!cMjayaM;Fm;F@Q^J>Y^ey_pm{HW*lq+(*? zKrpB}`31qR8Ghu4M~mMd@vQUX-toubr;K9FvjAPbZD6AE%XyKKk7pI+r%WdTvaJIb z0EDCx3U>`~jmiP4c(~Vrj{vt^1!_2YDOt%T1Yt|y!LyKsu#}JUYvw^;2iBq9z6(EP zG}g*XQr-XkunuG!qD;(}7kbLN$+iw$4}gu&)8QzOeAhZBUvxR}m~?6;+d2@(Fp@vt z6|Zcmc7$x}x_u^|`S8jXuH&b#>u?Mu`LnHaUH1sw4_Ot?7Hyks>pVM@_0N`I8y_@# zzG^#V=#y}>y!b9~-Q}2UyVp@x$L-RUfi8$XzF2Fb=_8B2Ix>6z8AcM@+r(Lkn{KSC z%;SCcs1Zh9{CF8wkfI1aVN#X`*EupAG(4_rE!g%u>`?i>s-lo&zya~PMsO!|@+LD1?)@|$(BEeD zif@99tYX!3HRD;|ZBe*R`0L};dUTK+H_?n`FUkIr?g3b%$>0HIGidz`@a|ClwQWhXroeM zx#T+Pz$jroeEPV-ePhbVIxfZNwbFDmol@{S4^$bJgY0*;YrSOGt6qasy?xHqmy+!O z{o2ZUa~s6$iB8rJHJoi;^A$RIKg6?t7^@$uz)tig?3F}dd6!qo7w7;`D z=5P0>{2l)GvY0>WJya?0J;AB))clZKU10?_;~h)b%_zoAR#oG9^+l;7^Y)fp+)u+o^Ip@}ed2s`!Boum8+s)`&He80es(wvF!%E|xm6fO{T3$=h zV_p5XqK6FMpZBrwt_;UYZwM>EuJh!DB)EsrK3CKfIMsC}j*~@4j@^faC%g90?(p3g zAlf0C0Mj){<$Vr=^5&1xo_JsHF4Vz}T|+(US_o!S-DB#$2!oe(7*V(H+OY$7pKu|o zM>M?OgWDe7Ph$@IU1e1Nd@elLSE(^)rZp&3fE>7))}Tojt{Lu)u*xVI#^9lkVFef* znD%L~>`~Pib`a0HeB*Fu-?I*uMU3XM}NidX*}!v(s0+nDx>84Hav8G3GfTS zkNh}}DSj{GS?BjQ-0b(2QRVysJam3Mn=61H`JubE_>md?jV>1ca4VVMZ9P|_`L!62@-LiH{&g;X)O%C16R4hfwyDd<{r+t7^}-+jEkj(b<+8&D;g7r~RM05g zr!x0=5V-4Ll~IqRN>+vyqcLUR5y0~jSjx&Vmvy1a7?0u&c<6T;D1Hpnjqd+m%sn_) zuuYDXlW9=SY-goTe6G}Wu<_H^$WDA7FS3^PV(?dQy&(bD$WDB|T<6$&7Wo1yh%!Fg zxL3AZBQF2)EYumlP{!wbZ5aIxAil_jFOv9>g3C9}asWTeh3A`N8-DA`b(wAEh#}L# z{CZqF09+$G@g?F02c9j(He5sNhG(J9_@&}@6Tmj;am^fgR_er;iTg~vAs-f|n(@h< z9ovK7zWzC!tnZDmrKqpJcDM`0Kf|pIrDuOcd<|?V%CmqD)5zRqo4VL1sA{f&wYzJU z03U65Hs=RemusHW$Lwswwc)2m>gl7h?qkf9^@)}-?Ks(FWBLax?ny_s4_Hn|IdPAG zWyd`Nz6ah##yI7zHgvH`5(5@rYjzH*tt6 z{7Z#EkmLiX#PKclFE^G6>I(}VhMsIrUyn=dvF!kJ@;Uv0(X_2O{fD6Wel_Ou55qnJ zD<<O-HMe6&rK+qmUw^I-H3w>TI2NzUQ+$Dt3P?C;mX&HTgwxzK zT;loCgB5R7oZjSV7>hkS;m^#v;3dt!rODGc7CSNFsgKv?-gR%w3ny@I?NNUsucIts z=p~}~rkRq-*~YE1v02esxVQ6z4I(l-Q$8MVxTmFXDqekgYe7fu#(jafai$ycWju|y zwEWwNT&z}fX8xovSrXjZoF54^^9J3-2IaHR@}Umy)?j&BEGbRe3m9skl% z%9y|C?My0iMQ&yP$I;dfwRnyfFZyNXW9Qcf=l{+8r}uQmp`~lwdU}m{kMQn}NQ`Oh z0)N^g@`Rfy@pfU6PG^RAM|9$n%%GHOHneQfPUU*_s_4%4K&mGikU1c}c527@{cW}J z-Sy@j(D19CS`zpDc}{(2*f{_G$OWC%YfSy&-PFe&uS@N15$QvjEm7ayl}S%SW#Xca zTHNuwsj)WZx%2ZaIWOOu$z3MWH)rN&;){2+UJyMy_=`YIuv4~2&*8gU@}>rMcp|Nx zSG0Im|Gf8%#JP|)ulCC?h%+w8G*6TJL(yi)y(+rZl6%?Ix@mHUr)uN#AI)hD2lxJP z?{{eHFRY4(f@QH_^;)?y-c8Nw@imbCoT)R=A}D!nJlqk2+@;C+hxfPmUS0{wS4_>x zu#Ja0JgW}}Ive-?Xz$aX`q8JJ4#z8F^C8{cEsvfkk5+U9lJQ6@bQn4tMRj2&81#fY z&)M7(j)_HgbyvplPB;1kc}w4VnYB~G+mRFa%sErEXyMTiw2qIp@s6$ks!2>PjOGP{ zNw%6m|EB8H1i7asZfx;9mlIl!bK_a8@sOd3kWGeB#-+YpbY! z-Rxq^utnF>b5qClc58b}mo;-Oe;c{C6( z!m9A)!fO+A(8}&_`PFf;$S=c-5#DLmm|r6DB;w8EGL{_4s2QW~@twI<)lJUt+M95hrdyDYUkp*HIljV3xI+Z}e?^;#VkvlvvEtjJK|fc2)-c1LaEi! zfj0CnO1thZvzRD-OK0$J9}P}Y)r%|?{;naKNHEpMH`8|6xi zH4|?QMT1DIv(8Sf%1Z6uPAo7}J1reBdoQ;4fK1J(`4Xh2YPJOFv8?ZE`PGR6v%k;n z5TUZzbG;&R@eYiCp={+mQ*FOF`GhQge5X?Dn|eH25IT&V#@g}IY6sJ&)#e^Afi_V& z?$Q3-E2~}!KyNAe%4WDe^UBuDBjXQ7ztV|&rSbJcC>V*g)IGc)-GIYC9iia9Kxtr#AY~X2ewMD@L7o)7Rsd z3=V9#E_wxaMa9%vuXrBvgqOc^t$|DbOUD1opYOr8b$aP5yJdU3VCtcLMqFPy7bB#2 z#ghpI|2{JoJw2JX!t+8-=y#ci7c_)J3y6w`j_gaczIxMDXq(3ZXT;*+D|bkLj0N-M zh#r$S_8aYvUjPN6p+-bb&8(@drc~)nb=>nvN#df!E4P&dFG?NQ;LUJ!{%+<%iNG%s zJS4);W@>_enYnNL=V*`7sU^XC78ICTbL-Pff|&({rt1UH`C1YzsPmidRnlEpS7f@E zr?>Arg0EASOogvMa{Zx}#ZzlKmjuJthl0g*v+Fk(7`d;6oJ)eI*M;hh@2{wv7Y^12 zS2WZ$mL{u`hcI^}Vr5;uSx2oct>=miW?^U*doz*FhZlrUPULoEUnuzMO-8PZrYdEg z3e(O!`;cRAx=hwqsYG-m*S_#&nG$jeuC6PVyfU{L@>Ne2%KpG_=^}d5{MCvB8*(-h zu_!ZBJJ-2q-IhXNzV4OMPiAjQ5<&Iy7z~utV&kmcLqL2h5zd`t_q3u>TE?>KBn_ z;HW8e%R>+OmDk9Mrd4OHQfC${93z9MeWOTwhIjFrYU8M*e`F`F{nkB3?RsWm^>+_Y zmrvozV>yLeh@uzhFA zA;p-Mp2`N_2csbD#)^C>Pkzd0o)sxC8z+Af%8botRT_V?dgA*^A0bB@0MwGI6Mi08 zwM)!>tZcXe7jCArp<7+JX1KYxri|i!A3XGQ<8UuhAW((78_)WV@&K3x;P(O80ux7i z3|8kyIc|hiM)CV5Jam3Hf?pl{$Pe3pGF|dJ0ju-l9R?fWr;OtF5Ae|W@qX$M{K&5u zmN@eJHLT8WD;(TIR7TYYb(3`5RWslsF5JiAZdS}dm3+L~ z!kx&%k7q_YKi+q(%8&U`{DxipmLY>%vhdsK;ulU0Ic>jYkirxRx^`74|13&7T76PZttr|b> zl`DSBUHo_lF255}M&+0H+UfjW0>2bMlrIFU`0?IzUA|82t+UTjM)AAE#cvz-)K&Wn z1FZO6@8b70@JnTp?^+kXTfy%k@S%K*G=4{1{MH~-{5Dh>CEr(E{F;`by&zrkI|Ek9 z_Y80aa4Qz~ptH!!FO3z`OZDJbwz7QA%Lh2O(X{Jh@1SuW25Np9L@6dZs^MMd1w1HvDed z8NXP34#AAS5tjP(jDHTSVbF*)L;ZSZ{Mq6w2xolGWxUjv*9>(JocKB7YY4aTb2K#D zTZs!_BIU8)GbcCd8aRDQC4Q^LRi81Ef4K`^F7eE}VK{@bjSo7UPX6=7_Yq9_Sw~)k zv%CVZhT)9KHa>(n;|C<3b!`|sCfz>FXq@;;iRW*y7=|+*+xQ@b6CV`RsiJ(G`*;yf z`BJckv0E11K5@D${^{ah;BUu2-4&lR8r%3p$Q3^%@o!s@koCj|9}Wzi@`fdTn}rHn zPX>OG3%^L>xfU>tU6Ka=3>W?kiRawXFh)4<|59$25AWSlZuLa!!_1Z8wyBZ2BXqMQ z`CGrb@j;u4x@0sY9=M(Hm&h>nhxc-Gy+LE(m%8wn{Aq^wbgR2741BE%ua6*lvz41B7typt663;Vi=nk6O_}IARxqyk+ zwsCO@w7!EoIDPZhkU`!VZ0_4Crouw2EZ|CC^*CK#=N_$MGRotM!7h8pl{>TUtEuf! zxgX2xsI9G7?NdN&gW0SmiDFgjO-V~?T96q}ol`KHU4P~Qg@YGU)NVR9k0l%sbsaI= zlg$u?QNJ41F_^&bM{52F{1~guops+du6DzP({{}51H<^z!6-!fF{2;gU7`uP$ArLt z;k`!4`<1-c8Q-CLFE-|I-jsP)D;8?!5C=ZZq=>(s6p=Y&@FSc(GyNqF{#)q=pKYZ0 z6C*`By`(AQ4qWf~raVY@BmFNm?+6B;O>~0~S46zimwgdwfc||(zWf-zIU{4d8dAjL z48x1ab)-WE_1|jV6%0J{>;JTnI>!Fb2=RHk!Tb?Yh2T2mK694NP!BL`mQH;}@A2k9MV{UN;@;buDHq}$EAk0IxOiy!2c{2-s? z2l-I6GT%}TlwX4B!}A7G$cO)u%5p~ePtbif?u;eHrrYbJD8IKsna@9vqP#e0u{=1x zWw}ykn(`NuB3*fBG4jWI09c-3@|k7qVUw?Hcc_OL`JoK2o&1uaiRVXHEZqGb!a@_)=1&%e4aYv5l1JlQMl$rca7|4UnQ<5~Ro< z+Y{SIk`(33^8)4zUQ)gTq$tEEP50lCmcs(ayP@hxk&lfgCMdN|SQlLieSl;2$FepZiSrL!?Om>!jFz_yH;8;u?tM!1)dH z$N417;U!X(ONJEh{cEJ?7hWetxp4l&{^3nhl$XGKgnZ|dA|G5kkxz^ie0g^<`B^=) zyrJsk-+VVVo_)%937fwiV(DcEMTPhP^s(zEsn0trDl%oz(wLhGdaL}w*4*R+69dh! zPE-|cYmWG~H9s)%>ckZuPeV`hofDqAn_GVVTp(EY6g9QQ zR#E%A^u2gWZz_zY!q19BTgB4frE@#Hp@UmL*?MqOD&m8Fl7SOX<>Z1##?#Di&SwRU zFDZ+mZv-w=MbY984>8dKL!@hX^$HQ?H{5;3!uLrxv{MxQy(wC&~rz5yC;;~Gd0@o$HubVKB#aFc)CGW1w~`p2p7_it0zql>}NAm?Eqa^BI*2h-%3bUUbyOTxX;3?orEbomb4 zF}OQnl~K4o@F-NCpuAtU1hf(s!-3>i0LpPuPnYup3=@{YFe1%o@mJ^f8}MU%@}ob~ zrTc%t>il@mCFcstD1J}CL+AGgjb9PM6u*DKv(B#>4h)Z$QT(2RkIpX#a}y;W9xZ30zcIbSdNO{)xfd5FddL)EBL|7GV1wLcu>y_ zB(By%*HMBYW8xfB8SPPdNviw57w2GXbGFHmvM~+Hne80RiO-eu@pCK&oT%7_=U`5Jo>+`v z^4|#SMR*vr8P+gd1=@z^V$S&a@)r&nzY~_{V$S&NF>J$cWS#N#7R&N4a)tAawhh05 zb;ftPcn;i8oY{PRWXE=BAjP`Dz_-5IL=T1(1xx}+<45Rlz z%7FB=Hr;$D`0KW+A7!6YihsW~!?#FxxhSOIrePdyL7+A*U2`97HfmD{ zV}>zpLW3KDTt_v7^7~mY-DqZPIixICuAi}F6n=C_XP9nwfDHe*Ny&%tSI}KA#9C6|S2ms< z(#^@fi*2Y|(`4XJ{#`8hPGGF{R~dRE-g9#%Yz=HXY{6tMzDx@wH#G+mK6%rOz)dsu z_pWOui=#RC%4c54xSLDV%$}MTGJdT^)D+-Zu3Tz-Q@)U~n!wFnH19v1c-KeZrjoh& zad_(hZi3r{U!ucr5IQcBk+ClB8{0I}Ka5?=JxU9`*KFaAUs3DXaiwwpr=>`aZ?)^Y zz;I*tQ13wBh^F?=MrXVv4i<*?w|&Wr`ncTG;&r@M@4>}l|1Zv?IhHD8G;wrW@L*S_ zMm&z8*>HRxbzJidxCdOg^>Bw^l~KI!frmZ{zJb1i{U~02IjlmTUIVL) z;`eoU==}Zwel_qTKaL5CUk1vNX4*#xr;J#ahYJ7;6m zYtjwpi)ua;LO?0<_b@1V@!jI@ImoHU^lsKVk#!9U>aGy?aG?D4fdGEf8F#56fM>Gu wf-lv9yQW0$f#KbT1LTEu#QQmdq?ks^c?Ysbf6hO`q^NE=zrYK_IwJ0W19zH5;Q#;t diff --git a/variants/RFduino/libRFduinoGZLL.a b/variants/RFduino/libRFduinoGZLL.a index 956c1ef0fb469b9375450b2f130c36f65536a937..03c89e7e7a9ab716b5dc42873b1a018f9bf8a91a 100644 GIT binary patch delta 2854 zcmcguZERCj7=G_ZySp;Bu47$4&X%*bqupR^E1fh1$XMeB=`e_BKol6XumxP_I&>P7 zyP&^}AHXq2G!YU>j9_qC*$*N^OfXS?b?6V=2p>N%L=qE?U*QM%zIVNFsewd|yy<)2 z_jx~_bMCq4p4;&Y%1;-Reg2a6*dt4#OWO7a*61q$nr{6wZ9fO_Z#3~PK(Xq@0m41M zKQz_<_rdn;0Jy*E4@y3Soc_Ss{r3r+*bDF=)hT)Q<-hB>_W>S)hVKk=?KHssRV-2K zM3d?j$5@4^Q_Ix!Knlbb#>6QlBtA|1#AK*cl-2rkDYd=Ye8I$FZ;c#l7hkqF>ZcSS zvBeA%0WY{gn_x-LpcYSbZdiF{{PrKWZc9OkH05iOcJA-Z^DB3g!4<#VFi zjKZgDZ8I{TX7bF2Iwf(Tg8F3aE6+=ud=-5yPo9FFlD8$LfN$Ma2zr<{d8W%4zi@Fd zZM8O`Fl|J`7FZxpK@&{PVO~bq$8m2h z9;SE7NzYboQoV|8D9(vD#-#l`sD7dxRhc3T!iXbpPr`zdymU+s9Nc_mTs^9MK$)^J zr#ZC=2);S?&A4b zan#;)@3wxB=8Ms;prndRVJ5EoE5#+;E}yfw$TLmkSgnG4NUUdVVku*`;q=JxBC${L z2@ms%o9w#Syj)vtr+Yx5O*2YPL5zDte<5nA8AN-r3?PoS29;_^HPjyQZCzMjg`Tx~ z-duc47^7+$$*j(xFBM{F;36s`ry%C&yAWIXLKZ$6)#Q5zedN=PL5Sl|)Cf5RF$wn} zwi3pW(1S6Wpaaz;JdVC~f*b+ewkamxQ4HMW!?U)>LWoOshwwY}t%Ms8bYRRBlQ55g zyMzEK3tu_r%nAO6zLoDi1opKi8(O*GS7X9j_#px_MN<|;55?4c=;w!~({p{f0 zrv2v#0?+~P2m!1k+W_zk+4=a;(8_**5wdjvuaFG`_$c29fGtLz-V4I?;!!GVV02lvO8t`)kt zS*ResGK8sY!|fml+lPt>v$`3QO@=xcGC#N}w(NtWQx=7ZC=4fpqOyAKOI~~<-Jk;vVk0?Dg*1LwY z;gHn525(+(H)doIGeH7xZdEP9)<(_ln z(l57`Ag0bc1|aU3Z_24$o^u})R!`PKT!!SmO5u<~A92VSqShxEbjRUnAwKskL@Wx^}w!nB-p>Cjlcb#6{#TK1B zP^i|{&<`Zjz2TXyAsL7)5*?cZ*MzKtxBy* z!p1Ig-#NN-*Ep~ksgCrPt&cr0+&Pp0r`t7D!Td^q)v%CU%fhUVH7Hov)PPaF3UBGX znAiR2S*hVrtBN^2f!lNsp3*Bx2I%g%@HIV%<1H(2pB{AV8XX&-#MH{~{r6BEM(iXO zlmhheVBa9Ac5@$L`ZF(+rSB$--ESS>`Nm-12$?I&&H%F>fLg*KVo^zKj7ofn*dG2I zV5TwH{t}t(;b(2(BFqZUmi0#$CqkKNH ziRMWySO1B0%BPk0?q@U_LdFd;+rxjgg;(0bYbe&J zL|fKobdn!!jt0f|AK(OT=WXl+9^j4QVwv;~ImInNlAuW=q)=R@1mO#Yi3eMmhD(%U zH?}pkv9q|P=>UG)ROxkq-|`a@udNT^Z%sb74&9N}EQM<$+gSjQksifMk+`FVoM!Nc zNEoBd6NWf{KXomxlqfH*k{=u}Si&1j?1V9r7K!J4*#aav@hq{37klBSC;za7V@<7AAz!O@~ZU1im07MZYK{C0?EE<#wVk#L`D14X$8*vh5AI zJjt@@P=0m%lvXy(hHLYG^qgE_8S>fm;}vD#8yb(5!OT?6dJCADbEmI*%Ld<2DF5~a Z$yqjt+7~an%3rKFGgX`a@%r=5KLI1y4x0b~ diff --git a/variants/RFduino/libRFduinoSystem.a b/variants/RFduino/libRFduinoSystem.a index a03f59b66bd5b16dd086558ce658ffad27e235d0..c2df2d645f5e3c186c31faf80db09bd3fae7ab1f 100644 GIT binary patch literal 6286 zcmeHLU2GiH6+ZjppEwSVO@PD>FbRP=fY&_tpuuaq?vQSbIv{Y&b{~Cd(Z4UVmYP_3BQ}eT7`MBlOkHxf0PZvY&qTQ-5 zJsrZO4Y$&$oeS~e!g8r>7Edk|=gisiQ__FAFg?4V3QiZwm8>dQTAaEY2=eN~)wVT~uLZcD_`O`4N(s6Cuf|waS%ZyiRF;F{VE?qry`0s0xe4d9zR` ztD@!UiVERB)`O>}OR-)rpDr%MTU^pdLmLR_V_yI~uC@p~q2WU+mWyC|qh+l%YT+D~ zZP$*LMm^B3`b)(n`$ElL_Zsb%8H!%CYhK$iJ!_?D6PAQ$ug$g^UQjHy9lO|U*Up_@ zuUnop2&F`$dZ@(%?*^3f0}t|QkLy{EcYfV$IcE=z<#V}Ad$eaX)caM#$eoNw?pQWE zISJW#{t>*Hsy*K+ojjIEBoM$pC1{u;MD$Kd$U7zk8>U^RZS0yD+pqsH*esnbTK z-EO+Z*|uX8%JW8PZN;wF?Ygn(v}?BOwjKANF_Fn<#*JJSD>9eM8^ey>v@O>@XgrH5 zqjpebWWvmktT#omc5iyZhhWJu z+!@sHV>hav42t`}+0GAfBHd2z1322L`zGvoru26ALMBPZ^1~2plS1%c@9_N(pv*S> zaC^K7sQwm#W#3T@%d47Q1^5gb1SH$71FP+BqTMOTxZN&1vfYa)tK;%cpaT;m{k;UF z`lH*T?_jy~_al_qpX~cDQQpKON&5RC1ggJo_~VM)zwLOWzn}Z!aNgEovk93b>F*K* zF@JqTJV)#gpC0;q4`uEj>zK0W=nH;PyjjQ32Y9en)`bwSw_rCW0XW+*_2ZFiit%OG z{f!F&Njv6pOjz|H7Oa8J-;VMfc=$VZ;^A*l{rv;?%|9p=r9YU(NR_AQ(=An*3VZ8I zQ?Z_Kduoe}(>VK7O4D6{kxY)d^w+8AScZ>ND1{Xl)n!GO@HZXW@QREmg;C)4B2s6T z`?p=w^NNWmg&B|6=M@l9im*5oN@3&&fq4u$h6nKd4=Q*+Fs|33p7C)Fa~#V0tgmU9 zcQjT1iiTy}aQj@J<50DKPs4xJ@W&dyrr~XHrurMw@Q8*V*YLcCpVRO;4S!q1uWR@x z8vccbf2-j?YWO1!|4YML8ty|3K_upv$M@aMj$>`83E-O5Xpw1)Yo_Vqa@nqN257q9vYj>*k;E2~8*YhT zavh8%o2HF5Tsud!8*4s^gLVSE2ODvo`C+0X%mMfuNj^eiPfk8cbdvF7M2pN}#Cvn{ zalDv68SsLC<|YsM_n73JM7^xX!SOJ2G|KHH_xSB3aX?Hl#)VU~hmD%gfaKjld-nwG z-Rs}Sk_ORptlvjeWxk)N&ip>2RptkXn#}L_FB!=Ph&;x)fL>reO!N}-gG3jZ<3Rc@ z^M{CDW{yt2#(ae64dxl5A21&!dXssU=*P@)Y56Jh9ML7_7OXi IPZEpm-|Zl#V*mgE literal 6154 zcmeHLO>9(E6h8A)T1v6BfIzGG_)&|%bY@!WfCw|4meLNTWjfHtpG>DSk95McQ)gZc zMG{GLK_VI>CKA!a1Qx_-Vq(}ytl|n26M}K!MqJ@S6EQA~3-CMdz5CvM7YHO8!-A8% z`R;e_x##}>oLRFySIJNAsBhQ266uI--5QH^#Uh#(HnZekO^Zc3?E>TVMD!$4;OqPA zYyN}C`g-((x!IDD-JP2*l=KP--ZM9yn=0lVeOj;TuGPzW-Y8eHMsA{{lYTg_<t> zbav8mQl)}j+EMHs>~~!4&Q%J#Je7_dNIJR0`gCFBfI~;-s+nT`ki&ds?usr`OZ!(f!FG zZ;d1BXea}Ld`}O+JLDR{I~Bgg!{@4oKGi>6Gzim(WU^e*lcjS0(Egc1&d^mYQM#Cu{!9Lg_5E*j|9z!C<-1C2gBKSLoCK>&p``uYxHiAbZo(ZQ ze#e{#8UNb|^d*zqw6>A*Y$dN(=Cr(EqZ1Z547A&eATAM|W(~c1&(qTiOWsBc>=M?#bBp`!McMa z*LxK8#-ZbSYw?MCk0C9O%O`doz!c%{D46W;3#lKh7yeEo&HhAtKSO#RpAg~iJt$;< z-@qRif9zWL`wD4ppO7#bx=|3I$h(9z z*2;{?dLDKif=G5vmYtLH7VLg>nCp-IiZS8r<5)Nv8nqPZ<@mULOYm_Y#2Q7C&f%^2 ztyEC7kMm@a^+CFRQ_c%Gy|T0cPfNHyxklze+*`5)X$7dOVq6Je#=Yfv1-KHRMwcKJz{s}%c?>mt&FKGA zHs_u;qd(m?&zQWHhJiwO-bMuhGM`ZRl)?>#zoPIr6@E(LAKH8#*o5);*uxjo1)FpG zn=qc=0Y(4TqJO+bW&W$e|5A7@jAi>33J)oKr^1I7t}FbA!cQptw8B4C_?HU5tni-| zeqG_bC7>b=ACFI?!q+N1qVR;m_bEKD@T$UJQ}{`RpHcYd3cm<0gx4S4^6<^mdV|&% zoLElW{^B*D-uvF$KC7GWiEI_Gh;p8v=~>-PR*&eFGBg%sOT~$Nwul#gHdm?S=Ij@} z`Q)F<6{qPzp!gtAtkB&8#jK7soIgbL2$r)S7cJix{*^>A##Kby8F6sO8SxP8VTAE+ z#z%?vFs>%^toA; zQJD4M5y5wYABD#lHxs?U7$O>HY$qx(h7lt&Mu_vEYSyyJBU7F+(~qnF>d$!VY}bJ2G#@7 zbQ4j9iEw3N)eO_E5E}8bcDHyr6797A>biTpT;M|&u@28IA(mcDc<`LBO|?$8E@*A^ zZCr4He;p|iVT+h|oOqpCV{Q!@|B5Sww+K&*conL4)|8ol zVct`$#OsR7$n|0yI1;o|37~9O0AJ!*S?iW5mbT}u|2-V=9_CkI4L Date: Fri, 25 Jul 2014 00:12:58 -0400 Subject: [PATCH 16/52] use include for rfduino include path Makes it find the include directory on case sensitive file systems. --- boards.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards.txt b/boards.txt index fa0e67d..c75a1fe 100644 --- a/boards.txt +++ b/boards.txt @@ -6,7 +6,7 @@ RFduino.build.core=arduino RFduino.build.extra_flags=-mthumb -D__RFduino__ RFduino.build.ldscript=linker_scripts/gcc/RFduino.ld RFduino.build.variant=RFduino -RFduino.build.variant_system_include="-I{build.system.path}/RFduino" "-I{build.system.path}/RFduino/Include" "-I{build.system.path}/CMSIS/CMSIS/Include" +RFduino.build.variant_system_include="-I{build.system.path}/RFduino" "-I{build.system.path}/RFduino/include" "-I{build.system.path}/CMSIS/CMSIS/Include" RFduino.build.variant_system_lib=libRFduinoSystem.a #RFduino.build.extra_flags=-DUSB_PID={build.pid} -DUSB_VID={build.vid} -DUSBCON #RFduino.build.vid=0x2341 From 935f994681b9f892d471f8d3d4d7b546af342f86 Mon Sep 17 00:00:00 2001 From: RFduino Date: Wed, 30 Jul 2014 18:00:51 -0600 Subject: [PATCH 17/52] Fixed issue with RFduinoBLE.begin --- CHANGELOG | 4 ++++ variants/RFduino/libRFduinoBLE.a | Bin 41176 -> 41200 bytes 2 files changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 5a1ad03..42a5810 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 2.1.1 + - Fix an issue with RFduinoBLE.begin() not starting in an isolated case. + - Fix to case of include directory in boards.txt (thanks jrobeson). + v 2.1 - Fixes required to support Arduino 1.5.7 (NOTE: Arduino 1.5.7 or higher is now required for RFduino 2.1 or above). diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a index a3e08ae2be6decf8af1ae326d031c6e111915c6b..64b915d8c30f587522ad2f3725f6fb744a984189 100644 GIT binary patch delta 1450 zcmai!ZA?>V6vzKhX@NpVDkW0rh16bIi=Bj*(Xp{)fJULWA`W7l&d|xrE&*rRYyH6J zm@JG<0~~cYox%7;r*4>QTwpPQ?8CBe?e;~;UR>tp_6@USbIFuFr==$QvNbvX-#P#1 z+;h)u(|dE#w6bWLaAgIasI3Xq1|~fp9lQ-xuSMflptT_t?KU7CoeJ=OF+KzQS4@Y1 z=@8lNB}R)_wybSXOQoI8jH*B-i5joyHV$T86!kZPLUn{=p06$6guj?=4`;aNT2}vj zusYXTtvjOdBT*CnY==*0?|SIE=8ia%d5wOJc3Jm}v-GL8Xn0yH)*YKn-<}K>$Z02n zGittmT71|fzMBduU)jUy`UZj|a&qV3ZiJ{CLL#=kt5Y^|nhTjOPu^Qd2bj9lR z^D&41Q!F*&%S2xYZujm~wUBrz7rCO{Ux=TS_*ec|CCfW{U+5%Pdfb~LOo8^ zQdtgMprcMz?se7a6*p7}+JGntDviWMp^@`@SSCG{R1mfB3`r0VpQ)Ck>`I!ukl zg;ZH=Pi9^bqe)rEWPL!}jEn4onf zUein_l?K;Sn>5zZ3ngCBMDI$yMps#lr4r37R*W)_VHOc%>CsEp;a}w!oHGIZvBn3? zEFe!vP6C^l#q$5koC128g}|%K0wBgD;4Cv2SYRFpR+zG1F{RkB#y6QKfQeK+j2TYe zlfMu1ec&?lD6q^t3H-vW0`5tgJ^=n^9+q2XNFD;r%)LN1a~iNQUjgjQQ$PW;8*nl^ zw5U+6DlflTKiOEY-^oUs`$Xg~t8rro4X{`y0QvJv8KN&Dh&| j#hf;bymo8)G+>l=4*Azk0>s1S#*aOcHjLKk@$7#9`~Z(y delta 1455 zcmai!Urbwd6vw~6((L>cgyKMoZl;?K zDpN8yB(Q^%%`BOj4_jQextl#~iw0s$_TU3mALgP4qS+)dh8c{SDEK=qEIetGb3W($ zy}zD&e!qKj=O!(;CM_eLw6fC8N&QUB@gFM;4vRBZ(63zD&89$1bREAW4D^a$`@ zF~yfvC8n-m?QjSEZOa5yt59fx-+RJ<2`k%H(B3^ck8||9?qER(hI!q=w7*ty}BpL zS9_;l($_>$R5;aBW7Tf#57%_)*%vx$6@O@xmgwBBuNw0l$-21vdh0-|zTWQj9I5c{ zzJ7M#MY?CN7F(z+QxlI+b7oax<=yf+r(g9VpIhhaSmz3_i?kc-USaLjvqMadBKjh; zBq!@G*Q&Sr^4zBrHAwt^dYo2gHPUpt&1}oE+6AaHXPZc;Ycea8k-JS)P_xXS^D-;+ zm&`7zbrlMO_PaEjx*j+~r(K#Tph;IiOwg>%F4n^6N^++-Ml^Z~Wu^gtGe-fJ9MGNzJjy%{G%<65JxnL?GLwKIW+rfvIR^Z|l@GCP0@<_>vM%y!@@W-IUvvlpmi?vl@vxksKPvkTb8w6*}xkuP|A`Kx6v1e;gg z7cW%(p0zCaduB%JFIiU@x#nYyzhy2N6^RvfEggj`j9fE*bohZ4MvnQ$_`dXi0mOEa A0{{R3 From 6960832a393a3dd4d16031c483e42a2aa0232ca5 Mon Sep 17 00:00:00 2001 From: RFduino Date: Mon, 25 Aug 2014 16:28:40 -0600 Subject: [PATCH 18/52] MIDI baudrate support & servo fix --- CHANGELOG | 4 ++++ libraries/Servo/Servo.cpp | 5 ----- libraries/Servo/Servo.h | 14 +++++++++++++- variants/RFduino/variant.cpp | 2 ++ variants/RFduino/variant.h | 2 ++ 5 files changed, 21 insertions(+), 6 deletions(-) mode change 100755 => 100644 libraries/Servo/Servo.cpp mode change 100755 => 100644 libraries/Servo/Servo.h diff --git a/CHANGELOG b/CHANGELOG index 42a5810..f9a429c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 2.1.2 + - Support for MIDI BaudRate of 31250 (thanks tolson) + - Fix so Servo can be moved from TIMER2 to TIMER1 for use with RFduinoGZLL + v 2.1.1 - Fix an issue with RFduinoBLE.begin() not starting in an isolated case. - Fix to case of include directory in boards.txt (thanks jrobeson). diff --git a/libraries/Servo/Servo.cpp b/libraries/Servo/Servo.cpp old mode 100755 new mode 100644 index 04d0d66..b116638 --- a/libraries/Servo/Servo.cpp +++ b/libraries/Servo/Servo.cpp @@ -154,9 +154,6 @@ void Servo_Handler(timer16_Sequence_t timer, NRF_TIMER_Type *tc, uint8_t channel static void _initISR(NRF_TIMER_Type *tc, uint32_t channel, uint32_t intenset, IRQn_Type irqn, void (*callback)(void)) { - __disable_irq(); - //*(uint32_t *)0x40000504 = 0xC007FFDF; // Workaround for PAN_028 rev1.1 anomaly 23 - System: Manual setup is required to enable use of peripherals - // Timer/Counter setup tc->TASKS_STOP = 1; tc->MODE = TIMER_MODE_MODE_Timer; @@ -170,9 +167,7 @@ static void _initISR(NRF_TIMER_Type *tc, uint32_t channel, uint32_t intenset, IR tc->INTENSET = intenset; // Enable interrupt - //NVIC_EnableIRQ(irqn); attachInterrupt(irqn, callback); - __enable_irq(); // Start clock tc->TASKS_START = 1; diff --git a/libraries/Servo/Servo.h b/libraries/Servo/Servo.h old mode 100755 new mode 100644 index 30c7079..69cc54a --- a/libraries/Servo/Servo.h +++ b/libraries/Servo/Servo.h @@ -105,7 +105,19 @@ #define IRQn_FOR_TIMER2 TIMER2_IRQn #endif -typedef enum { _timer2, _timer1, _timer0, _Nbr_16timers } timer16_Sequence_t ; +typedef enum +{ +#ifdef _useTimer2 + _timer2, +#endif +#ifdef _useTimer1 + _timer1, +#endif +#ifdef _useTimer0 + _timer0, +#endif + _Nbr_16timers +} timer16_Sequence_t ; #define Servo_VERSION 2 // software version of this library diff --git a/variants/RFduino/variant.cpp b/variants/RFduino/variant.cpp index 347df77..86b28e0 100644 --- a/variants/RFduino/variant.cpp +++ b/variants/RFduino/variant.cpp @@ -118,6 +118,7 @@ int UART0_BaudRate() case UART_BAUDRATE_BAUDRATE_Baud14400: return 14400; case UART_BAUDRATE_BAUDRATE_Baud19200: return 19200; case UART_BAUDRATE_BAUDRATE_Baud28800: return 28800; + case UART_BAUDRATE_BAUDRATE_Baud31250: return 31250; case UART_BAUDRATE_BAUDRATE_Baud38400: return 38400; case UART_BAUDRATE_BAUDRATE_Baud57600: return 57600; case UART_BAUDRATE_BAUDRATE_Baud76800: return 76800; @@ -162,6 +163,7 @@ void UART0_Start( int dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) case 14400: dw = UART_BAUDRATE_BAUDRATE_Baud14400; break; case 19200: dw = UART_BAUDRATE_BAUDRATE_Baud19200; break; case 28800: dw = UART_BAUDRATE_BAUDRATE_Baud28800; break; + case 31250: dw = UART_BAUDRATE_BAUDRATE_Baud31250; break; case 38400: dw = UART_BAUDRATE_BAUDRATE_Baud38400; break; case 57600: dw = UART_BAUDRATE_BAUDRATE_Baud57600; break; case 76800: dw = UART_BAUDRATE_BAUDRATE_Baud76800; break; diff --git a/variants/RFduino/variant.h b/variants/RFduino/variant.h index d1853a3..4fb61ac 100644 --- a/variants/RFduino/variant.h +++ b/variants/RFduino/variant.h @@ -194,6 +194,8 @@ uint64_t getDeviceId(); extern bool override_uart_limit; +#define UART_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud.(MIDI) */ + #ifdef __cplusplus } #endif From 92b120cbf222c61b246696f5ec302ef3b4c6beb1 Mon Sep 17 00:00:00 2001 From: DasBasti Date: Wed, 15 Oct 2014 07:16:37 +0200 Subject: [PATCH 19/52] mixed up temperature units Fahrenheit and Celsius got interchanged with given ranges --- variants/RFduino/libRFduino.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/variants/RFduino/libRFduino.h b/variants/RFduino/libRFduino.h index 65c64b2..c0c3b59 100644 --- a/variants/RFduino/libRFduino.h +++ b/variants/RFduino/libRFduino.h @@ -102,8 +102,8 @@ extern void RFduino_systemOff(void); * \param scale Either CELSIUS or FAHRENHEIT * * returns: - * degrees c (-198.00 to +260.00) - * degrees f (-128.00 to +127.00) + * degrees f (-198.00 to +260.00) + * degrees c (-128.00 to +127.00) */ extern float RFduino_temperature(int scale); From 24c9bac899c51563eac324fd62437862f71f080b Mon Sep 17 00:00:00 2001 From: RFduino Date: Wed, 29 Oct 2014 20:12:40 -0600 Subject: [PATCH 20/52] Support for nonconnectable advertisement --- CHANGELOG | 4 ++++ libraries/RFduinoBLE/RFduinoBLE.cpp | 2 ++ libraries/RFduinoBLE/RFduinoBLE.h | 4 ++++ .../AdvertisementRaw/AdvertisementRaw.ino | 4 ++++ .../AdvertisementRawMaxDeviceName.ino | 4 ++++ .../AdvertisementRawScanResponse.ino | 4 ++++ .../AdvertisementRawiBeacon.ino | 4 ++++ libraries/RFduinoBLE/keywords.txt | 1 + variants/RFduino/libRFduinoBLE.a | Bin 41200 -> 41412 bytes variants/RFduino/libRFduinoBLE.h | 4 ++++ 10 files changed, 31 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f9a429c..a4650cc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ CHANGELOG +v 2.2 + - Support for nonconnectable advertisement + - Corrected temperature comments (thanks DasBasti). + v 2.1.2 - Support for MIDI BaudRate of 31250 (thanks tolson) - Fix so Servo can be moved from TIMER2 to TIMER1 for use with RFduinoGZLL diff --git a/libraries/RFduinoBLE/RFduinoBLE.cpp b/libraries/RFduinoBLE/RFduinoBLE.cpp index 6c8495c..da28847 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.cpp +++ b/libraries/RFduinoBLE/RFduinoBLE.cpp @@ -45,6 +45,7 @@ RFduinoBLEClass::RFduinoBLEClass() iBeaconMeasuredPower = 0xC5; advertisementInterval = 80; txPowerLevel = +4; + connectable = true; } int RFduinoBLEClass::begin() @@ -80,6 +81,7 @@ int RFduinoBLEClass::begin() RFduinoBLE_ibeacon_measured_power = iBeaconMeasuredPower; RFduinoBLE_advertisement_interval = advertisementInterval; RFduinoBLE_tx_power_level = txPowerLevel; + RFduinoBLE_connectable = connectable; return RFduinoBLE_begin(); } diff --git a/libraries/RFduinoBLE/RFduinoBLE.h b/libraries/RFduinoBLE/RFduinoBLE.h index 500c3dd..f71940a 100644 --- a/libraries/RFduinoBLE/RFduinoBLE.h +++ b/libraries/RFduinoBLE/RFduinoBLE.h @@ -58,6 +58,10 @@ class RFduinoBLEClass // -20 dBm to +4 dBm - default +4 dBm int txPowerLevel; + // default true (false = nonconnectable advertising) + // nonconnectable forces minimum of 100ms advertisement_interval + bool connectable; + // true if the radio is active (or about to become active), false if not static volatile int& radioActive; diff --git a/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino b/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino index 6366062..ae7cb9b 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRaw/AdvertisementRaw.ino @@ -72,6 +72,10 @@ void setup() { RFduinoBLE_advdata = advdata; RFduinoBLE_advdata_len = sizeof(advdata); + // uncomment for nonconnectable advertising + // (nonconnectable forces a minimum 100ms advertisement_interval, >= 100ms intervals are okay) + // RFduinoBLE.connectable = false; + // start the BLE stack RFduinoBLE.begin(); } diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino b/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino index 0ab03f3..6d6b9e6 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRawMaxDeviceName/AdvertisementRawMaxDeviceName.ino @@ -86,6 +86,10 @@ void setup() { RFduinoBLE_advdata = advdata; RFduinoBLE_advdata_len = sizeof(advdata); + // uncomment for nonconnectable advertising + // (nonconnectable forces a minimum 100ms advertisement_interval, >= 100ms intervals are okay) + // RFduinoBLE.connectable = false; + // start the BLE stack RFduinoBLE.begin(); } diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino b/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino index ed51575..2f88497 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRawScanResponse/AdvertisementRawScanResponse.ino @@ -111,6 +111,10 @@ void setup() { RFduinoBLE_srdata = srdata; RFduinoBLE_srdata_len = sizeof(srdata); + // uncomment for nonconnectable advertising + // (nonconnectable forces a minimum 100ms advertisement_interval, >= 100ms intervals are okay) + // RFduinoBLE.connectable = false; + // start the BLE stack RFduinoBLE.begin(); } diff --git a/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino b/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino index 9969e31..d23fa17 100644 --- a/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino +++ b/libraries/RFduinoBLE/examples/AdvertisementRawiBeacon/AdvertisementRawiBeacon.ino @@ -91,6 +91,10 @@ void setup() { RFduinoBLE_advdata = advdata; RFduinoBLE_advdata_len = sizeof(advdata); + // uncomment for nonconnectable advertising + // (nonconnectable forces a minimum 100ms advertisement_interval, >= 100ms intervals are okay) + // RFduinoBLE.connectable = false; + // start the BLE stack RFduinoBLE.begin(); } diff --git a/libraries/RFduinoBLE/keywords.txt b/libraries/RFduinoBLE/keywords.txt index f8cef93..5237f58 100644 --- a/libraries/RFduinoBLE/keywords.txt +++ b/libraries/RFduinoBLE/keywords.txt @@ -21,6 +21,7 @@ iBeaconMinor KEYWORD2 iBeaconMeasuredPower KEYWORD2 advertisementInterval KEYWORD2 txPowerLevel KEYWORD2 +connectable KEYWORD2 radioActive KEYWORD2 begin KEYWORD2 diff --git a/variants/RFduino/libRFduinoBLE.a b/variants/RFduino/libRFduinoBLE.a index 64b915d8c30f587522ad2f3725f6fb744a984189..06c9ebf7b8e9555d321d06198e2a07d1c64117b7 100644 GIT binary patch delta 3284 zcmb`KZBSfS8OQ&3m$zLYa$c7dDS082<%7B++cO#^9pTbdV1Yf>~>-s;9iSO{cR zjoocRD#p-;oM;JZY+h_T6Vi~m>NuDvnbfg$9A{BKWV9V=ZLK=ip);MaV=eeRcb8<@ ze9#Y`;q31||MQ&Zob#M>Us$-Md-b;NbZ*e)uBvpGyEZFIxxyv(S5aJ5?g~v-yhZ>u zK=OwFYYqO-0V{tDEY}7zuro7K+vkDhdSC(gZ}l5Pz`aU=?irEma|&=y5lTj$+9K_d zQoH;6`g*&EI=c?_s^dB-L5wGjr$p0MB^E2P5?!uJw_DV=7n?4pQI>#2w+08cW1AXG zeqO4*-748l-jMA#iNE#UYH9c0p4KZ%|6E-9*$$U4HGopgReEne;_$I{qwR)A@td{l zO5cpwZTOsYSzI&Z6rA_u`b_JkH!^Lx-W=ZxwlmUr1K!N_8m=zcOZ^k#eS^SjAhV8`83a{Bd(waO~>g}OfReMuxij{pTeZdxc zsMM!eyF<0UOQBTXpF*s|@ryZs8x-ZSh&4NRq%G0|j+wb3Po57O4dKHchczcKNOK(Y zSOQBy>Nqez;K>i5tTf!$m|$0jeT{vd)l+>f8MfAPyB7M8XVqEDXxg=oneJm>@RV3B zqt&*KnM=ofo~$ZM;L@;ps?A;-QmonbpJ@J)t(yRS*M4qOaXTdQq$|BHTJO_e9d zhZ22QvezE}q*FI9*=)z(?R0x`16ZFN{?wJpPp(E7tAP3pZyQXB)Lcg?Anla$38XPe~L#X$mnRfg9D4 zv}#HGD&4Y1N+8F>PxcOV`|#<;p5cRi{eV!;-BD*({aPpfEoZ5!Y+Z4%#m&`S@)j4$ z2K#$DhdRp+4-LA?Tw<;1M?%?kO6|!^&>3bOKng{!7Xw*MhS%;|x5x^UMSs*LXEzx> zqRZDbtCOtR5+Fmfu9FoeD@C&;bCcoDU2C`5E}a&`X1igYv}uWBT`(6&d&MntvEg(n zK({JsACNXJ+>ey_I81=N@{hTuzJK zx!JOX%=^_UQfU$~z8A=Mf1K}G!RnFw)Ot&{JP{W`^WAcmRD(8p#Z% zvHioi-V=giu6aFfq{$>8Nxao$lK&9rKgny8^kU9pk}`y=*(9%}(6KAJqOE>woI0hc z`$>(>$yH4~5~oh{>er0Lt2C!wqJF?6UyR1Cp!IN>77}IadYu2Pc-opR-@Z@f%>MB{ zl`|_Pu3X71&!grO@{P@Gb4+IIXmo1U)>IhnUCvXY@@kU!X&_53Bbjo@r$;NB#6Vtg z;uFchR`K0DyTO_bl&1m>;(;#}B(~XrLG}H-rUYGzUR2qBDHV!GpDGX;_VX4e3YUXu zbmGgLcPct@HJB~J_6);lR7nzVl9Cz95asJ$5DV*+^zTPoGRa>O>4n>!TG!~09(8fi z>mXCxDVlnuFHsZoyy)#nQLNzy6xuSE|_!Aj)NYPs-WGCk0oQJa$_qYCva z+8x-tqP-MPu4s4T#ESOycxgqu3$I6Q9mns&2D}|BpcWrTZGKY7sDO!15tqmWH=!tM zMOu7qZnBM~a#w7nN z8kAWRWq=qoJ`bFX3O`_u0XLY>0<+BLfPXM2fPXPv^roPLtUCu}GQUDw!1M!F=04go z<|Iv+IYe(A=C^?j%pST$neBjEk05kqw0A5V1nQWZfNf05>O)M*YBQ6v*~X;o?qbqz z?O{F&>}Bo*KFj<(Wrn#M=wbE(hnQXT;9w2{L(I7rID4_`udF6b#?r!J#=wYPP@>7&ENFU)^2DdUPgUwN$`*CLXMD;!zAI9&|1eh|t z?ufi{ilwcbvaYTCJ4{;nWhR|Z?Of47tH?H909G?EM(-Bt&qa6W9_hpQK=eDKtlvrh zG`J&Q$2wP)x>&Jy)!mO}b$|VbY0K7T{&ZITJ6=hMRkGCw+CNB*RkGB!15cF3D%tAX P$+7fUB}+XzF_iKj?_Pt8 delta 3252 zcmb`Ke{56N7018tIlt_L5XXTyi4$J@aIh0%oHz-FK%1l#f*l~GsH3G7CO_DVAmFT^ zx!r=j09#Z>mvJf3($Y*BKcodlYsOS6B)U>Mqd!A}}ApL?N6b{(KC0db97HpHsely;`p?_nZy?;|>(5m+PGe^C_E{g37 zX4w@R`&4OP^s7;?rr0{8joL`mqWwA=kNd;%o;E1TBXQ}*_@1`-2sp1r#&-uwHB=kN zb_JZaqVO)7_^v=nm|goOdIDu(xU0tYu1!;4->u8(mjViW6HKzMZsv|TKJs*6(L$SGRt0sEa zMl#et?C%`R_-YeJJ2{pzjW z@4ffW)?1f@V;`N*J28<4h-a7o{MGsI$fD0;iQO{0B~fZ=mwn5{0n1hKa_iC9je<1U znCAqtC`Oa`$-;F;Yf>sLTxV2BqCc|rlGI9#JE*8dPsLcV*h_x7fC)*TC~J?yArVKqc#*Rl7>Vt>83~*kMt7hhQ)Q#eN4KL z?)N9swTgMgOI%tNps!l#vUnw0SeoilgTaKAW4trAURTxUK*W%TLOwT06tH#?i<;_@$$%KMW5;MH`BqcyS z=5yB6;uCB{b&Bl9niP3OEan=K=!lDLt?Dr(-{OCEuaJb(<9PIGK%rprZeTH!WDacl z62R|p)0gANk*Oc>u}t&sH8J9m})}nPN?i zIr0tADw2-KF-=3j-xB>Kr zG0ERXH)S>@cz_r&JqHXW6vNCTbm}v|4vaF70>5CM0N!WTP;x~1B=8CIDVilcYBIgu z(wL9Yv&lR~Ni(0MQ;PXKP{8b>C1Y-(2^kQ9OedzoiXK{HW<9;amdJkHz-1PxR^xdZ581#L2oNz1xh zd{A2up%f`7lI!+jV%Jd(Yk6&`R4bWOs{5E!s@8;_$FZKW)b;wVdkLTo3zL~jPUH+} zdGrjaT6%_b3q8Yc6F2fk)He{_D3=tbmw|ldaN@C`0NmtFpRr?i_x8l+hI{Wa`lp~S z`3d~&k;2&Tyv@0veH621eaoGkq$cLxbTcg}3AUTJe2|@)h#|(kg)t?#vucLI8asRB P=)4(= 100ms intervals are okay) +extern bool RFduinoBLE_connectable; + extern void RFduinoBLE_onAdvertisement(bool start) __attribute__((weak)); // received signal strength indication (-0dBm to -127dBm) extern void RFduinoBLE_onRSSI(int rssi) __attribute__((weak)); From 2e60f6bba42f29dda0256a5c215fca637f8d793b Mon Sep 17 00:00:00 2001 From: "Helen V. Holmes" Date: Wed, 19 Nov 2014 16:46:37 -0500 Subject: [PATCH 21/52] Update documentation with better specifics as to where you put folder; add in some syntax highlighting --- README.md | 49 +++++++++++++++++++++++++------------------------ docs.png | Bin 0 -> 9602 bytes 2 files changed, 25 insertions(+), 24 deletions(-) create mode 100644 docs.png diff --git a/README.md b/README.md index 040745f..cdb4b5c 100755 --- a/README.md +++ b/README.md @@ -1,47 +1,48 @@ -### RFduino: Shrunk down an Arduino to the size of a finger-tip and made it Wireless! +# RFduino: An Arduino shrunk to the size of a finger-tip and made wireless! -![logo](https://raw.github.com/RFduino/RFduino/master/4up%20image.jpg) +![logo](https://raw.github.com/RFduino/RFduino/master/4up%20image.jpg) [Video](http://www.youtube.com/watch?v=arWBdGwCJcM) -### Installation +## Installation -* Get the hardware here: [http://RFduino.com](http://RFduino.com) +* Get the [RFduino hardware](http://RFduino.com). -* Download Arduino 1.5 here: [http://arduino.cc](http://arduino.cc/en/Main/Software) - (on osx remember to open arduino first to make gatekeeper perform its magic) +* Download [Arduino 1.5](http://arduino.cc/en/Main/Software). + * _If you're on OSX_: Remember to open Arduino _first_ to make gatekeeper perform its magic! -* Copy the RFduino directory from this repository in Arduino - (on Windows, C:\arduino-1.5.4\hardware\arduino) - (on OSX, /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino) - or "git clone https://github.com/RFduino/RFduino" in the directory indicated +* Copy the Arduino library into the appropriate directory for your system. (Folder should be named ```RFduino```, not ```RFduino-master```): + ![location](docs.png) + * _Windows_: + * ```C:\arduino-1.5.4\hardware\arduino``` + * _OSX, Arduino 1.5.8_: + * ```/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino``` -* Install the FTDI drivers from here: [http://ftdichip.com](http://www.ftdichip.com/Drivers/VCP.htm) +* Install the [FTDI drivers](http://www.ftdichip.com/Drivers/VCP.htm). -Your ready to go! +You're ready to go! -Detailed instructions are available here: [Quick Start Guide](http://files.rfdigital.com/rfduino.quick.start.guide.pdf) +Detailed instructions are available in our [Quick Start Guide](http://files.rfdigital.com/rfduino.quick.start.guide.pdf). -### Getting Started +## Getting Started * Attach the USB shield -* Select RFduino from the Tools/Board menu +* Select RFduino from the ```Tools/Board``` menu -* Select the port from the Tools/Port menu +* Select the port from the ```Tools/Port``` menu -* Select an example from the Files/Examples/RFduinoNonBLE or Files/Examples/RFduinoBLE directory +* Select an example from the ```Files/Examples/RFduinoNonBLE``` or ```Files/Examples/RFduinoBLE``` directory -* Select Upload to compile, upload and execute the sketch +* Select ```Upload``` to compile, upload and execute the sketch -* Down the iPhone example apps from the iPhone App Store (search for "RFduino"). +* Download the iPhone example apps from the iPhone App Store (search for ```RFduino```). + * Detailed instructions for the Temperature app are available [here](http://files.rfdigital.com/rfduino.temperature.guide.pdf). + * Detailed instructions for the ColorWheel app are available [here](http://files.rfdigital.com/rfduino.rgb.colorwheel.guide.pdf). -Detailed instructions for the Temperature app are available here: [Temperature App](http://files.rfdigital.com/rfduino.temperature.guide.pdf) -Detailed instructions for the ColorWheel app are available here: [ColorWheel App](http://files.rfdigital.com/rfduino.rgb.colorwheel.guide.pdf) +# Communicating with us -### Communicating with us - -The best way to communiate with us is here: [RFduino Forum](http://forum.RFduino.com). +The best way to communiate with us is on the [RFduino Forum](http://forum.RFduino.com). ### A Lot More Coming! diff --git a/docs.png b/docs.png new file mode 100644 index 0000000000000000000000000000000000000000..f0d557eeda19b4bd7defb1e0d69e564414b2ab25 GIT binary patch literal 9602 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 literal 0 HcmV?d00001 From eae65e25f8a5f0c70c29302ae427c5342d79b731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98RFduino=E2=80=99?= <‘info@OpenSourceRF.com’> Date: Mon, 24 Nov 2014 08:17:13 -0700 Subject: [PATCH 22/52] analogRead/GZLL power consumption; updated README --- CHANGELOG | 5 +++++ cores/arduino/wiring_analog.c | 1 + libraries/RFduinoGZLL/RFduinoGZLL.cpp | 1 + 3 files changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a4650cc..af9dce4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ CHANGELOG +v 2.2.1 + - Resolved power consumption issues with ULP and analogRead/GZLL. + - Update documentation with better specifics as to where you put folder + (thanks Helen Holmes). + v 2.2 - Support for nonconnectable advertisement - Corrected temperature comments (thanks DasBasti). diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index f3084d1..798af99 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -117,6 +117,7 @@ uint32_t analogRead(uint32_t ulPin) ulValue = NRF_ADC->RESULT; // Read the value ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution); NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos); // Disable ADC + NRF_ADC->TASKS_STOP = 1; // GPIOs release regarding PAN028 NRF_ADC->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos) | (ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling << ADC_CONFIG_INPSEL_Pos) | diff --git a/libraries/RFduinoGZLL/RFduinoGZLL.cpp b/libraries/RFduinoGZLL/RFduinoGZLL.cpp index 9642aa2..b6d30d0 100644 --- a/libraries/RFduinoGZLL/RFduinoGZLL.cpp +++ b/libraries/RFduinoGZLL/RFduinoGZLL.cpp @@ -68,6 +68,7 @@ int RFduinoGZLLClass::begin(device_t device) void RFduinoGZLLClass::end() { RFduinoGZLL_end(); + NRF_RADIO->TASKS_RSSISTOP = 1; } bool RFduinoGZLLClass::sendToHost(const char *data, int len) From 6a97b0907e48355bb6d90248e354bcf3f0608452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98RFduino=E2=80=99?= <‘info@OpenSourceRF.com’> Date: Thu, 4 Dec 2014 19:04:53 -0700 Subject: [PATCH 23/52] Fixed race condition issue with analogRead --- CHANGELOG | 3 +++ cores/arduino/wiring_analog.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index af9dce4..9eee2ac 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ CHANGELOG +v 2.2.2 + - Resolved race condition issue with analogRead. + v 2.2.1 - Resolved power consumption issues with ULP and analogRead/GZLL. - Update documentation with better specifics as to where you put folder diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 798af99..a0843c2 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -112,8 +112,9 @@ uint32_t analogRead(uint32_t ulPin) NRF_ADC->INTENCLR = 0xFFFFFFFF; NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos); // Enable ADC NRF_ADC->TASKS_START = 1; // Start A-D conversion - while ((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) == (ADC_BUSY_BUSY_Busy << ADC_BUSY_BUSY_Pos)) // Wait for end of conversion - ; + NRF_ADC->EVENTS_END = 0; + while (! NRF_ADC->EVENTS_END) // Wait for end of conversion + ; ulValue = NRF_ADC->RESULT; // Read the value ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution); NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos); // Disable ADC From aa4cd233e917875c29b3d8629f2a4aa3006b88b7 Mon Sep 17 00:00:00 2001 From: Adam Eberbach Date: Sun, 11 Jan 2015 16:12:36 +1100 Subject: [PATCH 24/52] Remove dependence on UIKit; fix use of deprecated UUID attribute --- iPhone Apps/rfduino/RFduinoManagerDelegate.h | 1 + iPhone Apps/rfduino/RfduinoManager.m | 55 +++----------------- 2 files changed, 8 insertions(+), 48 deletions(-) diff --git a/iPhone Apps/rfduino/RFduinoManagerDelegate.h b/iPhone Apps/rfduino/RFduinoManagerDelegate.h index 50f750c..044b8a7 100755 --- a/iPhone Apps/rfduino/RFduinoManagerDelegate.h +++ b/iPhone Apps/rfduino/RFduinoManagerDelegate.h @@ -39,5 +39,6 @@ - (void)didConnectRFduino:(RFduino *)rfduino; - (void)didLoadServiceRFduino:(RFduino *)rfduino; - (void)didDisconnectRFduino:(RFduino *)rfduino; +- (void)shouldDisplayAlertTitled:(NSString *)title messageBody:(NSString *)body; @end diff --git a/iPhone Apps/rfduino/RfduinoManager.m b/iPhone Apps/rfduino/RfduinoManager.m index dec6846..cdf9d3b 100644 --- a/iPhone Apps/rfduino/RfduinoManager.m +++ b/iPhone Apps/rfduino/RfduinoManager.m @@ -98,16 +98,7 @@ - (bool)isBluetoothLESupported } -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Bluetooth LE Support" - message:message - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; - -#endif + [delegate shouldDisplayAlertTitled:@"Bluetooth LE Support" messageBody:message]; return NO; } @@ -193,16 +184,7 @@ - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPe if (error.code) { cancelBlock = block; -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Peripheral Disconnected with Error" - message:error.description - delegate:self - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; - -#endif + [delegate shouldDisplayAlertTitled:@"Peripheral Disconnected with Error" messageBody:error.description]; } else @@ -229,9 +211,9 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri // NSLog(@"didDiscoverPeripheral"); NSString *uuid = NULL; - if (peripheral.UUID) { + if ([peripheral.identifier.UUIDString length] > 0) { // only returned if you have connected to the device before - uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, peripheral.UUID); + uuid = peripheral.identifier.UUIDString; } else { uuid = @""; } @@ -259,7 +241,7 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri id manufacturerData = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey]; if (manufacturerData) { const uint8_t *bytes = [manufacturerData bytes]; - int len = [manufacturerData length]; + NSUInteger len = [manufacturerData length]; // skip manufacturer uuid NSData *data = [NSData dataWithBytes:bytes+2 length:len-2]; rfduino.advertisementData = data; @@ -283,17 +265,7 @@ - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(C { NSLog(@"didFailToConnectPeripheral"); -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connect Failed" - message:error.description - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; - -#endif - + [delegate shouldDisplayAlertTitled:@"Connect Failed" messageBody:error.description]; } - (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals @@ -302,7 +274,7 @@ - (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeriphera - (void)centralManagerDidUpdateState:(CBCentralManager *)aCentral { - NSLog(@"central manager state = %d", [central state]); + NSLog(@"central manager state = %ld", [central state]); bool success = [self isBluetoothLESupported]; if (success) { @@ -310,19 +282,6 @@ - (void)centralManagerDidUpdateState:(CBCentralManager *)aCentral } } -#pragma mark - UIAlertViewDelegate methods - -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - -- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger) buttonIndex -{ - if (buttonIndex == 0) { - cancelBlock(); - } -} - -#endif - #pragma mark - Rfduino methods - (bool)isScanning From be3233aba659ef8bda39f3239e520cb290ac5cf7 Mon Sep 17 00:00:00 2001 From: Adam Eberbach Date: Sun, 11 Jan 2015 16:41:39 +1100 Subject: [PATCH 25/52] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file From 08b78f0d9076cc28f3bec4fcbe8fb340edfa6168 Mon Sep 17 00:00:00 2001 From: Adam Eberbach Date: Sun, 11 Jan 2015 18:43:11 +1100 Subject: [PATCH 26/52] @optional requires check for respondsToSelector... --- iPhone Apps/rfduino/RfduinoManager.m | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/iPhone Apps/rfduino/RfduinoManager.m b/iPhone Apps/rfduino/RfduinoManager.m index cdf9d3b..5728f8b 100644 --- a/iPhone Apps/rfduino/RfduinoManager.m +++ b/iPhone Apps/rfduino/RfduinoManager.m @@ -98,7 +98,9 @@ - (bool)isBluetoothLESupported } - [delegate shouldDisplayAlertTitled:@"Bluetooth LE Support" messageBody:message]; + if ([delegate respondsToSelector:@selector(shouldDisplayAlertTitled:messageBody:)]) { + [delegate shouldDisplayAlertTitled:@"Bluetooth LE Support" messageBody:message]; + } return NO; } @@ -184,7 +186,9 @@ - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPe if (error.code) { cancelBlock = block; - [delegate shouldDisplayAlertTitled:@"Peripheral Disconnected with Error" messageBody:error.description]; + if ([delegate respondsToSelector:@selector(shouldDisplayAlertTitled:messageBody:)]) { + [delegate shouldDisplayAlertTitled:@"Peripheral Disconnected with Error" messageBody:error.description]; + } } else @@ -265,7 +269,9 @@ - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(C { NSLog(@"didFailToConnectPeripheral"); - [delegate shouldDisplayAlertTitled:@"Connect Failed" messageBody:error.description]; + if ([delegate respondsToSelector:@selector(shouldDisplayAlertTitled:messageBody:)]) { + [delegate shouldDisplayAlertTitled:@"Connect Failed" messageBody:error.description]; + } } - (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals From a0071df18f1a21ad03a532c38339d974bfec6e22 Mon Sep 17 00:00:00 2001 From: Jetty 840 Date: Sat, 17 Jan 2015 12:56:44 -0700 Subject: [PATCH 27/52] Adding changes to GZLL for host/device addressing provided by waynek in this post: http://forum.rfduino.com/index.php?topic=329.0 --- libraries/RFduinoGZLL/RFduinoGZLL.cpp | 4 ++++ libraries/RFduinoGZLL/RFduinoGZLL.h | 2 ++ source/libRFduinoGZLL/libRFduinoGZLL.c | 15 ++++++++++++++- source/libRFduinoGZLL/libRFduinoGZLL.h | 4 ++++ variants/RFduino/libRFduinoGZLL.a | Bin 60526 -> 56276 bytes variants/RFduino/libRFduinoGZLL.h | 4 ++++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/libraries/RFduinoGZLL/RFduinoGZLL.cpp b/libraries/RFduinoGZLL/RFduinoGZLL.cpp index b6d30d0..b502b65 100644 --- a/libraries/RFduinoGZLL/RFduinoGZLL.cpp +++ b/libraries/RFduinoGZLL/RFduinoGZLL.cpp @@ -56,11 +56,15 @@ RFduinoGZLLClass::RFduinoGZLLClass() ::RFduinoGZLL_used = 1; txPowerLevel = +4; + hostBaseAddress = 0U; + deviceBaseAddress = 0U; } int RFduinoGZLLClass::begin(device_t device) { RFduinoGZLL_tx_power_level = txPowerLevel; + RFduinoGZLL_host_base_address = hostBaseAddress; + RFduinoGZLL_device_base_address = deviceBaseAddress; return RFduinoGZLL_begin(device); } diff --git a/libraries/RFduinoGZLL/RFduinoGZLL.h b/libraries/RFduinoGZLL/RFduinoGZLL.h index c2a8ada..e6577ce 100644 --- a/libraries/RFduinoGZLL/RFduinoGZLL.h +++ b/libraries/RFduinoGZLL/RFduinoGZLL.h @@ -72,6 +72,8 @@ class RFduinoGZLLClass public: // -20 dBm to +4 dBm - default +4 dBm int txPowerLevel; + uint32_t hostBaseAddress; + uint32_t deviceBaseAddress; public: RFduinoGZLLClass(); diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.c b/source/libRFduinoGZLL/libRFduinoGZLL.c index 7f6f2f5..ce232f6 100644 --- a/source/libRFduinoGZLL/libRFduinoGZLL.c +++ b/source/libRFduinoGZLL/libRFduinoGZLL.c @@ -43,9 +43,12 @@ extern int RFduinoGZLL_enabled; // -20 dBm to +4 dBm = default +4 dBm int RFduinoGZLL_tx_power_level = 4; +uint32_t RFduinoGZLL_host_base_address = 0U; +uint32_t RFduinoGZLL_device_base_address = 0U; static device_t _device; + // 0 = success // 1 = init failed // 2 = set tx_power failed @@ -81,7 +84,17 @@ int RFduinoGZLL_begin(device_t device) if (! nrf_gzll_set_device_channel_selection_policy(NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT)) return 4; - + + if (RFduinoGZLL_host_base_address ) { + if ( !nrf_gzll_set_base_address_0(RFduinoGZLL_host_base_address) ) + return 5; + } + + if (RFduinoGZLL_device_base_address) { + if ( !nrf_gzll_set_base_address_1(RFduinoGZLL_device_base_address) ) + return 6; + } + if (! nrf_gzll_enable()) return 3; diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.h b/source/libRFduinoGZLL/libRFduinoGZLL.h index 9a4325a..7d28050 100644 --- a/source/libRFduinoGZLL/libRFduinoGZLL.h +++ b/source/libRFduinoGZLL/libRFduinoGZLL.h @@ -55,6 +55,8 @@ typedef enum // -20 dBm to +4 dBm - default +4 dBm extern int RFduinoGZLL_tx_power_level; +extern uint32_t RFduinoGZLL_host_base_address; +extern uint32_t RFduinoGZLL_device_base_address; extern void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) __attribute__((weak)); @@ -63,6 +65,8 @@ extern void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len // 2 = set tx_power failed // 3 = enabled failed // 4 = set channel selection policy failed +// 5 = failed to set host base address +// 6 = failed to set devive base address int RFduinoGZLL_begin(device_t device); void RFduinoGZLL_end(void); diff --git a/variants/RFduino/libRFduinoGZLL.a b/variants/RFduino/libRFduinoGZLL.a index 03c89e7e7a9ab716b5dc42873b1a018f9bf8a91a..dc3625a05ca74ad04d81fc8d8e89bd3a09699d41 100644 GIT binary patch literal 56276 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 Date: Sat, 24 Jan 2015 10:36:51 -0700 Subject: [PATCH 28/52] GZLL baseAddress enhancement --- CHANGELOG | 6 ++ .../Device0/Device0.ino | 79 ++++++++++++++++++ .../01.DeviceToHostSettings/Host/Host.ino | 52 ++++++++++++ libraries/RFduinoGZLL/keywords.txt | 2 + source/libRFduinoGZLL/build.bat | 2 +- source/libRFduinoGZLL/libRFduinoGZLL.c | 6 ++ variants/RFduino/libRFduinoGZLL.a | Bin 56276 -> 61096 bytes 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Device0/Device0.ino create mode 100644 libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Host/Host.ino diff --git a/CHANGELOG b/CHANGELOG index 9eee2ac..6e1cd7d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ CHANGELOG +v 2.2.3 + - GZLL baseAddress enhancement (thanks waynek/jetty840) + - Check base address msb is not 0x55 or 0xaa + - Updated libRFduinoGZLL keywords.txt + - Added DeviceToHostSettings example GZLL sketch + v 2.2.2 - Resolved race condition issue with analogRead. diff --git a/libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Device0/Device0.ino b/libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Device0/Device0.ino new file mode 100644 index 0000000..4bf2d01 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Device0/Device0.ino @@ -0,0 +1,79 @@ +/* +This sketch demonstrates how to send data from a Device +to a Host in a Gazell network. + +When Button A on the Device is pressed and released, +the green led on the host will toggle. +*/ + +#include + +device_t role = DEVICE0; + +// pin for Button A on the RGB Shield +int button_a = 5; + +// debounce time (in ms) +int debounce_time = 10; + +// maximum debounce timeout (in ms) +int debounce_timeout = 100; + +// starting state is off +char state = 0; + +void setup() +{ + pinMode(button_a, INPUT); + + // use the lowest power level + RFduinoGZLL.txPowerLevel = -20; + + // the host/device base address can be changed to create independent networks in the same area + // (note: the msb cannot be 0x55 or 0xaa) + RFduinoGZLL.hostBaseAddress = 0x12345678; // default host base address is 0x0D0A0704; + RFduinoGZLL.deviceBaseAddress = 0x87654321; // default device base address is 0x0E0B0805; + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +int debounce(int button, int state) +{ + int start = millis(); + int debounce_start = start; + + while (millis() - start < debounce_timeout) + if (digitalRead(button) == state) + { + if (millis() - debounce_start >= debounce_time) + return 1; + } + else + debounce_start = millis(); + + return 0; +} + +int delay_until_button(int button, int state) +{ + while (! debounce(button, state)) + ; +} + +void loop() +{ + delay_until_button(button_a, HIGH); + + // toggle state + state = ! state; + + // send state to Host + RFduinoGZLL.sendToHost(state); + + delay_until_button(button_a, LOW); +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ +} diff --git a/libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Host/Host.ino b/libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Host/Host.ino new file mode 100644 index 0000000..588fdc0 --- /dev/null +++ b/libraries/RFduinoGZLL/examples/01.DeviceToHostSettings/Host/Host.ino @@ -0,0 +1,52 @@ +/* +This sketch demonstrates how to send data from a Device +to a Host in a Gazell network. + +The host and upto 3 devices should have the RGB shield +attached. When Button A on a Device is pressed, the +associated led on the Host will toggle. Device1 is +associated with the Red led, Device2 with the Green led +and Device3 with the Blue led. + +The Green led on the Device will blink to indicate +that an acknowledgement from the Host was received. +*/ + +#include + +device_t role = HOST; + +// pin for the Green Led +int green_led = 3; + +void setup() +{ + pinMode(green_led, OUTPUT); + + // use the lowest power level + RFduinoGZLL.txPowerLevel = -20; + + // the host/device base address can be changed to create independent networks in the same area + // (note: the msb cannot be 0x55 or 0xaa) + RFduinoGZLL.hostBaseAddress = 0x12345678; // default host base address is 0x0D0A0704; + RFduinoGZLL.deviceBaseAddress = 0x87654321; // default device base address is 0x0E0B0805; + + // start the GZLL stack + RFduinoGZLL.begin(role); +} + +void loop() +{ +} + +void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len) +{ + char state = data[0]; + + // this test is not needed for a single device + if (device == DEVICE0) + digitalWrite(green_led, state); + + // no data to piggyback on the acknowledgement sent back to the Device + // RFduinoGZLL.sendToDevice(device, "OK"); +} diff --git a/libraries/RFduinoGZLL/keywords.txt b/libraries/RFduinoGZLL/keywords.txt index 513769d..2775c19 100644 --- a/libraries/RFduinoGZLL/keywords.txt +++ b/libraries/RFduinoGZLL/keywords.txt @@ -12,6 +12,8 @@ RFduinoGZLL KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### txPowerLevel KEYWORD2 +hostBaseAddress KEYWORD2 +deviceBaseAddress KEYWORD2 begin KEYWORD2 end KEYWORD2 diff --git a/source/libRFduinoGZLL/build.bat b/source/libRFduinoGZLL/build.bat index db87d65..827611b 100644 --- a/source/libRFduinoGZLL/build.bat +++ b/source/libRFduinoGZLL/build.bat @@ -1,6 +1,6 @@ @echo off -set arduino=C:\arduino-1.5.7 +set arduino=C:\arduino-1.5.8 set nordic="C:\Nordic Semiconductor\nRF51 SDK_v4.2.0.25053\Nordic\nrf51822" if not exist %nordic% ( diff --git a/source/libRFduinoGZLL/libRFduinoGZLL.c b/source/libRFduinoGZLL/libRFduinoGZLL.c index ce232f6..d31232b 100644 --- a/source/libRFduinoGZLL/libRFduinoGZLL.c +++ b/source/libRFduinoGZLL/libRFduinoGZLL.c @@ -86,11 +86,17 @@ int RFduinoGZLL_begin(device_t device) return 4; if (RFduinoGZLL_host_base_address ) { + uint8_t msb = RFduinoGZLL_host_base_address >> 24; + if (msb == 0x55 || msb == 0xAA) + return 5; // msb of base address should not be alternating 0s and 1s if ( !nrf_gzll_set_base_address_0(RFduinoGZLL_host_base_address) ) return 5; } if (RFduinoGZLL_device_base_address) { + uint8_t msb = RFduinoGZLL_device_base_address >> 24; + if (msb == 0x55 || msb == 0xAA) + return 6; // msb of base address should not be alternating 0s and 1s if ( !nrf_gzll_set_base_address_1(RFduinoGZLL_device_base_address) ) return 6; } diff --git a/variants/RFduino/libRFduinoGZLL.a b/variants/RFduino/libRFduinoGZLL.a index dc3625a05ca74ad04d81fc8d8e89bd3a09699d41..59156a9f0e535f4348603f13f7874e2873db1fdf 100644 GIT binary patch literal 61096 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 literal 56276 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 Vh*@t)J4tne;hCl0LC Date: Thu, 12 Feb 2015 12:54:49 -0700 Subject: [PATCH 29/52] Reduce compile times with Arduino 1.6 --- CHANGELOG | 3 +++ platform.txt | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6e1cd7d..c661f95 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ CHANGELOG +v 2.2.4 + - Reduce compile times with Arduino 1.6 on second and subsequent compiles. + v 2.2.3 - GZLL baseAddress enhancement (thanks waynek/jetty840) - Check base address msb is not 0x55 or 0xaa diff --git a/platform.txt b/platform.txt index c4f2aa6..7981d31 100644 --- a/platform.txt +++ b/platform.txt @@ -5,13 +5,13 @@ name=RFduino Boards compiler.path={runtime.ide.path}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/ compiler.c.cmd=arm-none-eabi-gcc -compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-builtin +compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-builtin -MMD compiler.c.elf.cmd=arm-none-eabi-g++ # -u _printf_float compiler.c.elf.flags=-Wl,--gc-sections --specs=nano.specs compiler.S.flags=-c -g -assembler-with-cpp compiler.cpp.cmd=arm-none-eabi-g++ -compiler.cpp.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fno-builtin +compiler.cpp.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fno-builtin -MMD compiler.ar.cmd=arm-none-eabi-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arm-none-eabi-objcopy From c0e96d223c7166cfdfe3b35a33cde9f42194ce9e Mon Sep 17 00:00:00 2001 From: Kevron Rees Date: Sat, 14 Feb 2015 19:57:12 -0800 Subject: [PATCH 30/52] make these virtual --- cores/arduino/HardwareSerial.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 83fcffe..906d7eb 100755 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -52,9 +52,9 @@ class HardwareSerial : public Stream { public: - void begin( const uint32_t dwBaudRate ) ; - void begin( const uint32_t dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) ; - void end(); + virtual void begin( const uint32_t dwBaudRate ) = 0; + virtual void begin( const uint32_t dwBaudRate, uint8_t rx_pin, uint8_t tx_pin ) = 0; + virtual void end() = 0; virtual int available(void) = 0; virtual int peek(void) = 0; virtual int read(void) = 0; From c5551edcc7c0fbf0eaa2c3cab59d7becd8c7e9aa Mon Sep 17 00:00:00 2001 From: Oren Lederman Date: Thu, 26 Mar 2015 10:20:26 -0400 Subject: [PATCH 31/52] fixing analogRead freeze problem + fixing indentation Sample end flag should be set before starting A-D, otherwise it might can an infinite loop See -http://forum.rfduino.com/index.php?topic=1012.0 --- cores/arduino/wiring_analog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index a0843c2..0f58d53 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -109,10 +109,10 @@ uint32_t analogRead(uint32_t ulPin) (analog_reference << ADC_CONFIG_REFSEL_Pos)| // DEFAULT: Use supply voltage with 1/3 prescaling as reference for conversion. Only usable when supply voltage is between 2.5V and 3.6V (pselValue << ADC_CONFIG_PSEL_Pos)| // Select ADC input (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); - NRF_ADC->INTENCLR = 0xFFFFFFFF; - NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos); // Enable ADC - NRF_ADC->TASKS_START = 1; // Start A-D conversion - NRF_ADC->EVENTS_END = 0; + NRF_ADC->INTENCLR = 0xFFFFFFFF; + NRF_ADC->ENABLE = (ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos); // Enable ADC + NRF_ADC->EVENTS_END = 0; // Reset end flag + NRF_ADC->TASKS_START = 1; // Start A-D conversion while (! NRF_ADC->EVENTS_END) // Wait for end of conversion ; ulValue = NRF_ADC->RESULT; // Read the value From b351cedf5d350c748900c96cbcafe5f8dfef7ab9 Mon Sep 17 00:00:00 2001 From: George Stocker Date: Thu, 9 Apr 2015 17:41:05 -0400 Subject: [PATCH 32/52] Include explicit information about Java 6 Arduino 1.5.8 requires Java 6 to be installed; on a Fresh Mac OS X installation, this may not be an issue, but if a user has upgraded Java or changed their JAVA_HOME to point to Java 7, the Arduino IDE will crash upon launch. Including this instruction to save others from the pain I endured. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cdb4b5c..9322c4a 100755 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ * Download [Arduino 1.5](http://arduino.cc/en/Main/Software). * _If you're on OSX_: Remember to open Arduino _first_ to make gatekeeper perform its magic! - + * _Mac OS X_: Requires Java 6 to be installed. Available [here](https://support.apple.com/kb/DL1572?locale=en_US). * Copy the Arduino library into the appropriate directory for your system. (Folder should be named ```RFduino```, not ```RFduino-master```): ![location](docs.png) * _Windows_: From 10515b619f4c76a54a2ce0109a29e5bab4365db2 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 14 Apr 2015 16:52:21 -0600 Subject: [PATCH 33/52] Added AlertView to ScanViewController by default --- iPhone Apps/rfduino/ScanViewController.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/iPhone Apps/rfduino/ScanViewController.m b/iPhone Apps/rfduino/ScanViewController.m index 44d9846..0b020db 100755 --- a/iPhone Apps/rfduino/ScanViewController.m +++ b/iPhone Apps/rfduino/ScanViewController.m @@ -270,6 +270,20 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath #pragma mark - RfduinoDiscoveryDelegate methods +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + +- (void)shouldDisplayAlertTitled:(NSString *)title messageBody:(NSString *)body +{ + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title + message:body + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alert show]; +} + +#endif + - (void)didDiscoverRFduino:(RFduino *)rfduino { NSLog(@"didDiscoverRFduino"); From bdf037baff2ddcf3e3a80341c927045bc93a2fc6 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 14 Apr 2015 17:13:36 -0600 Subject: [PATCH 34/52] merge SensiBots-master --- iPhone Apps/rfduino/RFduino.h | 1 - iPhone Apps/rfduino/RFduino.m | 1 - iPhone Apps/rfduino/RfduinoManager.m | 9 --------- iPhone Apps/rfduino/ScanViewController.m | 6 ------ 4 files changed, 17 deletions(-) diff --git a/iPhone Apps/rfduino/RFduino.h b/iPhone Apps/rfduino/RFduino.h index 4d102c6..f19a9ee 100644 --- a/iPhone Apps/rfduino/RFduino.h +++ b/iPhone Apps/rfduino/RFduino.h @@ -55,7 +55,6 @@ extern NSString *customUUID; @property(strong, nonatomic) RFduinoManager *rfduinoManager; @property(strong, nonatomic) NSString *name; -@property(strong, nonatomic) NSString *UUID; @property(strong, nonatomic) NSData *advertisementData; @property(strong, nonatomic) NSNumber *advertisementRSSI; @property(assign, nonatomic) NSInteger advertisementPackets; diff --git a/iPhone Apps/rfduino/RFduino.m b/iPhone Apps/rfduino/RFduino.m index 789db01..ea0c8f3 100644 --- a/iPhone Apps/rfduino/RFduino.m +++ b/iPhone Apps/rfduino/RFduino.m @@ -90,7 +90,6 @@ @implementation RFduino @synthesize peripheral; @synthesize name; -@synthesize UUID; @synthesize advertisementData; @synthesize advertisementRSSI; @synthesize advertisementPackets; diff --git a/iPhone Apps/rfduino/RfduinoManager.m b/iPhone Apps/rfduino/RfduinoManager.m index 5728f8b..e39daa3 100644 --- a/iPhone Apps/rfduino/RfduinoManager.m +++ b/iPhone Apps/rfduino/RfduinoManager.m @@ -214,14 +214,6 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri { // NSLog(@"didDiscoverPeripheral"); - NSString *uuid = NULL; - if ([peripheral.identifier.UUIDString length] > 0) { - // only returned if you have connected to the device before - uuid = peripheral.identifier.UUIDString; - } else { - uuid = @""; - } - bool added = false; RFduino *rfduino = [self rfduinoForPeripheral:peripheral]; @@ -231,7 +223,6 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri rfduino.rfduinoManager = self; rfduino.name = peripheral.name; - rfduino.UUID = uuid; rfduino.peripheral = peripheral; diff --git a/iPhone Apps/rfduino/ScanViewController.m b/iPhone Apps/rfduino/ScanViewController.m index 0b020db..d3b57bb 100755 --- a/iPhone Apps/rfduino/ScanViewController.m +++ b/iPhone Apps/rfduino/ScanViewController.m @@ -132,9 +132,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if (rfduino.outOfRange) { start = [UIColor colorWithRed:160/255.0 green:160/255.0 blue:160/255.0 alpha:0.8]; stop = [UIColor colorWithRed:160/255.0 green:160/255.0 blue:160/255.0 alpha:0.2]; - } else if (! rfduino.UUID.length) { - start = [UIColor colorWithRed:224/255.0 green:242/255.0 blue:224/255.0 alpha: 1.0]; - stop = [UIColor colorWithRed:224/255.0 green:242/255.0 blue:224/255.0 alpha: 0.7]; } else { start = [UIColor colorWithRed:253/255.0 green:255/255.0 blue:255/255.0 alpha: 1.0]; stop = [UIColor colorWithRed:253/255.0 green:255/255.0 blue:255/255.0 alpha: 0.7]; @@ -147,8 +144,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N NSString *text = [[NSString alloc] initWithFormat:@"%@", rfduino.name]; - NSString *uuid = rfduino.UUID; - int rssi = rfduino.advertisementRSSI.intValue; NSString *advertising = @""; @@ -162,7 +157,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [detail appendString:@" "]; [detail appendFormat:@"Packets: %d\n", rfduino.advertisementPackets]; [detail appendFormat:@"Advertising: %@\n", advertising]; - [detail appendFormat:@"%@", uuid]; cell.textLabel.text = text; cell.detailTextLabel.text = detail; From 78859f015e20d08635a2a08eb577b4ff95d0bfe7 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 14 Apr 2015 18:09:13 -0600 Subject: [PATCH 35/52] arduino 1.6.3 support --- CHANGELOG | 9 +++++++++ README.md | 24 ++++++++++-------------- boards.txt | 1 + platform.txt | 10 ++++++++-- preferences.png | Bin 0 -> 83737 bytes source/libRFduinoGZLL/build.bat | 21 ++++++++++++--------- system/RFduino/source/build.bat | 24 +++++++++++++----------- 7 files changed, 53 insertions(+), 36 deletions(-) mode change 100755 => 100644 README.md create mode 100644 preferences.png diff --git a/CHANGELOG b/CHANGELOG index c661f95..3db8f5a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,14 @@ CHANGELOG +v 2.3 + - Fixes required to support Arduino 1.6.3 + (NOTE: Arduino 1.6.3 or higher is now required for RFduino 2.3 or above). + - Include explicit information about Java 6 (thanks gortok) + - fixing analogRead freeze problem + fixing indentation (thanks OrenLederman) + - Removing deprecated field in iOS framework and sample projects (thanks SensiBots) + - make these virtual (thanks tripzero) + - Remove dependence on UIKit; fix use of deprecated UUID attribute (thanks aeberbach) + v 2.2.4 - Reduce compile times with Arduino 1.6 on second and subsequent compiles. diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 9322c4a..7b85ee1 --- a/README.md +++ b/README.md @@ -8,19 +8,19 @@ * Get the [RFduino hardware](http://RFduino.com). -* Download [Arduino 1.5](http://arduino.cc/en/Main/Software). - * _If you're on OSX_: Remember to open Arduino _first_ to make gatekeeper perform its magic! +* Install the [FTDI drivers](http://www.ftdichip.com/Drivers/VCP.htm). + +* Download [Arduino 1.6.3](http://arduino.cc/en/Main/Software) on newer. * _Mac OS X_: Requires Java 6 to be installed. Available [here](https://support.apple.com/kb/DL1572?locale=en_US). -* Copy the Arduino library into the appropriate directory for your system. (Folder should be named ```RFduino```, not ```RFduino-master```): - ![location](docs.png) - * _Windows_: - * ```C:\arduino-1.5.4\hardware\arduino``` - * _OSX, Arduino 1.5.8_: - * ```/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino``` -* Install the [FTDI drivers](http://www.ftdichip.com/Drivers/VCP.htm). +* Open Arduino + * edit preferences, and add rfduino.com as the Server (HTTP) under Proxy Settings and save. + ![preferences](preferences.png) + * Open the Boards Manager under Tools->Board menu. + * Select the RFduino package at the end of the list, and click Install to install it. + * Your new board will no show up in the Tools->Board menu. -You're ready to go! +Select the board and port, and you're ready to go! Detailed instructions are available in our [Quick Start Guide](http://files.rfdigital.com/rfduino.quick.start.guide.pdf). @@ -46,10 +46,6 @@ The best way to communiate with us is on the [RFduino Forum](http://forum.RFduin ### A Lot More Coming! -We are working on documentation as fast as we can. Until then, the best source for documentation is the sketch examples. - -This project has been a huge success, and we have many exciting things planned that we want to share with the community. At the same time, we are unbelievable busy, with a ton going on and lots of small items to clean up. We are just a small team working on this project ... please bear with us! - We hope you enjoy creating stuff with your RFduino as much as we do! The RFduino team. diff --git a/boards.txt b/boards.txt index c75a1fe..55c95ac 100644 --- a/boards.txt +++ b/boards.txt @@ -1,5 +1,6 @@ RFduino.name=RFduino +RFduino.build.board=RFduino RFduino.build.mcu=cortex-m0 RFduino.build.f_cpu=16000000 RFduino.build.core=arduino diff --git a/platform.txt b/platform.txt index 7981d31..6c07965 100644 --- a/platform.txt +++ b/platform.txt @@ -3,7 +3,7 @@ # ------------------------- name=RFduino Boards -compiler.path={runtime.ide.path}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/ +compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/ compiler.c.cmd=arm-none-eabi-gcc compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -fno-builtin -MMD compiler.c.elf.cmd=arm-none-eabi-g++ @@ -51,6 +51,12 @@ recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build recipe.size.regex=^(?:\.text|\.ARM.exidx|\.relocate)\s+([0-9]+).* recipe.size.regex.data=^(?:\.relocate|\.bss)\s+([0-9]+).* +## prebuild hook +recipe.hooks.prebuild.0.pattern= + +## postbuild hook +recipe.hooks.postbuild.0.pattern= + # RFduino Uploader tools # ---------------------- @@ -58,5 +64,5 @@ tools.RFDLoader.cmd=RFDLoader tools.RFDLoader.cmd.windows=RFDLoader.exe tools.RFDLoader.upload.params.verbose= tools.RFDLoader.upload.params.quiet= -tools.RFDLoader.path={runtime.ide.path}/hardware/arduino/RFduino +tools.RFDLoader.path={runtime.tools.RFDLoader.path} tools.RFDLoader.upload.pattern="{path}/{cmd}" -q {serial.port} "{build.path}/{build.project_name}.hex" diff --git a/preferences.png b/preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..c2162b0fd7a1e62915bb76b443961767fe0a8586 GIT binary patch literal 83737 zcmce-byQr-(msqNxC9Aq!QCB#Cb+wk3GVI=0fM_jAQ0T$A-D{Z49*}y27h9{Qr=IGLP*IXbM(z?5H+mig={p+g zH=nR2P#E3c8}u|%PzIa5*Uk*Kfi+ddQe|ciMw!PqRaKcA2+l9*Ko#!waaftiy2`zw z?amgs+RSEKXr){$Et-1>{U_v7^Oofe%BJ|kI38Ja*{u;vS z9Ldg3^1v;2Rl&)^r89c}?fuvKF%#u&WtT{5cI#AK%G_&Rb1uIS3*AIK2oF$UZK+M5$N&<@r%l3vc2+=w?P5*eY?p%hp{q9CVk_l z6-`#7t7L`{IzEG(bcp%+1%nvebs##w7*e7btqkHvF~qJw#CKwW{w8qeo}UGn2Gk|5 zO;NOvy_Rq}mQg$3lL&@P*0C3Wb#%e->~3@xkEd4+JM9QR?I#B6^k5t(q(hck3Dofe z&n98>{IjEWx+LR(tT3#uwbZ@)8S~S%FLlJ=oPXPCzswZFCxCVN08bLgbo|1f0_jtJ zQh$(HVCY0rkWw971uU^R89hwJ|=*BMffSql4|QS&U(lv$`ct*%6GGGZe%#rVy7t;WrUpZcchJ|ayj_X zUP}(8n;38erPHIKCWY#TFT^qoXnfq|uuE@GhaIEe5=sr$9LoG?Sc7KEoEl{qG~S12 z5@#|AsQ&0vBRL<(PZAr()i1CP=j7C)v1GmEz9eoyTJ>@+hPXdw?Zi{FgJA`oJknx) z;9B_J{~r0C=AQKam47yc0MsY48So>8dvsxls zl02j5-*qUGP%6da%7jt#sZleeG$d$9l+hT{yru0-OGx;c;FPM%+?TXKp-$-{x79Wl zIA&2tx$tRUQi(!-SZMh5Cf+IhsSir%N3oM{{p$V6q{)n>#xyqA8;2UTO*}kSJPvtVU@AYgpcOi7m*bh6=E=~C8MPf$d$^yl%q=# zOp!`?opO*|kfP0)#$c>+Sp0??o+u<$2`nq5xL4?xQOq%ELuRqk>rstr%2r`aY#Yz?O}|n6B7#V2{GDCxB1)sAwf2nBq;}?!U@nhnz~jyh<_y3M z=fd$~W>GetX7@hn5H^^ z@0??M6Z>iC8w#oD=li{DSND+^QlXQxNK(p~z%fj$O0uuBPp~gPEcueUBGJj?&Et)E z5pk<@%W!*l4!#g2Bp~W1u;sC2C*alKFeTU`m?aS5%_s08Fe6MMUgjDk6e27pBe6l1%@tT!0t$mW27SK=n`3>f9m(%mk170O z)&a2xx&x22F12>FhAPN(ne-5K9qR1s{4GpA_SG@ew_3>8UNjpzfGzK4C#GXfJcbXu z-p=@cebBnox^uvY#gGWs3&)avJM?Y{KGsi3P6?m{&Z!bI$?43Q6XFvJaCdUVYR`7R z0nRM(j5jX2c?PY)O$3{uA}qTurQ1s{-7fDOMjVQ^Uin!1u)iIB`^9V5yY6kAPuDT$ zrQC(!+QlGvRR6c%#9dNc)TCZ6o^e0lcfQr;DdnGRqt(+#rQNZjbKQdh+}}k$xQWSA z@UrtedVC<44C(o(!66kw5;BX>_%bPkDp)=wH#Gedl4K@cFKP(hq3*S3!XxElewfOu zQKV&@Tk0`(W~TkQftCS46cA4ovl+t}XN62WMu$w5^n?Q>Yc{F>s2>O&x-FQ&Nf!f8RoY8TS|Tp8;$uEV?`VQHf=0* zoC+W3$jWl&apv2^ut%O(OQOr78`}f#wp|=!rjvV$y4u$-HwA#NeBB?%;mU*8gR8;1 zV24M`2a}PwB%wqP*F)ENFH3xT`~dAE`?%$lP?S)C&=4QI!&0_bqNc2|1#xy@S=pCmSm{E9DFi-DTJdcrb>q;IN42cKr6&#Xh2NRE&U|h^wgw zDp=`VAo^%j+c5gVr-8=U0XuI=ecLXgr!p4nZ!Ivh3%&rW!*{i3;&{Jt zpYsj!xaVRDt}bpax*lpr88c-zW&v60jpw}*Tsf}RHw&}nO<00c=h9l!5cSiVMcS}^ zAV%Qzrit<%?P}w*Zui3F@&}Mx^WHe0fqi!Oj%)o|YG36o#$BvS_rjBV)zsJe$EJ;g zLDuc6qQjTV_(z^gt-frqe={eB>r~vjq8p>`pK+%Dgy}Tds7qW zLOCMQ&d%IAL3KNVG&kF~8WyGtInbeZWF#UaDQPwK>$nI^9*xalxiWHiR}U@`sG`J- z)bI3{=mqAI07{Gm@a_Nx1~$h^L&sG|Q9;ne!HyMR>hRHw)zi)q3Ugs#ggphJuXbjx z018h#TYDEl&$pC+l@Nr!KmW`|N%2<^SDUw#I*KY3k`B&h6g;fltn8E`C=?VF!p^4V zf@<%i{!<Y?_7u(i_&KeRLZ?dvMVRfMsTV;3GFx-z_KLji zC6?7|tXKN5@TxCxdfru6dLG2iP1szmD)r-ax*P2)Y2f0%#CnbP;$54`)^az`8OdzL zg4cvdUj|qA1)zRc_hQ-S(rB`bNP4mjoXY<&OUih(a8GlQKF)lNE&p{C{yy;^sl-&VN-##n-AW3MBvlQCrpxnJ z%JUUgvj)Zf9Tr7U{+k*`+z3rob0xkCLAU<${3=aVDJ8z>2-$z+4}4*b7F4FfT9zN3 z?V#iK``dPT?9C|Oc2+OipR&qO1d4SfNBcsEe?*)1gf2NvN-v)#6k|_Xtmq-w{n_X4 zdy3pqF_F^==`RASwGs!G#hTR;K)P+>!T)J6GFD74QsOHlX)#8wTs>DS6jY+j>b053 ztB+8gKW4i(>iVyCsHh`X2(P8^N z-@i*1FXn_Ztcg5K>&I)g-yUz{EmU2x9QtEtq7g$DM3?Y#`rE1QDiYmV8RJ|jLgybn zQ6X29#d?FBlZNRMF4}imi>`oN?(=1bB-?8KOAS`QR>zI4qoRV`Kh`*J>(y}66gi*a zqO-pTtv#W?l?#e~3hALOFgA&mh46b!l6GQNyt}{bXc6Tm9ey7gXNxt^KxMykcOB6L5hE9g%}(~{I@A`nk*Y%(Cu&1Xhv;_T77xj zMvk4A>Q3)^eT@1rU`KPXDQOgJwL|+~{e~(!JqDbt(52I6pJ`nT{6S3vz=I0x3h=re z)P(AMR$V^m(*WYY%TRa~9fNF7<6%gUs#kcS8OfjW0T1){D;x#qb_}+{5G$kK7Kl0s#K~JDOmZ4K=SuI~k|G_(A2_3HfCw zh{hM*e+7&eyLj`ext@%A8=nj>tR?Xj)xI-1J&SiV&b2Cf>-B33AWe$f6vFM6LsCA0RPvU-^_F) zTr#t4OX#R)HYB*I2r)!F*1RA4KTEc`?ag+3oo!{!RT;L&^aUCHVI*L&OYmOE$;lOs zXK-1Ze?rDtA?A1dg%gFxlDVx(GKz|ePoQsAvuvN8D@xDIOyX4K1a#ZLxoLFCrC0sr zxFj61dEdLt4kq8^*5c{ahnxz8i;%yT;9N~8HUAA@V^^p2dhN0JaxKM zeaIk*PPxmXyt1inLfydJhvviO``7rmmLA?AOI0NI>`lJ9G7C@QYfWfNPLL(nE`Qhk zDefjXtW<~iY+{UVQu8}IzEL#+bZIb=Hy1Nvb>pla9jk8LyHqw~rO=n(EdMl{Wh}60 z-wTYR9$9W%e;;|rSp7Eq{bX%Sa4_{)+cx6>Y;ij7E3wURfI$0Wq8T;#tHZ~(uCEI( z2P<`;{gG`oZ`>~-^(or?Xm#0slu!HEN{;@AUceyZ;=`W1{9L`zyZGe6a>}|44t``e z7iy@k;36kFe4oLO9=8#W7M&xl`}yg~339Kl|J90-MXM=DDRc{^Wewmjq_k{JW!&N< zZdJO?f(c&IzuFeC`g062dDlpJ-FuBFh{`((s6;!A%)iOYgRwWI1cfFh0H-G=U4BKmVt;z3qPXPOF8+UW>p1eYjsF`kWgL{zTaG`VecL+jj=8RPYz-Y*(hajn)zz@$OVwF z0gZf(^zH>!Gr8?48;L&3=6Mw3v8BF5#UI{xYnSQtLy)h$XqPrKTbDQYV*}D*q~QSv zWs+#o3*GxTL-S2f)O2e;)Q(j(XG|YBmrNV^73kcs=+uZ6DdkvSZg8LP7NMZvW(*jS z))JQ6ft!qU6+c3x-(XV&QBu{|mPHdhCMsNILRcJF`Or;cCbC9iADZG*34G+OQ}0=h z-d=SGpPdj0T(9e!-d%bYg8qgqxQs!U2jGH&+h&h7`8*Wq_!#pRCwGD+c1HEB^8KqM zRoyxFGv^J-2dnXhPk8I^%ha%Fw?|8i?Y?O?FZu&M0}WK=``G*HdewCnm2M<=s}>gJ zcTbq5^~z;UtacgT&^ud7zbNDckdq2*1QVuWD+8?bw-HO5Z+BP9dQ+~7-3!7%6|z)T z{8xw>yCc&pzov%?@#$$*barRTEt0Xvh<3)Xa0$kmO4O#lN`^;Ez_ULu9nYulr!=Qv zd=pctTyapd3zhC6dJ{_~uiWER@5AZge8^_lRCCfGvg+8~1&%V{M*mXalzOL0k2JzN zjdtwI`roU+gEM>{0IZjy!v$2u{4QZ1{%(28nG4l?(|dJVq;X9vahiG_fEACDUGmpM zes?J;p=D@N*?)_#a|Qjk7x1#naTBC#!Z3q5~vo`$WYr& z@vE~K&+91S;O>apZ}E479Qi^CM5Xm{L6y_aiF^l_Q&mlEJttnb{fn-89{Lxd18oMo zRpZ;MrSG4>M<6qxTt^UYh1l?NGV|H!C4yPq2+O$l<_h-KU--E^Tde4bSQSSbQ0r6X zo^8xaF9~^A@9TAzwVCY-HTxo!4cBny+-KW;Fw0GZHx#C@RVUhznPHa}dztF!CEtq{ zumpG1*9}Tu<*Sy2$yoSeyYv06megH~oQ1Dd>Zc4sJZipezU1v4mJLp0b7iNVx>{%% ztKtV=XI(;WhZSM2to#ENeVQ6>G(fsrkZrkEC3hs$cZn&!`PB)3oT}SoT6!g-BY-#4 zbr)vzo4)j5K>1&fXX73lyrC>c61+!8V3e ze6c!Ot*(Hk0?2jy5n95diN@&t0;Ws~~O%8C+V6nWjI zLUY~uu?#Mz@j(LEN2s4yS$ffNB_nzCpw?#F>V=qohMhK^;2?7Q-N&PW697ydkB`f3 zGZaZxH0ypNBnzYw9a&CWp%uLlP?>10i5knjj#zS8odjjW=73+ecJG z_|l3RY*^buVj#W&3}rn6m8h^<2(z9v?!5jDit|Bb|CKNt}KlxfQ%I(m3lINxUzoAlpNM0I1b@DfL}l z$8l-Mh0mCNQb2Rhqkj!l>tCwC0Z-q#xlfFd*4R<_QC);^YdqbS$>Ol7wV`4oM-Nn= zOLE+IcY5A#QaH(>54&N39sBG;l4L(AZH$v%GHUSY8boxzOC7AE224h8FPnbRpcb$zVXOhZD`so zFT3Wb3A7|X=X7USxF^py;=qMJ>@82{i4v7IXN4#iH(>@Z=40$v)IfF-SE19U!CtV zkq;MY@SU1Si0Z5u8}Sjj5;l%9FK4&8VWH`XDfFv4@ur!`w-Q5LqhWlyh?!v9eg*ju z1oRhKC$;zTuW54t4CUl?m1h1}uj^EAtcad*`1^O?^_|=1eJ1zMkLnAR!^7%aLyI*% zivabhpbn?EXGZiahSY_IZSv*bG+)T83vX90B9?q*Z`2qEewJ&bdcgtT96?%_T;>=u z7}V)LATK($9s}1Ht@a7Iwq!?kjSQ^t7e3^e7gf+et?_!Nz`3q(0~gcgOm~pBRt^Z8LB74#_DAi>=#}n9W8u~1mpTnjmIgAL%Vq6Y{b>UuuVY@X z(vGDZOaVpry_zB`m(a2we{mxN(%<(iQ!hk-cI}~6&cXbAW0RNyn^F98*P(Zz1G3wr z8mAWJ4H~2LQ83)2Jbzn}F%0d1a|K{g)^ISNbh>&k)MBjroz!u(&T>kVr`b1$+Zp6n_$*)zndF z`T~L@9F~G;x4sB_UU?t5m3G+fm1)~?Ezrl9NTI`voDcgiRaoM_`JIjt zv%2)3$6btW#MS1e7@|)IJF5QdVk7t6o8hui-_*-*IUVv-_^5$o2fb)m(8mq(NrO_c0;1Zc0Kp=WD26^ zV1(WoZgEOOU#Mx(_M$w-(Jg!-lZ^K?%r+&r+nYl!GMA_@k4jOR(Fz4n-(y6`Bp}TT z)dDzKAT`X=7dGM$#XXsF+NkH6>bICOS}@neh*LD4>Q!GnY{6#4))y9&P`L6dUONWG zO}z6JQn~$}J?D29VZSMPGb;?)6*2LYhnE7>klRsoYrCAIaDWbe8J z8#JPZLz8-H|mT5TLPCArb+L;%*F$!$IYp6IHR)rr_Q6?PzYpLKbc!MGbU zFlK3;AR?eUT@Hf_dDr{HuFDYT9Wv)>uXb4%mN3Gg)2I91SFdsHi^msYBofp4PyIRF({uIv?rnv}-1@5V7r)vs zar^e^$B~Qr<5E(Ni*kLND5?H->0weh>yQ-fxwH7Ct}cR)3RIsqOf(XU&1%SPxcj*A zPz9{0?o{WeOMSiC5Y>Fy9?ooB&^&GZiM%e_A=RtfERZlI6cwKc@{-|e2e9nV)Q$=#q; z|DLYw#TB)Bem4a@w$UW0D;9f${d=X;N4eT)suSo_n)dKJ%%c1w9JsS1PvPI8VHTLB z-P}LLQJJWfVgJfig#6$?tx||z#R%7b@NXin_Sc`q0MfH;4947*Idc(6{6TMs!3{`$ z2tnsPmRj&j!PC_Gq2pG55LUX{Xa|v4wwA=B9W|!aJPF`a9MA!#U7oUQQdUqh@;~Ef z4XmFE)78AaGY2*%m6ZP{_!fX|X4~h*&-pk!FC{ceRK-bDRrfg#r|7ii0W^OSv1G-> zV!wt$L2s~ONPJ3EWPg1jK@fclZ^y`DmUk`sM<6ezisN|K=O3dv0AJTs+h@pUinX=q z?%l$(g04J}>rgmQ^$m3>Hbj2|YK$&yh*BczY}Bn(O&k7XawF3NSEcUrw#q&Rd$#9R zjw1KY*a0b*cx8z39DrM!O6pd%#QR#KvFgn>R54+t;K{g}`MGbhN%7i)DiI@jd4K8L ze?tGfOzh*E1Cizcl4i3qSIchjWxM?_g@Ro&pna`bQ74-Pe+Sy06RIT529f@(JJs8J zS=JfOn9hSH@L(l8xkD4-W zOQdKUFkm+O?N#+=3w!Ivn26!BDeOY!R?ue zIfW=*S|x~`Zi}5L$R^#!X2rf`Pg~%BXgO+?iWf^F?DtKz7E1e$ZZ^XAnOc3nw3|l} z7i6JExCEC>+v;be_ULz1q^J;Il@3z-b{_QJ^HbC*ey}?au>FjIPAA~YAGmsFt{N%Q5S#6vic6XxU6%%3{(>61EY5yFSrC zT^eXuauAz^2(lD(12=7%gx|Dkf;Ik^gnSpMur` zpxDL_<44yfoC{M}QP5;y@kg&&dqd`b7m0Ef)jZWV{+1>0-Jj_lmHij{x_IXy00ZL4 z@UR7Ys{IFi+@cei^3kX;&4?VEVk6=lJF`AeyVJ4F^KSnD=3@c3{Ym#egARPSMf~Tr zM+v`uDhp(cmd&Nw7UQii9DMZpLr%duc zGZawAF9l~$uJd47-qz?);or@l7Q<5RloRPTyNiHhj~n zJ&lGDV|&qqZUQDEH%%-2_4GGW@t^-yI$i|d_PX=yVTwlEl`H5fz&;vl%0;2S=eX|q z$=+zFE3`CO323VH`tc{7PZ9Ky=EGHhA>U#Jpb3nDirT#KD@7d^PPRhiZGRdYnLGmI{vG^sw8d)sd0E9JZYKyOP+8q7f_V%Z z$r`5j0996Fwvk7v&#pTQab1lIn8uctn3yDcI}85b?}%@$M%`$PLF z5}~@U*-U$SMuoA)-c(sfq(xhM`jmH^g6-vKR^DJ~;#``T6As-pu3t-5Q?$Et?Y8m3 zF%wr{hi(>p1IM5xcd*^*$q=~(2!l*m$G+oaFj_P>wxlk9-KA0=be}Z3ttTquz?Dr_qBZ(LJC#gkKQ};wFURr8*!Yr^EHuhy0=9N8I;{mk3OlT84AeP zPQJH0#gHjwQBABr?2<|n(!8IsTRX3(WqMuhgX3Msw>5vSP2AMDRVycAvpYKvm4P<} z&eoE%7|jnvhZd5owKtG7<1uF7)oK8n-C~1mwg_|2f<-P%j*v%cc~u*uLbMasi+lc} zLLDjGam#;ccX|yt{|5ly*kjD={ssRQEQEqJv#!ynyFyI{A*DX&x^m|t8m0HI6Ir6z zg$y3t(^)V*NC^292UlwVk_;>?JdyIW?B6*&4hj-a!zz>_~3 zCOnGtG3xkiLWnJiob=xfsPg^A`gy>EDfgHiQ7`J?=Cg+++H4Y^=R~?XLkxW*{JReL z8DhWM)tT)yNa(z1RXoB_oK5+3e-`J^Rw$n~iX~0*X1UER$?tN3j>=`fc1RAI#29;w z+=vrh*^d&ZUQ+p3bF|SoXO#5#aF@j`P43sAJL|ev**w}GfdlEfI|OdN9O{E|8!De_ z?vc4fPN4cv;Lc~6>v5UJx^Z_R1481-1k%EvI0@x{0hM|oip@E>3+PG z_rBb>y6jiT6*0`@wxUEQ;%2wfYqU07VhkAL7#e16->1CTo8zme%p~83;s+(D;DS90 z$fjL4Tf{!cM>{Zuswc;bC8~ia86$KT80J`Z!DK{G9 z^O~%E<4HCBHNaO(F3Jm@8!_m`c1;VkTvO{qKPx3Q78uC~-Jz+U)0_)X!yn)&FA%B4 z?*q7c1`S10c>TjP>sjTwP0J#YF^xNsk6vA6OOd)hG0CQMi*dHGj*1Zx8IX+MG0(RB zpvk!xnJyh7EBbJrq$(VLz3j1?Qr&es%6w9$UaUkbx@;P7chD?@i)M~$ zP;lyZd+t=g`N(S6X1b(eo%e1YAu>KQl|_Fv)27Nw@LJ{LhoY8vPY_@D5fLe(y|W6EQ-- zECR5jrWtUuK5%-ooojKrU{#zG%^3m#K$p{o)2pWKhBu%zBZA240sh(ugmsCPspfrSh_A)o%abX{|*NAis z4^XO&jic$F*g-G~l^v(Ns*Kn3bK9y$|RTB^&)=!1Wn`31;6w=71?1z_8?2A6#bw9Ek{2$3xQXMuEDB`~iG>N;8%uH#PMggmgN--x{}Sm#PPC-Jvy+;~`0y(z#Dx0~~O7Z0mX z@*yw;W}0GYt7OeuI;GMXz?-Z};-UBlFq-)kxQuzZM|Z~~2{9n9Bic%7D*$ zAIE7j3dF^=hu0t!Vg|*GAJ5YT$FeEic>n$yzWK%HFhMCtP*X;~T#Kc3BUWgP440l& z1?59c0-2AY_xW$YWrLXP^(ELrk;MP$Wj9A~()X2sCqEnnFM1-O!9$BmOue)>AxgU@TPx}V_2t;GuZ=6P(AP-9=V4gXH4g3N2KU@zt)b$vB+6lca ziw;|OYycN{6(>4mkKLQ@*RVGa_P8%YQQc_Ltzq*mK-zHL0FH1Ty|X;VBXhd`OV0d< zBKWLUVm|xq3x`H#X!49582pyDswcu|ej|9IF;lnRoG{>QYn+E3^o7si%R-4!wb9!Q zUc1avCS0_+Um7g?oyem?j4R`8rJ{^ac}-NLslS78bb5b%DLL6Far$d*{xk(`*vAOp zuda4Q#@q3H@M9BLYHeHkSoisUdbZ3QZO^jLv+sH=?}nonoI+8k;0aM`Ez^}fmnva+ zZZs+0)-3f-YQiSHP1>Pn9G)5*O!~m+JV9;r_#nit5@;UDPiG7@$8URK3 zpt|994J+06{TEQXqeB1dvYuxwYGSwq4o;t~A8dco7xt6;zy19jnG6pCVVN%RgB{uv zj2>zZHP;ffo7OgY+o!rR_{ss6!hM&+bOA@G}&4oYC_Y!u=XK_ z0ZUSpIXSbJ;5DbSfs+~QH=U9V-xo-&AaTz#s=AAPdDlQAVVZ!ol{X5&}W z!|>z{9W=UuWpdoVdREMOc_3co02_}LGnU>CctOJ|-? z{qU#D!_&5js^YO1ov#+H;B4a{^LMjArH&Dn09K(CzI=TQZ>~MYwu0{Rpt`e>Y_q+# zS7qGYb<_Ep1YhBwy<20AT%l7d(e-${m(2(pYPQtk1o|q8*yE7Bb~RzCh5a2XeT}) z{}ZRHz4?(R4&T!(fPV&sVX~87-nxwBOMNqR=)BmR(KfEcvSUeO0co}@zwl^dN|ntWI=R*aBWn zerf89{l}VvCgLRSB_(~xp+uHd1UyV&Ihu17+aN!BJ{mGEC2X`Qt8teBG-a&)dB!9M z+MG3ekU{r&>%=t7gFIU&^;EHP8uW}wW@mMleOu|KUbRF=p;ZlIzxzzQVCY2}mNt7m zz0=`PnU-Gghc-9NB-BV$6pyoskte8!9$6oVG6S+SbKeMGOsj)BeLU)GmAM`tu2vyQ z$|4CN7=kh(WlQdRx{%kO>3>w_`lH2H0Q$l}tu7XS;Zn_VEi8eV4$HJ0?C%l$)g7mi z`%s9ddobetc(Vgsua{4cSEBV&9nx`RU!9|=pA&=<6oC&!t**mRj9`8C zFl7E%KOra&Ju^eS8t~M)fT)jjAYXtnQ1Yp;r||n3((V(&v)V)zeD6;IqUKBJkl{fu z_qZl!lUCa|9{6In7Ce5aZrf!HQp?}!MP*B#GxAaF9F!_Py+50*ex)@-*8Bwk*+3c| zNumpn_(rxpdjtg-3D8K%P~>i(D~R&*1Xrw42h@S6v9-VA91Cp)DuLm(hDbfKm;A1l ziITPNpn+5xrszF;wHdq1^FDx844iGVaS#*%&{k!S7Te>0oQAYtx%5+X_!(%Tm{)5k?6uvJ;LzrvDZ3Zu)u?yt1|+m!`LHDFuZz z@RPs*`)BoRSd!)vq{$eXm)*0neNRU~ZEiLhJT|Gn(#<}Zz+gB_le#7UvIKmCF3p44 z_3>JUceeL#=`)ZpyC--hc>EnchMbAdebvt+iH&#EM9Xk5E@|fYj)&eQNs%`J>Q4D^ ziaDL^AbmrXi`X*dqS;y^0wK)Qh3|=R@G&;mN3B;%7s>t36KtVC7t~-i_3p+W8X-#k zv|6Yutbpo;xnhNRU>cE;#%C~;y4>u%TA893SpQ5lCV$+Iqs)EcvOSSf)4~1K_-zOX z5C+dC;ObdRf(nfK5WMSl{!6K?l&T)%aBrTHwW%@P!8Fr<^JoDEaO4MSC?z^IS7 z{x!a_Z><23T-xOEd`g)XJvk_bcTuK>T24_%UsZZDR2OUMOvLYY7+MUFh`@o_Cap)d zPvOpg@RFRi0h24pq3fn7XY5Khlfxv;N|e{=W5gU3O&YyXBr)<>@v@**)X94D$p^>% zh?DTA_%kH*qR5jAcb`aFEWtJ(;b?areiNR4G&v!3WSjh^!{ek<&*z{K5`ro6DqAe_ zYB`xfee+_@n2(8*g3EOH71e5?Jbq82!8EM=#7W;Ql~go)Js(nEBs~2aM`OpHmvvzK z_Kdn!&kgi?62-k(PAy|UH$qYWj=btXGaI6`nDLBMVPVg5ULdvKw&vo{WuL}pxu{t# z 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 UQ^}tVd;(qp{vm#iz6VeI4^RkK&Hw-a literal 0 HcmV?d00001 diff --git a/source/libRFduinoGZLL/build.bat b/source/libRFduinoGZLL/build.bat index 827611b..c36fd6a 100644 --- a/source/libRFduinoGZLL/build.bat +++ b/source/libRFduinoGZLL/build.bat @@ -1,6 +1,5 @@ @echo off -set arduino=C:\arduino-1.5.8 set nordic="C:\Nordic Semiconductor\nRF51 SDK_v4.2.0.25053\Nordic\nrf51822" if not exist %nordic% ( @@ -8,16 +7,20 @@ echo Error: The Nordic SDK is required to build libRFduinoGZLL. goto end ) -cd %arduino%\hardware\arduino\RFduino\source\libRFduinoGZLL - if not exist _build\nul mkdir _build if exist _build\* del /q _build\* -set tools=%arduino%\hardware\tools\gcc-arm-none-eabi-4.8.3-2014q1 -set RFduino=%arduino%\hardware\arduino\RFduino +set package=%appdata%\Arduino15\packages\RFduino + +set base=%package%\hardware\RFduino +dir /b %base% >%temp%\ver.txt +set /p ver= <%temp%\ver.txt +set base=%base%\%ver% + +set toolchain=%package%\tools\arm-none-eabi-gcc\4.8.3-2014q1 -set gcc=%tools%\bin\arm-none-eabi-gcc -set ar=%tools%\bin\arm-none-eabi-ar +set gcc=%toolchain%\bin\arm-none-eabi-gcc +set ar=%toolchain%\bin\arm-none-eabi-ar set includes=-I%nordic%\Include set includes=%includes% -I%nordic%\Include\gzll @@ -51,8 +54,8 @@ set objs=%objs% _build\nrf_state_machine.o for %%f in (%objs%) do %ar% rcs _build/libRFduinoGZLL.a %%f echo copying libray and header to variants... -copy _build\libRFduinoGZLL.a %RFduino%\variants\RFduino\libRFduinoGZLL.a -copy libRFduinoGZLL.h %RFduino%\variants\RFduino\libRFduinoGZLL.h +copy _build\libRFduinoGZLL.a %base%\variants\RFduino\libRFduinoGZLL.a +copy libRFduinoGZLL.h %base%\variants\RFduino\libRFduinoGZLL.h :end pause diff --git a/system/RFduino/source/build.bat b/system/RFduino/source/build.bat index 4faeae9..e4b72f3 100644 --- a/system/RFduino/source/build.bat +++ b/system/RFduino/source/build.bat @@ -1,18 +1,20 @@ @echo off -set arduino=C:\arduino-1.5.7 - -cd %arduino%\hardware\arduino\RFduino\system\RFduino\source - if not exist _build\nul mkdir _build if exist _build\* del /q _build\* -set tools=%arduino%\hardware\tools\gcc-arm-none-eabi-4.8.3-2014q1 -set RFduino=%arduino%\hardware\arduino\RFduino +set package=%appdata%\Arduino15\packages\RFduino + +set base=%package%\hardware\RFduino +dir /b %base% >%temp%\ver.txt +set /p ver= <%temp%\ver.txt +set base=%base%\%ver% + +set toolchain=%package%\tools\arm-none-eabi-gcc\4.8.3-2014q1 -set gcc=%tools%\bin\arm-none-eabi-gcc -set ar=%tools%\bin\arm-none-eabi-ar -set nm=%tools%\bin\arm-none-eabi-nm +set gcc=%toolchain%\bin\arm-none-eabi-gcc +set ar=%toolchain%\bin\arm-none-eabi-ar +set nm=%toolchain%\bin\arm-none-eabi-nm set includes=-I../include set includes=%includes% -I../../CMSIS/CMSIS/Include @@ -39,8 +41,8 @@ for %%f in (%objs%) do %ar% rcs _build\%output% %%f %nm% _build\%output% >_build\%output%.txt echo copying libray and txt to variants... -copy _build\%output% %RFduino%\variants\RFduino\%output% -copy _build\%output%.txt %RFduino%\variants\RFduino\%output%.txt +copy _build\%output% %base%\variants\RFduino\%output% +copy _build\%output%.txt %base%\variants\RFduino\%output%.txt :end pause From e245092cc4ac5df55bcc4425206b251fea4e74d9 Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 14 Apr 2015 18:12:31 -0600 Subject: [PATCH 36/52] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 7b85ee1..94ba22e 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,4 @@ Detailed instructions are available in our [Quick Start Guide](http://files.rfdi The best way to communiate with us is on the [RFduino Forum](http://forum.RFduino.com). -### A Lot More Coming! - -We hope you enjoy creating stuff with your RFduino as much as we do! - The RFduino team. From b66af34005fac8250b22442bbc1f638d1419279c Mon Sep 17 00:00:00 2001 From: RFduino Date: Tue, 14 Apr 2015 18:13:32 -0600 Subject: [PATCH 37/52] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 94ba22e..7670feb 100644 --- a/README.md +++ b/README.md @@ -43,5 +43,3 @@ Detailed instructions are available in our [Quick Start Guide](http://files.rfdi # Communicating with us The best way to communiate with us is on the [RFduino Forum](http://forum.RFduino.com). - -The RFduino team. From af4a0fdd01c2cb6caa145ed360dbea3654ddbb2e Mon Sep 17 00:00:00 2001 From: RFduino Date: Wed, 15 Apr 2015 17:42:50 -0600 Subject: [PATCH 38/52] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7670feb..3f07e4b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ ![preferences](preferences.png) * Open the Boards Manager under Tools->Board menu. * Select the RFduino package at the end of the list, and click Install to install it. - * Your new board will no show up in the Tools->Board menu. + * Your new board will now show up in the Tools->Board menu. Select the board and port, and you're ready to go! From c5f88a7a37847802cb73a31a794aaebc763fa2e5 Mon Sep 17 00:00:00 2001 From: RFduino Date: Mon, 20 Apr 2015 22:43:20 -0600 Subject: [PATCH 39/52] Linux RFDLoader --- CHANGELOG | 9 + README.md | 21 + RFDLoader.exe | Bin 152788 -> 36878 bytes RFDLoader32_linux | Bin 0 -> 17964 bytes RFDLoader32_osx | Bin 0 -> 24844 bytes RFDLoader_linux | Bin 0 -> 18808 bytes RFDLoader_osx | Bin 0 -> 23292 bytes RFDLoader_pi | Bin 0 -> 22654 bytes iPhone Apps/rfduino/AppDelegate.h | 33 - iPhone Apps/rfduino/AppDelegate.m | 102 -- iPhone Apps/rfduino/CustomCellBackground.h | 36 - iPhone Apps/rfduino/CustomCellBackground.m | 81 -- iPhone Apps/rfduino/RFduino.h | 68 -- iPhone Apps/rfduino/RFduino.m | 205 ---- iPhone Apps/rfduino/RFduinoDelegate.h | 35 - iPhone Apps/rfduino/RFduinoManagerDelegate.h | 44 - iPhone Apps/rfduino/RfduinoManager.h | 56 -- iPhone Apps/rfduino/RfduinoManager.m | 347 ------- iPhone Apps/rfduino/ScanViewController.h | 39 - iPhone Apps/rfduino/ScanViewController.m | 328 ------- .../project.pbxproj | 469 ---------- .../contents.xcworkspacedata | 7 - .../UserInterfaceState.xcuserstate | Bin 12837 -> 0 bytes .../rfduinoBulkDataTransfer.xcscheme | 96 -- .../xcschemes/xcschememanagement.plist | 27 - .../AppViewController.h | 37 - .../AppViewController.m | 169 ---- .../AppIcon.appiconset/Contents.json | 53 -- .../LaunchImage.launchimage/Contents.json | 51 - .../en.lproj/InfoPlist.strings | 2 - .../rfduinoBulkDataTransfer/main.m | 18 - .../rfduinoBulkDataTransfer-Info.plist | 45 - .../rfduinoBulkDataTransfer-Prefix.pch | 16 - iPhone Apps/rfduinoColorWheel/icon-144.png | Bin 20800 -> 0 bytes iPhone Apps/rfduinoColorWheel/icon-72.png | Bin 9357 -> 0 bytes iPhone Apps/rfduinoColorWheel/icon.png | Bin 5378 -> 0 bytes iPhone Apps/rfduinoColorWheel/icon@2x.png | Bin 16875 -> 0 bytes .../project.pbxproj | 367 -------- .../contents.xcworkspacedata | 7 - .../rfduinoColorWheel/AppViewController.h | 66 -- .../rfduinoColorWheel/AppViewController.m | 317 ------- .../rfduinoColorWheel/AppViewController.xib | 717 -------------- .../rfduinoColorWheel/Default-568h@2x.png | Bin 18594 -> 0 bytes .../rfduinoColorWheel/Default.png | Bin 6540 -> 0 bytes .../rfduinoColorWheel/Default@2x.png | Bin 16107 -> 0 bytes .../rfduinoColorWheel/UIImage+Extras.h | 16 - .../rfduinoColorWheel/UIImage+Extras.m | 107 --- .../rfduinoColorWheel/colorWheel1.png | Bin 73771 -> 0 bytes .../en.lproj/InfoPlist.strings | 2 - .../rfduinoColorWheel/main.m | 18 - .../rfduinoColorWheel-Info.plist | 51 - .../rfduinoColorWheel-Prefix.pch | 14 - iPhone Apps/rfduinoLedButton/icon-144.png | Bin 22125 -> 0 bytes iPhone Apps/rfduinoLedButton/icon-72.png | Bin 8750 -> 0 bytes iPhone Apps/rfduinoLedButton/icon.png | Bin 3887 -> 0 bytes iPhone Apps/rfduinoLedButton/icon@2x.png | Bin 15505 -> 0 bytes .../project.pbxproj | 365 -------- .../contents.xcworkspacedata | 7 - .../rfduinoLedButton/AppViewController.h | 48 - .../rfduinoLedButton/AppViewController.m | 210 ----- .../rfduinoLedButton/AppViewController.xib | 467 ---------- .../rfduinoLedButton/Default-568h@2x.png | Bin 18594 -> 0 bytes .../rfduinoLedButton/Default.png | Bin 6540 -> 0 bytes .../rfduinoLedButton/Default@2x.png | Bin 16107 -> 0 bytes .../en.lproj/InfoPlist.strings | 2 - .../rfduinoLedButton/rfduinoLedButton/main.m | 18 - .../rfduinoLedButton/rfduinoLedButton/off.jpg | Bin 823 -> 0 bytes .../rfduinoLedButton/rfduinoLedButton/on.jpg | Bin 1256 -> 0 bytes .../rfduinoLedButton-Info.plist | 51 - .../rfduinoLedButton-Prefix.pch | 14 - iPhone Apps/rfduinoServo/icon-144.png | Bin 18282 -> 0 bytes iPhone Apps/rfduinoServo/icon-72.png | Bin 9101 -> 0 bytes iPhone Apps/rfduinoServo/icon.png | Bin 7312 -> 0 bytes iPhone Apps/rfduinoServo/icon@2x.png | Bin 14751 -> 0 bytes iPhone Apps/rfduinoServo/rfduinoServo.ipa | Bin 128528 -> 0 bytes .../rfduinoServo.xcodeproj/project.pbxproj | 365 -------- .../contents.xcworkspacedata | 7 - .../UserInterfaceState.xcuserstate | Bin 21843 -> 0 bytes .../WorkspaceSettings.xcsettings | 10 - .../xcschemes/rfduinoServo.xcscheme | 86 -- .../xcschemes/xcschememanagement.plist | 22 - .../rfduinoServo/AppViewController.h | 58 -- .../rfduinoServo/AppViewController.m | 332 ------- .../rfduinoServo/AppViewController.xib | 879 ------------------ .../rfduinoServo/Default-568h@2x.png | Bin 18594 -> 0 bytes .../rfduinoServo/rfduinoServo/Default.png | Bin 6540 -> 0 bytes .../rfduinoServo/rfduinoServo/Default@2x.png | Bin 16107 -> 0 bytes .../rfduinoServo/en.lproj/InfoPlist.strings | 2 - iPhone Apps/rfduinoServo/rfduinoServo/main.m | 18 - .../rfduinoServo/rfduinoServo-Info.plist | 59 -- .../rfduinoServo/rfduinoServo-Prefix.pch | 14 - .../rfduinoServo/rfduinoServo.ipa | Bin 64879 -> 0 bytes iPhone Apps/rfduinoTemperature/icon-72.png | Bin 6195 -> 0 bytes iPhone Apps/rfduinoTemperature/icon.png | Bin 4786 -> 0 bytes iPhone Apps/rfduinoTemperature/icon@2x.png | Bin 10484 -> 0 bytes .../project.pbxproj | 357 ------- .../contents.xcworkspacedata | 7 - .../rfduinoTemperature/AppViewController.h | 39 - .../rfduinoTemperature/AppViewController.m | 102 -- .../rfduinoTemperature/AppViewController.xib | 540 ----------- .../rfduinoTemperature/Default-568h@2x.png | Bin 18594 -> 0 bytes .../rfduinoTemperature/Default.png | Bin 6540 -> 0 bytes .../rfduinoTemperature/Default@2x.png | Bin 16107 -> 0 bytes .../en.lproj/InfoPlist.strings | 2 - .../rfduinoTemperature/main.m | 18 - .../rfduinoTemperature-Info.plist | 50 - .../rfduinoTemperature-Prefix.pch | 14 - .../rfduinoTemperature/thermometer.png | Bin 147540 -> 0 bytes platform.txt | 16 +- 109 files changed, 43 insertions(+), 8212 deletions(-) mode change 100755 => 100644 RFDLoader.exe create mode 100644 RFDLoader32_linux create mode 100644 RFDLoader32_osx create mode 100644 RFDLoader_linux create mode 100644 RFDLoader_osx create mode 100644 RFDLoader_pi delete mode 100755 iPhone Apps/rfduino/AppDelegate.h delete mode 100755 iPhone Apps/rfduino/AppDelegate.m delete mode 100755 iPhone Apps/rfduino/CustomCellBackground.h delete mode 100755 iPhone Apps/rfduino/CustomCellBackground.m delete mode 100644 iPhone Apps/rfduino/RFduino.h delete mode 100644 iPhone Apps/rfduino/RFduino.m delete mode 100755 iPhone Apps/rfduino/RFduinoDelegate.h delete mode 100755 iPhone Apps/rfduino/RFduinoManagerDelegate.h delete mode 100755 iPhone Apps/rfduino/RfduinoManager.h delete mode 100644 iPhone Apps/rfduino/RfduinoManager.m delete mode 100755 iPhone Apps/rfduino/ScanViewController.h delete mode 100755 iPhone Apps/rfduino/ScanViewController.m delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.pbxproj delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/rfduinoBulkDataTransfer.xcscheme delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.h delete mode 100644 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/AppIcon.appiconset/Contents.json delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/LaunchImage.launchimage/Contents.json delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/en.lproj/InfoPlist.strings delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/main.m delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Info.plist delete mode 100755 iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch delete mode 100755 iPhone Apps/rfduinoColorWheel/icon-144.png delete mode 100755 iPhone Apps/rfduinoColorWheel/icon-72.png delete mode 100755 iPhone Apps/rfduinoColorWheel/icon.png delete mode 100755 iPhone Apps/rfduinoColorWheel/icon@2x.png delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel.xcodeproj/project.pbxproj delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.h delete mode 100644 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.xib delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default-568h@2x.png delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default.png delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default@2x.png delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.h delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.m delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/colorWheel1.png delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/en.lproj/InfoPlist.strings delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/main.m delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Info.plist delete mode 100755 iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Prefix.pch delete mode 100755 iPhone Apps/rfduinoLedButton/icon-144.png delete mode 100755 iPhone Apps/rfduinoLedButton/icon-72.png delete mode 100755 iPhone Apps/rfduinoLedButton/icon.png delete mode 100755 iPhone Apps/rfduinoLedButton/icon@2x.png delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.pbxproj delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.h delete mode 100644 iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.xib delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default-568h@2x.png delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default.png delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default@2x.png delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/en.lproj/InfoPlist.strings delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/main.m delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/off.jpg delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/on.jpg delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/rfduinoLedButton-Info.plist delete mode 100755 iPhone Apps/rfduinoLedButton/rfduinoLedButton/rfduinoLedButton-Prefix.pch delete mode 100755 iPhone Apps/rfduinoServo/icon-144.png delete mode 100755 iPhone Apps/rfduinoServo/icon-72.png delete mode 100755 iPhone Apps/rfduinoServo/icon.png delete mode 100755 iPhone Apps/rfduinoServo/icon@2x.png delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.ipa delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.xcodeproj/project.pbxproj delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/WorkspaceSettings.xcsettings delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/rfduinoServo.xcscheme delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.h delete mode 100644 iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.m delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/AppViewController.xib delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/Default-568h@2x.png delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/Default.png delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/Default@2x.png delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/en.lproj/InfoPlist.strings delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/main.m delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/rfduinoServo-Info.plist delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/rfduinoServo-Prefix.pch delete mode 100755 iPhone Apps/rfduinoServo/rfduinoServo/rfduinoServo.ipa delete mode 100755 iPhone Apps/rfduinoTemperature/icon-72.png delete mode 100755 iPhone Apps/rfduinoTemperature/icon.png delete mode 100755 iPhone Apps/rfduinoTemperature/icon@2x.png delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature.xcodeproj/project.pbxproj delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.h delete mode 100644 iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.m delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/AppViewController.xib delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/Default-568h@2x.png delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/Default.png delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/Default@2x.png delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/en.lproj/InfoPlist.strings delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/main.m delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/rfduinoTemperature-Info.plist delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/rfduinoTemperature-Prefix.pch delete mode 100755 iPhone Apps/rfduinoTemperature/rfduinoTemperature/thermometer.png diff --git a/CHANGELOG b/CHANGELOG index 3db8f5a..179e5fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,14 @@ CHANGELOG +v 2.3.1 + - RFduino linux native support (test install on Ubuntu 14.04 32bit & 64bit, Fedora 21, + OpenSUSE 13.2) + - Created http://github.com/RFduino/RFduinoApps repository for separate installation + of projects/previews/demos. Separate installation should make finding them easier. + - Moved iPhone Apps folder to RFduinoApps repository. + - Added Raspberry PI folder to RFduinoApps to demonstrate Raspberry PI & RFduino + integration. + v 2.3 - Fixes required to support Arduino 1.6.3 (NOTE: Arduino 1.6.3 or higher is now required for RFduino 2.3 or above). diff --git a/README.md b/README.md index 3f07e4b..2e93beb 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,23 @@ Select the board and port, and you're ready to go! Detailed instructions are available in our [Quick Start Guide](http://files.rfdigital.com/rfduino.quick.start.guide.pdf). +## Linux + +``` +// FTDI drivers are not needed (they are built into the kernel) +wget http://downloads.arduino.cc/arduino-1.6.3-linux64.tar.xz +tar -xf arduino-1.6.3-linux64.tar.xz +``` + +Ubuntu: sudo apt-get install default-jre +Fedora: sudo yum install jre +OpenSUSE: sudo zypper install jre + +``` +// otherwise the com port open will fail with permission denied (you must logout/login for change to take effect) +sudo usermod -aG dialout +``` + ## Getting Started * Attach the USB shield @@ -40,6 +57,10 @@ Detailed instructions are available in our [Quick Start Guide](http://files.rfdi * Detailed instructions for the Temperature app are available [here](http://files.rfdigital.com/rfduino.temperature.guide.pdf). * Detailed instructions for the ColorWheel app are available [here](http://files.rfdigital.com/rfduino.rgb.colorwheel.guide.pdf). +## RFduinoApps + +Check out the [RFduinoApps](http://github/RFduino/RFduinoApps) repository for iPhone App source code & RFduino to Raspberry Pi integration projects. + # Communicating with us The best way to communiate with us is on the [RFduino Forum](http://forum.RFduino.com). diff --git a/RFDLoader.exe b/RFDLoader.exe old mode 100755 new mode 100644 index b22d8d3d418e890c03c53f23c057656237280e8d..1b764b53169b3b6f4c9f178414a2c09e5f035c66 GIT binary patch delta 7313 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 literal 152788 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

Bwe)_anqbnSBvbkAeP82WS?b=khz;@>Y9KKd3C* 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 diff --git a/RFDLoader32_linux b/RFDLoader32_linux new file mode 100644 index 0000000000000000000000000000000000000000..a998528c1d2436f6b835a35b074eb902a12ae489 GIT binary patch literal 17964 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 Dy)H!_ literal 0 HcmV?d00001 diff --git a/RFDLoader_linux b/RFDLoader_linux new file mode 100644 index 0000000000000000000000000000000000000000..220794983dc66c96b045d59d6924f70d50aad0ce GIT binary patch literal 18808 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 F{|%-y3(x=n literal 0 HcmV?d00001 diff --git a/RFDLoader_osx b/RFDLoader_osx new file mode 100644 index 0000000000000000000000000000000000000000..0caf0396ea62c93d72d28516cbc649736a1ea435 GIT binary patch literal 23292 zcmeHP4|G)3nSTR}LL|P_iq+k!4>6ihp$UZ+ii3$T_-KiZ2&-7>Bupk`G=GMf2@S5X znUb-2JjP~Q=;3s28~<#V({)|+qq}c3wNWXJmYV(j?!7aa zOhW8Ad-m*}J$WZ{@ArN8yWjWS?|%2*@4Yvf=RW$)$LDIAYo?~P%+NILe0&TL;w>&f znsy03CO$r2dFc(_+q@gTM(X%Wa*n5EW0X?>1wP+K@2wlhw~GEH<7t}0VT$I)=N#4S z^F;$qQH7w&me>9%3qv&Ptov}B?_UnJVNHIgP}%NtrE<-MRdQh2JvY$b2Z zKFage1ZqQpFqpFC^?X6fD_2e9E^A&sUntzL4R-lzaagGmclK$Vg888H% z2bxkP{6Jq&565sNK4-fMZq>A}PSPm$bGsy{?G5^2l=z9FUVE_Tny}v|}OZ|I1fuzyBmNIPT^6aEvle4`B$d zF<-zRH}8x@19gk9Uktwlw@Qguq2l;!Fh3=z3l+}!n!ctzFztb94@`St+5^)bnD)T5 z2c|vn-}S&9nrXdd?s{|Bw3}y}iN-wZqg_W`y>HAkUGJOL^Y6?uclFLTcdgJGPZM(X zT&`(WzZ0CVX{Xw8Z9?}h-Yjf+TEBdarV%$|L+zk+orBERv~$-j#;uM$$F#~uOsn~T z)%Y-U9kBX3HRo1{vE1dK*R+^tEy__`dK`~XG&A8jd4;BdXCYE(%i96lI&Durm{hMT zM6Zic^3wPAw!G(RIqA|5_F8>r>|;S}g|!s*9z>amWv5VeHwsejX~0gcp=n8Snh9^` zliE?2W<6^r<~;|CpXA+{_1rqE2S)EVt$#PI#`g6PZEphRZFAbu*X;Lp@-7KAZ&Fwf zsJch9HLcG(=<4&H#PFNjOuMn&$v3F0Ii<_;wmNe`Dn4x{Heq;cq1f`aICq0)xl4e> zJYPh~s}w^l#TZL5$Wo5-s2Tf+4SH&n=gCo?&rv4OU?y_&ILdqB1u@FQoT%a#Y|m?p zgliw=WV(L^B<6VzrEvegF-MkKJ?mm4<8=HjW(=PE8LIBTk~$s(>|Bx7!80AxdM2G2%AwsIwO~WEe0(|B+Mhjk5|CS#IZZ^u}u_X?c3R&64W6FQmFNw!0S$ZM}#z zC3npKv7t^1Y92wnJAkxc^N54kvYLmBPj|Jj?WmbZ)X*mDIj8ngYzCYfJ2wECR-%dx z{(Yi~y@46html6@n4Oc_=s22u32@BwHXb1m)#H3t>O?-PY5(YoEoaEKCH!n?#ppHX zHZ;VRF93*GkuAI9Y+vfS5?KJeDdpnpoQHZ?QGn^0v zpV*IumLuq)Ib~4l0XqgJR>^+=WQjk zTZ*ci8$P`IMZnG@f2O>9+B@pfTl3Ildq;9-poU$^^CX`CM~oVHS6y^g3wCfAWP4sI z5Vkx636}dMATiG`Q1Y7EmUl6uu;l=%?k|BGw)_mRW29`6?$9r9p{$JcI?*4uNE=Fo z4I6|F=AUH47HPwkwBb5w!&S85emqtbvp?P+jPFc;h#fi0A3wiZ_~S81u-tt>VxFf^ z@|xNo&to>>kNv2+ZvZ#^@k78)Udk5f4<-w^=nv->OvsTU@H&fN$`OOm0zl5Hbi;+| zh8#9<3T2N!e3a_(9w3Kn905Hpo{xw%ycI1+7!l5`k|(`?9bpRK{8L)c0Yah=kJ=-6 zQmQ#u5?V_LlcNHk!lXn#U1!2mk~zQJh7%Cg=KWYd*o;rv=!)m`R=5E^@eD(bey|Y> zchkpM$s2VsC2Hwp*&IM`vW&?5-h?Oh+XJUPI@p+)te8z4*)BD>T07%LPKO7y! zZje8UCT`pxI?qZE(D$G9my0FlEe(r z-=JvWwT*y~^^Dk!r<{?Il)_b@I-4^Trv29y9j9-e6g^&_CW#sP-lb%r@6EK1mkEj4 ztbn3^?=S>oR~TODJ*6iMz>WhB(_e;^chgAQtQ@q-qr^L$d=XxjQ@kK;B@guR@pTiW zgwq;p06Du5pkjmiIuc`2gB+49`K? z=Y3R54$R_299YC7WfAvi3CR=YVcYvKmQ3f00e$b$miJvPZ{VOkIx&?W{)`yeuTgbB z1{oOHTY#MhFy&%Uv?!&;>T_1k#$xb3WH%m&y-Q7|A1gEJ>4dI_Ry?b>(gj$a{|FiO zva4{)rTUuw0sY{{T)_zcKZL`?ir3OTxK}Vm#F$taUxoZ?%i95Y|7?}rzkA->a0TsG zLpWwVXU4c9$MW<=atMFMAsiCwbAuehYdGD-5Ms^uiw^NWqO#q4AyI##tYglA<=t;L z?|06HPPn?=j5W6l#@3A#V|&|ea~7+aX5PxO{TYrtW(}Ag$;xyK13tj0ODx-ms=H5+ za^D8*Y)%=GycAUD8l}oE+fTukl;2NLLZN9l&6bMuW|lo{`rmVY00F#NLu|L3)(xW7 zv`bI}_kSzTbd8v?K7<0MV$;KP;ac>t(HZjB*d=+Tu7NdHNnUavLIj@Rq{&>a&z+c$ zcPPnk$_A8Zh@gx$KP-^FXI~IcB9<}SpQ7r1nYt6X^Eli)E=Y$BXH}R5lNzzZ>rV_= zxfesDoqGYw-jlPe+&KV}@4JLyNO+;Y110pcqdtZH6;l6I)c*!}p}zyL^EPsQ6}FlB ze}^^1Kt^QUXU6(rjpm#L4fq~}!hJACe`3>~InP^VZB84S5e_YO8E!JYEpm=p`o(*^ zWQjCZ*!QP8YY)~EoV62G_q)(Tj?EXOWX-{dK|sA-EqRa zQ|Liz-T?~kVdp}m%+K+BqzAOF78JNmqOqnu?+S=B?F&q66CRTsssPb?oS8nFeu7*c zH&WQmWI^5r*R9UC*oKS-QNW_ z0`wA)oOMv6e13?QIxjMF>9rEK0NfmCj@um!>zfL?8zA~_^8!u#y$jXY<=O(u^bU@-L^YaB zzi84AKP5cnJc3!X;_J~bc8DeA=sy~J1T)c~yI=`C_bMWxo5utu>JUgy2YfCjN-CEJ z6g~Hp@SJnK&}0ftETyLO6iwpEJgF&6O+S&EzD`YF9MeRTdk1Ho7pKIwUfjad8K(U> z|)ikZQ0DKudTw*@DDP zYEj3v?e0e=W+%kiEf=emSOfcXv4re6VXV_0$iO^B^!=5%KcO3}{w{-6pEDoX6Qv=2J&noWrMJRh&AAf=T9AyR)kaco zm0m1v+@(j|KL@)2#nUyJUuXK~;*@`Io5BgtQLlwir~FQ0GVeosH#JnGEDo}?my0`$Y)(M3f7=scttAb{!g z9HhIIz}(!y&_u;@Nb<&5m8s_iUHrz2)hF-poWtlXxl`?`;ZV9EBR@wQ9##*>n$JL$ zrtjf&5@G1=p?W+=^A07K05TCbun~7dXY7q_*ILKT1(*skni73qUrEbpm;C&Pt3*He zlC^2b_734TCw-;tK}LBa^dM2*O_LIy>w)3v6bL&dp;Qn?K&X)fLl91Za0>|OC!A+_ zewy&Si-ig1g|fGnmVb%pt-LAh!ShLswY5htJd}qS)C(WyQ$M}%?}xEB=!JhXD5@VF z7uCKVQ6)M>74JZW^LIb0^;V)?RPi=JOmJ&4t$j_RdOUImV?SwL@L}2@r zUCRabxH7LuV25ZW#!~=ny&dPUFgd)LSr3oHov)nB=_)&p$EbM9YOs?P&f}XP)U*4q zpT$t_pMl!|1WPlP=d;*WA;o!9boAWHm5u&Zyav=xtg1u>n|GlZk17c+MpFi=7eXjiXQ+a`82KnJ)Qy~U{+(ffd5+}sy!z2sMPDNhruhK zi6G@**dyh5522c|fAjn_6Yl4kc_LpC$7ZuQY4z5HGze!$>P&}W!0{C6pW$6`nx)RJ z0WRg#E2(k$f|9>|GWqgQz}X~^WE{)lz~?~;xM{YNfUN?-U2+VtNNXlMKP*ybP``Hw zO95HO&`R$aJ;86snttz)IOy$JxM9ePeY6M+dVD(vlF_ug+|{<}9h{x-INiwZJZw)r z26zdUyOQFbhV4IOdv!+p6QZ391#@vH_8k3i<2#s-*YN<+^1dlzEcpPMTRgTnvg6$3 zz1oLi0Pn?WH>oN9q_S^wTcpj=O?_km=IzKzEbMLs$pPJZtuju@$c(4Lx z?_=v28}ZU!i0AWB%X>l^2o)-!_YTQrf zL&eDT_!^2zc(^~Jm5*nD-OO#!`zi>wB-9AP2@vj*gd*OgdtU@02!iE3-r~`@E$Xc} z$f4ld0*T)!rC%qduabSY31PoLU)~QwU6mkkLOv@AwSs`RV9t3UsFzkf&QVBnHoq>` zD+#v=5X0r-lv=w-^8wZ-G8F! zX0gdZQH~|&yn`pEPW4F?4-g$X&DWHeq4F(HkLG^^f=2TzM7dRzRidmGWsNBB5M`|> z>qQw7WmuF^QSK0BlPK>J<=vvZN0cq1{I)3R&C&dOMcF3G-J)a?IGTT-DBDH(JyGrz zGLcA?WK1PVSfAVL9zD1~m5FZAJyNj9!2<;*59|(P$&>=!ignmw_o)C}1 zB;O_1{3oH?2%RFtyYZSCh==4_LZ2dZEg^%@5<-lpBy*#hYYAOOXdR&o32i2nL#U3B zM(A!rr?IYT_7EB(^dmxizgzPNp%aAoWWxrCIJ(#{)hQ1O8~B>Kf6|7};w0E4S7L41Ys?y=theuLAEk z17V{w6sipds;<)-E5lJA1xu*0KG?L_9|~zI+9BV@MVL5k*K12mCv ze$kSqYYhAgih#86RxNYj!J0smQ5~!eXoP&V4V6^_66OZ$wQ!)a3M#dF{*MSXZf&go zdeIimUlZ`(8ELFD>VlEF%Ba7_Xs9=8gY^L;zv|1>=8<~Sb_iUXZv+~uA=JNU)sDJK z<8y`p{aYy+gfTTs#=xaob!9CaL{q3iV*wl3=jtzCEzw#`;v!>-B;Fn#M=e&=`m419 z@?B*VH5C;XateyHreb52sF%pP-niEAZ`E?N1>>$9%`l9cH?3anz4>Niehy3u)-IOU zOxvyg#T@sc;R0!b_Bw~>YWB92dXfx$|_7kB!U@S zj=B71I2eVW#k|rfa$*;1mEmoTb%FY*adp1`YJ;)eSYH(gN1_c4Ra$-|vpq7QeZ$%{ z>oNI=;vL0{m*r@y8$vtfIwy2vmU@*;ya0Z2B_zQ!>B4X!{o9>x-&cgo0a)Yq{W78P|%SWB9G2gBNW#JjV9M zU?3{6YGBosk*HCCV3#f_6b+#uTEdl)&{l-~P9qe=O@jQNna>iym09y#;s1^-Ma|D| zm}uc5j4TTOCo@C4P@F!Rs{}YMY!Mo0@|tYZTvYG=$eAe6=8Vye#ECAebiS+Y55RE0V8#3cjb%R<8K2 zn1b(3wB4%szA^>hT#UO#@%>nM2h5X;WIRGP2va6XP)9)uh=H@7w2=i;`2_y$N8*K ze3wtbC+1V}-97~$=d)e$)lI?2`8=Wc9-4xW^I0)CDz3BH_euUQQT>@zh-(tR(*Glh zZxzzov+)W4Gd05XQ!a8|lgOk0_w&U&u1di)IUoH$sQ9j&f{*@p6yNSC_~`#~q{6&- zLnE$9?4$qN6yNeG_~`$RKY@?ysY~%~m_i=c)3D+*rr>)Ke2(J7b6t5&GLAFg8&rJN zXW{##_{e)l`fDn?86T$ND>{oF&L88WT=6{!+r%}A-HeYDLsIXYDdLFn(eqo$w^2%) zG~O5=BZ}{n)@RYMly}Dz_Ax%1-jjUypM@`F4r{Uumde^u^{}c(RGrB`6>JnrIVGyD zQ1$UINczjFepA)&s(M7#GnPuexvIWM)rP7Us(PuaSE<@m^#)bnuIg%4hg5x+s#{fk zpQ`t(`axAcqUwXH?ostIRllg}*HrDO`h8WOQS~{?vPves*hQpTzI#Jkk3{RE!kz(v;dNYul8*~a zyw3x6LSW%QfK7u$f(?Gz%^_A7sPl(*vT<0UFq7yA(Ug>y89+k#xxZ*N+uDfoWe$;c zg``JIT)v6Cvbbnj5qUZ!EsFPXL=Px*hr&ArUO%RwOAw-AyZ|GA57DR}Bdm<#)gmYZ zk^);(l;fl{Mrs2AL;%K3bjO&)LE_?F6k2(?e7?FG_&4Bhj0W(#hsyxgb=b-Ii}S5HpoxuK$VS4Bxlg<*s$ ziaKYupHopWoL(n?>C&{zTrFDa`D&ZOQ_orVDLnPObr$?N)0HQ@iYD>9cc=-9>l&1q zIKRA=iLcJWH)Y}co=GNuBn!VM3%@rDzb^~_>n!|07XD}!{&*J7FQR1H^Gp`bucu_T zzmSEW$iiRG!ueH}%>KX4!he^A|1k@nDLbQ-7vJ?{%DW^BpPz*<%)`VgOTVQYt@6 zB}P7fMn)tNl?wS}o+Fc=RMvx<>5i{jbx5i}4$l!z(BN`ZEm%uLACWM-V1U|_Kc z#BF(M6fD$bE8R?6wo7-}y>XY`(q8n^YOULHpX*)eUY;)7<`1J0DPpf$Y^k}w-}#fA ze1@*OPxpE5{ov$1?|I+zp7*@xJ?}Z+H|P7>SJbZbcs#;fS)y1F^L7bQ2^e1}L{^R% zS1BBk3z{QtAU$3@Pl)1wP)SxmVGj72#v`$AWrs?JJ`QE1XOjm0%AG1*51ffK6w3r4 zM2AWx5XQv%EF+I9^8k9paTF9mDBC4H3!n=8RiH6l0?tG_+hD3gow}VWEeFnIXrIia zLO?%qvA!2+ZgZqzZgZ%#ITCGcD-9%Cni|WJu`*ah$siAPyl2gWERy=Lu7kuj3Xo_6 z(yz^bE|uSOX;N_Nik}Vr^Un%z==iVgH-mN?60g}vGh|NvVc*QfHh2{&AguQQTB~U_EijICek#dd`*}L$T69!@v*>FD9l5;NfYJxjKzquT&w(6op%7Q zL%IR!6G&5#CLmpnbPLiXBwnv{U{iL6zkVijCm`4`(_zjzs)sT2E2yV@7^rH$FHu|4}k{WxZ{Ic?3p z@p6!8t0E+GQBQNR&$LakE_n2RKfB|9eR%Qhf0?_>>zVz*p~s#`PC0h_!_&TS@tGYr z#};-~-~Y88Kc3vXWbT?J@4qzAF>}+!<|)NDbQM1KtNbY&zk27Cga2(`;qw>v{^VD0 z*4%#g=bzazOnLdV!068uY>W z9_erS82MHg{~Ip+uU+_OUHE2~{3aJZ!-YTRs{czD{yP``k1qUa7yh0L|CI}`b+!Mx zi$2dq&vM~kbMbe&@DdmQS{MFJ7yqYSxIlc~5)As2jLPN0@88lAi~5tPKqBS$3;%sv z{cFQpBFR)ZQPUhqCc{av1j2!ah`%-ZXe1i)2jg*nJW)HT==>Vc262bD3C0aH86z1nNCyMqu5LR|v7Fog~EK^eW+OtcBI3 zZ+=0Dw{kn4AI#}3&E)iUXD0XV>CL_PLgqXJ+RJCJNX zVcA1c!cv>hBS|p&KAy#zD~(oPxui(*Zts~>!b(vg7#JL zPx5V)bi~eyxxSg1EMMn9uJ7s$_Wb7*{-VTdrOc5w>mi42-lN;Bl=RL_38B>{?dyPd zA=)eijkYrVI}7_y!^W&+fk*hz*D9p-e}}y+H*5cne&6yj`+c|W_ogxWo#X0vj_(im zd&0-;_dUAbcmEsxu6Ff1jqyGpu7)ks0|gk50~nj%&P@+|IXk=83tajO#(qD1Adfis zIBr-5&gFqO*O{3S-t<6Le&-t;M-Tjubml(+zXN|K{B)o3(|3l3W^5`~WA_QCv!A{R zzkKe+ige!|r*|MbAATuT_j|k@m}fhCh4^x&WES|nU(WnsZo2OqrRlyb@6O&&cs>0d zr=iz_w)1a7nbXm?$BX*qs(!YwqZhjL3a2x3Ui*p%?Xe#PUiiKDN%&s6FWZ~$gD+Fh zfp2`M<`@0#IP0M9QC-)}A>r#CC_>*48kv}jSlVX1sO!=vbI_;fhK44-V3l2svLh&K zf}b{dyEB{6W(YD~1CR81)Z?6_zaw@G#4TNXYzw*+6M~QPpYyo{vMR@kw;Wminyhd8 zJpFx@_V*HuyASx|)?8nOv0sI;uk~J?StVv>j^%e}+O2kvaGcQYAw6EE-2=w57Bm?ANC2#&uoVkFg?n)0-0g^rkv5Vt*8z6O~T`$9~^U#*T&jYUm z{t9j9jP!xN%<(U$9RPbIy)z?YofU5m!uAIt<4N@60C)o6-$7nIj_L4ewJwZR29e)0vU&V_eCbE!JYq6cfGBvngl9UTmA~UUaobS>xb4 zNYZy`ho4(<)vOthO-Tp51arl|hsQ_)h4q0Bnvy^G+`yy~3%D)ci0Coeu zpvw;GGVU3^r_26Kmwg40GHqF{sJ}L>h;7fqC!4Cnc&j~BOkG=%@HxZ}*f$cDcT!24wTsEL??yIZ&y_TuEeDshhES2?ZTK0z0M@(-m6dai`?f2xj(<6EY@{~ULPgz zKO$!gowA)>QcvuIvEPQ?Rh&<%EZdYVMj6`s*!q^Z`fkY_ZU=q(NIM^+4UAXc_kF98 zHo_)vOPk>SM(*=C#@}}~_T5yJ?n}U43D8Lsf567JJT+f1Hdm1QapZCSaNdk1BM-i( zbW?h9JZTSEUQC@w%4vI94qKY?KhzJ??remDAp$T`h>St-Z2 ztC!{Wd@kU8L%XOmd>>i>JA0gE{RIwWf%YrRYt|ROV84keW7*Q^uvf2-jIVf%Bkv2j zj#3u)*c`VUtm)K)aRl3)FPSpJJnp@mUAS*ibgcP{SUyq9@`7&eP29Q@@8`M-8@T6N zCDv$TFUA|W57DyB{i`jT`LX1`3;EP%Ecy2Ma;+-Bo@28fJL=4Rm9fP*ti{}q~_{$_BJ*WUfM|6nUFTE#CpFHx)8VfIaVJz=5~8s z)}Da(nrY~K2)?$yLiOi>qn<5vpuddWRl3hw_BDtT*=C*K9**PlIQm(r>+_z@%RKsf z0KT>eFXoO2lc|9%ScdEa}8{fGR?T2C1#(RbRKV?^Ec{^2#)66q|`B_x5eTqH9m;_%P7_K|A%V;%PzSodguwoSXj2W5=F z?@sdh$2i1Q`ca(m7XE8u4}I`dc6a8~HLxA}_3FIt%<121`=d@=`#tZOpM}lYPCjC+ z8lRf}hv|=a4wB_`4Etj~_TTJ39@$TP9P&6<{}4a*$%kH>pvP?<@fQ2WG2l4=K;JVR zEnnT&0-ovULltGh@3sF-EJ3{j=>I(Q_kwm9`WwHv3wAg?SmE+Uy5Oe+BdPFy`yaXzLK>^OI=ndzPF+_)LzDX#zZ)@068m zWWpBG_P(9HS?C|_S_v88mHVt*H$UQ9wpXnc9E%)hS3lw|o-J{Il+H!c+fXI&zvEkuSe?iBKFpbmIWHtuo=>Kk*7ZlVm`ivdH!?op1?e>M;jay zJQI{-vdOxSJqkMeD4)SlSIn=pF59Tv$cEfmx(z;aVjH{B#%8q9k2d&RF)c>Fi}YA94_nExSfF*H9`1f$ z#QZ*q`F#PruV8*(>(c2)tKY{#XTQyJw`}a44(l@fBqZ%V&T7N-doSAHbG7%;2A{M1 z{)5rBEk_$A&|f__xf=VVnVAyZ59Y_|e!zz3RzX%FWPOOT>5z2}vJh`ZJu~+rZZNK# z24tLZ0G9)<2doC%47dYnH`0D26JyN%-a*JUe!SnxcMa#Ux5ixR@OEcDhxQpC=$9!; z@60q4!Y@or+6;4Y0(|%U-EznI2Wxv=L z_Uj<}z?hl_Jch)+PeL#}ZuM=V!1I38FF>0iKt3mEpgh3Mfa<;tzoqny*n@RCHP1tu zrwH^Z0>72$XY;ff`L=w7{zU(ONFX88PP6Uszd95VBc+Ss7#1GWmN9<&3|qbYc9)Pq629LnhbYQF{dJ;~B5`oFE(VQQmK2 z9hri7L0;Ks#6rmf-0XkYZWZN0=bRIGW-hw07Inz_MTj$e9wXx*VhG!(Eb6G&=-HSv z^UNB3nrpP7`xr~Hrdl}1fzJq7Kg$=Czde|7p&qm;%l9rCf1z>vu?vPq{PpdZF5J5P z#}~Ms82T5tZ@KWs_RAOcF1qdl;}_@kZSal3OYl$daUGQ7hc=6VkEQdkp)=d1A7H$P z?{kR%DQNV&Q;=uo%PRQoCZrQMw9*84|3Z)G#RTg>-uNSZk$W7@U3o78y=Z@XF4JGu zz_u*^xAxm_Ll4vb$JyVTy^N8|{R8I#_XM9pU+ACpfKsP1`t9D|n||>bqPdS`tYqIF z(0$`?GTb97ze3D{&zC~B1D}_^=c03L$TI=^p$XhqLANUC#2EMp>T%7@g4A?? zk9%9zYeKyxsCO0Wjn(Hm@KL7|-1A^e?7cF5Q2Xbo=VpIpjeRYAjsA8NzE+DkeG2d- z;AxldnP=(dx#3grvqBk%ln)5#nuR#W_;wv_>7u>x8x?P_1#QskKl(M}4Epdo=%)eC z0@BX?ntvkrZ9DUKV7b=o_(!|$8~>WAM>;0xTh^S8HSsPDu6VATeVd~QzNihfa@9`IB@jCrXx6rPL?nXFk|mB$wDK@nYc$eUhQnguFTTxvddn%E zGl#sD&W;_C8RpGYN(8)C8MIhH(@hf)b$ z9&U?6(@1oSbF;6at;E@aPBTaOH;0g|YIAN5O~lc=Xn3RVGc@3>i*7~RO<`kdMZ>u{ zr_`xX9GengvCGSKd6ebF-nF$Q;N0%W zY_NgCQ2^R-TL{j>`AQ)g1I@`W>p~yfFK7d&G15#Lj^-&Fvk)f+10j3N<_L}gS`38H zDhHTjN0h1;w*ss3r_9jK9(4)fIL^8UYid@kTj$I|Q_v^UT&AwEv*0OaA8F%xjg8Xn zVPqa4)YAiJ20wb?d79W7PDC2FIg}d?VL$^RXq-$+M<{XR=|k-))LywtAhD&jC5#T; zdUNnrhtsAt8VV7EJ}(7NL%jyRr0<&o~=P z8~G<5`HZue)A}xFu^cdtA|4OW)}@a)OPohqBM1TtZv@^L!1ODQ#vEmzIpm8+Kp2ii z4uTObIsf8`*p@_~r5Iz4QI&JG`dQD;o}P}!$@Bk9eyP-X=YOisQ=a>e*<|qaP&-yE zasFS1+7Ep=)ZY8AL+ytF&-`+z9lvk4r+SCldx!%b1r&Wl?Z*IX0gnT=0b<|M-UIj& z;AOy90KNS~?I!{20bd2&3wR3fFyLvx%YbJ9Hw~aoz`V0V?Rfs!UIa*e>fco5CjeQ# z{`^q;AmGu9L+$4QcfT{#evvrfyMQMFF9GKK8nOYq-i5A1;02WO-c#il-&f_KORAiH z)YXOc1Bn-TO}ZC(Jf9N9UsCUEOvhOPzB|Hqb8ysEo{Q)E5I*2I@+xuMYl!_jg?R77 zq1fqN>fMV|U(oLk!2=i@s1S~>$}_*%OUes-BH_b6Ba0C90>FGE9FY~5uy!*)2#BMs zvL24I%J(=v92$xpM)?pR>s|z`2mbH9_&$-jD$(En7ZdgCg^kRGJ`drT_9CZvdAK1G zh&q*J3(Dq|mRH`Mh)1v_N|Xn=!LgQm9mP{sR#_^k$cUv_ql7#pFFeJ_j$0tckI(f? z@J!5_nsbe(z%$KrUG{X(^`047GqVdlH+gV~zbv_}B^77@OeGX-GC3?j;Y3`NA$W(& zmM*)uG!@vQu`SWovWC_O-mi*;L>aNBK(a}cg|xS9Ma z6K_t5vPcwX)yr^X9e*2vfE43WFUpp#y}t~_)Kg_6p*B$#Zt^!Gq=r>Ze;|qRzR2U1>$GkXiID+(5`JNmQ&M9-5 z(Z#))d|!!tbvuzja10Y5=NT_<{;onIUmSdK@D(9%F2lD91>=y&w;z1_!M7Y~yk;aH z({d!7v5|9$^Y=6=Y#M`a4fr^RDX;QzBveiVp)O#Tvb=zwLgL&eALGC&G$;cSa9-r) z^;sk{hdF=ibCFPH^kaRdhmknvndiJe48CgQjSbibUfYo-Ad!!8V-S4Q$H*feibN+8 z`IaFu&RjyFPxp5c$_yXFBXwnc#=~L+GR8)8nRdU30>dX`2>8yJPJ%{0rY~E3d?(Wj zVY#zVs4pY$0B|FZ@ppQu(%a4V7n+a#b-?F<@0bySGL!w5#drESj4vFBzGW`M2NK(j z?*f$XgU(Y0lQpB^JFbeQor{lxw{oN{vKqdZk!M}{0@n||=V@pt8qWU{@_05U`M9q5 zuE6&T@K9~aW?oJTV9xDNTScRYeJbCHkf9VEkd z27G70hoKw3OrL&(63S(}ynh}9pZ&g<;kyhvT`X&nAQR@{(^@uLHW z#9ZXzm5;$-hR(R8F0Z5;{kQ_w z84@7dqx@Q{{-0ZTmTs@fqLZI-SzUQjKQlgzD2#jNGV*;c{=#AXriixafjBYUyyWqW21&Hi2mQybjqyW7(D2GIF#3`fL+pHXQqGv0h-o9{{*9B*()`P`?g zYqD4ey1|Y7qZXa=j6ZQV?FYZX@ur+?kL{~#hWNb6qQHzd&j_pQdeMa}amED?#%mvN zo?S-R7}lS-x@L%PBU^%Jfr@{I=mE|%_~bDCEgH7BSN89?OaJ00wKzTAK0SZvUmWie zi~e1<2b{6p*dzC;k@`OYUB35%A`c=P>laz{cR?p^*B5(6>R*MBCEp*h>K9t{a?pui zh8)xW<-H^It3l^`2%PC`pW|cV1EV(enf~+$Kj{~_Ns!lM(TMuFs6Pw1(O;fr*L3n9 z+9whGnJk_HKhKgg(ir~Z7M=Xg{to`sWs#KK80{K`oE@1Q+%8UK-IqGh47 zw`1|206+11(2c#~7M=2|{@zH;m-dRg#y@58{}l3w7ixKfE`8ns&fjp2KT7$0RxPg? z;u7fm&DYSgu_W>LUxRyr^S5Bup#RbyXZ}pproE?wPP`UHra#9leQyW7_yC@dYx-Tl zIi-e_(|ZV{!73MpT+xp zn*S8=H1H!Dr#)63#2@LzzR_-4>e{|;Mp=^qw82>v6$P5&t0JN$yUS})}J zIN6@^j{=MSe^8%z%4)B}qEp@>%RkuuZj1hV)F+W>x_zLvpZ@bfg5BJxi zlmDWHQ{KB4PWt9=QeqvOJ|kWWbxl!_G5dGTXf3nwQ$n; zPOG{mi=U2B|GY(Keed6n@V{-cfM&eR{*6)nXOL%b4{+8u`vrbQga?!i&i#XZQQq62 zoAq8k{Tc`T^?J(nb`o&2-}7L<$9L1sdQSd1z|H>8gD;h^zh?i+r+3t6`Ik(qlO%nW zh2M?(v=7ZP74zc(;O62Q5&(V%@pU=!r0;OipK{@8@@xGa=>Ips4?d&f0qegEybJ!( zq~)D<)jtQ^>{q>rx0hV>3F;O=s!08=2hR1YM9aGc_+IE+tMP@vIlhvfHCf!{s=vmC z`+;*lpV9SW!137k{4%f6s+aQn#?EO?g6;y6|cjz81JW{tp4?`l9+bLu_{OCxM&$ zTk5;rMSlW#HRkUo+5Tj42)Hf(2ypthk^h3msW0clPk@_?`kw*L_`U-J#`gF^1NW!K z-!B5sfqx$ZFX_1xO>O1#g}@!?<7oQbz`33r((={;m+vlsPXAgDoaYrfG~NK5>s>W) z%8vo(embr3cHmqu9gXh>ZZ7Ko=fKVV=2ScZ>UPn4T=+k_a51+vnUEhG!xwGl;#*_- zt7CXB&M($9HO|G;`?+Oh`u|uA!9=ROEGCLVqA2jk5f_2DAiiMZe>5C;*xwla<4BEC zDozljS{ob7g80SwzM8fE+I!d4^P@ffP|UxjIo1$p#$ke3BIysbwh26Bk2i;L?xAe{ zf_V$aX7clCzj|ix#{>BUKAgkn`uBpAgy`jm%%Lv2N4NC1>Ch~Y=z zNEF)OcZ`-u44)7JF#)Xsf=!aALe|#D9~w}EdZWu$l;7d^*R5SqU;kw^p4T!@H01J3lAsS=03O~?<@f*K1 z{yd(nKw)_~4$kCO#Qd?OzUw#uxW-H;Haha+rcW6o4IR1EGOIQtDd4)8vCTtbz zds?<6zaKvw4u7Srku%XIQ#l*=Z>W+J5eK^H`fyb_>HIi|f>GBW=i=wO>`L - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - -@end diff --git a/iPhone Apps/rfduino/AppDelegate.m b/iPhone Apps/rfduino/AppDelegate.m deleted file mode 100755 index 5f68204..0000000 --- a/iPhone Apps/rfduino/AppDelegate.m +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import "AppDelegate.h" - -#import "ScanViewController.h" -#import "RFduinoManager.h" - -@interface AppDelegate() -{ - RFduinoManager *rfduinoManager; - bool wasScanning; -} -@end - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - - rfduinoManager = RFduinoManager.sharedRFduinoManager; - - ScanViewController *viewController = [[ScanViewController alloc] init]; - - UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; - [self.window setRootViewController:navController]; - - navController.navigationBar.tintColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; - - self.window.backgroundColor = [UIColor whiteColor]; - [self.window makeKeyAndVisible]; - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application -{ - NSLog(@"applicationWillResignActive"); - - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. - - wasScanning = false; - - if (rfduinoManager.isScanning) { - wasScanning = true; - [rfduinoManager stopScan]; - } -} - -- (void)applicationDidEnterBackground:(UIApplication *)application -{ - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application -{ - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application -{ - NSLog(@"applicationDidBecomeActive"); - - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - - if (wasScanning) { - [rfduinoManager startScan]; - wasScanning = false; - } -} - -- (void)applicationWillTerminate:(UIApplication *)application -{ - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/iPhone Apps/rfduino/CustomCellBackground.h b/iPhone Apps/rfduino/CustomCellBackground.h deleted file mode 100755 index a3e14fa..0000000 --- a/iPhone Apps/rfduino/CustomCellBackground.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -@interface CustomCellBackground : UIView -{ -} - -@property (nonatomic, strong) UIColor *startColor; -@property (nonatomic, strong) UIColor *stopColor; - -@end diff --git a/iPhone Apps/rfduino/CustomCellBackground.m b/iPhone Apps/rfduino/CustomCellBackground.m deleted file mode 100755 index 4f92e3b..0000000 --- a/iPhone Apps/rfduino/CustomCellBackground.m +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import "CustomCellBackground.h" - -@implementation CustomCellBackground - -@synthesize startColor; -@synthesize stopColor; - -// http://www.raywenderlich.com/32283/core-graphics-tutorial-lines-rectangles-and-gradients - -void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor) -{ - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGFloat locations[] = { 0.0, 1.0 }; - - NSArray *colors = @[(__bridge id) startColor, (__bridge id) endColor]; - - CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations); - - CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)); - CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)); - - CGContextSaveGState(context); - CGContextAddRect(context, rect); - CGContextClip(context); - CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); - CGContextRestoreGState(context); - - CGGradientRelease(gradient); - CGColorSpaceRelease(colorSpace); -} - -- (id)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - // Initialization code - } - return self; -} - -// Only override drawRect: if you perform custom drawing. -// An empty implementation adversely affects performance during animation. -- (void)drawRect:(CGRect)rect -{ - CGContextRef context = UIGraphicsGetCurrentContext(); - - CGRect frameRect = self.bounds; - - // CGContextSetFillColorWithColor(context, redColor.CGColor); - // CGContextFillRect(context, self.bounds); - - drawLinearGradient(context, frameRect, startColor.CGColor, stopColor.CGColor); -} - -@end diff --git a/iPhone Apps/rfduino/RFduino.h b/iPhone Apps/rfduino/RFduino.h deleted file mode 100644 index f19a9ee..0000000 --- a/iPhone Apps/rfduino/RFduino.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -#import -#elif TARGET_OS_MAC -#import -#endif - -#import "RFduinoDelegate.h" - -@class RFduinoManager; - -char data(NSData *data); -uint8_t dataByte(NSData *data); -int dataInt(NSData *data); -float dataFloat(NSData *data); - -// default NULL (NULL = previous fixed RFduino uuid) -extern NSString *customUUID; - -@interface RFduino : NSObject -{ -} - -@property(assign, nonatomic) id delegate; - -@property(strong, nonatomic) CBPeripheral *peripheral; - -@property(strong, nonatomic) RFduinoManager *rfduinoManager; - -@property(strong, nonatomic) NSString *name; -@property(strong, nonatomic) NSData *advertisementData; -@property(strong, nonatomic) NSNumber *advertisementRSSI; -@property(assign, nonatomic) NSInteger advertisementPackets; -@property(strong, nonatomic) NSDate *lastAdvertisement; -@property(assign, nonatomic) NSInteger outOfRange; -- (void)connected; -- (void)disconnect; - -- (void)send:(NSData *)data; - -@end diff --git a/iPhone Apps/rfduino/RFduino.m b/iPhone Apps/rfduino/RFduino.m deleted file mode 100644 index ea0c8f3..0000000 --- a/iPhone Apps/rfduino/RFduino.m +++ /dev/null @@ -1,205 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import "RFduino.h" - -#import "RFduinoManager.h" - -static const int max_data = 12; - -// default NULL (NULL = previous fixed RFduino uuid) -NSString *customUUID = NULL; - -static CBUUID *service_uuid; -static CBUUID *send_uuid; -static CBUUID *receive_uuid; -static CBUUID *disconnect_uuid; - -char data(NSData *data) -{ - return (char)dataByte(data); -} - -uint8_t dataByte(NSData *data) -{ - uint8_t *p = (uint8_t*)[data bytes]; - NSUInteger len = [data length]; - return (len ? *p : 0); -} - -int dataInt(NSData *data) -{ - uint8_t *p = (uint8_t*)[data bytes]; - NSUInteger len = [data length]; - return (sizeof(int) <= len ? *(int*)p : 0); -} - -float dataFloat(NSData *data) -{ - uint8_t *p = (uint8_t*)[data bytes]; - NSUInteger len = [data length]; - return (sizeof(float) <= len ? *(float*)p : 0); -} - -// increment the 16-bit uuid inside a 128-bit uuid -static void incrementUuid16(CBUUID *uuid, unsigned char amount) -{ - NSData *data = uuid.data; - unsigned char *bytes = (unsigned char *)[data bytes]; - unsigned char result = bytes[3] + amount; - if (result < bytes[3]) - bytes[2]++; - bytes[3] += amount; -} - -@interface RFduino() -{ - CBCharacteristic *send_characteristic; - CBCharacteristic *disconnect_characteristic; - bool loadedService; -} -@end - -@implementation RFduino - -@synthesize delegate; -@synthesize rfduinoManager; -@synthesize peripheral; - -@synthesize name; -@synthesize advertisementData; -@synthesize advertisementRSSI; -@synthesize advertisementPackets; -@synthesize outOfRange; - -- (id)init -{ - NSLog(@"rfduino init"); - - self = [super init]; - if (self) { - } - - return self; -} - -- (void)connected -{ - NSLog(@"rfduino connected"); - - service_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2220")]; - receive_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2221")]; - if (customUUID) - incrementUuid16(receive_uuid, 1); - send_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2222")]; - if (customUUID) - incrementUuid16(send_uuid, 2); - disconnect_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2223")]; - if (customUUID) - incrementUuid16(disconnect_uuid, 3); - peripheral.delegate = self; - - [peripheral discoverServices:[NSArray arrayWithObject:service_uuid]]; -} - -#pragma mark - CBPeripheralDelegate methods - -- (void)peripheral:(CBPeripheral *)_peripheral didDiscoverServices:(NSError *)error -{ - NSLog(@"didDiscoverServices"); - - for (CBService *service in peripheral.services) { - if ([service.UUID isEqual:service_uuid]) - { - NSArray *characteristics = [NSArray arrayWithObjects:receive_uuid, send_uuid, disconnect_uuid, nil]; - [peripheral discoverCharacteristics:characteristics forService:service]; - } - } -} - -- (void)peripheral:(CBPeripheral *)_peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error -{ - NSLog(@"didDiscoverCharacteristicsForService"); - for (CBService *service in peripheral.services) { - if ([service.UUID isEqual:service_uuid]) { - for (CBCharacteristic *characteristic in service.characteristics) { - if ([characteristic.UUID isEqual:receive_uuid]) { - [peripheral setNotifyValue:YES forCharacteristic:characteristic]; - } else if ([characteristic.UUID isEqual:send_uuid]) { - send_characteristic = characteristic; - } else if ([characteristic.UUID isEqual:disconnect_uuid]) { - disconnect_characteristic = characteristic; - } - } - - loadedService = true; - [rfduinoManager loadedServiceRFduino:self]; - } - } -} - -- (void)peripheral:(CBPeripheral *)aPeripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error -{ - NSLog(@"didUpdateValueForCharacteristic"); - if ([characteristic.UUID isEqual:receive_uuid]) { - SEL didReceive = @selector(didReceive:); - if ([delegate respondsToSelector:didReceive]) { - [delegate didReceive:characteristic.value]; - } - } -} - -#pragma mark - RFduino methods - -- (void)send:(NSData *)data -{ - if (! loadedService) { - @throw [NSException exceptionWithName:@"sendData" reason:@"please wait for ready callback" userInfo:nil]; - } - - if ([data length] > max_data) { - @throw [NSException exceptionWithName:@"sendData" reason:@"max data size exceeded" userInfo:nil]; - } - - [peripheral writeValue:data forCharacteristic:send_characteristic type:CBCharacteristicWriteWithoutResponse]; -} - -- (void)disconnect -{ - NSLog(@"rfduino disconnect"); - - if (loadedService) { - NSLog(@"writing to disconnect characteristic"); - // fix for iOS SDK 7.0 - at least one byte must now be transferred - uint8_t flag = 1; - NSData *data = [NSData dataWithBytes:(void*)&flag length:1]; - [peripheral writeValue:data forCharacteristic:disconnect_characteristic type:CBCharacteristicWriteWithoutResponse]; - } - - [rfduinoManager disconnectRFduino:self]; -} - -@end diff --git a/iPhone Apps/rfduino/RFduinoDelegate.h b/iPhone Apps/rfduino/RFduinoDelegate.h deleted file mode 100755 index b91b720..0000000 --- a/iPhone Apps/rfduino/RFduinoDelegate.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -@protocol RFduinoDelegate - -@optional - -- (void)didReceive:(NSData *)data; - -@end diff --git a/iPhone Apps/rfduino/RFduinoManagerDelegate.h b/iPhone Apps/rfduino/RFduinoManagerDelegate.h deleted file mode 100755 index 044b8a7..0000000 --- a/iPhone Apps/rfduino/RFduinoManagerDelegate.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -@class RFduino; - -@protocol RFduinoManagerDelegate - -- (void)didDiscoverRFduino:(RFduino *)rfduino; - -@optional - -- (void)didUpdateDiscoveredRFduino:(RFduino *)rfduino; - -- (void)didConnectRFduino:(RFduino *)rfduino; -- (void)didLoadServiceRFduino:(RFduino *)rfduino; -- (void)didDisconnectRFduino:(RFduino *)rfduino; -- (void)shouldDisplayAlertTitled:(NSString *)title messageBody:(NSString *)body; - -@end diff --git a/iPhone Apps/rfduino/RfduinoManager.h b/iPhone Apps/rfduino/RfduinoManager.h deleted file mode 100755 index e2c1c28..0000000 --- a/iPhone Apps/rfduino/RfduinoManager.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -#import -#elif TARGET_OS_MAC -#import -#endif - -#import "RFduinoManagerDelegate.h" - -@interface RFduinoManager : NSObject -{ - CBCentralManager *central; -} - -+ (RFduinoManager *)sharedRFduinoManager; - -@property (nonatomic, assign) id delegate; -@property (nonatomic, strong) NSMutableArray *rfduinos; - -- (bool)isScanning; -- (void)startScan; -- (void)stopScan; - -- (void)connectRFduino:(RFduino *)rfduino; -- (void)disconnectRFduino:(RFduino *)rfduino; - -- (void)loadedServiceRFduino:(RFduino *)rfduino; - -@end diff --git a/iPhone Apps/rfduino/RfduinoManager.m b/iPhone Apps/rfduino/RfduinoManager.m deleted file mode 100644 index e39daa3..0000000 --- a/iPhone Apps/rfduino/RfduinoManager.m +++ /dev/null @@ -1,347 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include - -#import "RFduinoManager.h" - -#import "RFduino.h" - -static CBUUID *service_uuid; - -@interface RFduinoManager() -{ - NSTimer *rangeTimer; - int rangeTimerCount; - bool didUpdateDiscoveredRFduinoFlag; - void (^cancelBlock)(void); - bool isScanning; -} -@end - -@implementation RFduinoManager - -@synthesize delegate; -@synthesize rfduinos; - -+ (RFduinoManager *)sharedRFduinoManager -{ - static RFduinoManager *rfduinoManager; - if (! rfduinoManager) { - rfduinoManager = [[RFduinoManager alloc] init]; - } - return rfduinoManager; -} - -- (id)init -{ - NSLog(@"init"); - - self = [super init]; - - if (self) { - service_uuid = [CBUUID UUIDWithString:(customUUID ? customUUID : @"2220")]; - - rfduinos = [[NSMutableArray alloc] init]; - - central = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; - } - - return self; -} - -- (bool)isBluetoothLESupported -{ - if ([central state] == CBCentralManagerStatePoweredOn) - return YES; - - NSString *message; - - switch ([central state]) - { - case CBCentralManagerStateUnsupported: - message = @"This hardware doesn't support Bluetooth Low Energy."; - break; - case CBCentralManagerStateUnauthorized: - message = @"This app is not authorized to use Bluetooth Low Energy."; - break; - case CBCentralManagerStatePoweredOff: - message = @"Bluetooth is currently powered off."; - break; - case CBCentralManagerStateUnknown: - // fall through - default: - message = @"Bluetooth state is unknown."; - - } - - if ([delegate respondsToSelector:@selector(shouldDisplayAlertTitled:messageBody:)]) { - [delegate shouldDisplayAlertTitled:@"Bluetooth LE Support" messageBody:message]; - } - - return NO; -} - -- (void)startRangeTimer -{ - rangeTimerCount = 0; - - rangeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 - target:self - selector:@selector(rangeTick:) - userInfo:nil - repeats:YES]; - -} - -- (void)stopRangeTimer -{ - [rangeTimer invalidate]; -} - -- (void) rangeTick:(NSTimer*)timer -{ - bool update = false; - - rangeTimerCount++; - if ((rangeTimerCount % 60) == 0) { - // NSLog(@"restarting scanning"); - - [central stopScan]; - - NSDictionary *options = nil; - options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] - forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; - [central scanForPeripheralsWithServices:[NSArray arrayWithObject:service_uuid] options:options]; - } - - - NSDate *date = [NSDate date]; - for (RFduino *rfduino in rfduinos) { - if (!rfduino.outOfRange - && rfduino.lastAdvertisement != NULL - && [date timeIntervalSinceDate:rfduino.lastAdvertisement] > 2) - { - rfduino.outOfRange = true; - update = true; - } - } - - if (update) { - if (didUpdateDiscoveredRFduinoFlag) { - [delegate didUpdateDiscoveredRFduino:nil]; - } - } -} - -#pragma mark - CentralManagerDelegate methods - -- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral -{ - NSLog(@"didConnectPeripheral"); - - RFduino *rfduino = [self rfduinoForPeripheral:peripheral]; - if (rfduino) { - [rfduino connected]; - [delegate didConnectRFduino:rfduino]; - } -} - -- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error -{ - NSLog(@"didDisconnectPeripheral"); - - void (^block)(void) = ^{ - if ([delegate respondsToSelector:@selector(didDisconnectRFduino:)]) { - RFduino *rfduino = [self rfduinoForPeripheral:peripheral]; - if (rfduino) { - [delegate didDisconnectRFduino:rfduino]; - } - } - }; - - if (error.code) { - cancelBlock = block; - - if ([delegate respondsToSelector:@selector(shouldDisplayAlertTitled:messageBody:)]) { - [delegate shouldDisplayAlertTitled:@"Peripheral Disconnected with Error" messageBody:error.description]; - } - - } - else - block(); - - if (peripheral) { - [peripheral setDelegate:nil]; - peripheral = nil; - } -} - -- (RFduino *)rfduinoForPeripheral:(CBPeripheral *)peripheral -{ - for (RFduino *rfduino in rfduinos) { - if ([peripheral isEqual:rfduino.peripheral]) { - return rfduino; - } - } - return nil; -} - -- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI -{ - // NSLog(@"didDiscoverPeripheral"); - - bool added = false; - - RFduino *rfduino = [self rfduinoForPeripheral:peripheral]; - if (! rfduino) { - rfduino = [[RFduino alloc] init]; - - rfduino.rfduinoManager = self; - - rfduino.name = peripheral.name; - - rfduino.peripheral = peripheral; - - added = true; - - [rfduinos addObject:rfduino]; - } - - rfduino.advertisementData = nil; - - id manufacturerData = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey]; - if (manufacturerData) { - const uint8_t *bytes = [manufacturerData bytes]; - NSUInteger len = [manufacturerData length]; - // skip manufacturer uuid - NSData *data = [NSData dataWithBytes:bytes+2 length:len-2]; - rfduino.advertisementData = data; - } - - rfduino.advertisementRSSI = RSSI; - rfduino.advertisementPackets++; - rfduino.lastAdvertisement = [NSDate date]; - rfduino.outOfRange = false; - - if (added) { - [delegate didDiscoverRFduino:rfduino]; - } else { - if (didUpdateDiscoveredRFduinoFlag) { - [delegate didUpdateDiscoveredRFduino:rfduino]; - } - } -} - -- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error -{ - NSLog(@"didFailToConnectPeripheral"); - - if ([delegate respondsToSelector:@selector(shouldDisplayAlertTitled:messageBody:)]) { - [delegate shouldDisplayAlertTitled:@"Connect Failed" messageBody:error.description]; - } -} - -- (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals -{ -} - -- (void)centralManagerDidUpdateState:(CBCentralManager *)aCentral -{ - NSLog(@"central manager state = %ld", [central state]); - - bool success = [self isBluetoothLESupported]; - if (success) { - [self startScan]; - } -} - -#pragma mark - Rfduino methods - -- (bool)isScanning -{ - return isScanning; -} - -- (void)startScan -{ - NSLog(@"startScan"); - - isScanning = true; - - NSDictionary *options = nil; - - didUpdateDiscoveredRFduinoFlag = [delegate respondsToSelector:@selector(didUpdateDiscoveredRFduino:)]; - - if (didUpdateDiscoveredRFduinoFlag) { - options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] - forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; - } - - [rfduinos removeAllObjects]; - - [central scanForPeripheralsWithServices:[NSArray arrayWithObject:service_uuid] options:options]; - - if (didUpdateDiscoveredRFduinoFlag) { - [self startRangeTimer]; - } -} - -- (void)stopScan -{ - NSLog(@"stopScan"); - - if (didUpdateDiscoveredRFduinoFlag) { - [self stopRangeTimer]; - } - - [central stopScan]; - - isScanning = false; -} - -- (void)connectRFduino:(RFduino *)rfduino -{ - NSLog(@"connectRFduino"); - - [central connectPeripheral:[rfduino peripheral] options:nil]; -} - -- (void)disconnectRFduino:(RFduino *)rfduino -{ - NSLog(@"rfduinoManager disconnectPeripheral"); - - [central cancelPeripheralConnection:rfduino.peripheral]; -} - -- (void)loadedServiceRFduino:(id)rfduino -{ - if ([delegate respondsToSelector:@selector(didLoadServiceRFduino:)]) { - [delegate didLoadServiceRFduino:rfduino]; - } -} - -@end diff --git a/iPhone Apps/rfduino/ScanViewController.h b/iPhone Apps/rfduino/ScanViewController.h deleted file mode 100755 index 2da947f..0000000 --- a/iPhone Apps/rfduino/ScanViewController.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#import "RFduinoManagerDelegate.h" - -@class RFduinoManager; -@class RFduino; - -@interface ScanViewController : UITableViewController -{ - RFduinoManager *rfduinoManager; -} - -@end diff --git a/iPhone Apps/rfduino/ScanViewController.m b/iPhone Apps/rfduino/ScanViewController.m deleted file mode 100755 index d3b57bb..0000000 --- a/iPhone Apps/rfduino/ScanViewController.m +++ /dev/null @@ -1,328 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#import "ScanViewController.h" - -#import "RFduinoManager.h" -#import "RFduino.h" - -#import "AppViewController.h" - -#import "CustomCellBackground.h" - -@interface ScanViewController() -{ - bool editingRow; - bool loadService; -} -@end - -@implementation ScanViewController - -- (id)initWithStyle:(UITableViewStyle)style -{ - self = [super initWithStyle:style]; - if (self) { - UINavigationItem *navItem = [self navigationItem]; - [navItem setTitle:@"Found RFduinos"]; - - rfduinoManager = [RFduinoManager sharedRFduinoManager]; - } - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - // Uncomment the following line to preserve selection between presentations. - // self.clearsSelectionOnViewWillAppear = NO; - - // Uncomment the following line to display an Edit button in the navigation bar for this view controller. - // self.navigationItem.rightBarButtonItem = self.editButtonItem; - - rfduinoManager.delegate = self; - - int numberOfLines = 3; - self.tableView.rowHeight = (44.0 + (numberOfLines - 1) * 19.0); - - UIColor *start = [UIColor colorWithRed:58/255.0 green:108/255.0 blue:183/255.0 alpha:0.15]; - UIColor *stop = [UIColor colorWithRed:58/255.0 green:108/255.0 blue:183/255.0 alpha:0.45]; - - CAGradientLayer *gradient = [CAGradientLayer layer]; - // gradient.frame = [self.view bounds]; - gradient.frame = CGRectMake(0.0, 0.0, 1024.0, 1024.0); - gradient.colors = [NSArray arrayWithObjects:(id)start.CGColor, (id)stop.CGColor, nil]; - [self.tableView.layer insertSublayer:gradient atIndex:0]; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [[rfduinoManager rfduinos] count]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - static NSMutableArray *signalStrength = nil; - if (! signalStrength) { - signalStrength = [[NSMutableArray alloc] init]; - } - - static NSString *cellIdentifier = @"Cell"; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; - if (! cell) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; - - cell.textLabel.backgroundColor = [UIColor clearColor]; - cell.detailTextLabel.backgroundColor = [UIColor clearColor]; - - UIProgressView *view = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar]; - view.frame = CGRectMake(0.0, 0.0, 150.0, 0.0); - view.center = CGPointMake(225,14); - view.progressViewStyle = UIProgressViewStyleDefault; - view.progressTintColor = [UIColor colorWithRed:0.0 green:0.5 blue:0.0 alpha:1.0]; - - [cell addSubview:view]; - - [signalStrength setObject:view atIndexedSubscript:indexPath.row]; - } - - RFduino *rfduino = [rfduinoManager.rfduinos objectAtIndex:[indexPath row]]; - - UIColor *start; - UIColor *stop; - if (rfduino.outOfRange) { - start = [UIColor colorWithRed:160/255.0 green:160/255.0 blue:160/255.0 alpha:0.8]; - stop = [UIColor colorWithRed:160/255.0 green:160/255.0 blue:160/255.0 alpha:0.2]; - } else { - start = [UIColor colorWithRed:253/255.0 green:255/255.0 blue:255/255.0 alpha: 1.0]; - stop = [UIColor colorWithRed:253/255.0 green:255/255.0 blue:255/255.0 alpha: 0.7]; - } - - CustomCellBackground *ccb = [[CustomCellBackground alloc] init]; - ccb.startColor = start; - ccb.stopColor = stop; - cell.backgroundView = ccb; - - NSString *text = [[NSString alloc] initWithFormat:@"%@", rfduino.name]; - - int rssi = rfduino.advertisementRSSI.intValue; - - NSString *advertising = @""; - if (rfduino.advertisementData) { - advertising = [[NSString alloc] initWithData:rfduino.advertisementData encoding:NSUTF8StringEncoding]; - } - - NSMutableString *detail = [NSMutableString stringWithCapacity:100]; - [detail appendFormat:@"RSSI: %d dBm", rssi]; - while ([detail length] < 25) - [detail appendString:@" "]; - [detail appendFormat:@"Packets: %d\n", rfduino.advertisementPackets]; - [detail appendFormat:@"Advertising: %@\n", advertising]; - - cell.textLabel.text = text; - cell.detailTextLabel.text = detail; - cell.detailTextLabel.numberOfLines = 3; - - if (indexPath.row < signalStrength.count) { - UIProgressView *view = [signalStrength objectAtIndex:indexPath.row]; - if (view) { - int value = rssi; - - // only interested in graphing the rssi range between -75 and -103 - if (value > -75) { - value = -75; - } - if (value < -103) { - value = -103; - } - - // translate rssi to signal strength between 0 and 28 - value += 103; - - // calculate ratio - float ratio = (float)value / (-75 - -103); - - // moving average over 20 samples - int samples = 20; - if ([advertising hasPrefix:@"-"]) { - // device using non-default avertising (switch the instaneous sampling) - samples = 1; - } - - if (view.progress == 0.0) { - // use the instantaneous value for the first sample - view.progress = ratio; - } else { - view.progress = (ratio * 1.0/samples) + (view.progress * (samples - 1.0)/samples); - } - } - } - - return cell; -} - -// Override to support conditional editing of the table view. -- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath -{ - RFduino *rfduino = [rfduinoManager.rfduinos objectAtIndex:[indexPath row]]; - // Return NO if you do not want the specified item to be editable. - return (rfduino.outOfRange ? YES : NO); -} - -- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath -{ - editingRow = true; -} - -- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath -{ - editingRow = false; -} - -// Override to support editing the table view. -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath -{ - if (editingStyle == UITableViewCellEditingStyleDelete) { - // Delete the row from the data source - [rfduinoManager.rfduinos removeObjectAtIndex:[indexPath row]]; - [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; - } - /* - else if (editingStyle == UITableViewCellEditingStyleInsert) { - // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view - } - */ -} - -/* -// Override to support rearranging the table view. -- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath -{ -} -*/ - -/* -// Override to support conditional rearranging of the table view. -- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath -{ - // Return NO if you do not want the item to be re-orderable. - return YES; -} -*/ - -#pragma mark - Table view delegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - RFduino *rfduino = [[rfduinoManager rfduinos] objectAtIndex:[indexPath row]]; - - if (! rfduino.outOfRange) { - [rfduinoManager connectRFduino:rfduino]; - } else { - [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - } -} - -#pragma mark - RfduinoDiscoveryDelegate methods - -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - -- (void)shouldDisplayAlertTitled:(NSString *)title messageBody:(NSString *)body -{ - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title - message:body - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; -} - -#endif - -- (void)didDiscoverRFduino:(RFduino *)rfduino -{ - NSLog(@"didDiscoverRFduino"); - if (! editingRow) { - NSLog(@"reloadData"); - [self.tableView reloadData]; - } -} - -- (void)didUpdateDiscoveredRFduino:(RFduino *)rfduino -{ - // NSLog(@"didUpdateRFduino"); - if (! editingRow) { - [self.tableView reloadData]; - } -} - -- (void)didConnectRFduino:(RFduino *)rfduino -{ - NSLog(@"didConnectRFduino"); - - [rfduinoManager stopScan]; - - loadService = false; -} - -- (void)didLoadServiceRFduino:(RFduino *)rfduino -{ - AppViewController *viewController = [[AppViewController alloc] init]; - viewController.rfduino = rfduino; - - loadService = true; - [[self navigationController] pushViewController:viewController animated:YES]; -} - -- (void)didDisconnectRFduino:(RFduino *)rfduino -{ - NSLog(@"didDisconnectRFduino"); - - if (loadService) { - [[self navigationController] popViewControllerAnimated:YES]; - } - - [rfduinoManager startScan]; - [self.tableView reloadData]; -} - -@end diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.pbxproj b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.pbxproj deleted file mode 100755 index 976758a..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.pbxproj +++ /dev/null @@ -1,469 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - AABEB8C6185167E000833990 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABEB8C5185167E000833990 /* Foundation.framework */; }; - AABEB8C8185167E000833990 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABEB8C7185167E000833990 /* CoreGraphics.framework */; }; - AABEB8CA185167E000833990 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABEB8C9185167E000833990 /* UIKit.framework */; }; - AABEB8D0185167E000833990 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AABEB8CE185167E000833990 /* InfoPlist.strings */; }; - AABEB8D2185167E000833990 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB8D1185167E000833990 /* main.m */; }; - AABEB8D8185167E000833990 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AABEB8D7185167E000833990 /* Images.xcassets */; }; - AABEB8DF185167E000833990 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABEB8DE185167E000833990 /* XCTest.framework */; }; - AABEB8E0185167E000833990 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABEB8C5185167E000833990 /* Foundation.framework */; }; - AABEB8E1185167E000833990 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABEB8C9185167E000833990 /* UIKit.framework */; }; - AABEB901185167EC00833990 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB8F6185167EC00833990 /* AppDelegate.m */; }; - AABEB902185167EC00833990 /* CustomCellBackground.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB8F8185167EC00833990 /* CustomCellBackground.m */; }; - AABEB903185167EC00833990 /* RFduino.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB8FA185167EC00833990 /* RFduino.m */; }; - AABEB904185167EC00833990 /* RfduinoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB8FD185167EC00833990 /* RfduinoManager.m */; }; - AABEB905185167EC00833990 /* ScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB900185167EC00833990 /* ScanViewController.m */; }; - AABEB9081851682000833990 /* AppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AABEB9071851682000833990 /* AppViewController.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - AABEB8E2185167E000833990 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AABEB8BA185167E000833990 /* Project object */; - proxyType = 1; - remoteGlobalIDString = AABEB8C1185167E000833990; - remoteInfo = rfduinoBulkDataTransfer; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - AABEB8C2185167E000833990 /* rfduinoBulkDataTransfer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = rfduinoBulkDataTransfer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - AABEB8C5185167E000833990 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - AABEB8C7185167E000833990 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - AABEB8C9185167E000833990 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - AABEB8CD185167E000833990 /* rfduinoBulkDataTransfer-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "rfduinoBulkDataTransfer-Info.plist"; sourceTree = ""; }; - AABEB8CF185167E000833990 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - AABEB8D1185167E000833990 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - AABEB8D3185167E000833990 /* rfduinoBulkDataTransfer-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "rfduinoBulkDataTransfer-Prefix.pch"; sourceTree = ""; }; - AABEB8D7185167E000833990 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - AABEB8DD185167E000833990 /* rfduinoBulkDataTransferTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = rfduinoBulkDataTransferTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - AABEB8DE185167E000833990 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - AABEB8F5185167EC00833990 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - AABEB8F6185167EC00833990 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - AABEB8F7185167EC00833990 /* CustomCellBackground.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomCellBackground.h; sourceTree = ""; }; - AABEB8F8185167EC00833990 /* CustomCellBackground.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomCellBackground.m; sourceTree = ""; }; - AABEB8F9185167EC00833990 /* RFduino.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFduino.h; sourceTree = ""; }; - AABEB8FA185167EC00833990 /* RFduino.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RFduino.m; sourceTree = ""; }; - AABEB8FB185167EC00833990 /* RFduinoDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFduinoDelegate.h; sourceTree = ""; }; - AABEB8FC185167EC00833990 /* RfduinoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RfduinoManager.h; sourceTree = ""; }; - AABEB8FD185167EC00833990 /* RfduinoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RfduinoManager.m; sourceTree = ""; }; - AABEB8FE185167EC00833990 /* RFduinoManagerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFduinoManagerDelegate.h; sourceTree = ""; }; - AABEB8FF185167EC00833990 /* ScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanViewController.h; sourceTree = ""; }; - AABEB900185167EC00833990 /* ScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScanViewController.m; sourceTree = ""; }; - AABEB9061851682000833990 /* AppViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppViewController.h; sourceTree = ""; }; - AABEB9071851682000833990 /* AppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppViewController.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - AABEB8BF185167E000833990 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AABEB8C8185167E000833990 /* CoreGraphics.framework in Frameworks */, - AABEB8CA185167E000833990 /* UIKit.framework in Frameworks */, - AABEB8C6185167E000833990 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AABEB8DA185167E000833990 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AABEB8DF185167E000833990 /* XCTest.framework in Frameworks */, - AABEB8E1185167E000833990 /* UIKit.framework in Frameworks */, - AABEB8E0185167E000833990 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - AABEB8B9185167E000833990 = { - isa = PBXGroup; - children = ( - AABEB8F4185167EC00833990 /* rfduino */, - AABEB8CB185167E000833990 /* rfduinoBulkDataTransfer */, - AABEB8C4185167E000833990 /* Frameworks */, - AABEB8C3185167E000833990 /* Products */, - ); - sourceTree = ""; - }; - AABEB8C3185167E000833990 /* Products */ = { - isa = PBXGroup; - children = ( - AABEB8C2185167E000833990 /* rfduinoBulkDataTransfer.app */, - AABEB8DD185167E000833990 /* rfduinoBulkDataTransferTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - AABEB8C4185167E000833990 /* Frameworks */ = { - isa = PBXGroup; - children = ( - AABEB8C5185167E000833990 /* Foundation.framework */, - AABEB8C7185167E000833990 /* CoreGraphics.framework */, - AABEB8C9185167E000833990 /* UIKit.framework */, - AABEB8DE185167E000833990 /* XCTest.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - AABEB8CB185167E000833990 /* rfduinoBulkDataTransfer */ = { - isa = PBXGroup; - children = ( - AABEB9061851682000833990 /* AppViewController.h */, - AABEB9071851682000833990 /* AppViewController.m */, - AABEB8D7185167E000833990 /* Images.xcassets */, - AABEB8CC185167E000833990 /* Supporting Files */, - ); - path = rfduinoBulkDataTransfer; - sourceTree = ""; - }; - AABEB8CC185167E000833990 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - AABEB8CD185167E000833990 /* rfduinoBulkDataTransfer-Info.plist */, - AABEB8CE185167E000833990 /* InfoPlist.strings */, - AABEB8D1185167E000833990 /* main.m */, - AABEB8D3185167E000833990 /* rfduinoBulkDataTransfer-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - AABEB8F4185167EC00833990 /* rfduino */ = { - isa = PBXGroup; - children = ( - AABEB8F5185167EC00833990 /* AppDelegate.h */, - AABEB8F6185167EC00833990 /* AppDelegate.m */, - AABEB8F7185167EC00833990 /* CustomCellBackground.h */, - AABEB8F8185167EC00833990 /* CustomCellBackground.m */, - AABEB8F9185167EC00833990 /* RFduino.h */, - AABEB8FA185167EC00833990 /* RFduino.m */, - AABEB8FB185167EC00833990 /* RFduinoDelegate.h */, - AABEB8FC185167EC00833990 /* RfduinoManager.h */, - AABEB8FD185167EC00833990 /* RfduinoManager.m */, - AABEB8FE185167EC00833990 /* RFduinoManagerDelegate.h */, - AABEB8FF185167EC00833990 /* ScanViewController.h */, - AABEB900185167EC00833990 /* ScanViewController.m */, - ); - name = rfduino; - path = ../rfduino; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - AABEB8C1185167E000833990 /* rfduinoBulkDataTransfer */ = { - isa = PBXNativeTarget; - buildConfigurationList = AABEB8EE185167E000833990 /* Build configuration list for PBXNativeTarget "rfduinoBulkDataTransfer" */; - buildPhases = ( - AABEB8BE185167E000833990 /* Sources */, - AABEB8BF185167E000833990 /* Frameworks */, - AABEB8C0185167E000833990 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = rfduinoBulkDataTransfer; - productName = rfduinoBulkDataTransfer; - productReference = AABEB8C2185167E000833990 /* rfduinoBulkDataTransfer.app */; - productType = "com.apple.product-type.application"; - }; - AABEB8DC185167E000833990 /* rfduinoBulkDataTransferTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = AABEB8F1185167E000833990 /* Build configuration list for PBXNativeTarget "rfduinoBulkDataTransferTests" */; - buildPhases = ( - AABEB8D9185167E000833990 /* Sources */, - AABEB8DA185167E000833990 /* Frameworks */, - AABEB8DB185167E000833990 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - AABEB8E3185167E000833990 /* PBXTargetDependency */, - ); - name = rfduinoBulkDataTransferTests; - productName = rfduinoBulkDataTransferTests; - productReference = AABEB8DD185167E000833990 /* rfduinoBulkDataTransferTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - AABEB8BA185167E000833990 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0500; - ORGANIZATIONNAME = RFduino; - TargetAttributes = { - AABEB8DC185167E000833990 = { - TestTargetID = AABEB8C1185167E000833990; - }; - }; - }; - buildConfigurationList = AABEB8BD185167E000833990 /* Build configuration list for PBXProject "rfduinoBulkDataTransfer" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = AABEB8B9185167E000833990; - productRefGroup = AABEB8C3185167E000833990 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - AABEB8C1185167E000833990 /* rfduinoBulkDataTransfer */, - AABEB8DC185167E000833990 /* rfduinoBulkDataTransferTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - AABEB8C0185167E000833990 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AABEB8D0185167E000833990 /* InfoPlist.strings in Resources */, - AABEB8D8185167E000833990 /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AABEB8DB185167E000833990 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - AABEB8BE185167E000833990 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AABEB902185167EC00833990 /* CustomCellBackground.m in Sources */, - AABEB904185167EC00833990 /* RfduinoManager.m in Sources */, - AABEB8D2185167E000833990 /* main.m in Sources */, - AABEB905185167EC00833990 /* ScanViewController.m in Sources */, - AABEB901185167EC00833990 /* AppDelegate.m in Sources */, - AABEB9081851682000833990 /* AppViewController.m in Sources */, - AABEB903185167EC00833990 /* RFduino.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AABEB8D9185167E000833990 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - AABEB8E3185167E000833990 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = AABEB8C1185167E000833990 /* rfduinoBulkDataTransfer */; - targetProxy = AABEB8E2185167E000833990 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - AABEB8CE185167E000833990 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - AABEB8CF185167E000833990 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - AABEB8EC185167E000833990 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - AABEB8ED185167E000833990 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - AABEB8EF185167E000833990 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch"; - INFOPLIST_FILE = "rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - AABEB8F0185167E000833990 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch"; - INFOPLIST_FILE = "rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; - AABEB8F2185167E000833990 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/rfduinoBulkDataTransfer.app/rfduinoBulkDataTransfer"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = "rfduinoBulkDataTransferTests/rfduinoBulkDataTransferTests-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUNDLE_LOADER)"; - WRAPPER_EXTENSION = xctest; - }; - name = Debug; - }; - AABEB8F3185167E000833990 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/rfduinoBulkDataTransfer.app/rfduinoBulkDataTransfer"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch"; - INFOPLIST_FILE = "rfduinoBulkDataTransferTests/rfduinoBulkDataTransferTests-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUNDLE_LOADER)"; - WRAPPER_EXTENSION = xctest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - AABEB8BD185167E000833990 /* Build configuration list for PBXProject "rfduinoBulkDataTransfer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AABEB8EC185167E000833990 /* Debug */, - AABEB8ED185167E000833990 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - AABEB8EE185167E000833990 /* Build configuration list for PBXNativeTarget "rfduinoBulkDataTransfer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AABEB8EF185167E000833990 /* Debug */, - AABEB8F0185167E000833990 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; - AABEB8F1185167E000833990 /* Build configuration list for PBXNativeTarget "rfduinoBulkDataTransferTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AABEB8F2185167E000833990 /* Debug */, - AABEB8F3185167E000833990 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; -/* End XCConfigurationList section */ - }; - rootObject = AABEB8BA185167E000833990 /* Project object */; -} diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100755 index 076b6fe..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100755 index 3c6d2108fec8daba9569c6423e849b49ccd877fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12837 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

&DXylR?ix~fUlrn*UWvueJI zsqRqSqgtuDU-gjc5!Iur4%HUbv#J+VFRETry{39YwO@5WbyRgm^`+{Z>b&Y()i0_G zs^3+AsQ#_isZ-PyYOC6%o~53nzDa$vdcK;e7pNDh7pqsRA5uS}epKC|?ozK;Z&Ytq zZ&g30ep7uy{k8h9NO`0=GB>g^az^BW$mNl@N3Mum6}c{QYvhxWyCa{E+!OhF~e#nWCxD%+frl*{}Ihb3rT9hHKSYjW$ZF*BZ3x+I(%1 zwpd%D9jP6yZPdE7?b^B8dD;cqMcT#MrP|xHUE1y1r?oq^yR^HtFKG8`-_jn?zODUK z`-App?XTM3wSQ>;tqatJ=t6b`^RNV|+ zi>_7Y)V1km>zHnd?l#?W-5t6+br0)0bX~gjx-GhGy2o|fbf@-hQJ+Qq7OjYmj?RqEkDd^HQ}l}H)zKTGH%D)cemr`6 z^i$FAMSl@}F8X}*chNsY{}lb3-cKK_m+LuwKfPM7(d+bjy+L29Z_v-zFVQd4->zSw ze@MSYzfJ$Re!KoD{SN&z`d#`r^!xP(^l$6m)gRU$)t}Ix(toc1F(xD?CT2*?q?pE- zg)w)33V>)8C#B7UsJZ5{$Q!zVY_Qbpub2R3wm`jErLzE%cFvKv-P+%xB z6dUFk+=iuwWrjNpcNy+6JY?8l*kssh*kL$gIBB>Li(*NvU#vV<5gQhp6nkCl(AfOg z!q^?Ldt#5oo{arA_JYx1j5C%QYm80C7GtZ?X}sBZi*bQ*k?|qpCgYRF9mZ#kyN!E{ zuN(Ip|7Co~c-VNT#hT2fcvFHY!<1#pF%32iHRYM6n&z6;n4UGg zWZGwX#q_S}i0QcLl<9rbY10p;pUlWi&3@(pbC5a29B$T_qs%epSaY&D!<=Q#F%LE8 zn~TiF<}v2UW~;f*%$uj1o6W6ehk34fsrfeZGV|@`)#iuIYs?+yb>xPZ8jI4-V#oH8yhE;%kgt}?DQZh72_ zxVz%+jk`bYiMU;Hd*cqoeH(W%?o!-e7Gm+UL|Swfy(QLSvcy@EEm@Xa%MeSRrNA=M zGTJiMQf--JnQCdYOt&;!mRMF=R#_gjJZ#x%*=5;n*<;yjdDC*ha?tXw - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/xcschememanagement.plist b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100755 index 3c1b9fa..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer.xcodeproj/xcuserdata/steve.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,27 +0,0 @@ - - - - - SchemeUserState - - rfduinoBulkDataTransfer.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - AABEB8C1185167E000833990 - - primary - - - AABEB8DC185167E000833990 - - primary - - - - - diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.h b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.h deleted file mode 100755 index 5730d4c..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#import "RFduino.h" - -@interface AppViewController : UIViewController -{ -} - -@property(strong, nonatomic) RFduino *rfduino; - -@end diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m deleted file mode 100644 index e9e81be..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/AppViewController.m +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* -This is the matching iPhone for the bulk data transfer sketch. This -application has been included for completeness, and to demonstrate -how you could verify that no data was dropped. Its really for -educational use only - it's output is to the debug window, and it -doesn't have a UI. - -If you would like to test bulk data transfer with one of the existing -apps, you can use the ColorWheel application. Open the sketch in -Arduino, compile and open the Serial Monitor. Open the ColorWheel -application and connect to the sketch. Once connected, the sketch -will start transferring the data (The ColorWheel application receives -the data, but ignores it). After the transfer is complete, the -Serial Monitor will display the start time, end time, elapsed time, -and kbps. -*/ - -#import - -#import "AppViewController.h" - -@implementation AppViewController -{ - int packets; - char ch; - int packet; - double start; -} - -@synthesize rfduino; - -+ (void)load -{ - // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - UIButton *backButton = [UIButton buttonWithType:101]; // left-pointing shape - [backButton setTitle:@"Disconnect" forState:UIControlStateNormal]; - [backButton addTarget:self action:@selector(disconnect:) forControlEvents:UIControlEventTouchUpInside]; - - UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; - [[self navigationItem] setLeftBarButtonItem:backItem]; - - [[self navigationItem] setTitle:@"RFduino Bulk"]; - } - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view from its nib. - - [rfduino setDelegate:self]; - - UIColor *start = [UIColor colorWithRed:58/255.0 green:108/255.0 blue:183/255.0 alpha:0.15]; - UIColor *stop = [UIColor colorWithRed:58/255.0 green:108/255.0 blue:183/255.0 alpha:0.45]; - - CAGradientLayer *gradient = [CAGradientLayer layer]; - gradient.frame = [self.view bounds]; - gradient.colors = [NSArray arrayWithObjects:(id)start.CGColor, (id)stop.CGColor, nil]; - [self.view.layer insertSublayer:gradient atIndex:0]; - - packets = 500; - ch = 'A'; - packet = 0; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (IBAction)disconnect:(id)sender -{ - NSLog(@"disconnect pressed"); - - [rfduino disconnect]; -} - -- (void)didReceive:(NSData *)data -{ - // NSLog(@"RecievedRX"); - - /* - uint8_t *p = (uint8_t*)[data bytes]; - NSUInteger len = [data length]; - - // NSString *s = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; - // NSLog(@"%d=%@", len, s); - NSMutableString *s = [[NSMutableString alloc] init]; - - [s appendFormat:@"%d - ", len]; - - for (int i = 0; i < len; i++) - if (isprint(p[i])) - [s appendFormat:@"%c", p[i]]; - else - [s appendFormat:@"{%02x}", p[i]]; - - NSLog(@"%@", s); - */ - - if (packet == 0) - { - NSLog(@"start"); - start = CACurrentMediaTime(); - } - - uint8_t *p = (uint8_t*)[data bytes]; - NSUInteger len = [data length]; - - if (len != 20) - NSLog(@"len issue"); - for (int i = 0; i < 20; i++) - { - if (p[i] != ch) - NSLog(@"ch issue"); - ch++; - if (ch > 'Z') - ch = 'A'; - } - packet++; - if (packet >= packets) - { - NSLog(@"end"); - double end = CACurrentMediaTime(); - float secs = (end - start); - int bps = ((packets * 20) * 8) / secs; - NSLog(@"start: %f", start); - NSLog(@"end: %f", end); - NSLog(@"elapsed: %f", secs); - NSLog(@"kbps: %f", bps / 1000.0); - } -} - -@end diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/AppIcon.appiconset/Contents.json b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100755 index 91bf9c1..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/LaunchImage.launchimage/Contents.json b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100755 index 6f870a4..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/en.lproj/InfoPlist.strings b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/en.lproj/InfoPlist.strings deleted file mode 100755 index 477b28f..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/main.m b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/main.m deleted file mode 100755 index 8cadba0..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// rfduinoBulkDataTransfer -// -// Created by Steve on 12/5/13. -// Copyright (c) 2013 RFduino. All rights reserved. -// - -#import - -#import "AppDelegate.h" - -int main(int argc, char * argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Info.plist b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Info.plist deleted file mode 100755 index 1087eed..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${PRODUCT_NAME} - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.RFduino.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - LSRequiresIPhoneOS - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch b/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch deleted file mode 100755 index 743435c..0000000 --- a/iPhone Apps/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer/rfduinoBulkDataTransfer-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header -// -// The contents of this file are implicitly included at the beginning of every source file. -// - -#import - -#ifndef __IPHONE_3_0 -#warning "This project uses features only available in iOS SDK 3.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/iPhone Apps/rfduinoColorWheel/icon-144.png b/iPhone Apps/rfduinoColorWheel/icon-144.png deleted file mode 100755 index 1b20be23189c5de1d6585afe344bdf657df07a90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20800 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 diff --git a/iPhone Apps/rfduinoColorWheel/icon-72.png b/iPhone Apps/rfduinoColorWheel/icon-72.png deleted file mode 100755 index ae9bae90d087256ea00eb3e9d9ee597ae10b47e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9357 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 Hu0mjfZTzO@ diff --git a/iPhone Apps/rfduinoColorWheel/icon.png b/iPhone Apps/rfduinoColorWheel/icon.png deleted file mode 100755 index c8a914690d87f75b763f060c2ff5963a85d93595..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5378 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 TfF@C=e<=|v+R7!0)(`#*A-JB- diff --git a/iPhone Apps/rfduinoColorWheel/icon@2x.png b/iPhone Apps/rfduinoColorWheel/icon@2x.png deleted file mode 100755 index 82a0b27c705165067172f5e0f3859800238ed1c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16875 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 - - - - diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.h b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.h deleted file mode 100755 index 48b805a..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#import "RFduino.h" - -@interface AppViewController : UIViewController -{ - __weak IBOutlet UIImageView *colorWheel; - - __weak IBOutlet UIButton *colorSwatch; - - __weak IBOutlet UILabel *rLabel; - __weak IBOutlet UILabel *gLabel; - __weak IBOutlet UILabel *bLabel; - - __weak IBOutlet UISlider *rSlider; - __weak IBOutlet UISlider *gSlider; - __weak IBOutlet UISlider *bSlider; - - __weak IBOutlet UITextField *rValue; - __weak IBOutlet UITextField *gValue; - __weak IBOutlet UITextField *bValue; - - float red; - float green; - float blue; -} - -@property(strong, nonatomic) RFduino *rfduino; - -- (void) pickedColor:(UIColor*)color; - -- (IBAction)rSliderChanged:(id)sender; -- (IBAction)gSliderChanged:(id)sender; -- (IBAction)bSliderChanged:(id)sender; - -- (IBAction)rEditingDidEnd:(id)sender; -- (IBAction)gEditingDidEnd:(id)sender; -- (IBAction)bEditingDidEnd:(id)sender; - -@end diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m deleted file mode 100644 index 9db6f15..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.m +++ /dev/null @@ -1,317 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include - -#import "AppViewController.h" -#import "UIImage+Extras.h" - -@implementation AppViewController - -@synthesize rfduino; - -+ (void)load -{ - // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - UIButton *backButton = [UIButton buttonWithType:101]; // left-pointing shape - [backButton setTitle:@"Disconnect" forState:UIControlStateNormal]; - [backButton addTarget:self action:@selector(disconnect:) forControlEvents:UIControlEventTouchUpInside]; - - UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; - [[self navigationItem] setLeftBarButtonItem:backItem]; - - [[self navigationItem] setTitle:@"RFduino ColorWheel"]; - } - return self; -} - -- (void)manualLayout -{ - CGRect rect = [[UIScreen mainScreen] bounds]; - - if (UIDeviceOrientationIsLandscape(self.interfaceOrientation)) { - if (rect.size.height >= 1024) { // iPad - colorWheel.frame = CGRectMake(20,50,600,600); - - colorSwatch.frame = CGRectMake(667,260,330,16); - - rLabel.frame = CGRectMake(667,299,21,21); - gLabel.frame = CGRectMake(667,347,21,21); - bLabel.frame = CGRectMake(667,395,21,21); - - rSlider.frame = CGRectMake(694,300,242,23); - gSlider.frame = CGRectMake(694,348,242,23); - bSlider.frame = CGRectMake(694,396,242,23); - - rValue.frame = CGRectMake(950,296,45,30); - gValue.frame = CGRectMake(950,344,45,30); - bValue.frame = CGRectMake(950,392,45,30); - } else if (rect.size.height >= 568) { // iPhone 5 - colorWheel.frame = CGRectMake(7,7,250,250); - - colorSwatch.frame = CGRectMake(267,60,280,16); - - rLabel.frame = CGRectMake(267,89,21,21); - gLabel.frame = CGRectMake(267,127,21,21); - bLabel.frame = CGRectMake(267,165,21,21); - - rSlider.frame = CGRectMake(294,90,202,23); - gSlider.frame = CGRectMake(294,128,202,23); - bSlider.frame = CGRectMake(294,166,202,23); - - rValue.frame = CGRectMake(502,86,45,30); - gValue.frame = CGRectMake(502,124,45,30); - bValue.frame = CGRectMake(502,162,45,30); - } else { // iPhone 4S - colorWheel.frame = CGRectMake(0,7,250,250); - - colorSwatch.frame = CGRectMake(260,60,213,16); - - rLabel.frame = CGRectMake(260,89,21,21); - gLabel.frame = CGRectMake(260,127,21,21); - bLabel.frame = CGRectMake(260,165,21,21); - - rSlider.frame = CGRectMake(287,90,135,23); - gSlider.frame = CGRectMake(287,128,135,23); - bSlider.frame = CGRectMake(287,166,135,23); - - rValue.frame = CGRectMake(428,86,45,30); - gValue.frame = CGRectMake(428,124,45,30); - bValue.frame = CGRectMake(428,162,45,30); - } - } else { // UIDeviceOrientationIsPortrait(self.interfaceOrientation) - if (rect.size.height >= 1024) { // iPad - colorWheel.frame = CGRectMake(80,50,600,600); - - colorSwatch.frame = CGRectMake(40,704,685,16); - - rLabel.frame = CGRectMake(40,740,21,21); - gLabel.frame = CGRectMake(40,788,21,21); - bLabel.frame = CGRectMake(40,836,21,21); - - rSlider.frame = CGRectMake(67,741,602,23); - gSlider.frame = CGRectMake(67,789,602,23); - bSlider.frame = CGRectMake(67,837,602,23); - - rValue.frame = CGRectMake(680,737,45,30); - gValue.frame = CGRectMake(680,785,45,30); - bValue.frame = CGRectMake(680,833,45,30); - } else if (rect.size.height >= 568) { // iPhone 5 - colorWheel.frame = CGRectMake(35,20,250,250); - - colorSwatch.frame = CGRectMake(20,304,280,16); - - rLabel.frame = CGRectMake(20,330,21,21); - gLabel.frame = CGRectMake(20,368,21,21); - bLabel.frame = CGRectMake(20,406,21,21); - - rSlider.frame = CGRectMake(47,331,202,23); - gSlider.frame = CGRectMake(47,369,202,23); - bSlider.frame = CGRectMake(47,407,202,23); - - rValue.frame = CGRectMake(255,327,45,30); - gValue.frame = CGRectMake(255,365,45,30); - bValue.frame = CGRectMake(255,403,45,30); - } else { // iPhone 4S - colorWheel.frame = CGRectMake(35,13,250,250); - - colorSwatch.frame = CGRectMake(20,274,280,16); - - rLabel.frame = CGRectMake(20,300,21,21); - gLabel.frame = CGRectMake(20,338,21,21); - bLabel.frame = CGRectMake(20,376,21,21); - - rSlider.frame = CGRectMake(47,301,202,23); - gSlider.frame = CGRectMake(47,339,202,23); - bSlider.frame = CGRectMake(47,377,202,23); - - rValue.frame = CGRectMake(255,297,45,30); - gValue.frame = CGRectMake(255,335,45,30); - bValue.frame = CGRectMake(255,373,45,30); - } - } - - if (colorWheel.frame.size.width != colorWheel.image.size.width) { - UIImage *image1 = [UIImage imageNamed:@"colorWheel1.png"]; - UIImage *image2 = [image1 imageByScalingProportionallyToSize:colorWheel.frame.size]; - [colorWheel setImage:image2]; - } -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - // Do any additional setup after loading the view from its nib. - - [rfduino setDelegate:self]; - - // delegate needed so UITextField textFieldShouldReturn can dismiss the keyboard when the return key is pressed - rValue.delegate = self; - gValue.delegate = self; - bValue.delegate = self; - - UIColor *start = [UIColor colorWithRed:102/255.0 green:102/255.0 blue:102/255.0 alpha:1.0]; - UIColor *stop = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; - - CAGradientLayer *gradient = [CAGradientLayer layer]; - //gradient.frame = [self.view bounds]; - gradient.frame = CGRectMake(0, 0, 1024, 1024); - gradient.colors = [NSArray arrayWithObjects:(id)start.CGColor, (id)stop.CGColor, nil]; - [self.view.layer insertSublayer:gradient atIndex:0]; - - // self.view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"background.png"]]; - - [self manualLayout]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - [self manualLayout]; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (IBAction)disconnect:(id)sender -{ - NSLog(@"disconnect pressed"); - - [rfduino disconnect]; -} - -- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event -{ - UITouch* touch = [touches anyObject]; - CGPoint point = [touch locationInView:colorWheel]; - if (CGRectContainsPoint(colorWheel.frame, point)) { - UIColor *color = [colorWheel.image pixelColorAt:point]; - [self pickedColor:color]; - } -} - -- (void)setColor -{ - NSLog(@"colors: RGB %f %f %f", red, green, blue); - - UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0]; - - [colorSwatch setHighlighted:YES]; - [colorSwatch setTintColor:color]; - - uint8_t tx[3] = { red * 255, green * 255, blue * 255 }; - NSData *data = [NSData dataWithBytes:(void*)&tx length:3]; - - [rfduino send:data]; -} - -- (void)pickedColor:(UIColor*)color -{ - NSLog(@"Picked Color"); - - const CGFloat *components = CGColorGetComponents([color CGColor]); - - red = components[0]; - green = components[1]; - blue = components[2]; - - rSlider.value = red; - gSlider.value = green; - bSlider.value = blue; - - rValue.text = [[NSString alloc] initWithFormat:@"%d", (int)(red * 255)]; - gValue.text = [[NSString alloc] initWithFormat:@"%d", (int)(green * 255)]; - bValue.text = [[NSString alloc] initWithFormat:@"%d", (int)(blue * 255)]; - - [self setColor]; -} - -- (IBAction)rSliderChanged:(id)sender -{ - NSLog(@"rSliderChanged"); - red = [rSlider value]; - rValue.text = [[NSString alloc] initWithFormat:@"%d", (int)(red * 255)]; - [self setColor]; -} - -- (IBAction)gSliderChanged:(id)sender -{ - NSLog(@"gSliderChanged"); - green = [gSlider value]; - gValue.text = [[NSString alloc] initWithFormat:@"%d", (int)(green * 255)]; - [self setColor]; -} - -- (IBAction)bSliderChanged:(id)sender -{ - NSLog(@"bSliderChanged"); - blue = [bSlider value]; - bValue.text = [[NSString alloc] initWithFormat:@"%d", (int)(blue * 255)]; - [self setColor]; -} - -- (IBAction)rEditingDidEnd:(id)sender -{ - NSLog(@"rEditingDidEnd"); - red = rValue.text.intValue / 255.0; - rSlider.value = red; - [self setColor]; -} - -- (IBAction)gEditingDidEnd:(id)sender -{ - NSLog(@"gEditingDidEnd"); - green = gValue.text.intValue / 255.0; - gSlider.value = green; - [self setColor]; -} - -- (IBAction)bEditingDidEnd:(id)sender -{ - NSLog(@"bEditingDidEnd"); - blue = bValue.text.intValue / 255.0; - bSlider.value = blue; - [self setColor]; -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField -{ - NSLog(@"textFieldShouldReturn"); - [textField resignFirstResponder]; - return YES; -} - -@end diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.xib b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.xib deleted file mode 100755 index 48cda74..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/AppViewController.xib +++ /dev/null @@ -1,717 +0,0 @@ - - - - 1552 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 - - - IBProxyObject - IBUIButton - IBUIImageView - IBUILabel - IBUISlider - IBUITextField - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{20, 366}, {280, 16}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA - - - 3 - MC41AA - - - 2 - 2 - - - Helvetica-Bold - 18 - 16 - - - - - 256 - {{20, 37}, {280, 272}} - - - - NO - YES - 9 - IBCocoaTouchFramework - - - - 292 - {{50, 402}, {180, 23}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 0.5 - - - - 292 - {{50, 452}, {180, 23}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 0.5 - - - - 292 - {{50, 502}, {180, 23}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 0.5 - - - - 292 - {{245, 398}, {55, 30}} - - - - _NS:9 - - 3 - MC4zAA - - NO - YES - IBCocoaTouchFramework - 0 - 128 - 3 - - YES - YES - 17 - - 2 - IBCocoaTouchFramework - - - 2 - 14 - - - Helvetica-Bold - 14 - 16 - - - - - 292 - {{245, 448}, {55, 30}} - - - - _NS:9 - - NO - YES - IBCocoaTouchFramework - 0 - 128 - 3 - - YES - YES - 17 - - 2 - IBCocoaTouchFramework - - - - - - - 292 - {{245, 498}, {55, 30}} - - - _NS:9 - - NO - YES - IBCocoaTouchFramework - 0 - 128 - 3 - - YES - YES - 17 - - 2 - IBCocoaTouchFramework - - - - - - - 292 - {{20, 402}, {21, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - R: - - - 0 - - 1 - 17 - - - Helvetica - 17 - 16 - - NO - - - - 292 - {{20, 451}, {21, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - G: - - - 0 - - - NO - - - - 292 - {{20, 501}, {21, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - B: - - - 0 - - - NO - - - {{0, 20}, {320, 548}} - - - - - 3 - MC4zMzMzMzMzMzMzAA - - - - IBUIScreenMetrics - - YES - - - - - - {320, 568} - {568, 320} - - - IBCocoaTouchFramework - Retina 4 Full Screen - 2 - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - colorWheel - - - - 51 - - - - colorSwatch - - - - 52 - - - - rSlider - - - - 212 - - - - gSlider - - - - 213 - - - - bSlider - - - - 214 - - - - rValue - - - - 215 - - - - gValue - - - - 216 - - - - bValue - - - - 217 - - - - rLabel - - - - 251 - - - - gLabel - - - - 252 - - - - bLabel - - - - 253 - - - - rSliderChanged: - - - 7 - - 250 - - - - gSliderChanged: - - - 7 - - 249 - - - - bSliderChanged: - - - 7 - - 248 - - - - rEditingDidEnd: - - - 19 - - 229 - - - - gEditingDidEnd: - - - 19 - - 230 - - - - bEditingDidEnd: - - - 19 - - 231 - - - - - - 0 - - - - - - 1 - - - - - - - - - - - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 41 - - - - - - 42 - - - - - - 65 - - - - - - 69 - - - - - - 73 - - - - - - 95 - - - - - - 120 - - - - - - 130 - - - - - - 142 - - - - - - 149 - - - - - - 157 - - - - - - - - AppViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 264 - - - - - AppViewController - UIViewController - - id - id - id - id - id - id - id - - - - bEditingDidEnd: - id - - - bSliderChanged: - id - - - disconnect: - id - - - gEditingDidEnd: - id - - - gSliderChanged: - id - - - rEditingDidEnd: - id - - - rSliderChanged: - id - - - - UILabel - UISlider - UITextField - UIButton - UIImageView - UILabel - UISlider - UITextField - UILabel - UISlider - UITextField - - - - bLabel - UILabel - - - bSlider - UISlider - - - bValue - UITextField - - - colorSwatch - UIButton - - - colorWheel - UIImageView - - - gLabel - UILabel - - - gSlider - UISlider - - - gValue - UITextField - - - rLabel - UILabel - - - rSlider - UISlider - - - rValue - UITextField - - - - IBProjectSource - ./Classes/AppViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 2083 - - diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default-568h@2x.png b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default-568h@2x.png deleted file mode 100755 index 0891b7aabfcf3422423b109c8beed2bab838c607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18594 zcmeI4X;f257Jx&9fS`ixvS;&$x8J@slQFSel)6zJN=?13FB7H(lQjRkSy8x_-S~tvu2gzn1oS+dLcF#eqtq$ z%tf9TTvX?`)R@}3uBI;jzS-=ZR-Td&MHaS&;!0?Ni*#$#`n*~CcQK)Q9vAQ~TUpnI!j)a2biYK^R)M~A5wUDZhx?ULMX z3x1P&qt=trOY6P2U67L=m=U?F|5#Uj(eCueNTZaHs_ceWiHeET+j+tp3Jt9g(ekqP z2WOvfR{qV+9r+o4J5?qK>7;;^+I7tGv-i)es$X_D=EoKF+S?zsyj^oRFElP}c}JT< zd8SUs-?O?}2YD#ngKbnHgzHBcboxK_2r9l(?eNCl-pEzkJm}fY?WC*jnS?VBE4EpY zO$fEejz6fU;W2Kl>JeQBZBl-%Irg`obSlg*@4QB;Dd1H7^Oi5wvt4d{RZ!8Og?^aE z)k0$1g+V3fd(gdQ3d&q2q-FL*uy#}|bc^=VhFsl0jBgUGJ+-s3U8MK9A!YJJMxpci z5hJ%|{DwV48fZn0{n5l$N_KcSb#NKE4plB`9I6Zt=Z!~-zw0{9tg$L&Ju1F0X)Cy8 zKF;(&lJ>x)Jw(=;p~sF(Sd9VWGwFE2rnyS9!f^DZ8+aCLq zQ};>lcJ1GDLqjm6Hd>|Eabno@P`~Bn(~6^aD_#yoEH(a?Nm1S<;S+hSxI5d16^<1lEM3NPFi zkqPrpL)+ zgnseFikg`gJVBha1&7C4;O6>h=dt~`ND+;Zd?W(4v2JIb7Pt>Td42%M-Ju-XAH#Pns762L}K3 zDhvsRqN0Ni(1UrishD2YvV?4*h2iFj$+&N||Fn$4n|^NSU+o?~jq`0jVQt8T9l{7b zXiwwODFh2V!Q6sqP9S>WH$oOf$N~=d0-bqTlD61!=`&0eAP-F>XN?*|gtOXX{ zQVTWyYo4ZK0GAw!GHf|pz9`D;-bbb*5LBX*{bnz|+)$@&P9|ORM2o?95{;ejvo&r- zq8cBhTN6nn)7~W>54U)%-F_-b?YKdfk5I8MHcuzBD5)!;yv#Z&R&^y=@=>VTIMy#r zX&U<=BsPkdqcMe<_}2+>H%XKyrr5ZR8_KVe>ZqYN z^=^~TFD};;rHJ$U;{~w^hYojl4hRI@SH$^K{YEo=sg)WY87r!*7blQK&qnpDo0`Vn zkl)9u9g=mCh&ZCJS(L4yN3k0kQ zuvg$h2KEEk51T+O0JQ+r0`R>g{jvqM0Mr6d3qUOZwE!?PI7HY@CE|dr sfw?Q;rAv?G4&^^8-z_>&sWXMxvD*gPOU4CBe-*@OtE+wfmVJNyHv)PfH~;_u diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default.png b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/Default.png deleted file mode 100755 index 4c8ca6f693f96d511e9113c0eb59eec552354e42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6540 zcmeAS@N?(olHy`uVBq!ia0y~yU~~ZD2OMlbkt;o0To@QwR5G2N13aCb6#|O#(=u~X z85k@CTSM>X-wqM6>&y>YB4)1;;ojbLbbV-W^iFB1wa3^zCog^LCAReC4K0-?R_2{6 zrP*)4+_uWUy3w5N52M3PW_}MFMP9a~>YLvVZ1D_k*IMQ2QT^fwzoOb(*3gH$%aYWC zkHmcab=va2<#X%jakpJ;<1@F;k__#bwtC&%^D0v(FBh9K&$sK+<}2RJS609D)17$w ztdQP8(eLM8Ka}m_IQ@3wyMKP)l=oM4-?`YS_*P?4V_ORLPxsj&7Ju#kH;>6^Kp?T7~ zl+q?{UOOqV==?+d{=)5s|M~T1mwtH@+Z^$G&eEO9JNP^AX@3jZ*J*!!>lc|1-W%fA z@AOQpXZ_Lt>rxFXrGp*zLPiW@uo_c7C{As>j zWeX)wi+LTp_)@KYZCX{j;H?|1yXT4DnlS(Fr8gyP5|uaX_gLvaW0ScZdnG7o+u{T6 zFI-%d{ls*WuCDa5UJ@|RXv&ejZe}*BMkiWY51&pnRPw(hlykSzvj6e%mYz-GdvzBD zF10?szF_~!jS=?2HyQuPCvARXAe}C}WP|yQ*>5~~=*Nxq8+HHW1~FMDRCP^TcacKuk$ z(U#REVv)D!PhJ*ecH-ELFUrfyV&*)Z)>UCOuS?yd^L@Afk>ihynYPc{^CRwu+JHX+#$@YsC4c|l0tGigsn@jy) zXD($Ouk>H+V(Mr6NQT0S9BFM~V6nkj;1OBOz`zY;a|<&v%$g$sEJPk;hD4M^`1)8S z=jZArrsOB3>Q&?x097+E*i={nnYpPYi3%0DIeEoa6}C!X6;?ntNLXJ<0j#7X+g2&U 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 diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.h b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.h deleted file mode 100755 index 93add82..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// UIImage+Extras.h -// BitmapResearch2 -// -// Created by Steve on 8/6/13. -// Copyright (c) 2013 Steve. All rights reserved. -// - -#import - -@interface UIImage (Extras) - -- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize; -- (UIColor *)pixelColorAt:(CGPoint)point; - -@end diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.m b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.m deleted file mode 100755 index 6ed2a0c..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/UIImage+Extras.m +++ /dev/null @@ -1,107 +0,0 @@ -// -// UIImage+Extras.m -// BitmapResearch2 -// -// Created by Steve on 8/6/13. -// Copyright (c) 2013 Steve. All rights reserved. -// - -#import "UIImage+Extras.h" - -@implementation UIImage (Extras) - -// http://stackoverflow.com/questions/185652/how-to-scale-a-uiimageview-proportionally -- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize -{ - UIImage *sourceImage = self; - UIImage *newImage = nil; - - CGSize imageSize = sourceImage.size; - CGFloat width = imageSize.width; - CGFloat height = imageSize.height; - - CGFloat targetWidth = targetSize.width; - CGFloat targetHeight = targetSize.height; - - CGFloat scaleFactor = 0.0; - CGFloat scaledWidth = targetWidth; - CGFloat scaledHeight = targetHeight; - - CGPoint thumbnailPoint = CGPointMake(0.0,0.0); - - if (CGSizeEqualToSize(imageSize, targetSize) == NO) { - - CGFloat widthFactor = targetWidth / width; - CGFloat heightFactor = targetHeight / height; - - if (widthFactor < heightFactor) - scaleFactor = widthFactor; - else - scaleFactor = heightFactor; - - scaledWidth = width * scaleFactor; - scaledHeight = height * scaleFactor; - - // center the image - - if (widthFactor < heightFactor) { - thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; - } else if (widthFactor > heightFactor) { - thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; - } - } - - - // this is actually the interesting part: - - UIGraphicsBeginImageContext(targetSize); - - CGRect thumbnailRect = CGRectZero; - thumbnailRect.origin = thumbnailPoint; - thumbnailRect.size.width = scaledWidth; - thumbnailRect.size.height = scaledHeight; - - [sourceImage drawInRect:thumbnailRect]; - - newImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - if(newImage == nil) NSLog(@"could not scale image"); - - return newImage ; -} - -// http://stackoverflow.com/questions/448125/how-to-get-pixel-data-from-a-uiimage-cocoa-touch-or-cgimage-core-graphics -- (UIColor *)pixelColorAt:(CGPoint)point -{ - // First get the image into your data buffer - CGImageRef imageRef = [self CGImage]; - NSUInteger width = CGImageGetWidth(imageRef); - NSUInteger height = CGImageGetHeight(imageRef); - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char)); - NSUInteger bytesPerPixel = 4; - NSUInteger bytesPerRow = bytesPerPixel * width; - NSUInteger bitsPerComponent = 8; - CGContextRef context = CGBitmapContextCreate(rawData, width, height, - bitsPerComponent, bytesPerRow, colorSpace, - kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); - CGColorSpaceRelease(colorSpace); - - CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); - CGContextRelease(context); - - // rawData in the RGBA8888 pixel format. - int byteIndex = (bytesPerRow * (int)point.y) + (int)point.x * bytesPerPixel; - - unsigned char red = rawData[byteIndex]; - unsigned char green = rawData[byteIndex + 1]; - unsigned char blue = rawData[byteIndex + 2]; - unsigned char alpha = rawData[byteIndex + 3]; - - free(rawData); - - return [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f]; -} - -@end diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/colorWheel1.png b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/colorWheel1.png deleted file mode 100755 index 07a14c17201d0f3a58bbbcecfa837030f6ad79d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73771 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 diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/en.lproj/InfoPlist.strings b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/en.lproj/InfoPlist.strings deleted file mode 100755 index 477b28f..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/main.m b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/main.m deleted file mode 100755 index 2736a11..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// rfduinoColorWheel -// -// Created by Steve on 2/11/13. -// Copyright (c) 2013 RF Digital. All rights reserved. -// - -#import - -#import "AppDelegate.h" - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Info.plist b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Info.plist deleted file mode 100755 index b8d95ff..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Info.plist +++ /dev/null @@ -1,51 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - RFduino ColorWheel - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIcons - - CFBundlePrimaryIcon - - CFBundleIconFiles - - icon@2x.png - icon-72.png - icon.png - icon-144.png - - - - CFBundleIdentifier - com.OpenSourceRF.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - LSRequiresIPhoneOS - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Prefix.pch b/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Prefix.pch deleted file mode 100755 index bfe7e8c..0000000 --- a/iPhone Apps/rfduinoColorWheel/rfduinoColorWheel/rfduinoColorWheel-Prefix.pch +++ /dev/null @@ -1,14 +0,0 @@ -// -// Prefix header for all source files of the 'rfduinoColorWheel' target in the 'rfduinoColorWheel' project -// - -#import - -#ifndef __IPHONE_3_0 -#warning "This project uses features only available in iOS SDK 3.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/iPhone Apps/rfduinoLedButton/icon-144.png b/iPhone Apps/rfduinoLedButton/icon-144.png deleted file mode 100755 index 75bad77281070268eeae2b7dc55f97323714f6a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22125 zcmV)OK(@b$P)X+uL$Nkc;* zP;zf(X>4Tx07wm;mUmQB*%pV-y*Itk5+Wca^cs2zAksTX6$DXM^`x7XQc?|s+0 z08spb1j2M!0f022SQPH-!CVp(%f$Br7!UytSOLJ{W@ZFO_(THK{JlMynW#v{v-a*T zfMmPdEWc1DbJqWVks>!kBnAKqMb$PuekK>?0+ds;#ThdH1j_W4DKdsJG8Ul;qO2n0 z#IJ1jr{*iW$(WZWsE0n`c;fQ!l&-AnmjxZO1uWyz`0VP>&nP`#itsL#`S=Q!g`M=rU9)45( zJ;-|dRq-b5&z?byo>|{)?5r=n76A4nTALlSzLiw~v~31J<>9PP?;rs31pu_(obw)r zY+jPY;tVGXi|p)da{-@gE-UCa`=5eu%D;v=_nFJ?`&K)q7e9d`Nfk3?MdhZarb|T3 z%nS~f&t(1g5dY)AIcd$w!z`Siz!&j_=v7hZlnI21XuE|xfmo0(WD10T)!}~_HYW!e zew}L+XmwuzeT6wtxJd`dZ#@7*BLgIEKY9Xv>st^p3dp{^Xswa2bB{85{^$B13tWnB z;Y>jyQ|9&zk7RNsqAVGs--K+z0uqo1bf5|}fi5rtEMN^BfHQCd-XH*kfJhJnmIE$G z0%<@5vOzxB0181d*a3EfYH$G5fqKvcPJ%XY23!PJzzuK<41h;K3WmW;Fah3yX$XSw z5EY_9s*o0>51B&N5F1(uc|$=^I1~fLLy3?Ol0f;;Ca4%HgQ}rJP(Ab`bQ-z{U4#0d z2hboi2K@njgb|nm(_szR0JebHusa+GN5aeCM0gdP2N%HG;Yzp`J`T6S7vUT504#-H z!jlL<$Or?`Mpy_N@kBz9SR?@vA#0H$qyni$nvf2p8@Y{0k#Xb$28W?xm>3qu8RLgp zjNxKdVb)?wFx8l2m{v>|<~C*!GlBVnrDD~wrdTJeKXwT=5u1%I#8zOBU|X=4u>;s) z>^mF|$G{ol9B_WP7+f-LHLe7=57&&lfa}8z;U@8Tyei%l?}87(bMRt(A-)QK9Dg3) zj~~XrCy)tR1Z#p1A(kK{Y$Q|=8VKhI{e%(1G*N-5Pjn)N5P8I0VkxnX*g?EW941ba z6iJ387g8iCnY4jaNopcpCOsy-A(P2EWJhusSwLP-t|XrzUnLKcKTwn?CKOLf97RIe zPB}`sKzTrUL#0v;sBY9)s+hW+T2H-1eM)^VN0T#`^Oxhvt&^*fYnAJldnHel*Ozyf zUoM{~Um<@={-*r60#U(0!Bc^wuvVc);k3d%g-J!4qLpHZVwz%!VuRu}#Ze`^l7W)9 z5>Kf>>9Eozr6C$Z)1`URxU@~QI@)F0FdauXr2Es8>BaOP=)Lp_WhG@>R;lZ?BJkMlIuMhw8ApiF&yDYW2hFJ?fJhni{?u z85&g@mo&yT8JcdI$(rSw=QPK(Xj%)k1X|@<=e1rim6`6$RAwc!i#egKuI;BS(LSWz zt39n_sIypSqfWEV6J3%nTQ@-4i zi$R;gsG*9XzhRzXqv2yCs*$VFDx+GXJH|L;wsDH_KI2;^u!)^Xl1YupO;gy^-c(?^ z&$Q1BYvyPsG^;hc$D**@Sy`+`)}T4VJji^bd7Jqw3q6Zii=7tT7GEswEK@D(EFW1Z zSp`^awCb?>!`j4}Yh7b~$A)U-W3$et-R8BesV(1jzwLcHnq9En7Q0Tn&-M=XBKs!$ zF$X<|c!#|X_tWYh)GZit z(Q)Cp9CDE^WG;+fcyOWARoj*0TI>4EP1lX*cEoMO-Pk?Z{kZ!p4@(b`M~lalr<3Oz z&kJ6Nm#vN_+kA5{dW4@^Vjg_`q%qU1ULk& z3Fr!>1V#i_2R;ij2@(Z$1jE4r!MlPVFVbHmT+|iPIq0wy5aS{>yK?9ZAjVh%SOwMWgFjair&;wpi!{CU}&@N=Eg#~ zLQ&zpEzVmGY{hI9Z0+4-0xS$$Xe-OToc?Y*V;rTcf_ zb_jRe-RZjXSeas3UfIyD;9afd%<`i0x4T#DzE)vdabOQ=k7SRuGN`h>O0Q~1)u-yD z>VX=Mn&!Rgd$;YK+Q-}1zu#?t(*cbG#Ronf6db&N$oEidtwC+YVcg-Y!_VuY>bk#Y ze_ww@?MU&F&qswvrN_dLb=5o6*Egs)ls3YRlE$&)amR1{;Ppd$6RYV^Go!iq1UMl% z@#4q$AMc(FJlT1QeX8jv{h#)>&{~RGq1N2iiMFIRX?sk2-|2wUogK~{EkB$8eDsX= znVPf8XG_nK&J~=SIiGia@9y}|z3FhX{g&gcj=lwb=lWgyFW&aLedUh- zof`v-2Kw$UzI*>(+&$@i-u=-BsSjR1%z8NeX#HdC`Hh-Z(6xI-`hmHDqv!v)W&&nrf>M(RhcN6(D;jNN*%^u_SYjF;2ng}*8Ow)d6M ztDk;%`@Lsk$;9w$(d(H%O5UixIr`T2ZRcd@>!MN>M4ACyKtc$CBy1!XXKlpQy8`BFnJ{r})c)jQR#uCePX_K}04GbI4Ca%}zdV(nWRcaX@oB=G ztgfe=zQ#0coNz0&F#jBXn-TSMg>2&u7|%IbhVh)w%t&RNKx?Y~s|Gm!c04j!y?-`C zF1P|;pJb`YD*fwEUt=1!LQ^Ls+zP~9p~!?k$KgErvbo5U&p%Z#H#b>MyAG& zHP}Cy1c?-5d3Jwkq3lh7#dkclu=xD1_k*8EF zwl~>mFH5Q9JFS$sYdaP22fDy z>gs|6I5~Yh1854$nd{1E=eM32XNegf5JVJ_;_dPwV+Hu~iR1BAX_%6VjXyJrXPtG{ zj2Sb^6|aJDqoeI|sTw4%S2Pc<+WGLqkKTFbomX9T)$G}`ySwYfVp&;SoH1j)Pk!=~ z8*I4#$Vda8if4>-Gn54Z!!TaU&pYqDi!Z)dTpj_&YLQ3goHCf?;$<&;?FlEGPzI_{ zmj9dI{AR7Ip3#;q=g;(2&`)p(6QXAkAsH$~J3rO+p$~m%>#euWZ_ha6j6eSIk6ytO zK8geDr{W?CN>SF^G0Zz15}Xrd7;hakG6YYx1LY|(=LFEt@u1*%e8R}8G)w_Nfd(Z% zrKq)c$`pc*VG`?gNCXvH?GbJ8RZoQ>lFx7qICsziQ|o*(2$aUf~j7?E6o>CJX-?AMf{W~E+?4s2;)o= zmm%YjLCFKSbk7`Q5LrIui8t|Yz6X$U0F~f`{wbmXo)R-02#5;+=FHw^ta3!Uphj<% z1w@eIr$l-D^vqRAk;fAR&y;uUAtk@cIo0lG7RsDoI!=f~MqCw2=2GB~SCMhc(k8Q< zUWtH~BjS-eCFb;8ulUL#x&a_2460W$KQjpEM#~f4irjd^4GR|BSF3hK@lsHMJnpvJ zZX0Z{ftqTyioYX{IO6l4KL^r;xY=YgYIxjkjkY_58*aGa!3Q7I57k9};f zz4nBw79McG0W)Tt|JY-X)$84m03^&8k!+U~zv7B3m>TH|D+e)h=`w%Bvsx54ihQjIcUxk(MkUe4{FkvV?7Hv5u%~v z2BcWf-@sMKQdSHmhU6|-u;3TJ`1d{b*bTS*M0EYuqmMqSg}Hce3%gQZf-dm(3f_u~ zKt@47Wl%h)h#=Ocn{ImGfd_88?Y4>#e@@NKH{XmF-X;kMyXR*y@qO#9x87>2t)zfP zS?AB6pV<#GH1^tSuioBXapCscZ-3;GN7OFtvdb>(t+$>;Fr`CVB9xy0{O51J`R3FM zR=@epZ@dM6|NZy(RKMBBFTUxf zo9?*d4xEFPoS7QH3VyDFBdcOqF0XKo1iMl|omPtyghXo(!4YARm|{8ogk?^LhgZZC zkYr4{GG-uBG{9h=F;*})RZi)$$*-&k+4SnjBaeLh+ux3AGN=OlH@x8u-~RTuLDE9H zUoLZ4;*}!HmMuH%u*2T;rZ-6e`RiZ*I)9Jccq;(=?sva?`|Y=v)6e(4?|mpvbijG< zd*8d$PCI2dAO7%%vsJ{BV~;(StjND)$r4iXy4St#jc98S>i$_B*iC;y;wB9b>3h03U3lMo<_6b82vWb@8X0Ymw*1K> zu~-Vt^9thwPn~DG(;5wdL%{SGm{W#gkyAc4jgSRJdU{2P8M?r{F+6z6d)|BaD_>c7 zLJbI&vg@xu{hjZ8=l%EJ|BGMz0?rta+x5W@ocfyAye4(AZOFvvBS0zL*>lg`cirXe zFP`&doW}cRD>^yVc`JelA}fbU`>>ofb0W(H3MBQ$=3nSpGw>87|fI52R};d~wT%U^z|UJZ~+ zrAG69`O9DC;>_JiC!NGFJb_+m;lhO!T>}~3jW^i@5m4;3(@vwc*xWOvH`kSAWgJP+ zmJgFMOaUn7Vo*;MkA{iEpfySyO7D2*JC8fAQ7PBPB_j1t1?0<2o%Q?QUv$w$j9c!g zl+6G=(f5!;4jHdvJOVk?`TqC6FQNg`4?p~HjYL}9S}=e9M?UhA-~ayi(sc}Ped}94 z@S)S>Oc?%&%6h6BW zJKjMAm-a1FHd|3OLOY|e!gJDbSmuqA%Lj?MJnXYLsLwz+F(AC9EVLQ>U;Xlz(4q?D zC{qnx0*@pI;y{hlE@zM;BEVb2aBjm5H{5sMy-{XAnmwL8UnSI-@@=bZhyFDzcX z)JT*ZZ8vkKu@HJ{uUZ(G<*^+{FGp78bfgx=BS^TMmzdMZJIhctB~`A$Nn-9xxN|@K z=}$F@`b*4W3l%~Gr)YCxmrgRx~?JIWjUj>dc!A>hZ@P z=bmvBqL!q-a^@=3lJWGEm`NZmn-J|u8PGSsRiQlNMaE0Xmh*cnZZL1YEvLX1hZr=O z#hFB+sUaFGog*q8eB`_Q^2;B7_+bntNy-|nA`UP2)vtba*+{P4<^lcc(o3`g1PugD zE0#xQJU*#O%sFx~b!5RA2LyFi(RAOHSN>+>jW*SnFyAp{mHhaPH{MwHOG{WnIkVs} zQQ91wh&G6}KJ}?jU3uk|tO^t{0Pt)%(gVq8X}-x%Lv2Vm1~9J%<~EN>wY?2Vw?RaXCE|$_NUb{__(+>rtl@luI`tKdgJ`VrSo1EjN! zTW!7d*=L^}6dxXjJ>+1ZN#Zil3CJOY;)=jBhEHwqMr00+;%GC67{1s#bKgWZgxd_bV^iy?cEiqHm6LGzg4yvpp2nx(iP98WWZNHX;`gZC%BrEYm`%~bJZ(9CuP{mS#t{O6n}KNWr$N@$XcDz zPO(i<&N=5C19+&zLxz3#-Itrx-yaNv1ZHU-J5L$#S|0d$r2)B}3JPqkic&b9Qzxp3SBci1%yML)kqq2Z01&ih2~gGl|A>^i|~1y z1sC!(@_+*l0KvQrJm<`fiBr|dAfk592}6j+gaOd;AVZF45K&E%HR(WOg9zl1@-v_L z476}VJl_$-{O zm%QX9UZ^x1K-^LVtO%({)+BB;MMr3friBhV=pejj22@e4$NZUBnNk5K)hm*zmO-gq zdWI~XBT7MALAA&x-A}IssPZYaOGGx49S0wLFu#Kuc?)w5F}_qv1_ZqN>Z=u(6DUsw zCkvDIVerdH=QaSXCJ1HJ(U|#AQ%;wMSg=l4UU}s=zVVHBz3W|peXC_|&640d-+2;V z0;qTfO8_dBnAn9J%K(U1p3I|KK=TUf;t2hNAN=5N{^oBa%KZA*zn%}t3)NWo2NjeVX@zb<5)j@HW#X;nmYaq*H>j2kW^9156xRrkI;u+%n4lDZ z;o*U%O<^ z$a~Acjw1%94Bj%`bo%6zPu7`fFyw*436NzFSA;AQzPu)&I{1T@i>qS7u&ONr>JXHN znWvy(miX8=^$j;0A~JxhCe`OSQX0&jamE?P9(!y`=}ev4%Yq{=oD3K>Np{5N!~-Z% zikxZzN<^zPSi`_n5rB8!efL}5@|IIiJ@uGlj^P|jC&-swcA0_1=t$#lUw4$QNO7de zI3Ng^=bn2mW}A~`i->uy{rlhj-aq}*Kb`u4({znmq|~^%Ru-E*HAiOX$spqAz4zXm z$Lur=%-mjYA*>1J@6Fzd5IYoyeEz8koM(>MTi$%^;jen-7F%o~9r9%N)?0673B9Gk z+Ne@b#kCzAalj`G#Vm9azLTgukn_y^5U*9DhXA^F>XfYh6g;;I_TsRCsCah4xlg=b z@hm$T70fj!kOz_|tA)}5S4yQ)!1n}Jy2b#jVIVLpCI$Son4}Mf$&@KQ#(v(CXmCIX zgsEa7?17&Q9p91xWTOn{^PI9gfXI)L>M}$$p7#@;s>_6fi4+vf&CjINe2Ea_-JuC2 z)uO$gU@8k#@^iz4dJ71~TV6meGmY>E&F~cRny;Wd;0U?xO39F0t?bI7m z^I!pyQ%0LXM4>qv{(_puxs^2|6G8?RE53a9nbAs(WH4>u8FM#e20UdBTLBTK{~86JcFyJ`J1L-(Qy+@l3+CVkYpJ z)ZTTztufwwHmpMws7zmfvvmmFXHhL)dif2{QehpUK=Gc3(tee72<2xssxb-l%%;FP z*7`{&8P~CPJY&#(mSO7{tDj}qI>xY=+h4~}erBWlq;~#3vq|*V)%s^O?5~R-e-@iH z)`u;>UYA!0r3eM<)lLIh&MXye-Wly!nYA7mt9e4kFX!|#@=p?qtxlX|P8saKEmq3* z{@58gN%mDF+lkOA+h1H5E>`WWtdxp%`&8jJ@n71AX&8+pEt6imP2}N)*udZ6Dbz&BYgw?1z)`2@t3iM9v zwjszGt{pUK!`5oRkkzg#d+hoL2WsWoXmixQwb52{+Vq}kWn$i^<7IFSVX`KiwvEPg zxxH?BYC*`X3GiD(iQEom?p=22~t=?p8Y;apddDZu2PCEaw*st&1-B z@tiy2tj)?nMcH6@Wz&EiB2LrTow3czqz3l?(O|<9(%^?o?PA&>Biv zV+@1O3L54ohMn@Bx7zwbInvMAol&XPzwwQ49rB95^>&ss^9$j z2j`zh64Ew{u&Cpeu8@DSpPgcB?|lz>?Q4#5oY!U%IJoKP$3Of(*Zlg5Ns2t7d1_K? zvIZ zO&wOX*3}%g^=@om<_bkt{gZau+m2gKw>WMN>V$HoK&{g8fRasBaYs+NIAuz& zE^IipT;UrjrooKmoRiMg|ViYP#5!oTK->#yuobRbGK_OLO+Q8B*Yacgww2j4&M z*kfLQ*PK62pEjjhio-i=HLOX7WkfS4#*JIttrkt}j5yt2i0<0OKW(Bv$UA>xgL-yw z#M#oZXDLo|*Q%|XXI*{D$#1`V?j3HqS^@1f{&P)MFi!Vz?Gb5r8ik_GvkZkCzPsc0{iD7K^C ztXnxU9-pj{hHj;D)dfYtt*~B+Ywb~XX~T^++3ESa*?_66{-&pE%4nnAG0>VQ7=!J$ z`wL^lRCH-pyIShP@RYIbxL7!Z?UAyf)o5qynY(PW?T*c%e(E?p5ci1;4)s5H{{u^x zE@2pHS1?Y1O(=Z%l7IiVfBon09Ch3&OBVOB2iWUWx3ePYR9Uhz6XCPEX={;TtBcB0 z&0pDXzk|Q>)vw!5&snpXw>do0UF~VMCtK%p=}M_usSOUG@6d1;)z zVlpU?|I?OqJN|E;_4|4?)WBJ$e4I&q4Tg1|VQ!plcZM6IgWLiqT8Ep%+|st;Y|)iB z6Z|zBZTAJDH6r4cfrp`UxFV@fHE%KE&ZAJciVo7%2AS@IL&J^XX0cG|9~vHPG&kCG z(=*Qc$Bj4JGUbdp8w|?B%1bZ#6}2mtV%#Z6lxGcwb)R9W1M04K=`qN3cNccG_$Eed z6aS?ns`@J2V$;xiIhrOemK>b|DIZEOY>Q4f?n}{GwOcjpZFe4je9`lF-|OI)9vXv- z=)?4_MO~fPHCJD`Y}t~mcBQyGH}r4yMlh>n?>f&gy?wP*Zwxj#3{HfHeQdPqMr*p3 ziT*kT_hQ6Q&fz8fQw+vS4itr_h~a33g`9}Q36s`h6lTP;CS&kXr`77J*7}D=Uiz}b zYjFuAHU*2r3Kj|r7u@s6Ll5E+8w*g}#1i~UVzo+6Jjs{qzSGg^TzBm?C!KhFI?uyt z7;%9JZ@ukG+KIveFFyF>_q<=`8lzXPj|`7cnyhO4I*P|jOb#aw24Cr4ww(M=Vt|pR zo^hGx?6mVP^`7pLM%+Gu%`$|pHHH^1xOdy_cjnuKGntMyO@zo(Ok3v}W~BGnqWiDB z^1(dIhYThg!mY?Y_ex}$vGGQ2Q|uHarly_iibG&xp(Dw^r!KU@V9Rm9(4JyhC&_%G zy!8~03C|>s36G4<*l?rurmsJ+cv1M4F`%YL#%yjrc!(@8%6KROy3>MLeOE$fwG-BP zljs%>Q(vWasnRJ|xqh5FW{8DD_lf?xN^x+n*r}CAs)o6ie$2nf8O$n{k)B;M{lUHw z1t83RuxXfzopHL`t2PD{;zZwQ+o5-=rpN5W6&_Ks<(vM2AxAS??cunSq=}bh3udd$ znMn$)^BUIfglkTUlZuSBGR-DUY!Y2%HsWAyq0{Yj@9>ag$-Ujy>n0)3ll8<6M^{@p7`~2|6S)b48@I{V%92d5DB9dY;!Pt zd73RxB@-e(KVpqIU6Wzin0ACmzM28c)72F8n==`XWkMjJ;9}|x;S%>_a6VQO_Nub4 z^9nlL{dtCP zWhywxKhTP6D~!gti`8n6HB6r0$~jk^LPs0T;e5Mgo=bFfLEMwpiJLTH*Gae`VGP48 zQ+SJlYa*-}C~E?frw&6W-#0MO7%iH}jmh7^wDdNKhPex5v=rCT@Y_>=({jUCb{19( z19wupW5&>Xg;F4Iw&@n`2LdxzUy{?&vPQAmz2pjj$9}H!P6w0IF+y_pkli#sC(>yT zk2KxBIoYzNC6rhU(eN0vv`fSE3`YKy=T=eZNhULM4 zM0&PLV5{+Rt!tP`2L>nRLyb)A+%pXk_t`TP<^>oKjYQiJagB@?ntwBkTdu||T{~{b zwI3~(pC$_>ip6yZ5HY##2Jfo-h0?bOzX~jfl6f71FIP~??H`-)mq=|v1 z{$Zurm15j4wMN2PXBaG_wIv;Ubj})p58+Q2y5fkOdCS6UvDn?!ZQAlPpZm<**>_^64lq2Oa@^KL&s@fc z^%2ibM{06bxCyXd{iL@H+s@18`DyDYou3j8z_I7dmIxe;z95kn%r;5gF{!^r@R%wh5)oZ;r|GM!~wXTn% zF+tPl%nFUPyix@y3_)x9w7CD@u4M~lb`Z&P)2tg@s`ry0oSSBiS&cy6_}v8ZcH8XW zp3$t4nPHy7pQ?Y_v9->y=15riEWe2{#nF-G*U$ax1^;@XhDq0+Cm0rXzu3_ixlGOV zQB_`?k?s3VJ$<{GJH^V>L;+D}{r>vXPC40>t!bq+$<(onw`Iy{q7W1F)y^@;y#0U! z4lTqqG4Y7&fZ(7k^Bj%>1e(o@F8Hat=LY-xY#z1LDT4|AdGqEy@ZkNfBDOVwov)PY zqixqy#X!AWshxP@d)?_NTQ=|N*E-UW6>cJQRy%F2Gb~WXlJIMzuL`?YDqQ=!Yux2G zF|w}KZSl6|dC-A} z5{O3spzlFsg^)Rv*ngcuY};r~3sLb49*H8W9=gal3#&D=tZjng1ugSAtzKxSKqfMT@;j;vFty7^Sr6i(>6ktxi(Q)mot$S9Pu&2za7J zegvynCtM7}HepE9#93T|vMEm%2(0om=$p%?OPxX^VN0Js z2-zNvD_n;8G@ols!=Ok`v%N-zFn~$Qh6Z9T09P9A*oP#@=@qW!pPqjGDIVi7TY4>+ zvCXX%* z>FNZhFl>q&9&PmxS{HVz%PFS#UQD%XV%ZJjyOHp9eX^%QD^_c)(&@tl$tW;H7s9F9TIMcZQA^MtifE386|IB3-_j1CR?9JEsQ zn#G=6ucL!BLu7n}bg=<#LO7EpmMdN1<8Y+1novTP)V+>OV4tc^|B*#57LG#bluE-{F67o=`P%Jr3E|BQt z#n^o`>a0u)uT{z)CKFIF+Qkesgt7d32|#O#)n@M2b=<7v)HM1 zE?CFlAYJBDYI{P?iH+4?T2uVVhc(GCwQ5hUJ4dvWQBT~GkgWzH%QmU2py%Stn{PDY z%*rEwn8#QRjLw7e9$YFS*`LhplW(vq%5_Qx*2E%Q^O!!2eN=p$iGf6I!56Iv*D;Wf zJ^1j<=}M&rrt~=ew0Z(Gaix=|u3?7diXe?9+Cz|I!Xa}pJ)=F*{LICP@ltlU879jt zQ&7p~3zW5WB26tC&MK{EBn;R-$%MwlkfoaFFp*KMbepwB+VssHU#DpJn9L+)#$1l< zd&Iaf`5N&rM4s?6a(XapGSe{$^wmu+t|>2Zbt`^0|5KyDavtkb1MqCAzbplwW!PVq z-cP%>XBqaiN%)rq@GQgrvh;r1wLQzQr%l4YEP!Vj_Lrsi)2{7VhCOW({$&BgBu$$B ziRFV>tBoZ?*9cZ7S^tyEnz!*`L_AYGP?nbdV%1Q3ZbeKHtnFaNA=LiVR~KhQ69)KF!fk=eg}eiRsyi{!m1K``B$=X$neN z_cmD;YS@kT#6||9kcE1!Hk4Ti%Mi2wvEVW`MHEZ_>4Ug&OUl^h8Eu4*!~R1J>-~{g zL1$RTH!-YLJl7QPSY9G)nrBVO27k92)GR<~OWGK-ay3>|>7vW*v-9uY0_I7tY`pCn+JG zsi&)a$*=zP?6W_=|A7a6_Uz9-^zhOoc4Iy;yB8)heZSYWLJZ08uDbG^bI#dv%jcZ) zrLQzy-0LQe$rdoz9I9&sQeGiUyS>IdI!9Ax4(I=Ef;uCmh*vvHG<_TfOOYu4?lGO86Q9W?QcEiwp*_4saFR28$DgU3_v#Z zOk&n8JFb1}`H=_j{lrI3f9qS`aNTdOD0G^%&4!=JtjQ|s{jYiz_oK!Qow1hN;ZPyJ z^`da}f@>3mIFK3)qg^(LMW!(wDz}#{ef-Q%eAITP6W?*NZKIgJ3OEyheo9GS`JZ3< z{&&uM_<^}$#$$hHV_I+h!AFMO)PYsm6=WNIqTJplU$p<$*FO8uefMi7OK4L#|7v)6 zr0PPO`#b|WfaZkmv$?*ORC=%yR^>8SW1r7bAy{!$0xT7BjG;BD8^xK z+T|~{q{Loy4@bL(&iUNOcHMR6{s+Ed@sa^UfJ&*>w0Wk=udyK_773k~vTkhMSJz^1 zDNqtY&2Nn=j4hl!)d|^UlkAuy3obzHwq21z^T@6B_V#q&e#;GifBLDn{Nbih`cQOW zoYN`~+C5#ji6k!lvJ<3Ou5?eGdgt6bKl;IU-*nw?WwL0^P}l=HLQc7kYIZx7Qx#30 z5|8hq%aimn&P_U}#zlc7lMynJx_t3CLE%FFcA=|kd$uh@HO>q9uwkS*GF0!14~NIO zs#1+-rgu;2| zAaJe5jnPi$Nyds!i6@C$_MO8!`62=jT&XpB;-2)cASch9-&mOtF$C%92@k{hoSHZ=BA zU3oajvzYa$5=xw7HPL#w@pu zaMzI(p(-_<4-}14;%uV|70p;sPYmkBCK;!3SeS+P z-t)kN3k_7+(tN=n$C{&Y`4yKv^5{dGY`R55XU_d7$JiWx8j$8kg5vmN+jbrUNf(I> zju^G#>IVB{;<`H`O3$zg34>ihONSd>3skS-Vhqef4ua>%>RAPDr!?Y_v68F4j0>k&X$_O)>DPVX8BAAE_e(gow~6Y5|j&mno+a zWGXc&!^nhUfY021$Fslim7b~7h8vBrGWcfD69etx_Gsh0Z+-o%|MX>dohKA*oDZV# z5}mBte2eGCZcv$^;HaH%M7UGD*Xg`ymlHwNo-W&F<2sr&$PGELx1wF^>5;D}Gok}m zEY^HHW7q*pRW^~JUaysVyDC$<)0O^!#ju%%GaDtFdAqBHX}w*p!;1n<$1JBTiHO(DNqJYA7A6!RI2*I{=UZy zG)Y*o)CGL8X6S*iRDZjwQQa z!wD`{yQg-&|I`m$apk2q-*|(*fUE@d66*|cqEm08leA7xPtODQ-*?@$zaifNj-kWD zVqxoTpSSb#cVo~McJfE*Ql)gy{5dz>czxBxSCu=?dbXRb;T@j0n_cW}TG#3P>K7Nc zM+RqIe=WUAW+2X3B%5FS<88P8;Q#&rhVD+@eutfQ+civ^!-5SRH?qzE>9MyH}HY!c+o#LwBn`X`W?bTQP@wQv; zTQGlF-(sq^{(774yvr`G2-*Lj7jL`G_WI6cO9$d`ZEF|>m;tTS9%Aa&;0u2GGp$Zq zSjR<8+HuDn_t;~Pfq|jxuDa~%tFONH+G`$r>@g^9xZ#HT?RUUI2Oadn{SNA>)dvQf z1B3nDT|F-QH`XNhg*)dze*65TcP!|CU~&75vp!Fw5j>p0v7Vu{`wRA)J@4_k3x;Pe z9J=kErMJ(0{H}$A;&UHt+%fO*1rPTf`P!pHc2j2_PfA;?eB=BJA6V46WB#JK4=lUm zo@EOjYJcs#pOorT0Vdxh$*7uDfAa~a%zJQf?nA@3-Mi$Ddzaq1VCllgMn3!HZx(Ak zfkosb%QZIqEhn5Z|DoY~9v!)P_Jdn(w_Bu#uS0N3)w13tTnPyyWk1Xr_@t!5K7Y_Klb3xyn1&beetofs# zT>RogUR5af6sr_E{D9ba=-+Ul2uWr71{=Toln-Bb)7*z2@65it?~Zv(?Q6R2-pA)W zFnIgD%kF)!aotUG>QiPEa$Rvc9eVXof98w7zj^lIM;y&m0vS+Ew}c)Nzl+)CS4yiSI<|jUO+%bQ9&95&jw1zt_2CyIi!f5zo zMnd%4kEM$q`Nmhjc+AnSzT{Uw-)Ms=T0#HFhq+ehp%UA!6V)WGj**{EtvGtkZ>~K0 zbw~c<=NCEH5eKs4{Gu}mTopEh1Ju0YSO0$8F|VJ0_gzzZ>*`}j1LxFUkqH8B#V{)_ zWQsF1aIjOl&Z!7TB&NU>ro~_W@|XX3`|TlcD3C-B9d_Ssk8QTzt}z^)c6N4?PcH+i z835=!7#=Y79C7s^3TmW?XSe`KSM+j>VJskk8wf-XESjDyD3-fvFH(>`=Q4|#m=SbT z#{8740(3qtbJQmvqj}-OqMP7K(NINuze5eeb;4C%^k`7hL$`DLuU$nZQ;{R2p^>>^RJrcx=+V zL3A$p)xR&8f49K}-v^&igSqf0;-|z)p>@wacb)NxkLm>xBw7tMK3G&YQHXIvNMh;U zyXTy8@>_f}C0vle53AgY%t`FKd+wY^A6=BXDS!y7{@Yd7Jtv*~fr^We+k;#_JyB4i z+G#o?#8S1LMh!1kJ8=j{i|usP&}iI<5o4*Cv<)I?F3234Kof=dwA>|H)LH_FlJtU+ z%9ovEZIC9W3gar$=uWE@eMYTFOQRb_18y>wMV)cj!lwMNXsF7Js11(j-x%q*=3`2= z_}Q~R_wx&X7#R>Rj^PAOco`?1pk=feQsf+>!qI#CHLz^a2TyzFmYZ+A`(AtW4UFn? znj-_n>NFF7#*>;8XAh&{!9e+A$M^`Z3Xy{g0Rq&xccNry>`*RAy7sCoZn^Q=y$?8e zU`T~=?0!;)#jRN}m(hCc(T6X)>@w|94~&5pQJ4&bh=z4h3uiT!(#ZPBC%^aQFMGw{ zz>pItruF0Xnh1l9!8kO=Q#ODP*O&+BJ)WfqmKnF|wYts7TIZ7A z88bFuA0B)7AxtK_WCdRpq*DFM2F^V56W{&*cWb@t%O3-~n4pVg4S{qrMM_~6^T$Ir z+<4A5+r03F`ylTXS6sGi>7#U!HL8_r4%aBsXf|%Y{q}thJOq!`#Mn*Bun;Z?g}Jui z6lwuEAi{imXXz`QTnkMJK4wN1-hJ|WKmM^Zn+8=B$GsWt=9=PI8r8-@qpseb(?9(2 z!Di#88?XK8_s`ck;1A`-#WA z>DY}o+mxBQ?GLwp<;&;XGV3~ut@n|wk}i9`@%pQO{hP~P`?qg#gHjlI{7lE9PzceJ zqB=_vGR|nd@01Uo@UD~Bo4$cA=Js1}I_ae2@40I>)pQqo$UYWy3bSX=4n`;a4xR-% z69v{hjp5^XU3A4LkhsOy(zih(Os>m)Voo76J#0mxaOa(KX3d(l*WUY&`ka<417i5P zW&+be=nONRK6>?QUq5Af_fMux`+wj6PHq5W5F>+jXO9=`_3rn*d&!cxipbE-g6dI6 zA5*UtF8k##&i~eVG3k?}Jp`;+p1I>rZ-2+T6&xNNDU1~R`Ua*=pZbSeZocf2i_M+I zOaTLmu_4ywQ$O@~r~lnYi2|5YtJPP$YTMoRc)jp^xqW%gp#-5>dw4)B_bt zS6*?&n~r(IdEfkMPj7T}tI*)d>YXfo%q3B0s}ncB4i^Rn`J6hHut?*j28J4a1D*ci zk-lX^jGVuv4vP=9`vwe;bcOn|kfG>0&Cn847G4` ztXdG-Gc-DSV_sF*I>z`-Z$4hH<|8kBZ@ys9efXB%hUrX3OI%OP0}{#MPfdLy z<%t(DDMOiJ=90SeB}O}>*c>=jiUY<(2}|QD6a8hH8RBfiWN2W?CqMa-i!S`p)G0mD zORS-gJb8Uam_Czy(S1dTzEcg!v+@=nieZYv31xs{fFI&%ij~YI!-9_bv?PvE5VRPz z2cUR18bkka^G%Ws+mo1Po)wQc@<1EPm}bkUN%_S$RDz4kG=3e<>2#8}N% zdUWobIS@`xY+8+q_bDikwWad<>u<2*&d*=kKV&Lgy`ep=mIKsNr%iLzD*VQ9WWsw2 zW@q&Ze<}GV3DSxW*<$lisj~4Vn;mxe5jYclGL{rabc+NM=kH&*;Nb`FTd?3BOd~*= z&cksiAFQ)Kd)9#m9Wr(5Cauvhl}|q)lP0+VYP2~V^i5OaYDGF7HTOCkFYbf&%xa}C zS#P-rDz6W3qc<|jDRX2)gwd6al8Cw*k1`B`N7?s<2S3WC6Ph1VM((-Fz#k$?8sxNS^L2U7X0I7@7e zuOWt+&|{IwNl$lecxa?&s`>IDeGSzmMMlEDGa^?*<6E^9O##UEkQpS#V>v%m1A9d_9j z_cT4cZK4t7N;h2l+tJaXG`2v{kd%<>z?@r26v#WT*LqVdJH-&0pXF_-2r?Ma&ak^- z$y(?aehm$;@V=_`Sm30Heuf8Nyc%aV8#=s#hsOB}x7knDIYz-@X8nvO zhFMgFb~xIJd03?l?e17NtLD2S(||+)>vK_VEQBRU!S6{K7LH&-RBleP*=Ru9u=n13!%0r$2*C^V3J*N^pgC`CQ&%EE)TQdwl0e051&!fGBV(mr zafRWC&*~NnOP4N9)eH_*Qfos9U8#oxU44rO%@;!M+L<7)R>Iz6EYX7qhPZ!#J;O(xDmHz01B8ZFvfTsJEFo0 z1(QS7#ux^mDkMupE8i6rNv!QO8%Dul5vg!YE5x0kvV|EBA%dyyDqQXGQ%r3bx+TjW zJc4A;l-^A@+d@(8G8+=gNe+soyY9Nn{C#6^sO<8_U?%`(|Es3b=ggU{1!lR$}o+N%EF;)Ssd|8H(<3XoS)c#=nk3TTD{!WReNmFqqbWm zf@oeixH;%TW0;z@1)z2Gr7`Uks*uz!2+DJ@=7e}w5Xb>uo0nOz@Lof8Kx9Mf1a!={ zWXPF=!M31m&MEDhS|Ky!=5e__#0rjS!+G=O-TH@{2om;J!lZ{Ln|Yu4yytO} zl1K#w5+S`<17UK8#gHp%H}gF_*sn#=*EaguF$O$78tXclk)gSF-EsN{-+$-rx5-Iz z6~Q@eCDYr?+`hMGYT#(vqusVNhxFMHp;Nk8zC8ENxklL2dZr8y3>p^uo-()d*0k_X zsi+PTgb_{S5XYk3$HdYh3iyY~Zx(UQealPqNW9b<->i2(=KM_lndECaY zBNn|q)&Q!#J+&$H{k>EG01L)RL_t)(=uzg>wD#G1zjReu*vBYK77B%5UvbHge(=31 z-9)r#EfaS)TEBPM(nX*D%%}VMmJl`5;z<^%m;M48+M6co^pG(l|MnB#Ic4hf#r1qJVSjXMCeSRv>D&<)1LW6EL^$3Om|D}Vi~J$8S=!UyiZ?25}5J@kP5 z;W|fu!!-{a!rnd+LS>?N?6|Czu9&lrPD&n2ckRy4fA+JRZkn}d@e<1k$Gqi)gAaK* z^&TE=7?ZNLbW(qah}xmYy#Cs2UwPQUOO`F|?_YM*8&7z};YSV*HC@g2j+5SX@{QM0 zY+9IZM2vL$o|SE+|AmqJ7tT+3wuc6ma@w0i4FldyHrv$4*+xeO!*PmE zMF%5S>;C%}#$sq^bkO?3(9nqQOLWx^f7PpA`Xb9jJZrrf8!TBCyTr|#^wzB}$I4tr{^>tUBb~T+D}2GQV;YeJ zw&G%N(un%$Pe;ug_A^#zITGd$>ZY5G7sF*L)<$B%-r67?8+D7#N6+|&mmG5V(!TzD z`9CaKH7q#l*b|GjDfEwboR-R>83^I2elS@vs%pH#xuAHq zG&KhG6B}*uyug>)Obb-zpyHN%E=2Oy1_t_v`v>a9x@E%krfo2DJN-(C0fwipO>=dM zF`7`rqDSttPsC)R;{m1G^pBnOxn1`(Rxv0`jzl^eLKZ9z+U*6xQMi zyP~b=VkeJV=gdsP|4&=Y;tM}0sGCY2R;c?02D#-d@>9NNb$3V3hUs^Fo_xhub zF|JRBJt|#ZYk_>|k;l!lhR9S(!^4A{Y`Xb*-}=s>haJ(e&yJqKjWN{+1Fu^O3YqMP zD~ZFdw@c62YWpvK@oPuF{&-uj5M39*SHch#`Dub*BeW&v1Y*%7cvb5n@eR&%NLYB$ zB)-zHjuV>!!%+fTas3SHfntOn4j4knZRlX$dL-^%_m$SF;a4h>&K!6{6TCSjrS zdT-Cn9e4lG|2X5KfBoef-}IJP>$4#;?P)~|RE8GHLHne4zvqkp^V|(Ldrq>(#K|Tv z%rHe{ilegrdK-Q06QBC>|2nsK`uc5poc`#Wi>{46Eo}(e03Z$#oMVrB>v3;6p}T8p zs6u>^Dvho}uXQI?d(O~QvnpL>9o6wCocNyie$bj>NDxttQKoEKimp}L!c-Byc(sJA zCi=E`&bHtD=6BEi*0=ZC=YZg}sqh%D$M%X)4J0;ySgO=|roZi-@A>Zkz2N9K93NXL zlOW)_jU2(Yn05dd=}D7)39)AkZA~d!vNsZsD^XL|0IaQ6j0g@|(K5$r`0D0embiZ~ z_PnG@i^bdLFOIK#b~+BQ-0{cTet-RS2_U->vOGaR*Mu=tXeZ`RpFZ8@tc^F{V#5tK zHk82|(^+1@99iuw>+bHg`Ornn&?aYm=y~(z{qo-~y6(E`ZomE3{{DUtcGzJDe#*fI zAH2iPyW667@x>SG*!51iJ!;%`=1zO>vky^qjxAUFG`*cYa5I)QBP~Xr0?Lr+SF5(+i)sJkj;YKfe`76zq z#ZFRbX{#su`7am!1fXbjXd(06p0UBkFFW+`FiT-*+Qm5w<7Q2gt1+mL4axc8M1(%B z9GEQ@OgesmNRgEd>9GH((J+<*Bx|kNE9rWkQ1)tt+IbbUc49DnctIQb`j;wh(u93; zDJV?b5ex-Gb#cX2q|a<2jhdU27IPgE5&Yv z7#tqJuq46|VK6H_Q@V)Mka6GOAZSoBSmc$^9x3F^TqOiXhCHbKu9`rppOsP>ZLA$*&6fiOLd@!xKVijcT>D`B@z8pcGzE zIy@MHnEC^WS_J|&$P=4d164gl?BzUX{WDjUv!cvhXNM{_oyFeTu+82DRysgtrM32<0ju8F>um%qx)rAq^Fz0Fo(=xX>^}0|#BeQ9F@B=v;3syrj(Vi4MkY zM&u*NaZ5Do)2h~Dmt46R8Y!o@X`}^GNPudhxZbrITe#IFEuGY|Z_{q>24wV?mZ%9+ zxz5f&nOPb$8(I|pA_$eS?R(;5_($((Ge~r@HeOVGeJMG;_!A79eQ#g%z9IfWsc_R% z$>dl@9V>)z`;xAtcIJYii(sILDseluQKp;FgF~^QKnV*V(t~G&JzU;6A!3vI7`hrv z_w97h(V~d_j=eG(0Wh0E)9P`pWDrY;28T;dZezW}fs1&BfN(P+60{akx{TN*| zFetLO6^oJS;#`ZvVG>th$+JKInkg``XYtpJ@iQE^XBoDR3Ba=qdzNAA7zNfbbf49* oXBoDRQD7ZI_gM{F#~Aki0U-qPG~r$;8vpdQn+cp%)p@}0eRq4?yxE5tc4bvS7G(mF@PYHF&~l9JfgHMLFC8ly(Vq(&t|fW(Lu7eX~^P~rl}B0IwjGce5h*8ASQumA6! z@rA;WUub)N?|0|ibHDSQZ#&=l&Uen}*Ijp=c2e^TX0tP~!3`7fc zVCbU0rcx<-QKuI$6voQsa-|BN=*WPC{Cb~A*n0jF&@B5csv=H?lb}bi6EiED_wX6 z08VH@Qg8wW)lMD!0DvkS4$}+Hfuv451V9FuX;C@{fI0*5R5%re64_Krb+I?a7)>Ao zBNYawC&MV>pb1=H0d+hcr;!T1lyQQAPr#!VI?^3r1pp77ot>ByPrlLx68Q=YUFc2= zY|yv8y`52Fu^7zrinyr&rr-gl7qrn1W`$glO$%Tr7ZWPsM-2vQ)sxEAS6>Y&U{sAT z+1%W`Wy_YHo*sawOqnu%{CFyGLU)ir)7Gt9-+udT>d*=vJ~8*MxZ;Z8!-v1}$}9W# z???O~1Rg#i3xLIhYSE%apnzdmQX=H_-FM%m3*&Wn zche3*=bwN6q)C%DZ{ECp`*vj=5RH+eOpJ|zs0S97lC%mX`^igI&wgs|TWjs(104>-U6~$_Gbv2N!t*z(^?HxOI48w-LmX?-B z9(kmys_M|8L(l^}JcFvHrUsIfdO-+g+WATsx7Oz525%7Y+H0?U z{PD*?Qy(*C%*7X9JZ#u7u&d$s?%n&s3oihvG=_$iPG-%TrS$pcn{PsaA{6mmcG+cg z|JAR4_0dNk!N%>k-wwIYJo60v4<09@{wUtg~oAzzq!zi~#_{FwFp_eZ+_n z5FuCs|Hc?Fe90x3+;`u7K)(O}`&V6c6-cN9Loa3~Jiq$ttJGl(G4b_hKl>S|8XFtW zJoC(#UU~_o(Oz3yyI{crW;N!(5ZLM+cie%7Z@u+aa56evU3%%I3l}c@{`bGXeED*8 z2oll$ctv!oER~AljS93v<8Cf{bQ5gcbI(1`KmR<7B*x6B3bUHbh)f};f+0aJ^9P&6Nn&i!L(7mM zL!Nu?x%=bTxbSY`9`L1j@KD1My%062Zx&gja@C z=EOG&r0^N;F-6+JPRq)bD<6FDLAZi$Xo4BE_r@D<(3b*6EE9szEwkdSx8A}fVovy* zdGqFhghto{Ep-NFzVS*&TA+c#a2N}tgPHQ)d+%X>BS(&;5qpNnp+kqF;q~j+qjQij zH29%y;J|@6Cpscx$bdYGsD&m502FizFGE5)a~GL?_~D0l-E|kLL+_h5Z2~V8BXWRo z9uGY509}|8$`TN*LJe9FDkXp%7ywEI81xU7AW<+-kJ2DWAqNr@sH>|30ALv72|^0? ziHx9)A@I)tKrMQvi!uaYurFDHD11|u(zCq0oIaQevi#{!e~RjG9=F|g8>X*CT4A#pM3HO@XQ~a0V@*n#u^z(txj+Vex57_EEx2K4Zb32SVE1wLJ1_IMp_sM zzXwlC&5@^`BZy%&jm@r}H%$cA?h|C3$zy;kES4w+&X%ZtOC3_fyL_`IZbXEn1sjzwg z#;AyAz<>c@q)sm&kthI)N!l43B`~KM3}#q@K?@Qr90x;v=gys|2oW&Z=!;6h196ar z9OgfvK}xARqy~d%!=-e1qLW*AUzh75aHwkBH&cvYaf5XTA`@t z2`*I!0N$umQOf5@ofgl-N@YlZOJ8ZUZ3&l8E`ZUOLWKeVLqjO6@(Mye!3h``jTU9M zC*vVj>~pUtd}C)65Xvy>3rGn-`yx)o1C--R`SBX~RACIot08F&imc8E0bssKO~}Io z_n`{9{QiM_0t`H*5_Ew9Mq!A)#!v{KENEejW%&1Q!&;lxX^oFAC!c@M=7sv;$Cjsols+k~3R|B!9)(bF z1zv<#+|u!VOLa5v_l;d@>Z^nd2&DcQY0?ZLtV97&KfWg;1ucPZ3S5D(c; zF>$2*Gz+1!xfIVGq#0P&SlwAbY7-G;Bx_4iqmoRebxDgDnwK?9+x3dR=a-kolieMO zu&ssit|@UK@P;9KKd`ZYvW$kKAun&{GJZV9lG7QF+3DVlZI-!OFH^~|ooF;s@ceX! zh)>I9-H;(31ys-w*rtSg(xQ}j5)b{e3m7s}z^YQh_3dvjB@Q41IAP-C%dfm55)J1V zzvz*sVQLGQt`kW<`S=faZ2mwi=CcI}3y3Wc4eU{YAaI^BcKqTymnLErZ>)dq`R9Jr z)7>7ABtm*5TadJ0DxImV9WZxZBXXN=}Y#<=nhw8lN6KuypC&HMMq2%fUC+zv|`Kn>cP(i$twVI*YMtzP9>>73WMo zm%a0%FMa7~k4yLlODG&N6nRj1D#rR>{^_PVsGig@HtGo5GJQ?=G(TVTa?yxgaC4ZX zsf*+QU%>h)zi~O=En0;poc+`ShZ|ZxFTKS zgqdu}W%GycEm{1{wJ)wlte{m=?i=efB7r}-oKj;YVF9)0-i^DZFLXBH^lpa^UV=gC~r@`o5xrd*;%^(P>uQpn~s zzo`4VZ8{hr+c);CMT8&h-z>u;9d247*VmkA`HeS!t)|L8)|p4-3Y*a6r7~&qNQhmm zj^czPmtS_}=PtY;opcRd%Vv6S`O1y!URi6K)|+qr*Nz=K*s3UI09Gvh0me>gis%Q? zf1N=F2-qE&gSzb%up>E?!CaN6l8!n|%FE-5#;%(hzXQ?ww(`mOmsU=;%y*pK2U47#%e-Vzv+(I6+WJd=!ale7j zP~m6_|0Rb+n^*%vs~gE32}Z z6qwK$L&KQTlB)l27!yAc9FDGGY!WFFeu16G<_lj=LP1*)&GRM?nWzotb zS`(AW&876B?`AV>Lo=CN*d|LW3M}~jZ(B}jifZ_ipNI-Yz_wqM1cPJt9T9|W*>U6S z0|41d1I91!>XAsC&5<6mop2n9Xu8d>s=5L-!YXcv(>t9=L6dA(*sCuE#Vp=vp$DW0kWqvGOnIZ2Rsg}jGK{Gx4GxNSF=hE@C|lqk)> z^@J%iS%@Oxn5+RB`$EYPL0{dFdXuSRNOle1sn2k@P>-77 znGs7KA0%SytTCq>d7O$dFoBM*W=J=*B7*kduIS+s8O*lhx*sgA7#Y*a!{=BR%v%Uq z=okPB?YUgu^(60Wn_-lLfntmxA;?X{tk#}h&CrGptlId_CoL^aECa}d1UP+>8Ww@n zD7^Ay;C@LxZH>WL9zTe?t4Ks+;b=6R5%T>ohnE~N=UgWo&7^uuMuK|L4>^UvgoOnP zG$ms3PB+CXYrA9sJguxOCI}s^vLaSq=CmC-wtCGhwph93@kP#3abEY@nC6fnc* z{|{pbDbScs%JS)_o)iW`a&Qd0MZ+XAzNoR0HCJGS3B9fL;PcP@*kZX8M=58@&o*&Iv1%1&OXM`t3J2aGv4@2kIJo2d{vSuBfaXHG1@fbH<79z-ayA!96>_y<{grebRe)7V&vBTxe)RN5#zT~mTewgz(p~rjn5zJnpcEGT&eSI;xIziGG z_{vx2v#9G7?(Y=MeQ5jnqil@n4}ESrh2t|#JO>G53srWuw-E+M!x51soERa?E@m>x zkWS_q33J}f3}L(B`Q#6SJh?1ul6)_khAfhBWm1N$0C`0vAVu)!DU}22xK~uhYc1d`Wd7|r%s*9c^X;T_GCA{$*|-MQC1s#4f{SK zo6i(`@(}ut19FP@$Cr3i3;?|a%!ps2Lebb9+BQjSvd9#Y!FUK-SabVD?&c(d0R~hE zj)@mYLDqH}6;5lwo(`L*F_03mUqJUJm!n5am^409xy1II3!N21t zsDzCE=eJ|WAQu=M2?gGe7YJDn6hd&qv$6|WzGRToD5uSsTCWf)L_mQeg1TuqOl~9$ zi8KNLO~PJ5_E#sDOxnfv0HYU>>Znm_5%cA8u(oZFg@5cW>w^ zL0ArcGYRLJzu&R0>Fhbi_?kOV8fDAo?kB1=cQFzXBnxuuJ0K}MqfrqiEQ%)5V_J>>ALN3$N^qBi0Efle1CSe#_AhAJ~ zi@)rPG%MMYw8EAaE*9)O2@WE9XyOtc^9v$m7U{BiV@8Q-1y>3YHolG)7UD3Av>)>I zu%|g*(Pm*_=S6{BD8SgjlTKzr8Z@w$V3T0OzP4q7v8|9lpAt4~<@92o>Q zWLl`;8%0PBX+&Seya`=eju$<`&YW4!qF2ZetVS%&DCQm0t4y#{$W>Q_M~-Ola@kZ@ z61H*cg*;BeV9P>$FX0e-DV;qvmlnb*-f$dlClYLNU(t@oxKMx#(V`KR7(@&NuLiID zihd!R&P2lw2dkvF#P*6BTRj#t7B1=`(+Wq)4xnBqmvPhSY_RMx0nn%1_>+Vmn@(NN z0fdA@WX#N>ZkbUlmhDYG^YpUKA8yKK(*&ca0R?if>aZ(xq78Ko7hSYq*4(+VSZ&*} zj+hfCi3m%DLU1UWhfgsT{58WcW2oacOm=9JMTd+ng7I8P$fPFfg*2H%lnRPZ+z#i4I9?kCR$~G9>ky+8&QDd-?d+?S$X44xBk`Q zyQ&ja#Nuj5o)l~kYhrBIWjpK>*JGSehC#BUIdY_Z&AQc(JodN~E&J8W>tL0jsj?!z zZR^MX{_ywSc>UM6-*M;cS)YrSMahw^%sFB*&$& z*hQQ$sW7xl7XkJ)JM2WAaE7>yEonYisHx&E8o4J)JiwI`wsT~R3WTsE$vjNAy}kAE z#~+z8b;fzqKF2&_b4B1Dk8zO*0f83&S;st!TS{3`W8TdHf%bm%_+yX#+dZTNrc9lQ zo-tIo+WE#zIs{d;#2Ko6{|#!9)lWjnD*Jcc1!9y13TWDQ`7MjXl5G0iFyk_*bZ zSyB;YWpS-2*Nc&0I2J{r44Pu!mP`?LGm4lD+u*#P$2X8#fXqPy8*cmNo$;~?CQnay z$FA*LpMCBpxvbaI)4A^Tb+hMPR7`o%sF})il~Lo; z6t#T&u~yk(yP2BmN(4c0Y=pwOZ2D+h3$vU#8IOj6tE#9>W+Z{dj-a8o;_%@%kU%s@ zh=6&vx2ItW?Ug6WaFECd2WDEunyPZ##ooR9P0J?NUzvz!v-zIxUZ#gxGzUum!(=UL& zkGFonRSbe)tnr2$Zr~cv6Hh#`_N8A2n=z7{ z7_(*P;avwZ+jb}Sx1?9BSzFssAAByXYp`* z@t3cxC-o-3PEiN;$x-vB^Rj(f~_+P*GaPu*D-{It;_RL>=<8LrMGLP}9s(4j} zVTl_I8C)Q?Mvj@ZeC5k6ZP`!vw41ihx=`?QI3Jspp}p_S|*DP!Lk((nGxHHu+w^B*~9&P_cl)c!2WH|KKJzbbLMhC zU+z*_5!sCfHm#*osqNdgp*!7YAH^6xp2oDC^Jh#Sf7YPg`;Jv`9nZ^(FO>8;cj#Cj z_=&5O#X-E!N~?|i4Vx#_OOx4-k|dR!g1m)Nsn1#%4rnq>L^?4nmVxX#PIF%*s$ zH7k>2o$Fq`a`}VzJWyX1_t{nybGQd$9mE-S;&{+trPjkDcexVBEXVyeHZB}c*TC{k zQY(?Dy7ZDOM~xg?UY?jcXTELAISVnx@ZrNRyl{F=O*L1p_U_q(Tel<8uYUcn&c9%O zyrSx=Yp(tBpIsL+ZC^9rerLmhgL^q7g;au39CLM5{a0?fwXUw5JP%VE(Gr9qQ>4S9 zD#v-s1wj*NhYTC|*LN(5lvQ9$Wf6PVjxDQywtV~ctq1n){?QK}UU1>O@zbU|VS|N} z^@C|ccXqgTn45QmLJ}6ThG4^-(S<`CGH}U|NZDeg;qoY}3yJ=&u5J=PDmKPadVA&W z?(W^YnR&Q%X2G~~Cc61TM^|?=9yxo$IX;1qU*G`oQ1gD*o6aE)!3Vj>va-tZL``#Z zM?)QV)~cDv5R*)%C21M_D*!XKFKpuqHY0H*xu(9pBMIf%s}@}vHI1c9mtbvOoyRu( z`t_-EWL6S-}RMsj8S!V*%V;yIq7j^Lg`*DI>g3!duNUFvr zuqJd31&f_wvUn4T*^b;O%cOG>%fNU(*LI}2ETKDL^w2>zpRWu|T*S5z#JCz~dKw;f?yQNy#mJjCEkGiC@T#NosCty{v5SyNRB5Or2Uj>|Ck!Gnf#$&E-g zkQ-eKVZvf=S8_la7y#pHgbM0Zl@FwinH9O03x^Ku`Nith1x!ab zqh;mwgN9>EOqfVGo=cKo3GLgryS1&IDCOs?R&WZ#o=KF64ajK&SMA7EkW2DWBlj4+ zyfbOy_-Hhe$;y>tBC+P?=3oDM6BqZGCk+D!9&R}RxlcUygJDAl<2+tm{rZaKKlKYP zQkpaS;(-lAU=K=(0|GfnC#-fc@Jyd)i>O_=$fw;SopM1$FcSUdv-BTIGV4hZus`S z|1@`DV@Kx^j+oeIA#_iV^bpxY9Kk-DZj(chTu~>fM`}n`9TT3obTnb&l)Uc|$#SlP zH|0nY;SrLu9U9m$c+6Sjr%jtNdi2;d86}-9W9W;EzMQD6SiN$^2On-4I{b|DXV3cl z<(Iws>T3t~H{mb_4IJ8jw3A)gym|BQxbtt#CudcR!#*A5+Y`&s0a`)f=<3s;a z{N$5ux?v3;e&*OQP`?>09@8%ZWxh#V&(A8zCksRu)0r zBReF5P3B@qyk8NdJ*gzgQ2bj}MR_7&x3#t(J=#`TQ9fWmEtV2<_i@klkHHMU`XopH>EI0Eu{<=+51H*tWrcbxj?+l6=7fzOvkGYC6n3VJ;zD z?%6VFiMH8lLU)iY7T1jj;#xGs^mOIJ5fksl3Ise^J=2I0wd>oO1wd44=bNHaP5`dBw9!xF()8%$kwS=BRTVEqIJPp)D0Q zzpUd_0Dz#PE2}~xQP$PXJ#a(LPJ%>(rpv$6!2knMfLGfS$7Cl4kQ}3u9;QGx7bl{T zN}fdetZzcOW~5UjVI%t1COLhI2oD973`H;;#!*sPIgA1kIXxsTM{dETA6oEwvf&R> zhKvn7?~DXIWC2Dz2|-kR;?-b3iUz=mYe5iv!h3*+IV{O=Dy%$~x{V}~r9c&)lcE&m zrh;S^sW{CGa;(B3V73(_eUvZoRhBMf%b6nB^qnn|hy@~(O0(nM|mx6a4EVd^5UiZNKtH1W}o&WV1sZFq6Yv32tQzN1Opkw9|zr7!>8iIB8MN^n4?9*D7mE?lCD1L;Y%U`?#z2Fqv>W9>9q*OrNU+F% zI-+Nz=()L!VaxwL1~XWqX!gm9D=x(_91JoXJ9L(2G8g!=Y%WEXl1AJjUpXAa`@)#S zce2c4v0}q;i+Y%KoB@Z(4zSZEOdyhAUFT?(^(mjt5qUr_ahgO5dNG^J;#;u{vT~_p z52FWZCb_9X+NVJJ&Jf##8c@TAq$CWzkSTDLfPwP`7a4FZgs})~0ur(Pg4Bo@B>hO1 zreGArz*vLm!hIuBF6_V~j-7RLoI8nm`}vTB7i1tMUxX#$>LQVtULcWdW;iU)6Uv4D Y8|&RkE*h?$)1j4hzuwWZpbD+7=+I)2w_PAM3E(gB(h}dBqY7w{has5 zO`4{OBx+{f=l8w(>z-3}>;6uis=8I@UNmFI4Co4?l!mSmLjMeftfDBtT`ydYFZ?lG zqSI8!>bf2wK`AAKgx`QMzH%M_FvbxO2_X@ao#b|g+OaFo^A3jtfC2!eAW4$f>tz^* zV>ySz4woK;0)c=eNujYQiZL-UEiElquD?TWr?6_87Cu&0b838HNHNmVbZUx=%N5v{)>ZQbkd6az;;^Hhuowd1ops7=|(J zXKtUOs(0KzX6p1AbLPycs;V-%CM#lRD5VIYc5TnfvK&5ERD~GCYPD|Lx}~)A2cGA~ zjURX41NZMOEcE;R(GJJHefz%p@@tOc0HcbE3SHN|UT;)Xl&Y$_rdzF6P1j{vW?2>h zC{P3lDCmY>Tyi8J{k68XR#jDuv8t+~C^DGw1^gVxnr0G3k>`28-wyz$h7Pc*ng##| z4;|X}`F22HvstejILKzTH8wN?LSJ$o|J)1P?!@k7PMx8&q-Jpbv2 z4VyM^MhM-Ln>+E|d+pKDr^?D!u6(<)sxkuZ6<8HTRaF3Z@PYeAWoNT2n>BoRRmGX2 zl457Kctch19(UJ`Sy`B6>+9M0EpxHegg)ms=9pnTeI?J_vQEiEIn-=PBs=FXc}S6?4%cK|{co14qe zoMAbxv9U1_2n-!Oh-liIZ@qQ=#EAr#>#6*FRZ$g1HC4&7tg5P}X^JA7CQuYvRTKbN zzkdBkpM26cBQ0;{OqONGj2Y9?)Ua^T;_B*ZMOBu*{7Po#wcmXEtsn?LYgbuOR80kd zRjc0F{*RsSu33})hfza^4Ec1^CPh&gj^DNW%a@iewTdD_$S?@Th*A;=1T&?wA0Durkk`$h*u^d5? zq-#0=AcVYL@3YT6@AG<|f9~1jIz5kY!ntq(C4b z$&#Wd!Jy>#`6(fPTeD`lqNu7?9dv9Yn?K0qlIMbYVW zHZ?T{0;VBRN=gbs$nAE!TrRKI+tSh!a(TlrSeEVIzrWw_udc36OiZY&tCu9nZnvkW zr`Ocfc)i|k-MZD()Yxpc*x18p{j>^i) z`uh5CPc;cyt=5PsN~vKOVaXf_F#rH#Y#0W{I6O8@d0p2LLJY%%ZX|^0x*p2;48ssY z2q6r^m@5p45kf+_N!N9A81abTAEEKN_x)dE=q#bCx~{1S{{_@#_3OWYBI|=+M^`CH zuPmm*=YJ7(7ONS*SC-o*>6%7<=GiREB7_WGH!iQ=d7kG5K~puu=xjOLF;>hl?z)<1 zpMFe|rNKk9=03Y5qFBZl&wG0Ik3W`PXad?%FE_N{aS> zv3=`1>o#WgAEaq&7hr|fEfX|dXF0B20fu1#K(vSx?|;~8vr*c*-IT&Lz0-7!V$1*l z0=O%8Qc7x%fZtbAwEyIZV;3%*ePO|$KHRj6VVDj*xNBm|B&*dn|M^#3Ne*JP&QJnA zUr^WEpaVSg$m~%$qg9Q1nlDa&D7Wa~z9S_Eiw^7^b;}sFqm0y*SQSOty6M9hyMqz} z02HX*?zkyChv$Vb895kKRaLRa#{T=gQ;H7m1AwE459Qo;M~C{m601Mpdw%|t;WK^G zGPZwN)NV%8bv-$yyLnw-SJRmc)|FT>LKce{s&FX1w-PY--%|&2ByHO_P+I+B>bUd97(` z;oh$uv2o$=w$#*~8JYb;!yigZ2qm&C9VtGz`O^;oASo$jp#c-TW)870suO7*4u#uLaL%voGELs zYN6fYT}jE^D=W%^fk1nAQ>QB_DLJ|N{Q0IPH?$qxVT_|=?8zzJEf!HxIt8>-SWUPr z%L23$s)QJ3d)RKB000Ith+!}cW4>lXYaoOYV*H}Yuv0!jDUCQzjGzvWDGkFg+7j8X zrr%S$`2Se{In?T}f*@dqxr{@>Acm%@zsUU&!Wg4)*EG}FZ+F&KtQh0%+cwoypF^QY zM<9yU9zCzQVfaXkMeO7WzaR)+ucy&n-@WHGW`eU=#0Ga=Fc?TmPHneQ`$dFKo%OOT zdw=e&CB^%%WZyLM<~LTp-!0zNpJtuxa#v~r%fJz^hgoU^E{75(R!r#;H+tr%1@sZEF#ZeN{$T6T0~K_S}hil z33EJzTNPrAIi43qt3|Y$-H}O`hBx=k(iW1D7|p5>e2t0(9lp{QnX)^f*i-4 zE<4dsU&pfCz`@rG7K_)@a{O2+0Q9^jE#B!oSXf}Tqvy_6?ccjMIi-8?p+Zyb=~F)* z+F#f=a{$9IJTFvLoGvaZyx7?2bR`VCF}p|4-ijh)ggu^?6UV*>p#266s;Vq6JyK+~ zMvWYm)1zmf*3R+NS?`(Z;K=M80EmgUe^*piQ6rUK2o@YXnV6IU03$|@F24{w>(=j? zI2izLW=K6Tc6nO%cHf8HY#d7dYP z)YeotHoBvu?Rif;%`glFYL@Y#T??;dIF5^tcQrM-0l;dtB_^jvMMuZj9X?MB07OT} zBqXL-L~;AJO|LATZ_e~d%Q$`NL}R1-xw%iqI}`30cTY%R>CvJgL$d%->5)SX4fShR zy^(ceHbmrC-7rp`IQD(%;bT7>ZESP{fGsLYuvo6%U>Lfd-uK!St3P5{mI6F5W%}kF zdvYf{xM=B{6o3N!*W4G^Z`?@;d2jV{0B|^B-~C|Qwq1oQ*KV*{Z3Z#kedkSG(?eKu z{y28i_Ja35{yepNF94{%a88zGgwSPnTW-H@ z(9lB%_LiSMd9kSxw^cva4;vu}7K4y@r|bOrp9mq85D1Sl01!p%f`!XcQhOMN!LiIs zFU(!F;`OGchJD|CojD-0RfqxwK!76hWoT%gc~MHkPBbVbpzFGs_^ehNw0+AIMXR|p zx~_+kJJ0i!QlK=VV2(UZmnB&aO0p#Rd_Hem?-mYA)l@deH z04###hT$W19paq{03b`j)qnl-4Ot`JUjFK(MViM%2m!$Uy#)*B&z+h#C-iY*=k_h< zf2x`_C;!&5~?)Vzh~n@Gv=>g43q5chv}A1F9@(tM!+0E3wWN2?AW zug)5t9r1`e$4xk1dGV)u?SqY9m@{*qS#qwyC_CrtKVT35^y<~;c*VuCb3PUT2qCxK zad+?ZzM+l77;_vS*De00?9tZ`8=rF%|?10E83@f`BnY2r+xIPW4-nOKAH|p|f0s;0pPx xD`}U0O|5NTB^u!Mw!unV%|0)mP@MO<(J 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 TUi1CX~E(kNJ; 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 Ts*C9B00000NkvXXu0mjfpKG+r diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.pbxproj b/iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.pbxproj deleted file mode 100755 index 75c1456..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.pbxproj +++ /dev/null @@ -1,365 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - AA07EB7A176BA47F00AB755D /* CustomCellBackground.m in Sources */ = {isa = PBXBuildFile; fileRef = AA07EB79176BA47F00AB755D /* CustomCellBackground.m */; }; - AA4D789117DFBCF70029ACE0 /* off.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AA4D788F17DFBCF70029ACE0 /* off.jpg */; }; - AA4D789217DFBCF70029ACE0 /* on.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AA4D789017DFBCF70029ACE0 /* on.jpg */; }; - AA4D78A117E0052C0029ACE0 /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = AA4D789D17E0052C0029ACE0 /* icon-72.png */; }; - AA4D78A217E0052C0029ACE0 /* icon-144.png in Resources */ = {isa = PBXBuildFile; fileRef = AA4D789E17E0052C0029ACE0 /* icon-144.png */; }; - AA4D78A317E0052C0029ACE0 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = AA4D789F17E0052C0029ACE0 /* icon.png */; }; - AA4D78A417E0052C0029ACE0 /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AA4D78A017E0052C0029ACE0 /* icon@2x.png */; }; - AA6DEC4416D561CD00E83C0F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA6DEC4316D561CD00E83C0F /* QuartzCore.framework */; }; - AAC4273716C9D4A500149784 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAC4273616C9D4A500149784 /* UIKit.framework */; }; - AAC4273916C9D4A500149784 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAC4273816C9D4A500149784 /* Foundation.framework */; }; - AAC4273B16C9D4A500149784 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAC4273A16C9D4A500149784 /* CoreGraphics.framework */; }; - AAC4274116C9D4A500149784 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AAC4273F16C9D4A500149784 /* InfoPlist.strings */; }; - AAC4274316C9D4A500149784 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AAC4274216C9D4A500149784 /* main.m */; }; - AAC4274916C9D4A500149784 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = AAC4274816C9D4A500149784 /* Default.png */; }; - AAC4274B16C9D4A500149784 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AAC4274A16C9D4A500149784 /* Default@2x.png */; }; - AAC4274D16C9D4A500149784 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AAC4274C16C9D4A500149784 /* Default-568h@2x.png */; }; - AAC4276416C9D52700149784 /* AppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AAC4276216C9D52700149784 /* AppViewController.m */; }; - AAC4276516C9D52700149784 /* AppViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AAC4276316C9D52700149784 /* AppViewController.xib */; }; - AAC4276716C9D6B200149784 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAC4276616C9D6B200149784 /* CoreBluetooth.framework */; }; - AAC427C216C9DC9B00149784 /* RFduino.m in Sources */ = {isa = PBXBuildFile; fileRef = AAC427BA16C9DC9B00149784 /* RFduino.m */; }; - AAC427C316C9DC9B00149784 /* RfduinoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AAC427BD16C9DC9B00149784 /* RfduinoManager.m */; }; - AAC427C416C9DC9B00149784 /* ScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AAC427C016C9DC9B00149784 /* ScanViewController.m */; }; - AAC428BB16C9FE1300149784 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AAC428BA16C9FE1300149784 /* AppDelegate.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - AA07EB78176BA47F00AB755D /* CustomCellBackground.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomCellBackground.h; sourceTree = ""; }; - AA07EB79176BA47F00AB755D /* CustomCellBackground.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomCellBackground.m; sourceTree = ""; }; - AA4D788F17DFBCF70029ACE0 /* off.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = off.jpg; path = rfduinoLedButton/off.jpg; sourceTree = SOURCE_ROOT; }; - AA4D789017DFBCF70029ACE0 /* on.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = on.jpg; path = rfduinoLedButton/on.jpg; sourceTree = SOURCE_ROOT; }; - AA4D789D17E0052C0029ACE0 /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; - AA4D789E17E0052C0029ACE0 /* icon-144.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-144.png"; sourceTree = ""; }; - AA4D789F17E0052C0029ACE0 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; - AA4D78A017E0052C0029ACE0 /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; - AA6DEC4316D561CD00E83C0F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - AAC4273216C9D4A500149784 /* rfduinoLedButton.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = rfduinoLedButton.app; sourceTree = BUILT_PRODUCTS_DIR; }; - AAC4273616C9D4A500149784 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - AAC4273816C9D4A500149784 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - AAC4273A16C9D4A500149784 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - AAC4273E16C9D4A500149784 /* rfduinoLedButton-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "rfduinoLedButton-Info.plist"; sourceTree = ""; }; - AAC4274016C9D4A500149784 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - AAC4274216C9D4A500149784 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - AAC4274416C9D4A500149784 /* rfduinoLedButton-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "rfduinoLedButton-Prefix.pch"; sourceTree = ""; }; - AAC4274816C9D4A500149784 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - AAC4274A16C9D4A500149784 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; - AAC4274C16C9D4A500149784 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - AAC4276116C9D52700149784 /* AppViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppViewController.h; sourceTree = ""; }; - AAC4276216C9D52700149784 /* AppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppViewController.m; sourceTree = ""; }; - AAC4276316C9D52700149784 /* AppViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AppViewController.xib; sourceTree = ""; }; - AAC4276616C9D6B200149784 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; }; - AAC427B916C9DC9B00149784 /* RFduino.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFduino.h; sourceTree = ""; }; - AAC427BA16C9DC9B00149784 /* RFduino.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RFduino.m; sourceTree = ""; }; - AAC427BB16C9DC9B00149784 /* RFduinoDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFduinoDelegate.h; sourceTree = ""; }; - AAC427BC16C9DC9B00149784 /* RfduinoManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RfduinoManager.h; sourceTree = ""; }; - AAC427BD16C9DC9B00149784 /* RfduinoManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RfduinoManager.m; sourceTree = ""; }; - AAC427BE16C9DC9B00149784 /* RFduinoManagerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RFduinoManagerDelegate.h; sourceTree = ""; }; - AAC427BF16C9DC9B00149784 /* ScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanViewController.h; sourceTree = ""; }; - AAC427C016C9DC9B00149784 /* ScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScanViewController.m; sourceTree = ""; }; - AAC428B916C9FE1300149784 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - AAC428BA16C9FE1300149784 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - AAC4272F16C9D4A500149784 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AA6DEC4416D561CD00E83C0F /* QuartzCore.framework in Frameworks */, - AAC4276716C9D6B200149784 /* CoreBluetooth.framework in Frameworks */, - AAC4273716C9D4A500149784 /* UIKit.framework in Frameworks */, - AAC4273916C9D4A500149784 /* Foundation.framework in Frameworks */, - AAC4273B16C9D4A500149784 /* CoreGraphics.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - AAC4272716C9D4A500149784 = { - isa = PBXGroup; - children = ( - AA4D789D17E0052C0029ACE0 /* icon-72.png */, - AA4D789E17E0052C0029ACE0 /* icon-144.png */, - AA4D789F17E0052C0029ACE0 /* icon.png */, - AA4D78A017E0052C0029ACE0 /* icon@2x.png */, - AA4D789017DFBCF70029ACE0 /* on.jpg */, - AA4D788F17DFBCF70029ACE0 /* off.jpg */, - AAC427B716C9DC9B00149784 /* rfduino */, - AAC4273C16C9D4A500149784 /* rfduinoLedButton */, - AAC4273516C9D4A500149784 /* Frameworks */, - AAC4273316C9D4A500149784 /* Products */, - ); - sourceTree = ""; - }; - AAC4273316C9D4A500149784 /* Products */ = { - isa = PBXGroup; - children = ( - AAC4273216C9D4A500149784 /* rfduinoLedButton.app */, - ); - name = Products; - sourceTree = ""; - }; - AAC4273516C9D4A500149784 /* Frameworks */ = { - isa = PBXGroup; - children = ( - AA6DEC4316D561CD00E83C0F /* QuartzCore.framework */, - AAC4276616C9D6B200149784 /* CoreBluetooth.framework */, - AAC4273616C9D4A500149784 /* UIKit.framework */, - AAC4273816C9D4A500149784 /* Foundation.framework */, - AAC4273A16C9D4A500149784 /* CoreGraphics.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - AAC4273C16C9D4A500149784 /* rfduinoLedButton */ = { - isa = PBXGroup; - children = ( - AAC4276116C9D52700149784 /* AppViewController.h */, - AAC4276216C9D52700149784 /* AppViewController.m */, - AAC4276316C9D52700149784 /* AppViewController.xib */, - AAC4273D16C9D4A500149784 /* Supporting Files */, - ); - path = rfduinoLedButton; - sourceTree = ""; - }; - AAC4273D16C9D4A500149784 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - AAC4273E16C9D4A500149784 /* rfduinoLedButton-Info.plist */, - AAC4273F16C9D4A500149784 /* InfoPlist.strings */, - AAC4274216C9D4A500149784 /* main.m */, - AAC4274416C9D4A500149784 /* rfduinoLedButton-Prefix.pch */, - AAC4274816C9D4A500149784 /* Default.png */, - AAC4274A16C9D4A500149784 /* Default@2x.png */, - AAC4274C16C9D4A500149784 /* Default-568h@2x.png */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - AAC427B716C9DC9B00149784 /* rfduino */ = { - isa = PBXGroup; - children = ( - AAC428B916C9FE1300149784 /* AppDelegate.h */, - AAC428BA16C9FE1300149784 /* AppDelegate.m */, - AAC427B916C9DC9B00149784 /* RFduino.h */, - AAC427BA16C9DC9B00149784 /* RFduino.m */, - AAC427BB16C9DC9B00149784 /* RFduinoDelegate.h */, - AAC427BC16C9DC9B00149784 /* RfduinoManager.h */, - AAC427BD16C9DC9B00149784 /* RfduinoManager.m */, - AAC427BE16C9DC9B00149784 /* RFduinoManagerDelegate.h */, - AAC427BF16C9DC9B00149784 /* ScanViewController.h */, - AAC427C016C9DC9B00149784 /* ScanViewController.m */, - AA07EB78176BA47F00AB755D /* CustomCellBackground.h */, - AA07EB79176BA47F00AB755D /* CustomCellBackground.m */, - ); - name = rfduino; - path = ../rfduino; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - AAC4273116C9D4A500149784 /* rfduinoLedButton */ = { - isa = PBXNativeTarget; - buildConfigurationList = AAC4275016C9D4A500149784 /* Build configuration list for PBXNativeTarget "rfduinoLedButton" */; - buildPhases = ( - AAC4272E16C9D4A500149784 /* Sources */, - AAC4272F16C9D4A500149784 /* Frameworks */, - AAC4273016C9D4A500149784 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = rfduinoLedButton; - productName = rfduinoLedButton; - productReference = AAC4273216C9D4A500149784 /* rfduinoLedButton.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - AAC4272916C9D4A500149784 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0450; - ORGANIZATIONNAME = OpenSourceRF; - }; - buildConfigurationList = AAC4272C16C9D4A500149784 /* Build configuration list for PBXProject "rfduinoLedButton" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = AAC4272716C9D4A500149784; - productRefGroup = AAC4273316C9D4A500149784 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - AAC4273116C9D4A500149784 /* rfduinoLedButton */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - AAC4273016C9D4A500149784 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AAC4274116C9D4A500149784 /* InfoPlist.strings in Resources */, - AAC4274916C9D4A500149784 /* Default.png in Resources */, - AAC4274B16C9D4A500149784 /* Default@2x.png in Resources */, - AAC4274D16C9D4A500149784 /* Default-568h@2x.png in Resources */, - AAC4276516C9D52700149784 /* AppViewController.xib in Resources */, - AA4D789117DFBCF70029ACE0 /* off.jpg in Resources */, - AA4D789217DFBCF70029ACE0 /* on.jpg in Resources */, - AA4D78A117E0052C0029ACE0 /* icon-72.png in Resources */, - AA4D78A217E0052C0029ACE0 /* icon-144.png in Resources */, - AA4D78A317E0052C0029ACE0 /* icon.png in Resources */, - AA4D78A417E0052C0029ACE0 /* icon@2x.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - AAC4272E16C9D4A500149784 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AAC4274316C9D4A500149784 /* main.m in Sources */, - AAC4276416C9D52700149784 /* AppViewController.m in Sources */, - AAC427C216C9DC9B00149784 /* RFduino.m in Sources */, - AAC427C316C9DC9B00149784 /* RfduinoManager.m in Sources */, - AAC427C416C9DC9B00149784 /* ScanViewController.m in Sources */, - AAC428BB16C9FE1300149784 /* AppDelegate.m in Sources */, - AA07EB7A176BA47F00AB755D /* CustomCellBackground.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - AAC4273F16C9D4A500149784 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - AAC4274016C9D4A500149784 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - AAC4274E16C9D4A500149784 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - AAC4274F16C9D4A500149784 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - AAC4275116C9D4A500149784 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "rfduinoLedButton/rfduinoLedButton-Prefix.pch"; - INFOPLIST_FILE = "rfduinoLedButton/rfduinoLedButton-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - AAC4275216C9D4A500149784 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "rfduinoLedButton/rfduinoLedButton-Prefix.pch"; - INFOPLIST_FILE = "rfduinoLedButton/rfduinoLedButton-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - AAC4272C16C9D4A500149784 /* Build configuration list for PBXProject "rfduinoLedButton" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AAC4274E16C9D4A500149784 /* Debug */, - AAC4274F16C9D4A500149784 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - AAC4275016C9D4A500149784 /* Build configuration list for PBXNativeTarget "rfduinoLedButton" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AAC4275116C9D4A500149784 /* Debug */, - AAC4275216C9D4A500149784 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = AAC4272916C9D4A500149784 /* Project object */; -} diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100755 index 6ef6d3c..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.h b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.h deleted file mode 100755 index 3d186ae..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#import "RFduino.h" - -@interface AppViewController : UIViewController -{ - __weak IBOutlet UILabel *label1; - __weak IBOutlet UIButton *button1; - - __weak IBOutlet UILabel *label2; - __weak IBOutlet UIImageView *image1; - - UIImage *off; - UIImage *on; -} - -@property(strong, nonatomic) RFduino *rfduino; - -- (IBAction)buttonTouchDown:(id)sender; -- (IBAction)buttonTouchUpInside:(id)sender; - -@end diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m deleted file mode 100644 index 3b2b420..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.m +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (c) 2013 OpenSourceRF.com. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#import - -#import "AppViewController.h" - -@implementation AppViewController - -@synthesize rfduino; - -+ (void)load -{ - // customUUID = @"c97433f0-be8f-4dc8-b6f0-5343e6100eb4"; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil -{ - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - // Custom initialization - UIButton *backButton = [UIButton buttonWithType:101]; // left-pointing shape - [backButton setTitle:@"Disconnect" forState:UIControlStateNormal]; - [backButton addTarget:self action:@selector(disconnect:) forControlEvents:UIControlEventTouchUpInside]; - - UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; - [[self navigationItem] setLeftBarButtonItem:backItem]; - - [[self navigationItem] setTitle:@"RFduino LedBtn"]; - } - return self; -} - -- (void)iPhone5PortraitLayout -{ - label1.frame = CGRectMake(51,20,218,84); - button1.frame = CGRectMake(124,112,73,44); - - label2.frame = CGRectMake(51,279,218,84); - image1.frame = CGRectMake(123,371,75,75); -} - -- (void)iPhone5LandscapeLayout -{ - label1.frame = CGRectMake(20,65,218,84); - button1.frame = CGRectMake(93,173,73,44); - - label2.frame = CGRectMake(330,65,218,84); - image1.frame = CGRectMake(402,157,75,75); -} - -- (void)iPhone4SPortraitLayout -{ - label1.frame = CGRectMake(51,34,218,84); - button1.frame = CGRectMake(124,126,73,44); - - label2.frame = CGRectMake(51,211,218,84); - image1.frame = CGRectMake(123,303,75,75); -} - -- (void)iPhone4SLandscapeLayout -{ - label1.frame = CGRectMake(20,45,218,84); - button1.frame = CGRectMake(93,153,73,44); - - label2.frame = CGRectMake(262,45,218,84); - image1.frame = CGRectMake(334,137,75,75); -} - -- (void)iPadPortraitLayout -{ - label1.frame = CGRectMake(91,198,587,28); - button1.frame = CGRectMake(343,242,73,44); - - label2.frame = CGRectMake(113,648,543,38); - image1.frame = CGRectMake(347,694,75,75); -} - -- (void)iPadLandscapeLayout -{ - label1.frame = CGRectMake(224,144,587,28); - button1.frame = CGRectMake(476,188,73,44); - - label2.frame = CGRectMake(241,462,543,38); - image1.frame = CGRectMake(475,508,75,75); -} - -- (void)manualLayout -{ - CGRect rect = [[UIScreen mainScreen] bounds]; - - if (UIDeviceOrientationIsLandscape(self.interfaceOrientation)) { - if (rect.size.height >= 1024) { - [self iPadLandscapeLayout]; - } else if (rect.size.height >= 568) { - [self iPhone5LandscapeLayout]; - } else { - [self iPhone4SLandscapeLayout]; - } - } else { - if (rect.size.height >= 1024) { - [self iPadPortraitLayout]; - } else if (rect.size.height >= 568) { - [self iPhone5PortraitLayout]; - } else { - [self iPhone4SPortraitLayout]; - } - } -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view from its nib. - - [rfduino setDelegate:self]; - - UIColor *start = [UIColor colorWithRed:58/255.0 green:108/255.0 blue:183/255.0 alpha:0.15]; - UIColor *stop = [UIColor colorWithRed:58/255.0 green:108/255.0 blue:183/255.0 alpha:0.45]; - - CAGradientLayer *gradient = [CAGradientLayer layer]; - //gradient.frame = [self.view bounds]; - gradient.frame = CGRectMake(0.0, 0.0, 1024.0, 1024.0); - gradient.colors = [NSArray arrayWithObjects:(id)start.CGColor, (id)stop.CGColor, nil]; - [self.view.layer insertSublayer:gradient atIndex:0]; - - off = [UIImage imageNamed:@"off.jpg"]; - on = [UIImage imageNamed:@"on.jpg"]; -} - -- (void)viewDidLayoutSubviews { - [self manualLayout]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - [self manualLayout]; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (IBAction)disconnect:(id)sender -{ - NSLog(@"disconnect pressed"); - - [rfduino disconnect]; -} - -- (void)sendByte:(uint8_t)byte -{ - uint8_t tx[1] = { byte }; - NSData *data = [NSData dataWithBytes:(void*)&tx length:1]; - [rfduino send:data]; -} - -- (IBAction)buttonTouchDown:(id)sender -{ - NSLog(@"TouchDown"); - [self sendByte:1]; -} - -- (IBAction)buttonTouchUpInside:(id)sender -{ - NSLog(@"TouchUpInside"); - [self sendByte:0]; -} - -- (void)didReceive:(NSData *)data -{ - NSLog(@"RecievedData"); - - const uint8_t *value = [data bytes]; - // int len = [data length]; - - NSLog(@"value = %x", value[0]); - - if (value[0]) - [image1 setImage:on]; - else - [image1 setImage:off]; -} - -@end diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.xib b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.xib deleted file mode 100755 index d9f8307..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/AppViewController.xib +++ /dev/null @@ -1,467 +0,0 @@ - - - - 1552 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 - - - IBProxyObject - IBUIButton - IBUIImageView - IBUILabel - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{123, 371}, {75, 75}} - - _NS:9 - NO - IBCocoaTouchFramework - - NSImage - off.jpg - - - - - 292 - {{124, 112}, {73, 44}} - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Button - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - - - - 292 - {{51, 20}, {218, 84}} - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Press and hold the button below to turn on the green led on the RGB Shield. - - 1 - MCAwIDAAA - darkTextColor - - - 0 - 3 - - 1 - 17 - - - Helvetica - 17 - 16 - - NO - 218 - - - - 292 - {{51, 279}, {218, 84}} - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Press and hold Button1 on the RGB Shield to change the image below. - - - 0 - 3 - - - NO - 218 - - - {{0, 20}, {320, 548}} - - - - 3 - MQA - - 2 - - - - - IBUIScreenMetrics - - YES - - - - - - {320, 568} - {568, 320} - - - IBCocoaTouchFramework - Retina 4 Full Screen - 2 - - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{343, 242}, {73, 44}} - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Button - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - - - - - - 292 - {{91, 198}, {587, 28}} - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Press and hold the button below to turn on the green led on the RGB Shield. - - - 0 - 3 - - - NO - 587 - - - - 292 - {{113, 648}, {543, 38}} - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Press and hold Button1 on the RGB Shield to change the image below. - - - 0 - 3 - - - NO - 543 - - - - 292 - {{347, 694}, {75, 75}} - - _NS:9 - NO - IBCocoaTouchFramework - - - - {{0, 20}, {768, 1024}} - - - 3 - MQA - - - - - IBUISimulatedFreeformSizeMetricsSentinel - Freeform - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - button1 - - - - 31 - - - - image1 - - - - 32 - - - - label1 - - - - 50 - - - - label2 - - - - 51 - - - - buttonTouchDown: - - - 1 - - 34 - - - - buttonTouchUpInside: - - - 7 - - 35 - - - - buttonTouchDown: - - - 1 - - 64 - - - - buttonTouchUpInside: - - - 7 - - 65 - - - - - - 0 - - - - - - 1 - - - - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 27 - - - - - 29 - - - - - 36 - - - - - - 37 - - - - - - 59 - - - - - - - - - - - 60 - - - - - 61 - - - - - 62 - - - - - 63 - - - - - - - AppViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 65 - - - 0 - IBCocoaTouchFramework - YES - 3 - - off.jpg - {75, 75} - - 2083 - - diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default-568h@2x.png b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default-568h@2x.png deleted file mode 100755 index 0891b7aabfcf3422423b109c8beed2bab838c607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18594 zcmeI4X;f257Jx&9fS`ixvS;&$x8J@slQFSel)6zJN=?13FB7H(lQjRkSy8x_-S~tvu2gzn1oS+dLcF#eqtq$ z%tf9TTvX?`)R@}3uBI;jzS-=ZR-Td&MHaS&;!0?Ni*#$#`n*~CcQK)Q9vAQ~TUpnI!j)a2biYK^R)M~A5wUDZhx?ULMX z3x1P&qt=trOY6P2U67L=m=U?F|5#Uj(eCueNTZaHs_ceWiHeET+j+tp3Jt9g(ekqP z2WOvfR{qV+9r+o4J5?qK>7;;^+I7tGv-i)es$X_D=EoKF+S?zsyj^oRFElP}c}JT< zd8SUs-?O?}2YD#ngKbnHgzHBcboxK_2r9l(?eNCl-pEzkJm}fY?WC*jnS?VBE4EpY zO$fEejz6fU;W2Kl>JeQBZBl-%Irg`obSlg*@4QB;Dd1H7^Oi5wvt4d{RZ!8Og?^aE z)k0$1g+V3fd(gdQ3d&q2q-FL*uy#}|bc^=VhFsl0jBgUGJ+-s3U8MK9A!YJJMxpci z5hJ%|{DwV48fZn0{n5l$N_KcSb#NKE4plB`9I6Zt=Z!~-zw0{9tg$L&Ju1F0X)Cy8 zKF;(&lJ>x)Jw(=;p~sF(Sd9VWGwFE2rnyS9!f^DZ8+aCLq zQ};>lcJ1GDLqjm6Hd>|Eabno@P`~Bn(~6^aD_#yoEH(a?Nm1S<;S+hSxI5d16^<1lEM3NPFi zkqPrpL)+ zgnseFikg`gJVBha1&7C4;O6>h=dt~`ND+;Zd?W(4v2JIb7Pt>Td42%M-Ju-XAH#Pns762L}K3 zDhvsRqN0Ni(1UrishD2YvV?4*h2iFj$+&N||Fn$4n|^NSU+o?~jq`0jVQt8T9l{7b zXiwwODFh2V!Q6sqP9S>WH$oOf$N~=d0-bqTlD61!=`&0eAP-F>XN?*|gtOXX{ zQVTWyYo4ZK0GAw!GHf|pz9`D;-bbb*5LBX*{bnz|+)$@&P9|ORM2o?95{;ejvo&r- zq8cBhTN6nn)7~W>54U)%-F_-b?YKdfk5I8MHcuzBD5)!;yv#Z&R&^y=@=>VTIMy#r zX&U<=BsPkdqcMe<_}2+>H%XKyrr5ZR8_KVe>ZqYN z^=^~TFD};;rHJ$U;{~w^hYojl4hRI@SH$^K{YEo=sg)WY87r!*7blQK&qnpDo0`Vn zkl)9u9g=mCh&ZCJS(L4yN3k0kQ zuvg$h2KEEk51T+O0JQ+r0`R>g{jvqM0Mr6d3qUOZwE!?PI7HY@CE|dr sfw?Q;rAv?G4&^^8-z_>&sWXMxvD*gPOU4CBe-*@OtE+wfmVJNyHv)PfH~;_u diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default.png b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/Default.png deleted file mode 100755 index 4c8ca6f693f96d511e9113c0eb59eec552354e42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6540 zcmeAS@N?(olHy`uVBq!ia0y~yU~~ZD2OMlbkt;o0To@QwR5G2N13aCb6#|O#(=u~X z85k@CTSM>X-wqM6>&y>YB4)1;;ojbLbbV-W^iFB1wa3^zCog^LCAReC4K0-?R_2{6 zrP*)4+_uWUy3w5N52M3PW_}MFMP9a~>YLvVZ1D_k*IMQ2QT^fwzoOb(*3gH$%aYWC zkHmcab=va2<#X%jakpJ;<1@F;k__#bwtC&%^D0v(FBh9K&$sK+<}2RJS609D)17$w ztdQP8(eLM8Ka}m_IQ@3wyMKP)l=oM4-?`YS_*P?4V_ORLPxsj&7Ju#kH;>6^Kp?T7~ zl+q?{UOOqV==?+d{=)5s|M~T1mwtH@+Z^$G&eEO9JNP^AX@3jZ*J*!!>lc|1-W%fA z@AOQpXZ_Lt>rxFXrGp*zLPiW@uo_c7C{As>j zWeX)wi+LTp_)@KYZCX{j;H?|1yXT4DnlS(Fr8gyP5|uaX_gLvaW0ScZdnG7o+u{T6 zFI-%d{ls*WuCDa5UJ@|RXv&ejZe}*BMkiWY51&pnRPw(hlykSzvj6e%mYz-GdvzBD zF10?szF_~!jS=?2HyQuPCvARXAe}C}WP|yQ*>5~~=*Nxq8+HHW1~FMDRCP^TcacKuk$ z(U#REVv)D!PhJ*ecH-ELFUrfyV&*)Z)>UCOuS?yd^L@Afk>ihynYPc{^CRwu+JHX+#$@YsC4c|l0tGigsn@jy) zXD($Ouk>H+V(Mr6NQT0S9BFM~V6nkj;1OBOz`zY;a|<&v%$g$sEJPk;hD4M^`1)8S z=jZArrsOB3>Q&?x097+E*i={nnYpPYi3%0DIeEoa6}C!X6;?ntNLXJ<0j#7X+g2&U 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 diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/en.lproj/InfoPlist.strings b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/en.lproj/InfoPlist.strings deleted file mode 100755 index 477b28f..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/main.m b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/main.m deleted file mode 100755 index f87c5c3..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// rfduinoLedButton -// -// Created by Steve on 2/11/13. -// Copyright (c) 2013 RF Digital. All rights reserved. -// - -#import - -#import "AppDelegate.h" - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/off.jpg b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/off.jpg deleted file mode 100755 index 48f66016253550a7864b73de3b9717478c605206..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmex=^w zn~RG_fCmf&c=-4Q`1yE*g+)Y!g=M6rrDf#dfRUY@otKAKLO?)5N>or(3NAq`-KHKqVn`(-MRkm{4s^U=&nz4E%qKfd?qgB*-iX z49{mm4Gat-3ri<|U|^68*>&;<0|U>h*pxpE3~Zr#o9ci;t2I5+9;k4t_nP@YrKgr& z^FP4AkQ($_{Q(1m(Fz6z26mu{96--7vNFlZef0RTF)&+H43!W+5E`u*n$sG(Ni^&P zoEiS{KLc1V6G-oy`Cv9P5}S#M&7R2X#g;xgXO+^#1 zT@LXFGo!tt6IZ8%x#c7;5siR_POV%JiXY-ukh}`SO)w@RJOzN^A>gSp$x&sJC(9&H v6(LWR38-A4;3R*zO#)TZ>nGn1Z?1HiQ}OZf@qRfQ2xSkqO8{XPka-gT{@}c+ diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/on.jpg b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/on.jpg deleted file mode 100755 index 4f9b94c75022051634e02a23843b068cdc3e8580..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1256 zcmex=g@JlmS(um*rW-IC76LVY5KL@T{OA}ckg)LJ|62?^AOi%M1%UxR`P|WOmOC66 z7+E)ZSNEHG9-hR&z|%DC)qAD9$?Yl(43ez6SMRypRp$dng%MZu>OGyi{A4BoBUEI2 zc%^X397_cTh7+23>prQyv?u}^Ga=}1>=WNh1y33nm=%`p+I?d7l7}Z57}y-WOV987 z`n-XG;qmL&KqqhjLxz!+=~}k%D*pp6798!20uPjASezR=3IzF>6n`=;32$Zs4{vw8>eEFu6pT#2Wl1{6iiA?#~tux;+b@DTv zO*KcS`Onz&+wWP1!Z#v_xUkcyn{MW8i`Jb!e=5WZW=4C(x<;EfXEz($pSHiH#KIw< z;Ls@l^z~OkXfopu<7mjZeiGtvkn$Tmo+^_dC@<3MR9MiasZ-W0P1V-4iU%uV1}XXw zoZFk9wtaK-&9!f?eao&k-8<{v**Do`eY|-W53apsVY=I$ZF|OpYj0(w?k;YQ-cn%i z$|a%^u+V9KKhO|FG7@;HGAR&fnX1Ypk13Npm4ZA~I#Ib@K*#XIJtL4)TUKW{_x5Qw zn~IN*kN3+Ty!F>U5S9%aP4ip!ABTHIAaBF%-2L-@T4dDBF|qTLl2_;DpWN1d^04!h zhYLRyT=;2T&tVjM@gSS`E(?W| - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - RFduino LedButton - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIcons - - CFBundlePrimaryIcon - - CFBundleIconFiles - - icon@2x.png - icon.png - icon-72.png - icon-144.png - - - - CFBundleIdentifier - com.OpenSourceRF.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - LSRequiresIPhoneOS - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/rfduinoLedButton-Prefix.pch b/iPhone Apps/rfduinoLedButton/rfduinoLedButton/rfduinoLedButton-Prefix.pch deleted file mode 100755 index bf2495e..0000000 --- a/iPhone Apps/rfduinoLedButton/rfduinoLedButton/rfduinoLedButton-Prefix.pch +++ /dev/null @@ -1,14 +0,0 @@ -// -// Prefix header for all source files of the 'rfduinoLedButton' target in the 'rfduinoLedButton' project -// - -#import - -#ifndef __IPHONE_3_0 -#warning "This project uses features only available in iOS SDK 3.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/iPhone Apps/rfduinoServo/icon-144.png b/iPhone Apps/rfduinoServo/icon-144.png deleted file mode 100755 index 66fa6512f7f4b50796190d4978bb2928d531eece..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18282 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 RyS}rM$7yd=wQES~{{V=@qX+uL$Nkc;* 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 LNkvXXu0mjfB}h~d diff --git a/iPhone Apps/rfduinoServo/icon.png b/iPhone Apps/rfduinoServo/icon.png deleted file mode 100755 index 997762016faa9d8b5ec3196ead7d735a0ffcc3db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7312 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