now actionified & adding proper test files for all examples!
This commit is contained in:
parent
44362b4297
commit
f0de90d0e9
350 changed files with 1128 additions and 432 deletions
46
.github/ISSUE_TEMPLATE.md
vendored
Normal file
46
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||||
|
improve the speed of resolution please review the following guidelines and
|
||||||
|
common troubleshooting steps below before creating the issue:
|
||||||
|
|
||||||
|
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||||
|
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||||
|
something isn't working as expected. In many cases the problem is a common issue
|
||||||
|
that you will more quickly receive help from the forum community. GitHub issues
|
||||||
|
are meant for known defects in the code. If you don't know if there is a defect
|
||||||
|
in the code then start with troubleshooting on the forum first.
|
||||||
|
|
||||||
|
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||||
|
check all of the steps and commands to run have been followed. Consult the
|
||||||
|
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||||
|
|
||||||
|
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||||
|
|
||||||
|
- For uploading sketches or communicating with the board make sure you're using
|
||||||
|
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||||
|
very hard to tell the difference between a data and charge cable! Try using the
|
||||||
|
cable with other devices or swapping to another cable to confirm it is not
|
||||||
|
the problem.
|
||||||
|
|
||||||
|
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||||
|
your board and plug in an external power supply. In many cases just
|
||||||
|
plugging a board into your computer is not enough to power it and other
|
||||||
|
peripherals.
|
||||||
|
|
||||||
|
- **Double check all soldering joints and connections.** Flakey connections
|
||||||
|
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||||
|
|
||||||
|
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||||
|
guarantee a clone board will have the same functionality and work as expected
|
||||||
|
with this code and don't support them.
|
||||||
|
|
||||||
|
If you're sure this issue is a defect in the code and checked the steps above
|
||||||
|
please fill in the following fields to provide enough troubleshooting information.
|
||||||
|
You may delete the guideline and text above to just leave the following details:
|
||||||
|
|
||||||
|
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||||
|
|
||||||
|
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||||
|
VERSION HERE**
|
||||||
|
|
||||||
|
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||||
|
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
||||||
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||||
|
Before you open the request please review the following guidelines and tips to
|
||||||
|
help it be more easily integrated:
|
||||||
|
|
||||||
|
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||||
|
of the code were modified.** This will help us understand any risks of integrating
|
||||||
|
the code.
|
||||||
|
|
||||||
|
- **Describe any known limitations with your change.** For example if the change
|
||||||
|
doesn't apply to a supported platform of the library please mention it.
|
||||||
|
|
||||||
|
- **Please run any tests or examples that can exercise your modified code.** We
|
||||||
|
strive to not break users of the code and running tests/examples helps with this
|
||||||
|
process.
|
||||||
|
|
||||||
|
Thank you again for contributing! We will try to test and integrate the change
|
||||||
|
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||||
|
can't immediately respond to every request. There is no need to bump or check in
|
||||||
|
on a pull request (it will clutter the discussion of the request).
|
||||||
|
|
||||||
|
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||||
|
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||||
|
priorities of the pull request. Don't fret, the open source community thrives on
|
||||||
|
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||||
|
|
||||||
|
After reviewing the guidelines above you can delete this text from the pull request.
|
||||||
63
.github/workflows/githubci.yml
vendored
63
.github/workflows/githubci.yml
vendored
|
|
@ -3,9 +3,46 @@ name: Arduino Library CI
|
||||||
on: [pull_request, push, repository_dispatch]
|
on: [pull_request, push, repository_dispatch]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
arduino:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
arduino-platform: ["uno", "nrf52832", "cpx_ada", "pyportal", "protrinket_3v", "protrinket_5v", "metro_m0", "esp8266", "esp32", "trinket_3v", "trinket_5v", "gemma", "flora", "feather32u4", "feather_m0_express", "gemma_m0", "trinket_m0", "hallowing_m0", "monster_m4sk", "hallowing_m4", "neotrellis_m4", "pybadge", "cpb"]
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
#needs: pylint
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: '3.x'
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: adafruit/ci-arduino
|
||||||
|
path: ci
|
||||||
|
|
||||||
|
- name: pre-install
|
||||||
|
run: bash ci/actions_install.sh
|
||||||
|
|
||||||
|
# manually install some libraries
|
||||||
|
- name: extra libraries
|
||||||
|
run: |
|
||||||
|
git clone --quiet https://github.com/adafruit/Cryptosuite.git /home/runner/Arduino/libraries/Cryptosuite
|
||||||
|
git clone --quiet https://github.com/adafruit/WiFiNINA.git /home/runner/Arduino/libraries/WiFiNINA
|
||||||
|
git clone --quiet https://github.com/adafruit/Adafruit_LSM303.git /home/runner/Arduino/libraries/Adafruit_LSM303
|
||||||
|
git clone --quiet https://github.com/moderndevice/CapSense.git /home/runner/Arduino/libraries/CapSense
|
||||||
|
git clone --quiet https://github.com/PaintYourDragon/ffft.git /home/runner/Arduino/libraries/ffft
|
||||||
|
git clone --quiet https://github.com/adafruit/RadioHead.git /home/runner/Arduino/libraries/RadioHead
|
||||||
|
git clone --quiet https://github.com/me-no-dev/ESPAsyncTCP /home/runner/Arduino/libraries/ESPAsyncTCP
|
||||||
|
git clone --quiet https://github.com/adafruit/Talkie /home/runner/Arduino/libraries/Talkie
|
||||||
|
|
||||||
|
- name: test platforms
|
||||||
|
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
|
||||||
|
|
||||||
pylint:
|
pylint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# needs: build
|
needs: arduino
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Python 3.6
|
- name: Set up Python 3.6
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
|
|
@ -22,27 +59,3 @@ jobs:
|
||||||
|
|
||||||
- name: lint
|
- name: lint
|
||||||
run: ./pylint_check.sh
|
run: ./pylint_check.sh
|
||||||
|
|
||||||
arduino:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
arduino-platform: ["uno", "cpx_ada", "pyportal"]
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: '3.x'
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: adafruit/ci-arduino
|
|
||||||
path: ci
|
|
||||||
|
|
||||||
- name: pre-install
|
|
||||||
run: bash ci/actions_install.sh
|
|
||||||
|
|
||||||
- name: test platforms
|
|
||||||
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
ESP32BootROM - part of the Firmware Updater for the
|
||||||
|
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
|
||||||
|
|
||||||
|
Copyright (c) 2018 Arduino SA. All rights 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 "ESP32BootROM.h"
|
||||||
|
|
||||||
|
//#define DEBUG 1
|
||||||
|
|
||||||
|
ESP32BootROMClass::ESP32BootROMClass(HardwareSerial& serial, int gpio0Pin, int resetnPin) :
|
||||||
|
_serial(&serial),
|
||||||
|
_gpio0Pin(gpio0Pin),
|
||||||
|
_resetnPin(resetnPin)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::begin(unsigned long baudrate)
|
||||||
|
{
|
||||||
|
_serial->begin(115200);
|
||||||
|
|
||||||
|
pinMode(_gpio0Pin, OUTPUT);
|
||||||
|
pinMode(_resetnPin, OUTPUT);
|
||||||
|
|
||||||
|
digitalWrite(_gpio0Pin, LOW);
|
||||||
|
|
||||||
|
digitalWrite(_resetnPin, LOW);
|
||||||
|
delay(10);
|
||||||
|
digitalWrite(_resetnPin, HIGH);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
int synced = 0;
|
||||||
|
|
||||||
|
for (int retries = 0; !synced && (retries < 5); retries++) {
|
||||||
|
synced = sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!synced) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(ARDUINO_AVR_UNO_WIFI_REV2)
|
||||||
|
(void)baudrate;
|
||||||
|
#else
|
||||||
|
if (baudrate != 115200) {
|
||||||
|
if (!changeBaudrate(baudrate)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
_serial->end();
|
||||||
|
_serial->begin(baudrate);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!spiAttach()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32BootROMClass::end() {
|
||||||
|
_serial->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::sync()
|
||||||
|
{
|
||||||
|
const uint8_t data[] = {
|
||||||
|
0x07, 0x07, 0x12, 0x20,
|
||||||
|
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55
|
||||||
|
};
|
||||||
|
|
||||||
|
command(0x08, data, sizeof(data));
|
||||||
|
|
||||||
|
int results[8];
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
results[i] = response(0x08, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (results[0] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::changeBaudrate(unsigned long baudrate)
|
||||||
|
{
|
||||||
|
const uint32_t data[2] = {
|
||||||
|
baudrate,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
command(0x0f, data, sizeof(data));
|
||||||
|
|
||||||
|
return (response(0x0f, 3000) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::spiAttach()
|
||||||
|
{
|
||||||
|
const uint8_t data[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
command(0x0d, data, sizeof(data));
|
||||||
|
|
||||||
|
return (response(0x0d, 3000) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize) {
|
||||||
|
const uint32_t data[4] = {
|
||||||
|
size,
|
||||||
|
size / chunkSize,
|
||||||
|
chunkSize,
|
||||||
|
offset
|
||||||
|
};
|
||||||
|
|
||||||
|
command(0x02, data, sizeof(data));
|
||||||
|
|
||||||
|
_flashSequenceNumber = 0;
|
||||||
|
_chunkSize = chunkSize;
|
||||||
|
|
||||||
|
return (response(0x02, 120000) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::dataFlash(const void* data, uint32_t length)
|
||||||
|
{
|
||||||
|
uint32_t cmdData[4 + (_chunkSize / 4)];
|
||||||
|
|
||||||
|
cmdData[0] = length;
|
||||||
|
cmdData[1] = _flashSequenceNumber++;
|
||||||
|
cmdData[2] = 0;
|
||||||
|
cmdData[3] = 0;
|
||||||
|
|
||||||
|
memcpy(&cmdData[4], data, length);
|
||||||
|
|
||||||
|
if (length < _chunkSize) {
|
||||||
|
memset(&cmdData[4 + (length / 4)], 0xff, _chunkSize - length);
|
||||||
|
}
|
||||||
|
|
||||||
|
command(0x03, cmdData, sizeof(cmdData));
|
||||||
|
|
||||||
|
return (response(0x03, 3000) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::endFlash(uint32_t reboot) {
|
||||||
|
const uint32_t data[1] = {
|
||||||
|
reboot
|
||||||
|
};
|
||||||
|
|
||||||
|
command(0x04, data, sizeof(data));
|
||||||
|
|
||||||
|
return (response(0x04, 3000) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::md5Flash(uint32_t offset, uint32_t size, uint8_t* result)
|
||||||
|
{
|
||||||
|
const uint32_t data[4] = {
|
||||||
|
offset,
|
||||||
|
size,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
command(0x13, data, sizeof(data));
|
||||||
|
|
||||||
|
uint8_t asciiResult[32];
|
||||||
|
|
||||||
|
if (response(0x13, 3000, asciiResult) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[3] = { 0, 0, 0 };
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
temp[0] = asciiResult[i * 2];
|
||||||
|
temp[1] = asciiResult[i * 2 + 1];
|
||||||
|
|
||||||
|
result[i] = strtoul(temp, NULL, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32BootROMClass::command(int opcode, const void* data, uint16_t length)
|
||||||
|
{
|
||||||
|
uint32_t checksum = 0;
|
||||||
|
|
||||||
|
if (opcode == 0x03) {
|
||||||
|
checksum = 0xef; // seed
|
||||||
|
|
||||||
|
for (uint16_t i = 16; i < length; i++) {
|
||||||
|
checksum ^= ((const uint8_t*)data)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_serial->write(0xc0);
|
||||||
|
_serial->write((uint8_t)0x00); // direction
|
||||||
|
_serial->write(opcode);
|
||||||
|
_serial->write((uint8_t*)&length, sizeof(length));
|
||||||
|
writeEscapedBytes((uint8_t*)&checksum, sizeof(checksum));
|
||||||
|
writeEscapedBytes((uint8_t*)data, length);
|
||||||
|
_serial->write(0xc0);
|
||||||
|
#ifdef ARDUINO_SAMD_MKRVIDOR4000
|
||||||
|
// _serial->flush(); // doesn't work!
|
||||||
|
#else
|
||||||
|
_serial->flush();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32BootROMClass::response(int opcode, unsigned long timeout, void* body)
|
||||||
|
{
|
||||||
|
uint8_t data[10 + 256];
|
||||||
|
uint16_t index = 0;
|
||||||
|
|
||||||
|
uint8_t responseLength = 4;
|
||||||
|
|
||||||
|
for (unsigned long start = millis(); (index < (uint16_t)(10 + responseLength)) && (millis() - start) < timeout;) {
|
||||||
|
if (_serial->available()) {
|
||||||
|
data[index] = _serial->read();
|
||||||
|
|
||||||
|
if (index == 3) {
|
||||||
|
responseLength = data[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (index) {
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
byte b = data[i];
|
||||||
|
|
||||||
|
if (b < 0x10) {
|
||||||
|
Serial.print('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print(b, HEX);
|
||||||
|
Serial.print(' ');
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (index != (uint16_t)(10 + responseLength)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data[0] != 0xc0 || data[1] != 0x01 || data[2] != opcode || data[responseLength + 5] != 0x00 || data[responseLength + 6] != 0x00 || data[responseLength + 9] != 0xc0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body) {
|
||||||
|
memcpy(body, &data[9], responseLength - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data[responseLength + 5];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32BootROMClass::writeEscapedBytes(const uint8_t* data, uint16_t length)
|
||||||
|
{
|
||||||
|
uint16_t written = 0;
|
||||||
|
|
||||||
|
while (written < length) {
|
||||||
|
uint8_t b = data[written++];
|
||||||
|
|
||||||
|
if (b == 0xdb) {
|
||||||
|
_serial->write(0xdb);
|
||||||
|
_serial->write(0xdd);
|
||||||
|
} else if (b == 0xc0) {
|
||||||
|
_serial->write(0xdb);
|
||||||
|
_serial->write(0xdc);
|
||||||
|
} else {
|
||||||
|
_serial->write(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP32BootROMClass ESP32BootROM(SerialNina, NINA_GPIO0, NINA_RESETN);
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
ESP32BootROM - part of the Firmware Updater for the
|
||||||
|
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
|
||||||
|
|
||||||
|
Copyright (c) 2018 Arduino SA. All rights 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 <Arduino.h>
|
||||||
|
|
||||||
|
class ESP32BootROMClass {
|
||||||
|
public:
|
||||||
|
ESP32BootROMClass(HardwareSerial& hwSerial, int gpio0Pin, int resetnPin);
|
||||||
|
|
||||||
|
int begin(unsigned long baudrate);
|
||||||
|
void end();
|
||||||
|
|
||||||
|
int beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize);
|
||||||
|
int dataFlash(const void* data, uint32_t length);
|
||||||
|
int endFlash(uint32_t reboot);
|
||||||
|
|
||||||
|
int md5Flash(uint32_t offset, uint32_t size, uint8_t* result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int sync();
|
||||||
|
int changeBaudrate(unsigned long baudrate);
|
||||||
|
int spiAttach();
|
||||||
|
|
||||||
|
void command(int opcode, const void* data, uint16_t length);
|
||||||
|
int response(int opcode, unsigned long timeout, void* body = NULL);
|
||||||
|
|
||||||
|
void writeEscapedBytes(const uint8_t* data, uint16_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HardwareSerial* _serial;
|
||||||
|
int _gpio0Pin;
|
||||||
|
int _resetnPin;
|
||||||
|
|
||||||
|
uint32_t _flashSequenceNumber;
|
||||||
|
uint32_t _chunkSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ESP32BootROMClass ESP32BootROM;
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
FirmwareUpdater - Firmware Updater for the
|
||||||
|
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
|
||||||
|
|
||||||
|
Copyright (c) 2018 Arduino SA. All rights 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 "ESP32BootROM.h"
|
||||||
|
#include <SD.h>
|
||||||
|
|
||||||
|
static const int MAX_PAYLOAD_SIZE = 1024;
|
||||||
|
uint32_t firmsize;
|
||||||
|
static uint8_t payload[MAX_PAYLOAD_SIZE];
|
||||||
|
|
||||||
|
#define SD_CS 32
|
||||||
|
File myFile;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
if (!SD.begin(SD_CS)) {
|
||||||
|
Serial.println("Card init. failed!");
|
||||||
|
while (1);
|
||||||
|
} else {
|
||||||
|
Serial.println("SD OK!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
myFile = SD.open("/NINAW102.bin", FILE_READ);
|
||||||
|
if (!myFile) {
|
||||||
|
Serial.println("Failed to open firmware file");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
firmsize = myFile.size();
|
||||||
|
Serial.print(firmsize); Serial.println(" bytes");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
while (!ESP32BootROM.begin(921600)) {
|
||||||
|
Serial.println("Unable to communicate with ESP32 boot ROM!");
|
||||||
|
delay(100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println("Ready!");
|
||||||
|
|
||||||
|
uint32_t timestamp = millis();
|
||||||
|
|
||||||
|
while (!ESP32BootROM.beginFlash(0, firmsize, MAX_PAYLOAD_SIZE)) {
|
||||||
|
Serial.println("Failed to erase flash");
|
||||||
|
delay(100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println("Erase OK");
|
||||||
|
|
||||||
|
for (uint32_t i=0; i<firmsize; i+=MAX_PAYLOAD_SIZE) {
|
||||||
|
memset(payload, 0xFF, MAX_PAYLOAD_SIZE);
|
||||||
|
uint32_t num_read = myFile.read(&payload, MAX_PAYLOAD_SIZE);
|
||||||
|
Serial.print("Packet #"); Serial.print(i/MAX_PAYLOAD_SIZE); Serial.print(": ");
|
||||||
|
Serial.print(num_read); Serial.print(" byte payload...");
|
||||||
|
|
||||||
|
if (!ESP32BootROM.dataFlash(payload, MAX_PAYLOAD_SIZE)) {
|
||||||
|
Serial.print("Failed to flash data");
|
||||||
|
while (1);
|
||||||
|
} else {
|
||||||
|
Serial.println("OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
myFile.close();
|
||||||
|
|
||||||
|
uint8_t md5[16];
|
||||||
|
if (!ESP32BootROM.md5Flash(0, firmsize, md5)) {
|
||||||
|
Serial.println("Error calculating MD5");
|
||||||
|
} else {
|
||||||
|
Serial.print("MD5 OK: ");
|
||||||
|
for (int i=0; i<16; i++) {
|
||||||
|
Serial.print("0x"); Serial.print(md5[i], HEX); Serial.print(" ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("Took "); Serial.print(millis()-timestamp); Serial.println(" millis");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
Endianess.ino - Network byte order conversion functions.
|
||||||
|
Copyright (c) 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
|
||||||
|
*/
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
bool isBigEndian() {
|
||||||
|
uint32_t test = 0x11223344;
|
||||||
|
uint8_t *pTest = reinterpret_cast<uint8_t *>(&test);
|
||||||
|
return pTest[0] == 0x11;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fromNetwork32(uint32_t from) {
|
||||||
|
static const bool be = isBigEndian();
|
||||||
|
if (be) {
|
||||||
|
return from;
|
||||||
|
} else {
|
||||||
|
uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);
|
||||||
|
uint32_t to;
|
||||||
|
to = pFrom[0]; to <<= 8;
|
||||||
|
to |= pFrom[1]; to <<= 8;
|
||||||
|
to |= pFrom[2]; to <<= 8;
|
||||||
|
to |= pFrom[3];
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t fromNetwork16(uint16_t from) {
|
||||||
|
static bool be = isBigEndian();
|
||||||
|
if (be) {
|
||||||
|
return from;
|
||||||
|
} else {
|
||||||
|
uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);
|
||||||
|
uint16_t to;
|
||||||
|
to = pFrom[0]; to <<= 8;
|
||||||
|
to |= pFrom[1];
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t toNetwork32(uint32_t to) {
|
||||||
|
return fromNetwork32(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t toNetwork16(uint16_t to) {
|
||||||
|
return fromNetwork16(to);
|
||||||
|
}
|
||||||
|
|
@ -71,6 +71,8 @@ unsigned long baud = 115200;
|
||||||
#define ESP32_RESETN 5 // Reset pin
|
#define ESP32_RESETN 5 // Reset pin
|
||||||
#define ESP32_GPIO0 -1 // Not connected
|
#define ESP32_GPIO0 -1 // Not connected
|
||||||
#define NEOPIXEL_PIN 8
|
#define NEOPIXEL_PIN 8
|
||||||
|
#elif defined(ADAFRUIT_PYPORTAL)
|
||||||
|
#define NEOPIXEL_PIN 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(1, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(1, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
||||||
|
|
@ -110,4 +112,4 @@ void loop() {
|
||||||
pixel.setPixelColor(0, 0, 0, 10); pixel.show();
|
pixel.setPixelColor(0, 0, 0, 10); pixel.show();
|
||||||
Serial.write(SerialESP32.read());
|
Serial.write(SerialESP32.read());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
#define SECRET_SSID "ssid"
|
||||||
|
#define SECRET_PASS "password"
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
// Stream MP3s over WiFi on Metro M4 Express and play via music maker shield
|
||||||
|
|
||||||
|
//#define DEBUG_OUTPUT
|
||||||
|
|
||||||
|
#include <ArduinoHttpClient.h>
|
||||||
|
#include <WiFiNINA.h>
|
||||||
|
#include <CircularBuffer.h> // From Agileware
|
||||||
|
#include "Adafruit_MP3.h"
|
||||||
|
#include "arduino_secrets.h"
|
||||||
|
|
||||||
|
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
|
||||||
|
char ssid[] = SECRET_SSID; // your network SSID (name)
|
||||||
|
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
|
||||||
|
|
||||||
|
// Use ~64Kbps streams if possible, 128kb+ is too much data ;)
|
||||||
|
|
||||||
|
// CircuitPython weekly
|
||||||
|
//const char *xmlfeed = "http://adafruit-podcasts.s3.amazonaws.com/circuitpython_weekly_meeting/audio-podcast.xml";
|
||||||
|
const char *xmlfeed = "http://www.2600.com/oth.xml"; // yay they have a 16 kbps
|
||||||
|
|
||||||
|
// Too high bitrate!
|
||||||
|
//const char *xmlfeed = "http://feeds.soundcloud.com/users/soundcloud:users:93913472/sounds.rss";
|
||||||
|
//const char *xmlfeed = "https://theamphour.com/feed/";
|
||||||
|
|
||||||
|
/************* WiFi over ESP32 client for MP3 datastream */
|
||||||
|
WiFiClient http_client; // Use WiFiClient class to create HTTP/TCP connection
|
||||||
|
WiFiSSLClient https_client; // Use WiFiClient class to create HTTP/TCP connection
|
||||||
|
char *stream_host, *stream_path;
|
||||||
|
int stream_port = 80;
|
||||||
|
|
||||||
|
/************* Native MP3 decoding supported on M4 chips */
|
||||||
|
Adafruit_MP3 player; // The MP3 player
|
||||||
|
#define BUFFER_SIZE 8000 // we need a lot of buffer to keep from underruns! but not too big?
|
||||||
|
CircularBuffer<uint8_t, BUFFER_SIZE> buffer;
|
||||||
|
bool paused = true;
|
||||||
|
float gain = 1;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial);
|
||||||
|
delay(100);
|
||||||
|
Serial.println("\nAdafruit Native MP3 Podcast Radio");
|
||||||
|
|
||||||
|
/************************* INITIALIZE WIFI */
|
||||||
|
Serial.print("Connecting to SSID "); Serial.println(ssid);
|
||||||
|
WiFi.begin(ssid, pass);
|
||||||
|
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.print("WiFi connected. ");
|
||||||
|
Serial.print("My IP address: "); Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
|
||||||
|
char *mp3_stream, *pubdate;
|
||||||
|
getLatestMP3(xmlfeed, &mp3_stream, &pubdate);
|
||||||
|
Serial.println(mp3_stream);
|
||||||
|
Serial.println(pubdate);
|
||||||
|
|
||||||
|
splitURL(mp3_stream, &stream_host, &stream_port, &stream_path);
|
||||||
|
if (stream_port == 443) {
|
||||||
|
Serial.println("We don't support SSL MP3 playback, defaulting back to port 80");
|
||||||
|
stream_port = 80;
|
||||||
|
}
|
||||||
|
player.begin();
|
||||||
|
|
||||||
|
//do this when there are samples ready
|
||||||
|
player.setSampleReadyCallback(writeDacs);
|
||||||
|
|
||||||
|
//do this when more data is required
|
||||||
|
player.setBufferCallback(getMoreData);
|
||||||
|
|
||||||
|
analogWrite(A0, 2048);
|
||||||
|
player.play();
|
||||||
|
player.pause();
|
||||||
|
|
||||||
|
|
||||||
|
connectStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getLatestMP3(String xmlfeed, char **mp3_url, char **date_str) {
|
||||||
|
char *xml_host, *xml_path;
|
||||||
|
int xml_port = 80;
|
||||||
|
|
||||||
|
bool found_mp3=false, found_date=false;
|
||||||
|
|
||||||
|
splitURL(xmlfeed, &xml_host, &xml_port, &xml_path);
|
||||||
|
|
||||||
|
Serial.print("XML Server: "); Serial.println(xml_host);
|
||||||
|
Serial.print("XML Port #"); Serial.println(xml_port);
|
||||||
|
Serial.print("XML Path: "); Serial.println(xml_path);
|
||||||
|
|
||||||
|
WiFiClient *xml_client;
|
||||||
|
if (xml_port == 443) {
|
||||||
|
xml_client = &https_client;
|
||||||
|
} else {
|
||||||
|
xml_client = &http_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xml_client->connect(xml_host, xml_port)) {
|
||||||
|
Serial.println("Connection failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now create a URI for the request
|
||||||
|
Serial.print("Requesting XML URL: "); Serial.println(xml_path);
|
||||||
|
|
||||||
|
// This will send the request to the server
|
||||||
|
xml_client->print(String("GET ") + xml_path + " HTTP/1.1\r\n" +
|
||||||
|
"Host: " + xml_host + "\r\n" +
|
||||||
|
"Connection: close\r\n\r\n");
|
||||||
|
|
||||||
|
while (xml_client->connected()) {
|
||||||
|
if (!xml_client->available()) { continue; }
|
||||||
|
char c = xml_client->read();
|
||||||
|
Serial.print(c);
|
||||||
|
if (c == '<') {
|
||||||
|
String tag = xml_client->readStringUntil('>');
|
||||||
|
Serial.print(tag);
|
||||||
|
|
||||||
|
if (!found_mp3 && (tag.indexOf("enclosure") != -1)) { // get first enclosure
|
||||||
|
int i = tag.indexOf("url=\"");
|
||||||
|
if (i == -1) continue;
|
||||||
|
tag = tag.substring(i+5);
|
||||||
|
int end = tag.indexOf("\"");
|
||||||
|
if (end == -1) continue;
|
||||||
|
tag = tag.substring(0, end);
|
||||||
|
*mp3_url = (char *)malloc(tag.length()+1);
|
||||||
|
tag.toCharArray(*mp3_url, tag.length()+1);
|
||||||
|
// Serial.print("****"); Serial.println(*mp3_url);
|
||||||
|
found_mp3 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_date && (tag.indexOf("pubDate") != -1)) { // get first pubdate
|
||||||
|
String date = xml_client->readStringUntil('<');
|
||||||
|
*date_str = (char *)malloc(date.length()+1);
|
||||||
|
date.toCharArray(*date_str, date.length()+1);
|
||||||
|
// Serial.print("****"); Serial.println(*date_str);
|
||||||
|
found_date = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_date && found_mp3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xml_client->stop();
|
||||||
|
return (found_date && found_mp3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void connectStream(void) {
|
||||||
|
http_client.stop();
|
||||||
|
/************************* INITIALIZE STREAM */
|
||||||
|
Serial.print("Stream Server: "); Serial.println(stream_host);
|
||||||
|
Serial.print("Stream Port #"); Serial.println(stream_port);
|
||||||
|
Serial.print("Stream Path: "); Serial.println(stream_path);
|
||||||
|
|
||||||
|
if (!http_client.connect(stream_host, stream_port)) {
|
||||||
|
Serial.println("Connection failed");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now create a URI for the request
|
||||||
|
Serial.print("Requesting URL: "); Serial.println(stream_path);
|
||||||
|
|
||||||
|
// This will send the request to the server
|
||||||
|
http_client.print(String("GET ") + stream_path + " HTTP/1.1\r\n" +
|
||||||
|
"Host: " + stream_host + "\r\n" +
|
||||||
|
"Connection: close\r\n\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (!http_client.connected()) {
|
||||||
|
connectStream();
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_OUTPUT
|
||||||
|
Serial.print("Client Avail: "); Serial.print(http_client.available());
|
||||||
|
Serial.print("\tBuffer Avail: "); Serial.println(buffer.available());
|
||||||
|
#endif
|
||||||
|
int ret = player.tick();
|
||||||
|
|
||||||
|
if (ret != 0) { // some error, best to pause & rebuffer
|
||||||
|
Serial.print("MP3 error: "); Serial.println(ret);
|
||||||
|
player.pause(); paused = true;
|
||||||
|
}
|
||||||
|
if ( paused && (buffer.size() > 6000)) { // buffered, restart!
|
||||||
|
player.resume(); paused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prioritize reading data from the ESP32 into the buffer (it sometimes stalls)
|
||||||
|
if (http_client.available() && buffer.available()) {
|
||||||
|
|
||||||
|
uint8_t minibuff[BUFFER_SIZE];
|
||||||
|
|
||||||
|
int bytesread = http_client.read(minibuff, buffer.available());
|
||||||
|
#ifdef DEBUG_OUTPUT
|
||||||
|
Serial.print("Client read: "); Serial.print(bytesread);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
noInterrupts();
|
||||||
|
for (int i=0; i<bytesread; i++) {
|
||||||
|
buffer.push(minibuff[i]); // push every byte we read
|
||||||
|
}
|
||||||
|
interrupts();
|
||||||
|
#ifdef DEBUG_OUTPUT
|
||||||
|
Serial.println(" OK");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeDacs(int16_t l, int16_t r){
|
||||||
|
uint16_t val = map(l, -32768, 32767, 0, 4095 * gain);
|
||||||
|
analogWrite(A0, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int getMoreData(uint8_t *writeHere, int thisManyBytes){
|
||||||
|
#ifdef DEBUG_OUTPUT
|
||||||
|
Serial.print("Wants: "); Serial.print(thisManyBytes);
|
||||||
|
#endif
|
||||||
|
int toWrite = min(buffer.size(), thisManyBytes);
|
||||||
|
#ifdef DEBUG_OUTPUT
|
||||||
|
Serial.print(" have: "); Serial.println(toWrite);
|
||||||
|
#endif
|
||||||
|
// this is a bit of a hack but otherwise the decoder chokes
|
||||||
|
if (toWrite < 128) {
|
||||||
|
//return 0; // we'll try again later!
|
||||||
|
}
|
||||||
|
for (int i=0; i<toWrite; i++) {
|
||||||
|
writeHere[i] = buffer.shift();
|
||||||
|
}
|
||||||
|
return toWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool splitURL(String url, char **host, int *port, char **path){
|
||||||
|
Serial.println(url);
|
||||||
|
if (url.startsWith("http://")) {
|
||||||
|
Serial.println("Regular HTTP stream");
|
||||||
|
url = url.substring(7);
|
||||||
|
*port = 80;
|
||||||
|
}
|
||||||
|
if (url.startsWith("https://")) {
|
||||||
|
Serial.println("Secure HTTPS stream");
|
||||||
|
url = url.substring(8);
|
||||||
|
*port = 443;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract host before port
|
||||||
|
int colon = url.indexOf(':');
|
||||||
|
int slash = url.indexOf('/');
|
||||||
|
if ((slash != -1) && (colon != -1) && (colon < slash)) {
|
||||||
|
String host_str = url.substring(0, colon);
|
||||||
|
*host = (char *)malloc(host_str.length()+1);
|
||||||
|
host_str.toCharArray(*host, host_str.length()+1);
|
||||||
|
url = url.substring(colon+1);
|
||||||
|
// extract port before /
|
||||||
|
slash = url.indexOf('/');
|
||||||
|
if (slash != -1) {
|
||||||
|
String port_str = url.substring(0, slash);
|
||||||
|
*port = port_str.toInt();
|
||||||
|
} else {
|
||||||
|
Serial.println("Couldn't locate path /");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
url = url.substring(slash);
|
||||||
|
} else {
|
||||||
|
// extract host before /
|
||||||
|
slash = url.indexOf('/');
|
||||||
|
if (slash != -1) {
|
||||||
|
String host_str = url.substring(0, slash);
|
||||||
|
*host = (char *)malloc(host_str.length()+1);
|
||||||
|
host_str.toCharArray(*host, host_str.length()+1);
|
||||||
|
url = url.substring(slash);
|
||||||
|
} else {
|
||||||
|
Serial.println("Couldn't locate path /");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*path = (char *)malloc(url.length()+1);
|
||||||
|
url.toCharArray(*path, url.length()+1);
|
||||||
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ http://www.adafruit.com/products/14
|
||||||
|
|
||||||
// Green LED does a "sleep throb" when camera is idle. This table
|
// Green LED does a "sleep throb" when camera is idle. This table
|
||||||
// contains the brightness levels over time (reverse for second half).
|
// contains the brightness levels over time (reverse for second half).
|
||||||
PROGMEM byte sleepTab[] = {
|
const PROGMEM byte sleepTab[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
1, 1, 2, 3, 4, 5, 6, 8, 10, 13,
|
1, 1, 2, 3, 4, 5, 6, 8, 10, 13,
|
||||||
15, 19, 22, 26, 31, 36, 41, 47, 54, 61,
|
15, 19, 22, 26, 31, 36, 41, 47, 54, 61,
|
||||||
|
|
|
||||||
BIN
Adafruit_LED_Sequins/.DS_Store
vendored
BIN
Adafruit_LED_Sequins/.DS_Store
vendored
Binary file not shown.
0
Adafruit_LED_Sequins/.gemma.test.only
Normal file
0
Adafruit_LED_Sequins/.gemma.test.only
Normal file
|
|
@ -1,10 +1,10 @@
|
||||||
/ Test code for Adafruit GPS modules using MTK driver
|
// Test code for Adafruit GPS modules using MTK driver
|
||||||
// such as www.adafruit.com/products/660 (discontinued)
|
// such as www.adafruit.com/products/660 (discontinued)
|
||||||
// For new use see www.adafruit.com/products/746 (needs different code)
|
// For new use see www.adafruit.com/products/746 (needs different code)
|
||||||
// help support open source hardware & software! -adafruit
|
// help support open source hardware & software! -adafruit
|
||||||
|
|
||||||
#include <SoftSerial.h>
|
#include <SoftwareSerial.h>
|
||||||
SoftSerial mySerial(2, 3);
|
SoftwareSerial mySerial(2, 3);
|
||||||
|
|
||||||
// Connect the GPS Power pin to 3.3V
|
// Connect the GPS Power pin to 3.3V
|
||||||
// Connect the GPS Ground pin to ground
|
// Connect the GPS Ground pin to ground
|
||||||
|
|
|
||||||
0
Adafruit_TPL5111_Breakout/tpl5111demo/.esp8266.test.only
Normal file
0
Adafruit_TPL5111_Breakout/tpl5111demo/.esp8266.test.only
Normal file
0
Adafruit_TPL5111_Breakout/tpl5111demo/.uno.test.only
Normal file
0
Adafruit_TPL5111_Breakout/tpl5111demo/.uno.test.only
Normal file
|
|
@ -131,7 +131,7 @@ unsigned long
|
||||||
currentTime = 0L;
|
currentTime = 0L;
|
||||||
EthernetClient
|
EthernetClient
|
||||||
client;
|
client;
|
||||||
PROGMEM byte
|
const PROGMEM byte
|
||||||
sleepTab[] = { // "Sleep throb" brightness table (reverse for second half)
|
sleepTab[] = { // "Sleep throb" brightness table (reverse for second half)
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
1, 1, 2, 3, 4, 5, 6, 8, 10, 13,
|
1, 1, 2, 3, 4, 5, 6, 8, 10, 13,
|
||||||
|
|
|
||||||
0
Adafruit_UDA1334A/SineTone/.metro_m0.test.only
Normal file
0
Adafruit_UDA1334A/SineTone/.metro_m0.test.only
Normal file
|
|
@ -199,10 +199,9 @@ void setup(void) {
|
||||||
// from either mirrorOLED[] (first eye) or rotateOLED[] (others).
|
// from either mirrorOLED[] (first eye) or rotateOLED[] (others).
|
||||||
// The OLED library doesn't normally use the remap reg (TFT does).
|
// The OLED library doesn't normally use the remap reg (TFT does).
|
||||||
for(e=0; e<NUM_EYES; e++) {
|
for(e=0; e<NUM_EYES; e++) {
|
||||||
eye[e].display->writeCommand(SSD1351_CMD_SETREMAP);
|
uint8_t d = e ? rotateOLED[eyeInfo[e].rotation & 3] :
|
||||||
eye[e].display->writeData(e ?
|
mirrorOLED[eyeInfo[e].rotation & 3];
|
||||||
rotateOLED[eyeInfo[e].rotation & 3] :
|
eye[e].display->sendCommand(SSD1351_CMD_SETREMAP, &d, 1);
|
||||||
mirrorOLED[eyeInfo[e].rotation & 3]);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
0
Animated_NeoPixel_Glow_Fur_Scarf/.gemma.test.only
Normal file
0
Animated_NeoPixel_Glow_Fur_Scarf/.gemma.test.only
Normal file
0
AtariFruit_Joystick/.nrf52832.test.only
Normal file
0
AtariFruit_Joystick/.nrf52832.test.only
Normal file
0
Bluetooth_NeoMatrix_Snowflake/basic/.uno.test.only
Normal file
0
Bluetooth_NeoMatrix_Snowflake/basic/.uno.test.only
Normal file
|
|
@ -273,6 +273,7 @@ void SnowFlake12(uint32_t c){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void showAllSnowflakes(uint32_t c){
|
void showAllSnowflakes(uint32_t c){
|
||||||
SnowFlake1(matrix.Color(red, green, blue));
|
SnowFlake1(matrix.Color(red, green, blue));
|
||||||
matrix.show(); // This sends the updated pixel colors to the hardware.
|
matrix.show(); // This sends the updated pixel colors to the hardware.
|
||||||
|
|
@ -322,3 +323,4 @@ void showAllSnowflakes(uint32_t c){
|
||||||
matrix.show(); // This sends the updated pixel colors to the hardware.
|
matrix.show(); // This sends the updated pixel colors to the hardware.
|
||||||
delay(500);
|
delay(500);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
0
Buzzing_Mindfulness_Bracelet/.gemma.test.only
Normal file
0
Buzzing_Mindfulness_Bracelet/.gemma.test.only
Normal file
0
CPX_Compass/.ada_cpx.test.only
Normal file
0
CPX_Compass/.ada_cpx.test.only
Normal file
0
Chirping_Plush_Owl_Toy/.gemma.test.only
Normal file
0
Chirping_Plush_Owl_Toy/.gemma.test.only
Normal file
0
Close_Encounters_Hat/.gemma_m0.test.only
Normal file
0
Close_Encounters_Hat/.gemma_m0.test.only
Normal file
0
Crickit_AdafruitIO/crickit_io/.esp8266.test.only
Normal file
0
Crickit_AdafruitIO/crickit_io/.esp8266.test.only
Normal file
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue