diff --git a/README.md b/README.md index 5aedb27..a3f7e78 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Included smartwatches: 3. [ID107HR](https://github.com/micooke/micooke.github.io/blob/master/arduino-nRF5-smartwatches/images/ID107HR_back.jpg) 4. [ID107HR Plus](https://github.com/micooke/micooke.github.io/blob/master/arduino-nRF5-smartwatches/images/ID107HRPlus_disected.jpg) (alpha) - dont expect this to work 5. [LEMDOIE T28](https://github.com/micooke/micooke.github.io/blob/master/nRF52832_Lemdoie_T28.md) +6. [MyPow DS-D6](https://github.com/fanoush/ds-d6) Included Generic development boards: 6. [Taida Century nRF52 mini board / nRF52832 Gold Core](https://github.com/micooke/micooke.github.io/blob/master/nRF52832_TaidaCentury_GoldCore.md) @@ -72,6 +73,7 @@ Progamming is via a SWD programmer (J-Link, ST-Link etc.) using sandeep's core. ### Pin allocation The nRF52 based T28 is quite different. Its pin allocation table is located [here](https://github.com/micooke/micooke.github.io/blob/master/nRF52832_Lemdoie_T28.md) +@fanoush has done a great job on getting the DS-D6 pin allocation. It is hosted [here](https://github.com/fanoush/ds-d6) | peripheral type | name | pin | IDO003 | ID100HR | ID107HR | ID107HR Plus @@ -120,4 +122,5 @@ The nRF52 based T28 is quite different. Its pin allocation table is located [her * (Modified) [IDO003 picture](https://espruino.microco.sm/api/v1/files/ba591802419c40145d825db2924360eb162cc026.JPG) is from Gordon, embedded in this [conversation](http://forum.espruino.com/conversations/280747/) * ID107HR picture is my own * [ID107HR Plus picture](http://www.rogerclark.net/wp-content/uploads/2017/06/id107plus-7-770x1024.jpg) is from Curt, embedded on Roger's website [article](http://www.rogerclark.net/new-nrf52832-based-smart-watch-available/) -* (Modified) [ID107HR Plus pads](http://www.rogerclark.net/wp-content/uploads/2017/06/id107plus-3.jpg) is from Curt, embedded on Roger's website [article](http://www.rogerclark.net/new-nrf52832-based-smart-watch-available/) \ No newline at end of file +* (Modified) [ID107HR Plus pads](http://www.rogerclark.net/wp-content/uploads/2017/06/id107plus-3.jpg) is from Curt, embedded on Roger's website [article](http://www.rogerclark.net/new-nrf52832-based-smart-watch-available/) +* [DS-D6](https://github.com/fanoush/ds-d6) from [@fanoush](https://github.com/fanoush) \ No newline at end of file diff --git a/boards.txt b/boards.txt index 6a546a0..ed08115 100644 --- a/boards.txt +++ b/boards.txt @@ -199,6 +199,52 @@ T28.menu.softdevice.none.softdeviceversion= T28.menu.lfclk.lfrc=RC Oscillator T28.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC +T28.menu.board_variant.accel_hwi2c=I2C:Accel=HW, HeartRate=SW +T28.menu.board_variant.accel_hwi2c.build.lfclk_flags=-DUSE_LFXO -DACCEL_HWI2C + +T28.menu.board_variant.heartrate_hwi2c=I2C:Accel=SW, HeartRate=HW +T28.menu.board_variant.heartrate_hwi2c.build.lfclk_flags=-DUSE_LFXO -DHEARTRATE_HWI2C + +# ----------------------------------------------------------------------------- +DS_D6.name=MPow DS-D6 + +DS_D6.upload.tool=sandeepmistry:openocd +DS_D6.upload.target=nrf52 +DS_D6.upload.maximum_size=524288 + +DS_D6.bootloader.tool=sandeepmistry:openocd + +DS_D6.build.mcu=cortex-m4 +DS_D6.build.f_cpu=16000000 +DS_D6.build.board=DS_D6 +DS_D6.build.core=sandeepmistry:nRF5 +DS_D6.build.variant=DS_D6 +DS_D6.build.variant_system_lib= +DS_D6.build.extra_flags=-DCONFIG_NFCT_PINS_AS_GPIOS -DNRF52 -DDS_D6 -I{build.path} +DS_D6.build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +DS_D6.build.ldscript=nrf52_{build.chip}.ld +DS_D6.build.chip=xxaa + +DS_D6.menu.softdevice.s132=S132 +DS_D6.menu.softdevice.s132.softdevice=s132 +DS_D6.menu.softdevice.s132.softdeviceversion=2.0.1 +DS_D6.menu.softdevice.s132.upload.maximum_size=409600 +DS_D6.menu.softdevice.s132.build.extra_flags=-DNRF52 -DS132 -DNRF52_S132 +DS_D6.menu.softdevice.s132.build.ldscript=armgcc_s132_nrf52832_{build.chip}.ld + +DS_D6.menu.softdevice.none=None +DS_D6.menu.softdevice.none.softdevice=none +DS_D6.menu.softdevice.none.softdeviceversion= + +DS_D6.menu.lfclk.lfrc=RC Oscillator +DS_D6.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC + +DS_D6.menu.board_variant.accel_hwi2c=I2C:Accel=HW, HeartRate=SW +DS_D6.menu.board_variant.accel_hwi2c.build.lfclk_flags=-DUSE_LFXO -DACCEL_HWI2C + +DS_D6.menu.board_variant.heartrate_hwi2c=I2C:Accel=SW, HeartRate=HW +DS_D6.menu.board_variant.heartrate_hwi2c.build.lfclk_flags=-DUSE_LFXO -DHEARTRATE_HWI2C + # ----------------------------------------------------------------------------- Waveshare_BLE400_HRM.name=Waveshare BLE400 diff --git a/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_OLED.h b/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_OLED.h new file mode 100644 index 0000000..2dd469b --- /dev/null +++ b/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_OLED.h @@ -0,0 +1,115 @@ +#ifndef ID107_OLED_H +#define ID107_OLED_H + +#include "ID107_sensors.h" + +#include +#include + +U8G2_SH1106_64X32_1_4W_HW_SPI u8g2(U8G2_R0, OLED_CS, OLED_DC, OLED_RST); + +class ID107_OLED{ +private: + const uint8_t _numPages = 4; + uint32_t _splashTime; + uint8_t _pageNum; + time_t compileTime(); + + ID107_sensors _id107_sensors; + + void splash(uint32_t splash_time_ms); + void draw(); +public: + ID107_OLED(uint32_t splash_time_ms = 2000): _splashTime(splash_time_ms), _pageNum(0) {} + ~ID107_OLED() {} + void begin(); + void heartrate(uint8_t ambiant_sensor = 0); + void accelerometer(); + void clock(); + void nextPage(); + uint8_t getPageCount() { return _numPages; } + void drawPage(uint8_t pageNum = 0); +}; + +void ID107_OLED::begin() +{ + _id107_sensors.begin(); + + u8g2.begin(); + u8g2.setFont(u8g2_font_6x10_tf); + u8g2.setFontRefHeightExtendedText(); + u8g2.setDrawColor(1); + u8g2.setFontPosTop(); + u8g2.setFontDirection(0); + + splash(_splashTime); +} + +void ID107_OLED::drawPage(uint8_t pageNum) +{ + switch(pageNum) { + case 0: + heartrate(0); break; + case 1: + heartrate(1); break; + case 2: + accelerometer(); break; + default: + clock(); + } +} + +void ID107_OLED::draw() +{ + u8g2.firstPage(); + do { + u8g2.setFont(u8g2_font_6x10_tf); + u8g2.drawStr( 0, 0, _id107_sensors.row[0].c_str()); + u8g2.drawStr(0, 10, _id107_sensors.row[1].c_str()); + u8g2.drawStr(0, 20, _id107_sensors.row[2].c_str()); + } while ( u8g2.nextPage() ); +} + +void ID107_OLED::nextPage() +{ + // increment the page number + _pageNum = (_pageNum < _numPages - 1)?_pageNum + 1:0; + + // draw the page + drawPage(_pageNum); +} + + +void ID107_OLED::heartrate(uint8_t ambiant_sensor) +{ + _id107_sensors.get_heartrate(ambiant_sensor); + + draw(); +} + +void ID107_OLED::accelerometer() +{ + _id107_sensors.get_accelerometer(); + + draw(); +} + +void ID107_OLED::clock() +{ + _id107_sensors.get_clock(); + + draw(); +} + +void ID107_OLED::splash(uint32_t splash_time_ms) +{ + _id107_sensors.row[0] = "github.com"; + _id107_sensors.row[1] = "/micooke"; + _id107_sensors.row[2] = __TIME__; + + draw(); + + delay(splash_time_ms); +} + +#endif diff --git a/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_sensors.h b/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_sensors.h new file mode 100644 index 0000000..355528b --- /dev/null +++ b/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_sensors.h @@ -0,0 +1,169 @@ +#ifndef ID107_SENSORS_H +#define ID107_SENSORS_H + +#include + +#include +#include + +#include // https://github.com/JChristensen/Timezone + +TimeChangeRule ACST = {"ACST", First, Sun, Apr, 3, 570}; // Australian Central Daylight Time = UTC +9:30 hours +TimeChangeRule ACDT = {"ACDT", First, Sun, Oct, 2, 630}; // Australian Central Standard Time = UTC +10:30 hours +Timezone AdelaideTimezone(ACST, ACDT); +TimeChangeRule *tcr; // pointer to the time change rule, use to get TZ abbrev + +#ifdef ACCEL_HWI2C +// Kx022 - Hardware I2C (Wire) +KX022<> acc(Wire); + +// Si1143 - Software I2C +SoftwareI2C sWire(PIN_WIRE1_SDA, PIN_WIRE1_SCL); +PulsePlug pulse(sWire); +#else +// Kx022 - Software I2C (Wire) +SoftwareI2C sWire(PIN_WIRE1_SDA, PIN_WIRE1_SCL); +KX022 acc(sWire); + +// Si1143 - Hardware I2C +PulsePlug<> pulse(Wire); +#endif + +class ID107_sensors{ +private: + uint8_t _retries; + void float2chars(float &in, char (&out)[5]); + time_t compileTime(); +public: + ID107_sensors(uint8_t retries = 5) : _retries(retries) {} + ~ID107_sensors() {} + void begin(); + void get_heartrate(uint8_t ambiant_sensor = 0); + void get_accelerometer(); + void get_clock(); + String row[3]; +}; + +void ID107_sensors::begin() +{ + // Clock + setTime(AdelaideTimezone.toUTC(compileTime())); + + // Si1143 - Heartrate + uint8_t attempts = 0; + while ((pulse.isPresent() == false) & (attempts < _retries)) + { + delay(100); + ++attempts; + } + if (pulse.isPresent()) + { + pulse.init(); + } + + // Kx022 - Accelerometer + acc.init(); +} + +void ID107_sensors::get_heartrate(uint8_t ambiant_sensor) +{ + if (pulse.isPresent()) + { + pulse.readSensor(ambiant_sensor + 1); // sensorIdx = 1(HeartRate),2(Ambiant),3(Both) + if (ambiant_sensor) + { + + row[0] = "VIS " + String(pulse.als_vis); + row[1] = "IR " + String(pulse.als_ir); + row[2] = ""; + } + else + { + row[0] = "RED " + String(pulse.led_red); + row[1] = "IR1 " + String(pulse.led_ir1); + row[2] = "IR2 " + String(pulse.led_ir2); + } + } + else + { + row[0] = "Si1143 (HRM)"; + row[1] = "Not"; + row[2] = "Present"; + } +} + +void ID107_sensors::get_accelerometer() +{ + row[0] = "X "; + row[1] = "Y "; + row[2] = "Z "; + + char fltBuf[5]; + float xyz[3]; + acc.getAccelXYZ(xyz); + + float2chars(xyz[0],fltBuf); row[0] += String(fltBuf); + float2chars(xyz[1],fltBuf); row[1] += String(fltBuf); + float2chars(xyz[2],fltBuf); row[2] += String(fltBuf); +} + +void ID107_sensors::get_clock() +{ + time_t utc = now(); + time_t local = AdelaideTimezone.toLocal(utc, &tcr); + + char timeString[10]; + + sprintf(timeString, "%.2d:%.2d:%.2d", hour(local), minute(local), second(local)); + + char dateString[11]; + + sprintf(dateString, "%.2d/%.2d/%d", day(local), month(local), year(local)); + /* + char dayString[7]; + char monthYearString[9]; + char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) + strcpy(m, monthShortStr(month(local))); + + sprintf(dayString, "%s %.2d", dayShortStr(weekday(local)), day(local)); + sprintf(buf, "%s %d", m, year(local)); + */ + row[0] = timeString; + row[1] = dateString; + row[2] = ""; +} + +// Function to return the compile date and time as a time_t value +time_t ID107_sensors::compileTime() +{ + const time_t FUDGE(4); // fudge factor to allow for compile time (seconds, YMMV) + const char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec"; + char chMon[3], *m; + tmElements_t tm; + + strncpy(chMon, compDate, 3); + chMon[3] = '\0'; + m = strstr(months, chMon); + tm.Month = ((m - months) / 3 + 1); + + tm.Day = atoi(compDate + 4); + tm.Year = atoi(compDate + 7) - 1970; + tm.Hour = atoi(compTime); + tm.Minute = atoi(compTime + 3); + tm.Second = atoi(compTime + 6); + time_t t = makeTime(tm); + return t + FUDGE; // add fudge factor to allow for compile time +} + +void ID107_sensors::float2chars(float &in, char (&out)[5]) +{ + bool sign_bit = (in < 0); + uint16_t tmp = sign_bit?(-in * 10):(in * 10); + out[0] = (sign_bit)?'-':' '; + out[1] = char('0' + (tmp / 10)); + out[2] = '.'; + out[3] = char('0' + (tmp % 10)); + out[4] = '\0'; +} + +#endif diff --git a/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_u8g2_sensors_clock.ino b/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_u8g2_sensors_clock.ino new file mode 100644 index 0000000..1ba837a --- /dev/null +++ b/libraries/examples/Examples/ID107_u8g2_sensors_clock/ID107_u8g2_sensors_clock.ino @@ -0,0 +1,44 @@ +#include "ID107_OLED.h" + +bool button_wasPressed = false; + +ID107_OLED id107_oled; +uint8_t page_num = 0; +uint32_t tPage; + +void setup() +{ + id107_oled.begin(); + + Serial.begin(9600); + Serial.println(__FILE__); + + pinMode(PIN_BUTTON1, INPUT_PULLUP); + + tPage = millis(); +} + +void loop() +{ + if (Button_isPressed(PIN_BUTTON1)) + { + page_num = (page_num + 1 < id107_oled.getPageCount())?page_num+1:0; + } + + if (millis() - tPage > 20) // 20ms = 50Hz + { + tPage = millis(); + id107_oled.drawPage(page_num); + } + yield(); +} + +// debounce the button +bool Button_isPressed(uint8_t ButtonPin) +{ + bool button_isPressed = (digitalRead(ButtonPin) == 0); + + bool result = (button_wasPressed == false) & (button_isPressed == true); + button_wasPressed = button_isPressed; + return result; +} diff --git a/libraries/examples/Examples/ReverseEngineerSmartwatchPins/ReverseEngineerSmartwatchPins.ino b/libraries/examples/Examples/ReverseEngineerSmartwatchPins/ReverseEngineerSmartwatchPins.ino new file mode 100644 index 0000000..65959f9 --- /dev/null +++ b/libraries/examples/Examples/ReverseEngineerSmartwatchPins/ReverseEngineerSmartwatchPins.ino @@ -0,0 +1,46 @@ +#include + +#include "SerialCommands.h" + +#include // https://github.com/kroimon/Arduino-SerialCommand +#include // https://github.com/zacsketches/Arduino_Vector + +#define ANALOG_PINS = 8; +#define DIGITAL_PINS = 28; + +DigitalPins[DIGITAL_PINS] = { + PIN_BUTTON1,PIN_BUTTON2,PIN_TOUCH,PIN_VIBRATE,LED_BUILTIN, /*1-5*/ + PIN_HR_ON,PIN_OLED_VPP,PIN_OLED_SW, /*6-8*/ + PIN_SERIAL_RX,PIN_SERIAL_TX,PIN_SERIAL1_RX,PIN_SERIAL1_TX, /*9-12*/ + PIN_SPI_MISO,PIN_SPI_MOSI,PIN_SPI_SCK, /*13-15*/ + PIN_SPI1_MISO,PIN_SPI1_MOSI,PIN_SPI1_SCK, /*16-18*/ + PIN_SPI1_CS,SS,MOSI,MISO,SCK, /*19-23*/ + OLED_RST,OLED_CS,OLED_DC, /*24-26*/ + PIN_WIRE_SDA,PIN_WIRE_SCL}; /*27-28*/ + +AnalogPins[ANALOG_PINS] = { PIN_A0, PIN_A1, PIN_A2, PIN_A3, PIN_A4, PIN_A5, PIN_A6, PIN_A7 }; + +void setup() +{ + // turn off the vibration motor + digitalWrite(PIN_VIBRATE, HIGH); + pinMode(PIN_VIBRATE, OUTPUT); + + Serial1.begin(9600); + + populate_UNUSED_PINS(); + + sCmd.addCommand("T", togglePinCommand); + sCmd.addCommand("KX", findKx022IntPinCommand); + sCmd.addCommand("B", findBatteryCommand); + sCmd.addCommand("DO", digitalOutputCommand); + sCmd.addCommand("S", scanCommand); + sCmd.addCommand("S", scanWideCommand); + sCmd.addCommand("P", printCommand); + + sCmd.setDefaultHandler(unrecognized); + + unrecognized(NULL); +} + +void loop(void) { sCmd.readSerial(); } diff --git a/libraries/examples/Examples/ReverseEngineerSmartwatchPins/SerialCommands.h b/libraries/examples/Examples/ReverseEngineerSmartwatchPins/SerialCommands.h new file mode 100644 index 0000000..788137a --- /dev/null +++ b/libraries/examples/Examples/ReverseEngineerSmartwatchPins/SerialCommands.h @@ -0,0 +1,204 @@ +#ifndef SERIALCOMMANDS_H +#define SERIALCOMMANDS_H + +#include // https://github.com/kroimon/Arduino-SerialCommand +#include // https://github.com/zacsketches/Arduino_Vector + +SerialCommand sCmd; +SoftwareSerial Serial1(PIN_SERIAL1_RX, PIN_SERIAL1_TX); + +Vector UNUSED_PINS; +uint8_t NUM_UNUSED_PINS = 0; + +void populate_UNUSED_PINS() +{ + // Note : AnalogPins arent dedicated to a function so will be used by rev eng tools + for (uint8_t p=0; p < PINS_COUNT; ++p) + { + bool isAllocated = false; + for (uint8_t idx=0; idx < DIGITAL_PINS; ++idx) + { + if (p == DigitalPins[idx]) + { + isAllocated = true; + break; + } + } + + // If it isnt one of the digital pins, save it as unused + if (isAllocated == false) + { + UNUSED_PINS.push_back(p); + ++NUM_UNUSED_PINS; + } + } +} + +void unrecognized(const char *c) +{ + Serial1.println( + F("Commands are :\n" + "T pin_number - toggle digital pin\n" + "KX - find Kx022/023 interrupt pin\n" + "B - find battery voltage pin\n" + "DO - toggle unused digital output pins (outputs pin number to serial)\n" + "S - scan unused pins, which includes analog pins (outputs pin number and pin value to serial)\n" + "SW - same as scan, but output is in wide format\n" + "P - print all un-allocated (and Analog) pins\n")); + + Serial1.println("Example: T 4 -> toggle D4 high for 3 seconds, then set it low"); +} + +void findBatteryCommand() +{ + const uint8_t tolerance = 10; // tolerance on successive measurements (i.e. error margin) + + //pinMode(LED_BUILTIN, OUTPUT); + pinMode(LED_VIBRATE, OUTPUT); + + for (uint8_t p = 0; p < ANALOG_PINS; ++p) + { + pinMode(AnalogPins[p], OUTPUT); + uint8_t val = analogRead(AnalogPins[p]); + + // if we are reading a value, try running down the battery for 1 minute + if (val > 0) + { + Serial1.print(F("Testing pin ")); + Serial1.print(AnalogPins[p]); + Serial1.println(F(" to see if it is the battery pin (test will take approximately 1 minute)")); + + //digitalWrite(LED_BUILTIN, HIGH); + digitalWrite(PIN_VIBRATE, LOW); // vibration motor on + for (uint8_t wait=0; wait < 60; ++wait) + { + delay(1000); + } + //digitalWrite(LED_BUILTIN, LOW); + digitalWrite(PIN_VIBRATE, HIGH); // vibration motor off + + if (analogRead(AnalogPins[p] + tolerance < val)) + { + Serial1.print(F("SUCCESS! Battery pin is ")); + Serial1.println(AnalogPins[p]); + } + else + { + Serial1.print(F("FAIL! Battery pin is not")); + Serial1.println(AnalogPins[p]); + } + } + } +} + +//"W device_address reg_num reg_val - writes 'reg_val' to register 'reg_num'\n" +void findKx022IntPinCommand() +{ + // setup the Kx022 + // clear the interrupt/s + // set the interrupt/s as sticky bits + // prompt the user to tap the watch and wait for 5 seconds + // check for a change in status +} + +void togglePinCommand() +{ + char *arg; + + arg = sCmd.next(); + uint8_t pin_number = strtoul(arg, NULL, 16); + + if (arg != NULL) + { + pinMode(pin_number, OUTPUT); + digitalWrite(pin_number, HIGH); + delay(3000); + digitalWrite(pin_number, LOW); + } + else + { + Serial1.println("One argument is required : T pin_number"); + } +} + +void digitalOutputCommand() +{ + for (uint8_t p = 0; p < NUM_UNUSED_PINS; ++p) + { + Serial1.print(F("D")); + Serial1.println(UNUSED_PINS[p]); + pinMode(UNUSED_PINS[p], OUTPUT); + digitalWrite(UNUSED_PINS[p], HIGH); + delay(3000); + digitalWrite(UNUSED_PINS[p], LOW); + } +} + +void scanCommand() +{ + for (uint8_t p = 0; p < NUM_UNUSED_PINS; ++p) + { + pinMode(UNUSED_PINS[p], INPUT); + uint8_t val = analogRead(UNUSED_PINS[p], HIGH); + + Serial1.print(F("D")); + Serial1.print(UNUSED_PINS[p]); + Serial1.print(F(" = ")); + Serial1.println(val); + } +} + +void scanWideCommand() +{ + for (uint8_t p = 0; p < NUM_UNUSED_PINS; ++p) + { + if (p%5 == 0) + { + Serial1.print(F("\n[")); + print3digits(UNUSED_PINS[p]); + const uint8_t upper_value = min(NUM_UNUSED_PINS, p+4); + for (uint8_t sp = p+1; sp < upper_value; ++sp) + { + Serial1.print(F(" ")); + print3digits(UNUSED_PINS[p]); + } + Serial1.println(F("]")); + } + pinMode(UNUSED_PINS[p], INPUT); + uint8_t val = analogRead(UNUSED_PINS[p], HIGH); + + Serial1.print(F(" ")); + print3digits(val); + } +} + +void printCommand() +{ + Serial1.println(F("Unallocated and Analog pins:")); + for (uint8_t p = 0; p < NUM_UNUSED_PINS; p+=4) + { + print3digits(UNUSED_PINS[p]); + const uint8_t upper_value = min(NUM_UNUSED_PINS, p+4); + for (uint8_t sp = p+1; sp < upper_value; ++sp) + { + Serial1.print(F(" ")); + print3digits(UNUSED_PINS[p]); + } + Serial1.println(""); + } +} + +void print3digits(uint8_t val) +{ + if (val % 100 > 0) + { + Serial1.print(F("0")); + } + if (val % 10 > 0) + { + Serial1.print(F("0")); + } + Serial1.print(val); +} + +#endif \ No newline at end of file diff --git a/examples/u8g2/README.md b/libraries/examples/Examples/u8g2/README.md similarity index 100% rename from examples/u8g2/README.md rename to libraries/examples/Examples/u8g2/README.md diff --git a/examples/u8g2/sys/sdl/watch_64x32/Makefile b/libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/Makefile similarity index 100% rename from examples/u8g2/sys/sdl/watch_64x32/Makefile rename to libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/Makefile diff --git a/examples/u8g2/sys/sdl/watch_64x32/fonts.h b/libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/fonts.h similarity index 100% rename from examples/u8g2/sys/sdl/watch_64x32/fonts.h rename to libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/fonts.h diff --git a/examples/u8g2/sys/sdl/watch_64x32/main.cpp b/libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/main.cpp similarity index 100% rename from examples/u8g2/sys/sdl/watch_64x32/main.cpp rename to libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/main.cpp diff --git a/examples/u8g2/sys/sdl/watch_64x32/main.o b/libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/main.o similarity index 100% rename from examples/u8g2/sys/sdl/watch_64x32/main.o rename to libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/main.o diff --git a/examples/u8g2/sys/sdl/watch_64x32/screens.h b/libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/screens.h similarity index 100% rename from examples/u8g2/sys/sdl/watch_64x32/screens.h rename to libraries/examples/Examples/u8g2/sys/sdl/watch_64x32/screens.h diff --git a/libraries/examples/Examples/u8g2_ScreenTest/u8g2_ScreenTest.ino b/libraries/examples/Examples/u8g2_ScreenTest/u8g2_ScreenTest.ino new file mode 100644 index 0000000..0279074 --- /dev/null +++ b/libraries/examples/Examples/u8g2_ScreenTest/u8g2_ScreenTest.ino @@ -0,0 +1,88 @@ +/* + ScreenTest.ino using: + Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) +*/ + +#include +#include + +#ifdef U8X8_HAVE_HW_SPI +#include +#endif +#ifdef U8X8_HAVE_HW_I2C +#include +#endif + +/* + U8glib Example Overview: + Frame Buffer Examples: clearBuffer/sendBuffer. Fast, but may not work with all Arduino boards because of RAM consumption + Page Buffer Examples: firstPage/nextPage. Less RAM usage, should work with all Arduino boards. + U8x8 Text Only Example: No RAM usage, direct communication with display controller. No graphics, 8x8 Text only. + + This is a page buffer example. +*/ + +#if defined(_VARIANT_T28_) + U8G2_SH1107_64X128_1_4W_HW_SPI u8g2(U8G2_R0, OLED_CS, OLED_DC, OLED_RST); +#elif defined (_VARIANT_IDO003_) | defined (_VARIANT_ID100HR_) | defined(_VARIANT_ID107HR_) + U8G2_SH1106_64X32_1_4W_HW_SPI u8g2(U8G2_R0, OLED_CS, OLED_DC, OLED_RST); +#else + // generic example for the common 128x64 SSD1306 OLED + #define OLED_CS 10 + #define OLED_DC 9 + #define OLED_RST 8 + U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, OLED_CS, OLED_DC, OLED_RST); +#endif + +void u8g2_prepare(void) { + u8g2.setFont(u8g2_font_6x10_tf); + u8g2.setFontRefHeightExtendedText(); + u8g2.setDrawColor(1); + u8g2.setFontPosTop(); + u8g2.setFontDirection(0); +} + +void u8g2_box_title() { + u8g2.drawStr( 5, 5, "U8g2"); + u8g2.drawStr( 5, 20, "ScreenTest"); + + u8g2.drawFrame(0, 0, u8g2.getDisplayWidth(), u8g2.getDisplayHeight()); +} + +void displayPage() +{ + u8g2.firstPage(); + do { + u8g2_box_title(); + } while( u8g2.nextPage() ); +} + +void setup(void) +{ + #if defined (_VARIANT_T28_) + // Turn off the vibration motor and hr sensor (both are driven by P-mosfets, so drive HIGH to turn off) + pinMode(PIN_VIBRATE, OUTPUT); + pinMode(PIN_HR_ON, OUTPUT); + digitalWrite(PIN_VIBRATE, HIGH); + digitalWrite(PIN_HR_ON, HIGH); + #endif + + Serial.begin(9600); + Serial.println(__FILE__); + Serial.print(__DATE__); Serial.print(F(" @ ")); Serial.println(__TIME__); + + u8g2.begin(); + u8g2_prepare(); + displayPage(); + Serial.println("end setup"); +} + +void loop(void) +{ + delay(5000); + u8g2.setFlipMode(true); + displayPage(); + delay(5000); + u8g2.setFlipMode(false); + displayPage(); +} \ No newline at end of file diff --git a/libraries/examples/README.md b/libraries/examples/README.md new file mode 100644 index 0000000..1bc125b --- /dev/null +++ b/libraries/examples/README.md @@ -0,0 +1,3 @@ +### u8g2_ScreenTest +This is a page buffer example that draws a border around the whole screen, and prints "U8g2" and "ScreenTest" on line 1 and line 2 respectively. + \ No newline at end of file diff --git a/libraries/examples/examples.h b/libraries/examples/examples.h new file mode 100644 index 0000000..bec47da --- /dev/null +++ b/libraries/examples/examples.h @@ -0,0 +1 @@ +/* examples.h */ \ No newline at end of file diff --git a/libraries/examples/library.properties b/libraries/examples/library.properties new file mode 100644 index 0000000..5fcafb7 --- /dev/null +++ b/libraries/examples/library.properties @@ -0,0 +1,9 @@ +name=examples +version=0.0 +author=Mark Cooke (https://github/micooke) +maintainer=Mark Cooke (https://github/micooke) +sentence=various nRF5 smartwatch examples +paragraph= +category=Uncategorized +url=https://github.com/micooke/arduino-nRF5-smartwatches +architectures=* diff --git a/platform.txt b/platform.txt new file mode 100644 index 0000000..502cf53 --- /dev/null +++ b/platform.txt @@ -0,0 +1,19 @@ +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# Copyright (c) 2016 Mark Cooke 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 + +name=nRF5 smartwatches +version=0.2.1 diff --git a/variants/DS_D6/pins_arduino.h b/variants/DS_D6/pins_arduino.h new file mode 100644 index 0000000..3ef4d4a --- /dev/null +++ b/variants/DS_D6/pins_arduino.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. 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 +*/ + +// API compatibility +#include "variant.h" diff --git a/variants/DS_D6/variant.cpp b/variants/DS_D6/variant.cpp new file mode 100644 index 0000000..22256e1 --- /dev/null +++ b/variants/DS_D6/variant.cpp @@ -0,0 +1,56 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2019 Mark Cooke 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 +*/ + +#include "variant.h" + +// https://github.com/fanoush/ds-d6/wiki/Hardware +const uint32_t g_ADigitalPinMap[] = { + 0, + 1, + 2, // charge detect: vmul-5/analogRead(D2) + 3, // battery voltage: vmul*analogRead(D3) + 4, // OLED RST - 128x32 SSD1306 + 5, // OLED MOSI - 128x32 SSD1306 + 6, // OLED SCK - 128x32 SSD1306 + 7, // HR sensor SCL - PAH8001 + 8, // HR sensor SDA - PAH8001 + 9, + 10, + 11, + 12, + 13, // Accel SCL - Kx023 + 14, // Accel SDA - Kx023 + 15, // Accel INT1 - Kx023 + 16, + 17, + 18, + 19, + 20, + 21, + 22, // UART RX + 23, // UART TX + 24, + 25, // Vibration Motor + 26, // HR sensor ENABLE - PAH8001 + 27, + 28, // OLED DC - 128x32 SSD1306 + 29, // OLED CS - 128x32 SSD1306 + 30, // Button1 / Touch Button (Pull Up) + 31 +}; diff --git a/variants/DS_D6/variant.h b/variants/DS_D6/variant.h new file mode 100644 index 0000000..2d45fbe --- /dev/null +++ b/variants/DS_D6/variant.h @@ -0,0 +1,130 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2019 Mark Cooke 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 +*/ + +#ifndef _VARIANT_DS_D6_ +#define _VARIANT_DS_D6_ + +/** Master clock frequency */ +#ifdef NRF52 +#define VARIANT_MCK (64000000ul) +#else +#define VARIANT_MCK (16000000ul) +#endif + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT 32u +#define NUM_DIGITAL_PINS 20u +#define NUM_ANALOG_INPUTS 8u +#define NUM_ANALOG_OUTPUTS 0u + +// Buttons +#define PIN_BUTTON1 30u +#define PIN_TOUCH PIN_BUTTON1 + +#define PIN_VIBRATE 25u +#define PIN_HR_ON 26u + +#define LED_BUILTIN PIN_VIBRATE + +/* + * Analog pins + */ +#define PIN_A0 2u +#define PIN_A1 3u +#define PIN_A2 4u +#define PIN_A3 5u +#define PIN_A4 28u +#define PIN_A5 29u +#define PIN_A6 30u +#define PIN_A7 31u + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +#ifdef NRF52 +#define ADC_RESOLUTION 14 +#else +#define ADC_RESOLUTION 10 +#endif + +/* + * Serial interfaces + */ +// Serial + +#define PIN_SERIAL_RX 22u +#define PIN_SERIAL_TX 23u + +/* + * SPI Interfaces + */ + +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO 31u // pin 31 unallocated +#define PIN_SPI_MOSI 5u // 128x32 SSD1306 OLED +#define PIN_SPI_SCK 6u +#define PIN_SPI_RST 4u +#define PIN_SPI_DC 28u +#define PIN_SPI_CS 29u + +static const uint8_t SS = PIN_SPI_CS; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +#define OLED_RST PIN_SPI_RST +#define OLED_CS PIN_SPI_CS +#define OLED_DC PIN_SPI_DC + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#ifdef ACCEL_HWI2C +#define PIN_WIRE_SDA 13u // Kx023 (Address 0x1f)- Accelerometer Sensor +#define PIN_WIRE_SCL 14u +#define PIN_WIRE_INT1 15u +#define PIN_WIRE1_SDA 7u // PAH8001 (Address 0x6b) - HeartRate Sensor +#define PIN_WIRE1_SCL 8u +#else +#define PIN_WIRE_SDA 7u // PAH8001 (Address 0x6b) - HeartRate Sensor +#define PIN_WIRE_SCL 8u +#define PIN_WIRE1_SDA 13u // Kx023 (Address 0x1f) - Accelerometer Sensor +#define PIN_WIRE1_SCL 14u +#define PIN_WIRE1_INT1 15u +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/variants/ID100HR/variant.cpp b/variants/ID100HR/variant.cpp index 02d405b..fa133dd 100644 --- a/variants/ID100HR/variant.cpp +++ b/variants/ID100HR/variant.cpp @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/ID100HR/variant.h b/variants/ID100HR/variant.h index bc1e4bb..2c35b57 100644 --- a/variants/ID100HR/variant.h +++ b/variants/ID100HR/variant.h @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/ID107HR/variant.cpp b/variants/ID107HR/variant.cpp index 02d405b..fa133dd 100644 --- a/variants/ID107HR/variant.cpp +++ b/variants/ID107HR/variant.cpp @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/ID107HR/variant.h b/variants/ID107HR/variant.h index ddb8d7e..e3a75ac 100644 --- a/variants/ID107HR/variant.h +++ b/variants/ID107HR/variant.h @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 @@ -103,9 +103,13 @@ static const uint8_t SCK = PIN_SPI_SCK; #ifdef ACCEL_HWI2C #define PIN_WIRE_SDA 14 // Kx022 - Accelerometer Sensor #define PIN_WIRE_SCL 16 +#define PIN_WIRE1_SDA 22u // Si1143 - HeartRate Sensor +#define PIN_WIRE1_SCL 23u #else #define PIN_WIRE_SDA 22u // Si1143 - HeartRate Sensor #define PIN_WIRE_SCL 23u +#define PIN_WIRE1_SDA 14 // Kx022 - Accelerometer Sensor +#define PIN_WIRE1_SCL 16 #endif #ifdef __cplusplus diff --git a/variants/ID107HRPlus/variant.cpp b/variants/ID107HRPlus/variant.cpp index 02d405b..fa133dd 100644 --- a/variants/ID107HRPlus/variant.cpp +++ b/variants/ID107HRPlus/variant.cpp @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/ID107HRPlus/variant.h b/variants/ID107HRPlus/variant.h index 3951b03..cdc26ea 100644 --- a/variants/ID107HRPlus/variant.h +++ b/variants/ID107HRPlus/variant.h @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/IDO003/variant.cpp b/variants/IDO003/variant.cpp index 02d405b..fa133dd 100644 --- a/variants/IDO003/variant.cpp +++ b/variants/IDO003/variant.cpp @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/T28/variant.cpp b/variants/T28/variant.cpp index 1c92d70..abbf09c 100644 --- a/variants/T28/variant.cpp +++ b/variants/T28/variant.cpp @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 diff --git a/variants/T28/variant.h b/variants/T28/variant.h index 2f9e86e..0d02a35 100644 --- a/variants/T28/variant.h +++ b/variants/T28/variant.h @@ -1,6 +1,6 @@ /* Copyright (c) 2014-2015 Arduino LLC. All right reserved. - Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018 Mark Cooke 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 @@ -44,7 +44,7 @@ extern "C" // Buttons #define PIN_BUTTON1 20u // TOP #define PIN_BUTTON2 24u // BOTTOM -#define PIN_TOUCH 2u // RH6015-C, input OC +#define PIN_TOUCH 2u // RH6015-C, input OC #define PIN_VIBRATE 10u #define PIN_HR_ON 9u @@ -96,8 +96,8 @@ static const uint8_t A5 = PIN_A5; // [ ] - P0.26 // debug Tx // [Bottom] - P0.25 // debug Rx // -#define PIN_SERIAL1_RX 31u -#define PIN_SERIAL1_TX 11u +#define PIN_SERIAL1_RX 31u // UBLOX Tx (9600 BAUD) +#define PIN_SERIAL1_TX 11u // UBLOX Rx /* * SPI Interfaces @@ -127,10 +127,19 @@ static const uint8_t SCK = PIN_SPI_SCK; /* * Wire Interfaces */ -#define WIRE_INTERFACES_COUNT 0 +#define WIRE_INTERFACES_COUNT 1 -#define PIN_WIRE_SDA 13u // Kx023 -#define PIN_WIRE_SCL 16u // Kx023 +#ifdef ACCEL_HWI2C +#define PIN_WIRE_SDA 13u // Kx023 - Accelerometer Sensor +#define PIN_WIRE_SCL 16u +#define PIN_WIRE1_SDA 22u // Si1143 - HeartRate Sensor +#define PIN_WIRE1_SCL 23u +#else +#define PIN_WIRE_SDA 22u // Si1143 - HeartRate Sensor +#define PIN_WIRE_SCL 23u +#define PIN_WIRE1_SDA 13u // Kx023 - Accelerometer Sensor +#define PIN_WIRE1_SCL 16u +#endif #ifdef __cplusplus }