From 9cc720ee3134571e33a9e496c33b719087e676b9 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Fri, 21 Jun 2019 17:15:19 -0600 Subject: [PATCH 1/5] Move examples to new directory. Add empty header and library properties files. The header and property file are blank. By having these files in place, Arduino will disply the Examples under File->Examples->"Examples for SparkFun Artemis BlackBoard" which is very handy. --- .../examples/example5_Wire/example5_Wire.ino | 102 ------------- libraries/Examples/README.md | 139 ++++++++++++++++++ .../ClassFunctions/ClassFunctions.ino | 0 .../GlobalObjectConstructors.ino | 0 .../Example0_Compilation.ino} | 0 .../Example10_Interrupts.ino} | 0 .../Example11_BitsAndBytes.ino} | 53 +++---- .../Example1_Blink/Example1_Blink.ino} | 8 +- .../Example2_Serial/Example2_Serial.ino} | 27 +++- .../Example4_TestAllGPIOs.ino | 0 .../examples/Example5_Wire/Example5_Wire.ino | 73 +++++++++ .../examples/Example6_SPI/Example6_SPI.ino} | 22 ++- .../Example7_analogRead.ino | 11 +- .../Example8_millis/Example8_millis.ino | 0 .../Example9_analogWrite.ino} | 34 +++-- libraries/Examples/keywords.txt | 4 + libraries/Examples/library.properties | 10 ++ libraries/Examples/src/Examples.h | 4 + 18 files changed, 318 insertions(+), 169 deletions(-) delete mode 100644 libraries/CoreTesting/examples/example5_Wire/example5_Wire.ino create mode 100644 libraries/Examples/README.md rename libraries/{CoreTesting => Examples}/examples/Advanced/ClassFunctions/ClassFunctions.ino (100%) rename libraries/{CoreTesting => Examples}/examples/Advanced/GlobalObjectConstructors/GlobalObjectConstructors.ino (100%) rename libraries/{CoreTesting/examples/example0_compilation/example0_compilation.ino => Examples/examples/Example0_Compilation/Example0_Compilation.ino} (100%) rename libraries/{CoreTesting/examples/example10_interrupts/example10_interrupts.ino => Examples/examples/Example10_Interrupts/Example10_Interrupts.ino} (100%) rename libraries/{CoreTesting/examples/example11_bits_bytes/example11_bits_bytes.ino => Examples/examples/Example11_BitsAndBytes/Example11_BitsAndBytes.ino} (68%) rename libraries/{CoreTesting/examples/example1_blink/example1_blink.ino => Examples/examples/Example1_Blink/Example1_Blink.ino} (90%) rename libraries/{CoreTesting/examples/example2_serial/example2_serial.ino => Examples/examples/Example2_Serial/Example2_Serial.ino} (56%) rename libraries/{CoreTesting => Examples}/examples/Example4_TestAllGPIOs/Example4_TestAllGPIOs.ino (100%) create mode 100644 libraries/Examples/examples/Example5_Wire/Example5_Wire.ino rename libraries/{CoreTesting/examples/example6_SPI/example6_SPI.ino => Examples/examples/Example6_SPI/Example6_SPI.ino} (63%) rename libraries/{CoreTesting => Examples}/examples/Example7_analogRead/Example7_analogRead.ino (90%) rename libraries/{CoreTesting => Examples}/examples/Example8_millis/Example8_millis.ino (100%) rename libraries/{CoreTesting/examples/example9_analogWrite/example9_analogWrite.ino => Examples/examples/Example9_analogWrite/Example9_analogWrite.ino} (51%) create mode 100644 libraries/Examples/keywords.txt create mode 100644 libraries/Examples/library.properties create mode 100644 libraries/Examples/src/Examples.h diff --git a/libraries/CoreTesting/examples/example5_Wire/example5_Wire.ino b/libraries/CoreTesting/examples/example5_Wire/example5_Wire.ino deleted file mode 100644 index 9c24e608..00000000 --- a/libraries/CoreTesting/examples/example5_Wire/example5_Wire.ino +++ /dev/null @@ -1,102 +0,0 @@ -/* Author: Owen Lyke - Created: May 13 2019 - License: MIT. See SparkFun Arduino Apollo3 Project for more information - - This example demonstrates how to use Arduino Wire (I2C) by scanning all - possible I2C addresses and indicating which have responding devices - - Wire objects use IOMaster objects (which represent the IO Master peripherals on the - Apollo3) and you can declare your own by simply providing which IOmaster instance - to use. Like this: - - TwoWire myWire(2); //Starts I2C on pads 27/25 - - Because there is no pin multiplexing on the IO master peripherals the instance number - that you choose directly determines which pads it is connected to. Here's the list: - - IO Master 0 - AP3_IOM_I2C_SCL : pad = 5 - AP3_IOM_I2C_SDA : pad = 6 - - IO Master 1 - AP3_IOM_I2C_SCL : pad = 8 - AP3_IOM_I2C_SDA : pad = 9 - - IO Master 2 - AP3_IOM_I2C_SCL : pad = 27 - AP3_IOM_I2C_SDA : pad = 25 - - IO Master 3 - AP3_IOM_I2C_SCL : pad = 42 - AP3_IOM_I2C_SDA : pad = 43 - - IO Master 4 - AP3_IOM_I2C_SCL : pad = 39 - AP3_IOM_I2C_SDA : pad = 40 - - IO Master 5 - AP3_IOM_I2C_SCL : pad = 48 - AP3_IOM_I2C_SDA : pad = 49 -*/ - -#include "Wire.h" - -// Lastly, the Variant you use will probably have one or more TwoWire objects declared. -// For example on the Edge board 'Wire' corresponds to the I2C bus that connects to the -// Qwiic connector (and you can also use 'WireQwiic' to access it) while Wire1 (also -// 'WireAccel') is connected to the onboard LIS2DH accelerometer. - -//Wire should be used to scan devices on the Qwiic connector on the Edge board -//WireAccel should be used to scan for devices on Wire1 (connects to the onboard accelerometer on the Edge board) - -void setup() { - Serial.begin(9600); - while (!Serial) {}; //Wait for user to open terminal window - - Serial.println("SparkFun Arduino Apollo3 Wire Example (I2C Scanner)"); - Serial.printf("Compiled on %s, %s\n\n", __DATE__, __TIME__); - - Wire.begin(); -} - -void loop() -{ - uint8_t error, address; - int nDevices; - - Serial.println("Scanning..."); - - nDevices = 0; - for (address = 1; address < 127; address++ ) - { - // The i2c_scanner uses the return value of - // the Write.endTransmisstion to see if - // a device did acknowledge to the address. - Wire.beginTransmission(address); - error = Wire.endTransmission(); - - if (error == 0) - { - Serial.print("I2C device found at address 0x"); - if (address < 16) - Serial.print("0"); - Serial.print(address, HEX); - Serial.println(" !"); - - nDevices++; - } - else if (error == 4) - { - Serial.print("Unknown error at address 0x"); - if (address < 16) - Serial.print("0"); - Serial.println(address, HEX); - } - } - if (nDevices == 0) - Serial.println("No I2C devices found\n"); - else - Serial.println("done\n"); - - delay(1000); // wait 1 second for next scan -} diff --git a/libraries/Examples/README.md b/libraries/Examples/README.md new file mode 100644 index 00000000..a6241361 --- /dev/null +++ b/libraries/Examples/README.md @@ -0,0 +1,139 @@ +## **EEPROM Library V2.0** for Arduino + +**Written by:** _Christopher Andrews_. + +### **What is the EEPROM library.** + +Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips. + +### **How to use it** +The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch. + +```Arduino +#include + +void setup(){ + +} + +void loop(){ + +} + +``` + +The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below. + +You can view all the examples [here](examples/). + +### **Library functions** + +#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino) + +This function allows you to read a single byte of data from the eeprom. +Its only parameter is an `int` which should be set to the address you wish to read. + +The function returns an `unsigned char` containing the value read. + +#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino) + +The `write()` method allows you to write a single byte of data to the EEPROM. +Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`). + +This function does not return any value. + +#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino) + +This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells. + +This function does not return any value. + +#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino) + +This function will retrieve any object from the EEPROM. +Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read. + +This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. + +#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino) + +This function will write any object to the EEPROM. +Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write. + +This function uses the _update_ method to write its data, and therefore only rewrites changed cells. + +This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. + +#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino) + +This operator allows using the identifier `EEPROM` like an array. +EEPROM cells can be read _and_ **_written_** directly using this method. + +This operator returns a reference to the EEPROM cell. + +```c++ +unsigned char val; + +//Read first EEPROM cell. +val = EEPROM[ 0 ]; + +//Write first EEPROM cell. +EEPROM[ 0 ] = val; + +//Compare contents +if( val == EEPROM[ 0 ] ){ + //Do something... +} +``` + +#### **`EEPROM.length()`** + +This function returns an `unsigned int` containing the number of cells in the EEPROM. + +--- + +### **Advanced features** + +This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`. + +#### **`EERef` class** + +This object references an EEPROM cell. +Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. +This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. + +```C++ +EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell. + +ref = 4; //write to EEPROM cell. + +unsigned char val = ref; //Read referenced cell. +``` + +#### **`EEPtr` class** + +This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects. +Just like a normal pointer type, this type can be dereferenced and repositioned using +increment/decrement operators. + +```C++ +EEPtr ptr = 10; //Create a pointer to 11th cell. + +*ptr = 4; //dereference and write to EEPROM cell. + +unsigned char val = *ptr; //dereference and read. + +ptr++; //Move to next EEPROM cell. +``` + +#### **`EEPROM.begin()`** + +This function returns an `EEPtr` pointing to the first cell in the EEPROM. +This is useful for STL objects, custom iteration and C++11 style ranged for loops. + +#### **`EEPROM.end()`** + +This function returns an `EEPtr` pointing at the location after the last EEPROM cell. +Used with `begin()` to provide custom iteration. + +**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell. diff --git a/libraries/CoreTesting/examples/Advanced/ClassFunctions/ClassFunctions.ino b/libraries/Examples/examples/Advanced/ClassFunctions/ClassFunctions.ino similarity index 100% rename from libraries/CoreTesting/examples/Advanced/ClassFunctions/ClassFunctions.ino rename to libraries/Examples/examples/Advanced/ClassFunctions/ClassFunctions.ino diff --git a/libraries/CoreTesting/examples/Advanced/GlobalObjectConstructors/GlobalObjectConstructors.ino b/libraries/Examples/examples/Advanced/GlobalObjectConstructors/GlobalObjectConstructors.ino similarity index 100% rename from libraries/CoreTesting/examples/Advanced/GlobalObjectConstructors/GlobalObjectConstructors.ino rename to libraries/Examples/examples/Advanced/GlobalObjectConstructors/GlobalObjectConstructors.ino diff --git a/libraries/CoreTesting/examples/example0_compilation/example0_compilation.ino b/libraries/Examples/examples/Example0_Compilation/Example0_Compilation.ino similarity index 100% rename from libraries/CoreTesting/examples/example0_compilation/example0_compilation.ino rename to libraries/Examples/examples/Example0_Compilation/Example0_Compilation.ino diff --git a/libraries/CoreTesting/examples/example10_interrupts/example10_interrupts.ino b/libraries/Examples/examples/Example10_Interrupts/Example10_Interrupts.ino similarity index 100% rename from libraries/CoreTesting/examples/example10_interrupts/example10_interrupts.ino rename to libraries/Examples/examples/Example10_Interrupts/Example10_Interrupts.ino diff --git a/libraries/CoreTesting/examples/example11_bits_bytes/example11_bits_bytes.ino b/libraries/Examples/examples/Example11_BitsAndBytes/Example11_BitsAndBytes.ino similarity index 68% rename from libraries/CoreTesting/examples/example11_bits_bytes/example11_bits_bytes.ino rename to libraries/Examples/examples/Example11_BitsAndBytes/Example11_BitsAndBytes.ino index b98fdf3c..eac30c51 100644 --- a/libraries/CoreTesting/examples/example11_bits_bytes/example11_bits_bytes.ino +++ b/libraries/Examples/examples/Example11_BitsAndBytes/Example11_BitsAndBytes.ino @@ -1,22 +1,27 @@ -void setup() { - // put your setup code here, to run once: - Serial.begin(9600); - - Serial.printf("abs(-5.14): %f\n", abs(-5.14)); +/* Author: Owen Lyke + Created: June 21 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + This example demonstrates usage of the various bit and byte + functions built into Arduino. +*/ +void setup() +{ + Serial.begin(9600); + Serial.printf("abs(-5.14): %f\n", abs(-5.14)); Serial.printf("constrain(1, 3, 5): %f\n", constrain(1, 3, 5)); - Serial.printf("max(4,2.4): %f\n", max(4,2.4)); - Serial.printf("min(4,2.4): %f\n", min(4,2.4)); + Serial.printf("max(4,2.4): %f\n", max(4, 2.4)); + Serial.printf("min(4,2.4): %f\n", min(4, 2.4)); Serial.printf("sq(9.3): %f\n", sq(9.3)); Serial.printf("sqrt(9.3): %f\n", sqrt(9.3)); - Serial.printf("cos((float)3.1415/3): %f\n", cos((float)3.1415/3)); - Serial.printf("sin((float)3.1415/3): %f\n", sin((float)3.1415/3)); - Serial.printf("tan((float)3.1415/3): %f\n", tan((float)3.1415/3)); + Serial.printf("cos((float)3.1415/3): %f\n", cos((float)3.1415 / 3)); + Serial.printf("sin((float)3.1415/3): %f\n", sin((float)3.1415 / 3)); + Serial.printf("tan((float)3.1415/3): %f\n", tan((float)3.1415 / 3)); Serial.printf("isAplha('a'): %d\n", isAlpha('a')); Serial.printf("isAplha('1'): %d\n", isAlpha('1')); @@ -40,22 +45,18 @@ void setup() { Serial.printf("isLowerCase('1'): %d\n", isLowerCase('1')); Serial.printf("isLowerCase(0x03): %d\n", isLowerCase(0x03)); -// bit(3) -// bit(5) -// bit(30) -// bit(31) -// -// bitClear(0xFF, 3) -// bitClear(0xFF, 31) -// -// bitRead(0xAA,3) -// bitRead(0xAA,4) - - - + // bit(3) + // bit(5) + // bit(30) + // bit(31) + // + // bitClear(0xFF, 3) + // bitClear(0xFF, 31) + // + // bitRead(0xAA,3) + // bitRead(0xAA,4) } -void loop() { - // put your main code here, to run repeatedly: - +void loop() +{ } diff --git a/libraries/CoreTesting/examples/example1_blink/example1_blink.ino b/libraries/Examples/examples/Example1_Blink/Example1_Blink.ino similarity index 90% rename from libraries/CoreTesting/examples/example1_blink/example1_blink.ino rename to libraries/Examples/examples/Example1_Blink/Example1_Blink.ino index ed390b6b..9cd0ea27 100644 --- a/libraries/CoreTesting/examples/example1_blink/example1_blink.ino +++ b/libraries/Examples/examples/Example1_Blink/Example1_Blink.ino @@ -11,14 +11,16 @@ //Most have LED_BUILTIN defined so just use that //But if you want, you can blink any pin -//#define blinkPin 37 +//#define blinkPin 5 #define blinkPin LED_BUILTIN -void setup() { +void setup() +{ pinMode(blinkPin, OUTPUT); } -void loop() { +void loop() +{ digitalWrite(blinkPin, LOW); delay(1000); digitalWrite(blinkPin, HIGH); diff --git a/libraries/CoreTesting/examples/example2_serial/example2_serial.ino b/libraries/Examples/examples/Example2_Serial/Example2_Serial.ino similarity index 56% rename from libraries/CoreTesting/examples/example2_serial/example2_serial.ino rename to libraries/Examples/examples/Example2_Serial/Example2_Serial.ino index eac435f8..2ff134dc 100644 --- a/libraries/CoreTesting/examples/example2_serial/example2_serial.ino +++ b/libraries/Examples/examples/Example2_Serial/Example2_Serial.ino @@ -5,9 +5,14 @@ This example demonstrates usage of: Serial Serial1 + + This example works best on the BlackBoard Artemis and BlackBoard Artemis ATP that have + the TX1 and RX1 pins exposed. See the advanced serial example for setting up a serial + port on other pins and other carrier boards. */ -void setup() { +void setup() +{ Serial.begin(9600); Serial.println("Hello debug window!"); @@ -15,15 +20,18 @@ void setup() { Serial1.println("This prints on TX1/RX1 pins"); } -void loop() { +void loop() +{ Serial.println("Time for a menu:"); Serial.println("a) Activate the cheese"); Serial.println("x) Exit"); Serial.println(); - while (Serial.available() == true) Serial.read(); //Read any characters that may be sitting in the RX buffer before we wait for user input + while (Serial.available() == true) + Serial.read(); //Read any characters that may be sitting in the RX buffer before we wait for user input - while (Serial.available() == false) delay(1); //Wait for user input + while (Serial.available() == false) + delay(1); //Wait for user input char incoming = Serial.read(); @@ -31,13 +39,15 @@ void loop() { { Serial.println("How many cheeses to dispense?"); - while (Serial.available() == true) Serial.read(); //Read any characters that may be sitting in the RX buffer before we wait for user input + while (Serial.available() == true) + Serial.read(); //Read any characters that may be sitting in the RX buffer before we wait for user input - while (Serial.available() == false); //Wait for user to type a number + while (Serial.available() == false) + ; //Wait for user to type a number unsigned int cheeseCount = Serial.parseInt(); //That's a lot of potential cheese //Print to second serial port - for (unsigned int x = 0; x < cheeseCount ; x++) + for (unsigned int x = 0; x < cheeseCount; x++) { Serial1.println("Cheese!"); } @@ -47,7 +57,8 @@ void loop() { else if (incoming == 'x' || incoming == 'X') { Serial.println("Exiting... Have a nice day."); - while (1); //Freeze + while (1) + ; //Freeze } else { diff --git a/libraries/CoreTesting/examples/Example4_TestAllGPIOs/Example4_TestAllGPIOs.ino b/libraries/Examples/examples/Example4_TestAllGPIOs/Example4_TestAllGPIOs.ino similarity index 100% rename from libraries/CoreTesting/examples/Example4_TestAllGPIOs/Example4_TestAllGPIOs.ino rename to libraries/Examples/examples/Example4_TestAllGPIOs/Example4_TestAllGPIOs.ino diff --git a/libraries/Examples/examples/Example5_Wire/Example5_Wire.ino b/libraries/Examples/examples/Example5_Wire/Example5_Wire.ino new file mode 100644 index 00000000..74c4e153 --- /dev/null +++ b/libraries/Examples/examples/Example5_Wire/Example5_Wire.ino @@ -0,0 +1,73 @@ +/* Author: Owen Lyke + Created: May 13 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + This example demonstrates how to use Arduino Wire (I2C) by scanning all + possible I2C addresses and indicating which have responding devices + + The Variant you use may have one or more TwoWire objects declared. + For example on the Edge board 'Wire' corresponds to the I2C bus that connects to the + Qwiic connector (and you can also use 'WireQwiic' to access it) while Wire1 (also + 'WireAccel') is connected to the onboard LIS2DH accelerometer. + + 'Wire' should be used to scan devices on the Qwiic connector on all Artemis carrier boards. + + The I2C scan code comes from here: https://playground.arduino.cc/Main/I2cScanner/ +*/ + +#include "Wire.h" + +void setup() +{ + Serial.begin(9600); + while (!Serial) + { + }; //Wait for user to open terminal window + + Serial.println("SparkFun Arduino Apollo3 Wire Example (I2C Scanner)"); + Serial.printf("Compiled on %s, %s\n\n", __DATE__, __TIME__); + + Wire.begin(); +} + +void loop() +{ + uint8_t error, address; + int nDevices; + + Serial.println("Scanning..."); + + nDevices = 0; + for (address = 1; address < 127; address++) + { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + Wire.beginTransmission(address); + error = Wire.endTransmission(); + + if (error == 0) + { + Serial.print("I2C device found at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.print(address, HEX); + Serial.println(" !"); + + nDevices++; + } + else if (error == 4) + { + Serial.print("Unknown error at address 0x"); + if (address < 16) + Serial.print("0"); + Serial.println(address, HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found\n"); + else + Serial.println("done\n"); + + delay(1000); // wait 1 second for next scan +} diff --git a/libraries/CoreTesting/examples/example6_SPI/example6_SPI.ino b/libraries/Examples/examples/Example6_SPI/Example6_SPI.ino similarity index 63% rename from libraries/CoreTesting/examples/example6_SPI/example6_SPI.ino rename to libraries/Examples/examples/Example6_SPI/Example6_SPI.ino index f4a904fb..3f87d3f4 100644 --- a/libraries/CoreTesting/examples/example6_SPI/example6_SPI.ino +++ b/libraries/Examples/examples/Example6_SPI/Example6_SPI.ino @@ -9,23 +9,21 @@ #define CS_PIN 2 -#define SPI_SPEED 2000000 +#define SPI_SPEED 1000000 #define SPI_ORDER MSBFIRST -#define SPI_MODE SPI_MODE3 - -#define SPI_SPEED_2 1000000 -#define SPI_ORDER_2 MSBFIRST -#define SPI_MODE_2 SPI_MODE0 +#define SPI_MODE SPI_MODE0 SPISettings mySettings(SPI_SPEED, SPI_ORDER, SPI_MODE); -SPISettings mySettings2(SPI_SPEED_2, SPI_ORDER_2, SPI_MODE_2); -const char* msg = "Hello world!"; +const char *msg = "Hello world!"; -void setup() { +void setup() +{ Serial.begin(9600); - while (!Serial) {}; //Wait for user to open terminal window + while (!Serial) + { + }; //Wait for user to open terminal window Serial.println("SparkFun Arduino Apollo3 SPI Example"); Serial.printf("Compiled on %s, %s\n\n", __DATE__, __TIME__); @@ -42,8 +40,8 @@ void loop() SPI.transfer(0xAA); SPI.endTransaction(); - SPI.beginTransaction(mySettings2); - SPI.transferOut((void*)msg, strlen(msg)); + SPI.beginTransaction(mySettings); + SPI.transferOut((void *)msg, strlen(msg)); SPI.endTransaction(); digitalWrite(CS_PIN, HIGH); delay(1000); diff --git a/libraries/CoreTesting/examples/Example7_analogRead/Example7_analogRead.ino b/libraries/Examples/examples/Example7_analogRead/Example7_analogRead.ino similarity index 90% rename from libraries/CoreTesting/examples/Example7_analogRead/Example7_analogRead.ino rename to libraries/Examples/examples/Example7_analogRead/Example7_analogRead.ino index fc9c8a3a..6e75b4da 100644 --- a/libraries/CoreTesting/examples/Example7_analogRead/Example7_analogRead.ino +++ b/libraries/Examples/examples/Example7_analogRead/Example7_analogRead.ino @@ -16,15 +16,15 @@ SparkFun Edge: https://www.sparkfun.com/products/15170 Hardware Connections: - Connect an Edge via programmer Upload code - Use a trimpot or other device to send a 0 to 3V (no 5V!) signal to pin 'A16' + Use a trimpot or other device to send a 0 to 3.3V (no 5V!) signal to pin 'A16' ADC can resolve up to 2V but is 3.3V safe */ -#define LED 13 //Status LED on Artemis BlackBoard +#define LED LED_BUILTIN //Status LED on Artemis carrier boards -void setup() { +void setup() +{ Serial.begin(9600); Serial.println("SparkFun Arduino Apollo3 Analog Read example"); @@ -34,7 +34,8 @@ void setup() { //analogReadResolution(16); //Set resolution to 16 bit - will pad ADC output with two zeros } -void loop() { +void loop() +{ digitalWrite(LED, LOW); int myValue1 = analogRead(A1); //Automatically sets pin to analog input diff --git a/libraries/CoreTesting/examples/Example8_millis/Example8_millis.ino b/libraries/Examples/examples/Example8_millis/Example8_millis.ino similarity index 100% rename from libraries/CoreTesting/examples/Example8_millis/Example8_millis.ino rename to libraries/Examples/examples/Example8_millis/Example8_millis.ino diff --git a/libraries/CoreTesting/examples/example9_analogWrite/example9_analogWrite.ino b/libraries/Examples/examples/Example9_analogWrite/Example9_analogWrite.ino similarity index 51% rename from libraries/CoreTesting/examples/example9_analogWrite/example9_analogWrite.ino rename to libraries/Examples/examples/Example9_analogWrite/Example9_analogWrite.ino index 8b7db8b4..79e714c9 100644 --- a/libraries/CoreTesting/examples/example9_analogWrite/example9_analogWrite.ino +++ b/libraries/Examples/examples/Example9_analogWrite/Example9_analogWrite.ino @@ -14,31 +14,37 @@ 39 47 35 48 37 49 11 - these numbers refer to the _pad_ number which does not necessarily mean the _pin_ number of the Apollo3-based variant + these numbers refer to the _pad_ number which does not necessarily mean the _pin_ number of the + Apollo3-based variant - This sketch assumes you are using a "directly mapped" (pin == pad) variant such as the SparkFun Edge board + This sketch assumes you are using a "directly mapped" (pin == pad) variant such as the SparkFun Edge board or + the SparkFun Artemis ATP (All the Pins!). */ -void setup() { +void setup() +{ Serial.begin(9600); - while (!Serial) {}; //Wait for user to open terminal window + while (!Serial) + { + }; //Wait for user to open terminal window Serial.println("SparkFun Arduino Apollo3 analogWrite() Example"); Serial.printf("Compiled on %s, %s\n\n", __DATE__, __TIME__); // Look! You can use printf, if you so choose - analogWrite(46, 127); // analogWrite uses a high frequency counter/timer module to generate a PWM value with f ~= 350 Hz - analogWriteResolution(15); // you can increase the resolution of the write from the default (8-bit, 0-255) to up to 15 bits (0-32767) - analogWrite(37, 16383); // subsequent cals to analogWrite use the new resolution, so both this call and the original have a 50% duty cycle, or 3.3/2 V + analogWrite(46, 127); // analogWrite uses a high frequency counter/timer module to generate a PWM value with f ~= 350 Hz + analogWriteResolution(15); // you can increase the resolution of the write from the default (8-bit, 0-255) to up to 15 bits (0-32767) + analogWrite(37, 16383); // subsequent cals to analogWrite use the new resolution, so both this call and the original have a 50% duty cycle, or 3.3/2 V - servoWrite(44, 127); // The servoWrite function produces a PWM signal with a pulse width between 1 and 2 ms at 500 Hz - servoWriteResolution(15); // You can also increase the servoWrite() resolution - servoWrite(47, 16383); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions + servoWrite(44, 127); // The servoWrite function produces a PWM signal with a pulse width between 1 and 2 ms at 500 Hz + servoWriteResolution(15); // You can also increase the servoWrite() resolution + servoWrite(47, 16383); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions delay(5000); } -void loop() { +void loop() +{ // All the PWM generation is done in hardware, so the remainder of the code is both simple and efficient! // analog and servo write resolutions remain at the last value they were set to @@ -51,10 +57,12 @@ void loop() { servoWrite(47, val); val += 5 * sign; - if (val > 32767) { + if (val > 32767) + { sign = -1; } - if ( val <= 0 ) { + if (val <= 0) + { sign = 1; } diff --git a/libraries/Examples/keywords.txt b/libraries/Examples/keywords.txt new file mode 100644 index 00000000..718ac7f9 --- /dev/null +++ b/libraries/Examples/keywords.txt @@ -0,0 +1,4 @@ +####################################### +# This is a place holder file to get the examples for +# the Artemis boards to render correctly. +####################################### diff --git a/libraries/Examples/library.properties b/libraries/Examples/library.properties new file mode 100644 index 00000000..2fc9eb60 --- /dev/null +++ b/libraries/Examples/library.properties @@ -0,0 +1,10 @@ +name=Artemis Examples +version=1.0 +author=SparkFun +maintainer=SparkFun Electronics +sentence=Place holder to get the Arduino IDE to display examples for the core boards. +paragraph=These are the various examples demonstrating the standard and advanced built-in features of the Artemis module. +category=Other +url=https://github.com/sparkfun/Arduino_Apollo3 +architectures=apollo3 + diff --git a/libraries/Examples/src/Examples.h b/libraries/Examples/src/Examples.h new file mode 100644 index 00000000..afe973a0 --- /dev/null +++ b/libraries/Examples/src/Examples.h @@ -0,0 +1,4 @@ +/* + This is just an empty place holder header file so that the + Arduino IDE renders the example list correctly. +*/ \ No newline at end of file From e3b249506ea2061af0c67d3178060e967ea59b06 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 24 Jun 2019 09:54:35 -0600 Subject: [PATCH 2/5] Add 2 I2C port example --- .../Additional_I2C_Ports.ino | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 libraries/Examples/examples/Advanced/Additional_I2C_Ports/Additional_I2C_Ports.ino diff --git a/libraries/Examples/examples/Advanced/Additional_I2C_Ports/Additional_I2C_Ports.ino b/libraries/Examples/examples/Advanced/Additional_I2C_Ports/Additional_I2C_Ports.ino new file mode 100644 index 00000000..66db40b1 --- /dev/null +++ b/libraries/Examples/examples/Advanced/Additional_I2C_Ports/Additional_I2C_Ports.ino @@ -0,0 +1,68 @@ +/* + Making more I2C ports on the Artemis + By: Nathan Seidle + SparkFun Electronics + Date: June 21, 2019 + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example shows how to add a 2nd (or 3rd) I2C bus to an Artemis carrier board. + + The key to success is that when the SPIClass or TwoWire objects above are constructed they don't actually + change any of the Special Function Registers (SFRs) in the Apollo3. That all happens when you use the .begin() + method. This way it is acceptable to define as many different TwoWire or SPIClass objects as you want at one + time using only one IOMaster instance. However it is *not* well-characterized how it will perform if you try + to 'begin' more than one. + + For this example, you'll need: + BlackBoard Artemis (or any Artemis board): https://www.sparkfun.com/products/15332 + Qwiic Accel: https://www.sparkfun.com/products/14587 + Qwiic Breadboard cable: https://www.sparkfun.com/products/14425 + + Hardware Connections: + Connect the Qwiic cable to the Accel + Plug the male pins into the following pins on the BlackBoard Artemis: + Red -> 3.3V + Black -> GND + Yellow -> SCK + Blue -> MISO +*/ + +#include + +//Create a TwoWire object that uses a given IOMaster +TwoWire myWire(0); //Will use pads 5/6, pins labeled SCK/MISO on BlackBoard Artemis +//TwoWire myWire(1); //Will use pads 8/9 +//TwoWire myWire(2); //Will use pads 25/27, pins labeled D6/RX1 on BlackBoard Artemis +//TwoWire myWire(3); //Will use pads 42/43 +//TwoWire myWire(4); //Will use pads 39/40, pins labeled SCL/SDA on BlackBoard Artemis +//TwoWire myWire(5); //Will use pads 48/49, pins labeled TX0/RX0 on BlackBoard Artemis + +#include "SparkFun_MMA8452Q.h" // Click here to get the library: http://librarymanager/All#SparkFun_MMA8452Q +MMA8452Q accel; // Create instance of the MMA8452 class + +void setup() { + Serial.begin(9600); + Serial.println("MMA8452Q on non-standard I2C port!"); + + myWire.begin(); + + //Here's the next trick. You need to pass this Wire port to your library. + //SparkFun libraries allow any Wire port to be passed in. Other folk's libraries may not do this. + if (accel.begin(myWire) == false) { + Serial.println("Not Connected. Please check connections and read the hookup guide."); + while (1); + } +} + +void loop() { + if (accel.available()) { // Wait for new data from accelerometer + // Acceleration of x, y, and z directions in g units + Serial.print(accel.getCalculatedX(), 3); + Serial.print("\t"); + Serial.print(accel.getCalculatedY(), 3); + Serial.print("\t"); + Serial.print(accel.getCalculatedZ(), 3); + Serial.println(); + } +} From 36482f05f67d7f310e09fffdc4c195e7db29b9a2 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 24 Jun 2019 11:54:58 -0600 Subject: [PATCH 3/5] Adding EEPROM example --- .../Advanced/EEPROM_GetPut/EEPROM_GetPut.ino | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 libraries/Examples/examples/Advanced/EEPROM_GetPut/EEPROM_GetPut.ino diff --git a/libraries/Examples/examples/Advanced/EEPROM_GetPut/EEPROM_GetPut.ino b/libraries/Examples/examples/Advanced/EEPROM_GetPut/EEPROM_GetPut.ino new file mode 100644 index 00000000..ea86af35 --- /dev/null +++ b/libraries/Examples/examples/Advanced/EEPROM_GetPut/EEPROM_GetPut.ino @@ -0,0 +1,52 @@ +/* + Reading and writing to flash using the EEPROM library + By: Nathan Seidle + SparkFun Electronics + Date: June 24th, 2019 + This example code is in the public domain. + + SparkFun labored with love to create this code. Feel like supporting open source hardware? + Buy a board from SparkFun! https://www.sparkfun.com/products/15376 + + This example shows how to use the EEPROM get and put functions + to read and write to EEPROM inside Artemis. + + Artemis doesn't actually have EEPROM. Instead we are writing to a protected + section of flash. 1028 bytes of flash are updated each time a variable is written. + This can take up to 30ms. + + Page erase takes 15ms + Write byte takes 30ms - This is much longer than Arduino that takes 3.3ms + Float write across two words takes 30ms + Update (no write) takes 1ms +*/ + +#include + +void setup() +{ + Serial.begin(9600); + Serial.println("EEPROM Examples"); + + byte myValue1 = 200; + EEPROM.put(0, myValue1); //(location, data) + byte response1; + EEPROM.get(0, response1); + Serial.printf("Location %d should be %d: %d\n\r", 0, myValue1, response1); + + int myValue5 = -245000; //Note that ints are 4 bytes on the Artemis + EEPROM.put(2, myValue5); + int response5; + EEPROM.get(2, response5); + Serial.printf("Location %d should be %d: %d\n\r", 2, myValue5, response5); + + float myValue9 = -7.35; + EEPROM.put(10, myValue9); + float response9; + EEPROM.get(10, response9); + Serial.printf("Location %d should be %f: %f\n\r", 10, myValue9, response9); +} + +void loop() +{ +} From f21caaa97a39e337157243a9c27089dc2b97362d Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 24 Jun 2019 14:24:51 -0600 Subject: [PATCH 4/5] Update README.md --- libraries/Examples/README.md | 140 +---------------------------------- 1 file changed, 2 insertions(+), 138 deletions(-) diff --git a/libraries/Examples/README.md b/libraries/Examples/README.md index a6241361..2ccd28c7 100644 --- a/libraries/Examples/README.md +++ b/libraries/Examples/README.md @@ -1,139 +1,3 @@ -## **EEPROM Library V2.0** for Arduino +## Artemis Examples -**Written by:** _Christopher Andrews_. - -### **What is the EEPROM library.** - -Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips. - -### **How to use it** -The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch. - -```Arduino -#include - -void setup(){ - -} - -void loop(){ - -} - -``` - -The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below. - -You can view all the examples [here](examples/). - -### **Library functions** - -#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino) - -This function allows you to read a single byte of data from the eeprom. -Its only parameter is an `int` which should be set to the address you wish to read. - -The function returns an `unsigned char` containing the value read. - -#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino) - -The `write()` method allows you to write a single byte of data to the EEPROM. -Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`). - -This function does not return any value. - -#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino) - -This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells. - -This function does not return any value. - -#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino) - -This function will retrieve any object from the EEPROM. -Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read. - -This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. - -#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino) - -This function will write any object to the EEPROM. -Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write. - -This function uses the _update_ method to write its data, and therefore only rewrites changed cells. - -This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. - -#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino) - -This operator allows using the identifier `EEPROM` like an array. -EEPROM cells can be read _and_ **_written_** directly using this method. - -This operator returns a reference to the EEPROM cell. - -```c++ -unsigned char val; - -//Read first EEPROM cell. -val = EEPROM[ 0 ]; - -//Write first EEPROM cell. -EEPROM[ 0 ] = val; - -//Compare contents -if( val == EEPROM[ 0 ] ){ - //Do something... -} -``` - -#### **`EEPROM.length()`** - -This function returns an `unsigned int` containing the number of cells in the EEPROM. - ---- - -### **Advanced features** - -This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`. - -#### **`EERef` class** - -This object references an EEPROM cell. -Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. -This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. - -```C++ -EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell. - -ref = 4; //write to EEPROM cell. - -unsigned char val = ref; //Read referenced cell. -``` - -#### **`EEPtr` class** - -This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects. -Just like a normal pointer type, this type can be dereferenced and repositioned using -increment/decrement operators. - -```C++ -EEPtr ptr = 10; //Create a pointer to 11th cell. - -*ptr = 4; //dereference and write to EEPROM cell. - -unsigned char val = *ptr; //dereference and read. - -ptr++; //Move to next EEPROM cell. -``` - -#### **`EEPROM.begin()`** - -This function returns an `EEPtr` pointing to the first cell in the EEPROM. -This is useful for STL objects, custom iteration and C++11 style ranged for loops. - -#### **`EEPROM.end()`** - -This function returns an `EEPtr` pointing at the location after the last EEPROM cell. -Used with `begin()` to provide custom iteration. - -**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell. +These are various basic examples demonstrating the Arduino reference functions. The advanced directory contains additional functions and methods that are specific to Artemis. \ No newline at end of file From 7e1109e059ab6fc22c155e8d85569d56650823a3 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 24 Jun 2019 15:59:44 -0600 Subject: [PATCH 5/5] Add Artemis Bootloader In case people over-write the SparkFun bootloader this is a handy example to have in the sub menu. --- .../Artemis_Bootloader/Artemis_Bootloader.ino | 320 ++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 libraries/Examples/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino diff --git a/libraries/Examples/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino b/libraries/Examples/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino new file mode 100644 index 00000000..9010d2fa --- /dev/null +++ b/libraries/Examples/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino @@ -0,0 +1,320 @@ +/* + Artemis Bootloader + By: Nathan Seidle + SparkFun Electronics + Date: May 2nd, 2019 + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This is a serial bootloader that receives commands from a python script and loads + user's code as quickly as possible. + + Feel like supporting open source hardware? + Buy a board from SparkFun! + SparkFun Edge: https://www.sparkfun.com/products/15170 + + Based on SparkFun XBee Bootloader from 2009: https://www.sparkfun.com/tutorials/122 + + The Apollo3 memory looks like this: + + 0xFF000 -> ------- + | | + | | + ... + | | + | | + | | + 0x10000 -> | APP | + | SFE | + 0xC000 -> | SBL | + ------- + + The Ambiq secure bootloader (SBL) lives at 0x00 to 0xC000. + The SparkFun Artemis bootloader begins at 0xC000 and takes ~7300 bytes (with debug statements it's ~10k) + We load user code starting at 0xC000 + 16384 = 0x10000 + If our bootloader completes or times out, we jump to 0x10000+4 to begin running user code +*/ + +#define BOOTLOADER_VERSION 0x01 + +static uint32_t ui32Source[512]; + +#define MAX_WAIT_IN_MS 50 //Millisecond wait before bootload timeout and begin user code + +enum BL_COMMANDS { + BL_COMMAND_ANNOUNCE = 127, //Delete + BL_COMMAND_AOK = 0x06, + BL_COMMAND_BAD_CRC, + BL_COMMAND_NEXT_FRAME, + BL_COMMAND_ALL_DONE, + BL_COMMAND_COMPUTER_READY, +}; + +bool retransmit_flag = false; +uint16_t frame_size = 0; +uint32_t incoming_crc32 = 0; +uint32_t crc32 = 0; +uint32_t frame_address = 0; +uint16_t last_page_erased = 0; + +// Location in flash to begin storing user's code +// Linker script needs to be adjusted to offset user's flash to this address +#define USERCODE_OFFSET 0xC000 + 0x4000 + +//Comment out this line to turn off debug statements on Serial1 +//#define DEBUG 1 + +void setup() { + Serial.begin(9600); //Start comm with computer at low baud rate. We'll go faster later. + +#ifdef DEBUG + Serial1.begin(921600); + Serial1.println(); + Serial1.println(); + Serial1.println("Debug"); +#endif + + delay(3); //Necessary to separate a blip on TX line when port opens from annouce command + Serial.write(BL_COMMAND_ANNOUNCE); //Tell the world we can be bootloaded + + //Check to see if the computer responded + uint16_t count = 0; + while (Serial.available() == 0) + { + if (count++ > MAX_WAIT_IN_MS) + { +#ifdef DEBUG + Serial1.println("No response from computer"); +#endif + app_start(); + } + delay(1); + } + if (Serial.read() != BL_COMMAND_AOK) + { +#ifdef DEBUG + Serial1.println("Invalid response from computer"); +#endif + app_start(); //If the computer did not respond correctly with a AOK, we jump to user's program + } + + //Now get upload baud rate from caller + uint32_t uploadRate = get4Bytes(); + + Serial.write(BOOTLOADER_VERSION); + delay(5); //Small delay before baud change. Otherwise baud fails to change. + + Serial.begin(uploadRate); //Go to new baud rate + + delay(10); //Give the computer some time to switch baud rates + +#ifdef DEBUG + Serial1.print("Bootloading @ "); + Serial1.println(uploadRate); +#endif +} + +//This is the main bootloader +//We'll loop until the whole file is received +void loop() { + //Determine if the last received data was good or bad + if (crc32 != incoming_crc32) + { +RESTART: + Serial.write(BL_COMMAND_BAD_CRC); //Tell client to resend last frame +#ifdef DEBUG + Serial1.println("RESTART!"); +#endif + } + else + { + Serial.write(BL_COMMAND_NEXT_FRAME); //Get next frame +#ifdef DEBUG + Serial1.println(); + Serial1.println("Getting next frame"); +#endif + } + + while (1) //Wait for the computer to tell us its ready to chat + { + if (getch() == BL_COMMAND_COMPUTER_READY) break; //This is the "gimme the next chunk" command + if (retransmit_flag == true) goto RESTART; + } + + frame_size = ((uint16_t)getch() << 8) | getch(); //Get the size of this frame + if (retransmit_flag == true)goto RESTART; + + if (frame_size == BL_COMMAND_ALL_DONE) //Check to see if we are done + { +#ifdef DEBUG + Serial1.println("Done!"); +#endif + am_hal_reset_control(AM_HAL_RESET_CONTROL_SWPOI, 0); //Cause a system Power On Init to release as much of the stack as possible + } + +#ifdef DEBUG + Serial1.print("frame_size: "); + Serial1.println(frame_size); +#endif + + //Get the memory address at which to store this block of data + frame_address = get4Bytes(); + if (retransmit_flag == true) goto RESTART; + + //Serial1.print("frame_address: "); + //Serial1.println(frame_address); + + //Get CRC from client + incoming_crc32 = get4Bytes(); + if (retransmit_flag == true) goto RESTART; + + //Serial1.print("incoming_crc32: "); + //Serial1.println(incoming_crc32); + + //Receive this frame + crc32 = 0; + for (uint16_t i = 0 ; i < frame_size / 4 ; i++) + { + ui32Source[i] = get4BytesReversed(); + crc32 += ui32Source[i]; //Calculate CRC as we go + } + + if (incoming_crc32 == crc32) + { +#ifdef DEBUG + Serial1.println("CRC good."); +#endif + + int32_t i32ReturnCode = 0; + + //Frames coming from the computer are 2k bytes, but we erase 8k bytes in a page + //Only erase a page if we haven't erased it before + if (last_page_erased < AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET)) + { +#ifdef DEBUG + Serial1.printf("Erasing instance %d, page %d\n\r", AM_HAL_FLASH_ADDR2INST(frame_address + USERCODE_OFFSET), AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET)); +#endif + + //Erase the 8k page for this address + i32ReturnCode = am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY, + AM_HAL_FLASH_ADDR2INST(frame_address + USERCODE_OFFSET), + AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET) ); + last_page_erased = AM_HAL_FLASH_ADDR2PAGE(frame_address + USERCODE_OFFSET); + } + +#ifdef DEBUG + if (i32ReturnCode) + { + Serial1.printf("FLASH_MASS_ERASE i32ReturnCode = 0x%x.\n\r", i32ReturnCode); + } +#endif + + //Record the array + i32ReturnCode = program_array(frame_address + USERCODE_OFFSET); + +#ifdef DEBUG + if (i32ReturnCode) + Serial1.printf("FLASH_WRITE error = 0x%x.\n\r", i32ReturnCode); + else + Serial1.println("Array recorded to flash"); +#endif + } + else + { +#ifdef DEBUG + Serial1.println("Bad CRC:"); + Serial1.printf("incoming_crc32: 0x%04X\n\r", incoming_crc32); + Serial1.printf("CRC: 0x%04X\n\r", crc32); +#endif + } +} + +//Gets a character from Serial +uint8_t getch() +{ + retransmit_flag = false; + + uint16_t counter = 0; + while (Serial.available() == 0) + { + delayMicroseconds(10); + if (counter++ > 10000) + { + retransmit_flag = true; + return (0); //Timeout + } + } + return (Serial.read()); +} + +uint32_t get4Bytes(void) +{ + uint32_t incoming = 0; + for (byte x = 0 ; x < 4 ; x++) + { + incoming <<= 8; + incoming |= getch(); + } + return (incoming); +} + +uint32_t get4BytesReversed(void) +{ + uint32_t incoming = 0; + for (byte x = 0 ; x < 4 ; x++) + { + incoming >>= 8; + incoming |= (getch() << 8 * 3); + } + return (incoming); +} + +void app_start() +{ +#ifdef DEBUG + // Print a section of flash + uint32_t start_address = USERCODE_OFFSET; + Serial1.printf("Printing page starting at offset 0x%04X", start_address); + for (uint16_t x = 0; x < 512; x++) + { + if (x % 8 == 0) + { + Serial1.println(); + Serial1.printf("Adr: 0x%04X", start_address + (x * 4)); + } + Serial1.printf(" 0x%08X", *(uint32_t *)(start_address + (x * 4))); + } + Serial1.println(); +#endif + + uint32_t entryPoint = *(uint32_t *)(USERCODE_OFFSET + 4); + +#ifdef DEBUG + Serial1.printf("Jump to 0x%08X", entryPoint); +#endif + delay(10); //Wait for prints to complete + + goto *entryPoint; //Jump to start of user code + +#ifdef DEBUG + Serial1.println("Not here"); +#endif + while (1); +} + +//Commits whatever is in the ui32Source to the given location +int32_t program_array(uint32_t ui32PrgmAddr) +{ + uint32_t *pui32Dst; + int32_t i32ReturnCode; + // + // Program a few words in a page in the main block of instance 1. + // + pui32Dst = (uint32_t *) ui32PrgmAddr; + i32ReturnCode = am_hal_flash_program_main(AM_HAL_FLASH_PROGRAM_KEY, + ui32Source, + pui32Dst, + 512); + + return (i32ReturnCode); +}