diff --git a/boards.txt b/boards.txt index afc903e4..543bd330 100644 --- a/boards.txt +++ b/boards.txt @@ -23,7 +23,7 @@ artemis.name=SparkFun Artemis Module artemis.build.variant=SparkFun_Artemis artemis.build.board=SFE_ARTEMIS -artemis.upload.tool=artemis_bin2board +artemis.upload.tool=artemis_uart artemis.upload.maximum_size=960000 artemis.build.arch=APOLLO3 artemis.build.mcu=cortex-m4 @@ -43,7 +43,7 @@ artemis.upload.baud=115200 amap3blackboard.name=SparkFun BlackBoard Artemis amap3blackboard.build.variant=SparkFun_BlackBoard_Artemis amap3blackboard.build.board=AM_AP3_SFE_BB_ARTEMIS -amap3blackboard.upload.tool=artemis_bin2board +amap3blackboard.upload.tool=artemis_uart amap3blackboard.upload.maximum_size=960000 amap3blackboard.build.arch=APOLLO3 amap3blackboard.build.mcu=cortex-m4 @@ -60,30 +60,10 @@ amap3blackboard.upload.baud=115200 ############################################################### -amap3blackboardBL.name=SparkFun BlackBoard Artemis 80k Offset -amap3blackboardBL.build.variant=SparkFun_BlackBoard_Artemis_BL -amap3blackboardBL.build.board=AM_AP3_SFE_BB_ARTEMIS_BL -amap3blackboardBL.upload.tool=artemis_bin2board -amap3blackboardBL.upload.maximum_size=960000 -amap3blackboardBL.build.arch=APOLLO3 -amap3blackboardBL.build.mcu=cortex-m4 -amap3blackboardBL.build.f_cpu=48000000L -amap3blackboardBL.build.core=arduino -amap3blackboardBL.build.defs= -amap3blackboardBL.build.includes=-I{build.variant.path}/config -amap3blackboardBL.build.libs= -amap3blackboardBL.build.extra_flags=-DPART_apollo3 -DAM_PACKAGE_BGA -DAM_PART_APOLLO3 -amap3blackboardBL.build.ldscript={build.variant.path}/linker_scripts/gcc/flash_with_bootloader.ld -amap3blackboardBL.upload.maximum_size=960000 -edge.upload.use_menu_baud=0 -amap3blackboardBL.upload.baud=115200 - -############################################################### - amap3nano.name=SparkFun BlackBoard Artemis Nano amap3nano.build.variant=SparkFun_BlackBoard_Artemis_Nano amap3nano.build.board=AM_AP3_SFE_BB_ARTEMIS_NANO -amap3nano.upload.tool=artemis_bin2board +amap3nano.upload.tool=artemis_uart amap3nano.upload.maximum_size=960000 amap3nano.build.arch=APOLLO3 amap3nano.build.mcu=cortex-m4 @@ -103,7 +83,7 @@ amap3nano.upload.baud=115200 amap3mega.name=SparkFun BlackBoard Artemis Mega amap3mega.build.variant=SparkFun_BlackBoard_Artemis_Mega amap3mega.build.board=AM_AP3_SFE_BB_ARTEMIS_MEGA -amap3mega.upload.tool=artemis_bin2board +amap3mega.upload.tool=artemis_uart amap3mega.upload.maximum_size=960000 amap3mega.build.arch=APOLLO3 amap3mega.build.mcu=cortex-m4 @@ -139,10 +119,29 @@ edge.upload.baud=921600 ############################################################### +amap3SBL.name=Abmiq SBL +amap3SBL.build.variant=SparkFun_Ambiq_SBL +amap3SBL.build.board=SFE_AMB_SBL +amap3SBL.upload.tool=artemis_bin2board +amap3SBL.upload.maximum_size=960000 +amap3SBL.build.arch=APOLLO3 +amap3SBL.build.mcu=cortex-m4 +amap3SBL.build.f_cpu=48000000L +amap3SBL.build.core=arduino +amap3SBL.build.defs= +amap3SBL.build.includes=-I{build.variant.path}/config +amap3SBL.build.libs= +amap3SBL.build.extra_flags=-DPART_apollo3 -DAM_PACKAGE_BGA -DAM_PART_APOLLO3 +amap3SBL.build.ldscript={build.variant.path}/linker_scripts/gcc/flash_with_bootloader.ld +amap3SBL.upload.use_menu_baud=0 +amap3SBL.upload.baud=115200 + +############################################################### + # edgeV2.name=SparkFun Edge V2 # edgeV2.build.variant=SparkFun_Edge_V2 # edgeV2.build.board=SFE_EDGE_V2 -# edgeV2.upload.tool=artemis_bin2board +# edgeV2.upload.tool=artemis_uart # edgeV2.upload.maximum_size=960000 # edgeV2.build.arch=APOLLO3 # edgeV2.build.mcu=cortex-m4 @@ -158,3 +157,4 @@ edge.upload.baud=921600 # edgeV2.upload.baud=115200 # ############################################################### + diff --git a/cores/arduino/ard_sup/Arduino.h b/cores/arduino/ard_sup/Arduino.h index 09e6ea9f..2016dfb9 100644 --- a/cores/arduino/ard_sup/Arduino.h +++ b/cores/arduino/ard_sup/Arduino.h @@ -39,7 +39,9 @@ extern "C" // Include Apollo headers #include "am_mcu_apollo.h" #include "am_util.h" -// #include "am_bsp.h" + // #include "am_bsp.h" + +#include //Gets us pow() #ifdef ARDUINO_REDEFINE_OVERFLOW #warning "restoring OVERFLOW from value in ARDUINO_REDEFINE_OVERFLOW" @@ -70,6 +72,8 @@ extern "C" #define RAD_TO_DEG 57.295779513082320876798154814105 #define EULER 2.718281828459045235360287471352 +typedef bool boolean; + enum BitOrder { LSBFIRST = 0, diff --git a/libraries/CoreTesting/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino b/libraries/CoreTesting/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino deleted file mode 100644 index 6e780eb7..00000000 --- a/libraries/CoreTesting/examples/Advanced/Artemis_Bootloader/Artemis_Bootloader.ino +++ /dev/null @@ -1,324 +0,0 @@ -/* - 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 XBee Bootloader from 2009: https://www.sparkfun.com/tutorials/122 - - The Apollo3 memory looks like this: - - 0xFF000 -> ------- - | | - | | - ... - | | - | | - | | - 0x14000 -> | APP | - | SFE | - 0xC000 -> | SBL | - ------- - - The factory 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 + 8192 = 0xE000 - If our bootloader completes or times out, we jump to 0xE000+4 to begin running user code - - TODO: - Protect bootloader section in flash - Combine Ambiq SBL with SparkFun BL - Upload combined over JTAG - Adjust Arduino linker script for all varients - Adjust Arduino tools to artemis uart loader - Make sure all RAM is released -*/ - -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 = 0x05, - BL_COMMAND_AOK, - 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 reponse 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.flush(); - 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); -} diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 427bfd12..4f441a12 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -30,68 +30,90 @@ const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); SPIClass::SPIClass(uint8_t iom_instance) : IOMaster(iom_instance) { - _duplex = ap3_spi_full_duplex; + _duplex = ap3_spi_full_duplex; } SPIClass::SPIClass(uint8_t iom_instance, ap3_spi_duplex_e duplex) : IOMaster(iom_instance) { - _duplex = duplex; + _duplex = duplex; } void SPIClass::begin() { - ap3_err_t retval = AP3_OK; - am_hal_gpio_pincfg_t pincfg = AP3_GPIO_DEFAULT_PINCFG; - uint8_t funcsel = 0; - - // init(); - - // Set up pins - // clock - retval = ap3_iom_pad_funcsel( _instance, AP3_IOM_SPI_SCLK, &_padSCLK, &funcsel); - if( retval != AP3_OK ){ return /*retval*/; } - pincfg.uFuncSel = funcsel; - pincfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - pincfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - pincfg.uIOMnum = _instance; - padMode( _padSCLK, pincfg, &retval ); if( retval != AP3_OK){ return /*ap3_return(retval)*/; } - pincfg = AP3_GPIO_DEFAULT_PINCFG; // set back to default for use with next pin - - // mosi - if( _duplex & ap3_spi_tx_only ){ - retval = ap3_iom_pad_funcsel( _instance, AP3_IOM_SPI_MOSI, &_padMOSI, &funcsel); - if( retval != AP3_OK ){ return /*retval*/; } - pincfg.uFuncSel = funcsel; - pincfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - pincfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - pincfg.uIOMnum = _instance; - padMode( _padMOSI, pincfg, &retval ); if( retval != AP3_OK){ return /*ap3_return(retval)*/; } - pincfg = AP3_GPIO_DEFAULT_PINCFG; // set back to default for use with next pin - } - - // miso - if( _duplex & ap3_spi_rx_only ){ - retval = ap3_iom_pad_funcsel( _instance, AP3_IOM_SPI_MISO, &_padMISO, &funcsel); - if( retval != AP3_OK ){ return /*retval*/; } - pincfg.uFuncSel = funcsel; - pincfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; - pincfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; - pincfg.uIOMnum = _instance; - padMode( _padMISO, pincfg, &retval ); if( retval != AP3_OK){ return /*ap3_return(retval)*/; } - pincfg = AP3_GPIO_DEFAULT_PINCFG; // set back to default for use with next pin - } - - - config(DEFAULT_SPI_SETTINGS); + ap3_err_t retval = AP3_OK; + am_hal_gpio_pincfg_t pincfg = AP3_GPIO_DEFAULT_PINCFG; + uint8_t funcsel = 0; + + // init(); + + // Set up pins + // clock + retval = ap3_iom_pad_funcsel(_instance, AP3_IOM_SPI_SCLK, &_padSCLK, &funcsel); + if (retval != AP3_OK) + { + return /*retval*/; + } + pincfg.uFuncSel = funcsel; + pincfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; + pincfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; + pincfg.uIOMnum = _instance; + padMode(_padSCLK, pincfg, &retval); + if (retval != AP3_OK) + { + return /*ap3_return(retval)*/; + } + pincfg = AP3_GPIO_DEFAULT_PINCFG; // set back to default for use with next pin + + // mosi + if (_duplex & ap3_spi_tx_only) + { + retval = ap3_iom_pad_funcsel(_instance, AP3_IOM_SPI_MOSI, &_padMOSI, &funcsel); + if (retval != AP3_OK) + { + return /*retval*/; + } + pincfg.uFuncSel = funcsel; + pincfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; + pincfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; + pincfg.uIOMnum = _instance; + padMode(_padMOSI, pincfg, &retval); + if (retval != AP3_OK) + { + return /*ap3_return(retval)*/; + } + pincfg = AP3_GPIO_DEFAULT_PINCFG; // set back to default for use with next pin + } + + // miso + if (_duplex & ap3_spi_rx_only) + { + retval = ap3_iom_pad_funcsel(_instance, AP3_IOM_SPI_MISO, &_padMISO, &funcsel); + if (retval != AP3_OK) + { + return /*retval*/; + } + pincfg.uFuncSel = funcsel; + pincfg.eDriveStrength = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA; + pincfg.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL; + pincfg.uIOMnum = _instance; + padMode(_padMISO, pincfg, &retval); + if (retval != AP3_OK) + { + return /*ap3_return(retval)*/; + } + pincfg = AP3_GPIO_DEFAULT_PINCFG; // set back to default for use with next pin + } + + config(DEFAULT_SPI_SETTINGS); } void SPIClass::config(SPISettings settings) { - memset( (void*)&_config, 0x00, sizeof(am_hal_iom_config_t) ); // Set the IOM configuration - _config.eInterfaceMode = AM_HAL_IOM_SPI_MODE; - _config.ui32ClockFreq = settings.clockFreq; - _config.eSpiMode = settings.dataMode; - _order = settings.bitOrder; + memset((void *)&_config, 0x00, sizeof(am_hal_iom_config_t)); // Set the IOM configuration + _config.eInterfaceMode = AM_HAL_IOM_SPI_MODE; + _config.ui32ClockFreq = settings.clockFreq; + _config.eSpiMode = settings.dataMode; + _order = settings.bitOrder; initialize(); // Initialize the IOM } @@ -188,7 +210,7 @@ void SPIClass::setBitOrder(BitOrder order) void SPIClass::setDataMode(uint8_t mode) { - _config.eSpiMode = mode; + _config.eSpiMode = (am_hal_iom_spi_mode_e)mode; initialize(); } @@ -203,18 +225,29 @@ void SPIClass::setDataMode(uint8_t mode) byte SPIClass::transfer(uint8_t data) { - _transfer( &data, NULL, 1); + _transfer(&data, NULL, 1); } -uint16_t SPIClass::transfer16(uint16_t data) { - union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t; +uint16_t SPIClass::transfer16(uint16_t data) +{ + union { + uint16_t val; + struct + { + uint8_t lsb; + uint8_t msb; + }; + } t; t.val = data; - if ( _order == LSBFIRST) { + if (_order == LSBFIRST) + { t.lsb = transfer(t.lsb); t.msb = transfer(t.msb); - } else { + } + else + { t.msb = transfer(t.msb); t.lsb = transfer(t.lsb); } @@ -222,75 +255,84 @@ uint16_t SPIClass::transfer16(uint16_t data) { return t.val; } -void SPIClass::transfer(void *buf, size_t count){ - _transfer( buf, buf, count); // todo: not sure how the HAL will handle sending and receiving from the same buffer... +void SPIClass::transfer(void *buf, size_t count) +{ + _transfer(buf, buf, count); // todo: not sure how the HAL will handle sending and receiving from the same buffer... } -void SPIClass::transferOut(void *buf, size_t count){ - _transfer( buf, NULL, count); +void SPIClass::transferOut(void *buf, size_t count) +{ + _transfer(buf, NULL, count); } -void SPIClass::transferIn(void *buf, size_t count){ - _transfer( NULL, buf, count); +void SPIClass::transferIn(void *buf, size_t count) +{ + _transfer(NULL, buf, count); } -void SPIClass::_transfer(void* buf_out, void* buf_in, size_t count) +void SPIClass::_transfer(void *buf_out, void *buf_in, size_t count) { - am_hal_iom_transfer_t iomTransfer = {0}; - // iomTransfer.uPeerInfo.ui32SpiChipSelect = cs_pad; - iomTransfer.ui32InstrLen = 0; // No instructions - iomTransfer.ui32Instr = 0; // No instructions - iomTransfer.ui32NumBytes = count; // How many bytes to transfer - // iomTransfer.eDirection = AM_HAL_IOM_TX; // AM_HAL_IOM_FULLDUPLEX - Note: Ambiq SDK says that FULLDUPLEX is not yet supported // todo: - iomTransfer.pui32TxBuffer = (uint32_t*)buf_out; // todo: does this have the proper lifetime? - iomTransfer.pui32RxBuffer = (uint32_t*)buf_in; - iomTransfer.bContinue = false; - iomTransfer.ui8RepeatCount = 0; // ? - iomTransfer.ui8Priority = 1; // ? - iomTransfer.ui32PauseCondition = 0; // ? - iomTransfer.ui32StatusSetClr = 0; // ? - - // Determine direction - if( (buf_out != NULL) && (buf_in != NULL) ){ - iomTransfer.eDirection = AM_HAL_IOM_TX; // AM_HAL_IOM_FULLDUPLEX - Note: Ambiq SDK says that FULLDUPLEX is not yet supported // todo: - }else if( buf_out != NULL ){ - iomTransfer.eDirection = AM_HAL_IOM_TX; - }else if( buf_in != NULL ){ - iomTransfer.eDirection = AM_HAL_IOM_RX; - } - - uint32_t retVal32 = am_hal_iom_blocking_transfer(_handle, &iomTransfer); + am_hal_iom_transfer_t iomTransfer = {0}; + // iomTransfer.uPeerInfo.ui32SpiChipSelect = cs_pad; + iomTransfer.ui32InstrLen = 0; // No instructions + iomTransfer.ui32Instr = 0; // No instructions + iomTransfer.ui32NumBytes = count; // How many bytes to transfer + // iomTransfer.eDirection = AM_HAL_IOM_TX; // AM_HAL_IOM_FULLDUPLEX - Note: Ambiq SDK says that FULLDUPLEX is not yet supported // todo: + iomTransfer.pui32TxBuffer = (uint32_t *)buf_out; // todo: does this have the proper lifetime? + iomTransfer.pui32RxBuffer = (uint32_t *)buf_in; + iomTransfer.bContinue = false; + iomTransfer.ui8RepeatCount = 0; // ? + iomTransfer.ui8Priority = 1; // ? + iomTransfer.ui32PauseCondition = 0; // ? + iomTransfer.ui32StatusSetClr = 0; // ? + + // Determine direction + if ((buf_out != NULL) && (buf_in != NULL)) + { + iomTransfer.eDirection = AM_HAL_IOM_TX; // AM_HAL_IOM_FULLDUPLEX - Note: Ambiq SDK says that FULLDUPLEX is not yet supported // todo: + } + else if (buf_out != NULL) + { + iomTransfer.eDirection = AM_HAL_IOM_TX; + } + else if (buf_in != NULL) + { + iomTransfer.eDirection = AM_HAL_IOM_RX; + } + + uint32_t retVal32 = am_hal_iom_blocking_transfer(_handle, &iomTransfer); if (retVal32 != 0) { - // Serial.printf("got an error on _transfer: %d\n", retVal32); - return /*retVal32*/; + // Serial.printf("got an error on _transfer: %d\n", retVal32); + return /*retVal32*/; } } -void SPIClass::attachInterrupt() { +void SPIClass::attachInterrupt() +{ // Should be enableInterrupt() } -void SPIClass::detachInterrupt() { +void SPIClass::detachInterrupt() +{ // Should be disableInterrupt() } #if SPI_INTERFACES_COUNT > 0 - SPIClass SPI ( AP3_SPI_IOM, AP3_SPI_DUP ); +SPIClass SPI(AP3_SPI_IOM, AP3_SPI_DUP); #endif #if SPI_INTERFACES_COUNT > 1 - SPIClass SPI1(AP3_SPI1_IOM, AP3_SPI1_DUP ); +SPIClass SPI1(AP3_SPI1_IOM, AP3_SPI1_DUP); #endif #if SPI_INTERFACES_COUNT > 2 - SPIClass SPI2(AP3_SPI2_IOM, AP3_SPI2_DUP ); +SPIClass SPI2(AP3_SPI2_IOM, AP3_SPI2_DUP); #endif #if SPI_INTERFACES_COUNT > 3 - SPIClass SPI3(AP3_SPI3_IOM, AP3_SPI3_DUP ); +SPIClass SPI3(AP3_SPI3_IOM, AP3_SPI3_DUP); #endif #if SPI_INTERFACES_COUNT > 4 - SPIClass SPI4(AP3_SPI4_IOM, AP3_SPI4_DUP ); +SPIClass SPI4(AP3_SPI4_IOM, AP3_SPI4_DUP); #endif #if SPI_INTERFACES_COUNT > 5 - SPIClass SPI5(AP3_SPI5_IOM, AP3_SPI5_DUP ); +SPIClass SPI5(AP3_SPI5_IOM, AP3_SPI5_DUP); #endif - diff --git a/libraries/Wire/keywords.txt b/libraries/Wire/keywords.txt index dd8366d8..960e1e44 100644 --- a/libraries/Wire/keywords.txt +++ b/libraries/Wire/keywords.txt @@ -16,6 +16,7 @@ endTransmission KEYWORD2 requestFrom KEYWORD2 onReceive KEYWORD2 onRequest KEYWORD2 +setClock KEYWORD2 ####################################### # Instances (KEYWORD2) diff --git a/platform.txt b/platform.txt index d7e51afd..2f97ebbd 100644 --- a/platform.txt +++ b/platform.txt @@ -125,6 +125,7 @@ preproc.macros.flags=-w -x c++ -E -CC recipe.preproc.macros="{compiler.path}/{compiler.cmd.cpp}" {compiler.flags.cpp} {preproc.macros.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.extra_flags.cpp} {build.extra_flags} {includes.all} "{source_file}" -o "{preprocessed_file_path}" ##### The following tool settings are for the Ambiq SBL + # Host-specific definitions for upload tool # Default host tools.artemis_bin2board.pgm={runtime.platform.path}/tools/artemis/macosx/artemis_bin_to_board/artemis_bin_to_board diff --git a/tools/artemis/artemis_uart_loader.py b/tools/artemis/artemis_uart_loader.py index a3f4be50..039e2ba2 100644 --- a/tools/artemis/artemis_uart_loader.py +++ b/tools/artemis/artemis_uart_loader.py @@ -15,7 +15,7 @@ from sys import exit # Bootloader command constants -BL_COMMAND_ANNOUNCE = 5 +BL_COMMAND_ANNOUNCE = 127 BL_COMMAND_AOK = 6 BL_COMMAND_BAD_CRC = 7 BL_COMMAND_NEXT_FRAME = 8 @@ -97,21 +97,35 @@ def main(): response = ser.read() - if(ord(response) == BL_COMMAND_ANNOUNCE): - # Respond with 'AOK' - # values = bytearray([6]) - ser.write(BL_COMMAND_AOK.to_bytes(1, byteorder='big')) + if(len(response) > 0): + if(ord(response) == BL_COMMAND_ANNOUNCE): + # Respond with 'AOK' + # values = bytearray([6]) + ser.write(BL_COMMAND_AOK.to_bytes(1, byteorder='big')) - verboseprint("Bootload response received") - break - else: - verboseprint("Unkown response: " + str(ord(response))) - response = '' + verboseprint("Bootload response received") + break + else: + verboseprint("Unkown response: " + str(ord(response))) + response = '' # Send upload baud rate baud_in_bytes = args.baud.to_bytes(4, byteorder='big') ser.write(baud_in_bytes) + # Wait for incoming char indicating bootloader version + i = 0 + response = '' + while len(response) == 0: + i = i + 1 + if(i == 10): + print("No version from Artemis bootloader") + exit() + + response = ser.read() + + verboseprint("Bootloader version: " + str(ord(response))) + ser.flush() # Wait for all previous bytes to transmit before changing bauds time.sleep(0.010) diff --git a/tools/artemis/windows/artemis_uart_loader.exe b/tools/artemis/windows/artemis_uart_loader.exe index 94cf7b76..0e067f08 100644 Binary files a/tools/artemis/windows/artemis_uart_loader.exe and b/tools/artemis/windows/artemis_uart_loader.exe differ diff --git a/variants/SparkFun_Ambiq_SBL/bsp/README.md b/variants/SparkFun_Ambiq_SBL/bsp/README.md new file mode 100644 index 00000000..001fd130 --- /dev/null +++ b/variants/SparkFun_Ambiq_SBL/bsp/README.md @@ -0,0 +1,15 @@ +# Variant BSP +The Board Support Package (BSP) is a feature of the AmbiqSuite SDK that allows you to: +- define names and default configurations for pins +- write globally-accessible routines for common functions + +These features are potentially useful when: +- designing an Apollo3-based board for a custom purpose where pin functions will be mainly static +- using AmbiqSuite examples within Arduino + +For an example of a BSP see the AmbiqSuite release 2.1.0 SDK under 'SDK/boards/Apollo3_EVB/bsp' + +To include BSP files (i.e. am_bsp.h, am_bsp.c, am_bsp_pins.h, am_bsp_pins.c, as well as +bsp_pins.src and pinconfig.py) add " -I{build.variant.path}/bsp" to the board definition in +boards.txt as part of the board.build.includes parameter. + diff --git a/variants/SparkFun_Ambiq_SBL/config/variant.cpp b/variants/SparkFun_Ambiq_SBL/config/variant.cpp new file mode 100644 index 00000000..25430778 --- /dev/null +++ b/variants/SparkFun_Ambiq_SBL/config/variant.cpp @@ -0,0 +1,79 @@ +/* +Copyright (c) 2019 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "variant.h" + +const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS] = { + 0, + 1, + AP3_GPIO_PAD_UNUSED, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + AP3_GPIO_PAD_UNUSED, + 17, + AP3_GPIO_PAD_UNUSED, + AP3_GPIO_PAD_UNUSED, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + AP3_GPIO_PAD_UNUSED, + AP3_GPIO_PAD_UNUSED, + AP3_GPIO_PAD_UNUSED, + 33, + AP3_GPIO_PAD_UNUSED, + AP3_GPIO_PAD_UNUSED, + 36, + 37, + 38, + 39, + 40, + AP3_GPIO_PAD_UNUSED, + 42, + 43, + 44, + AP3_GPIO_PAD_UNUSED, + 46, + 47, + 48, + 49, +}; + +// Uart Definitions +Uart Serial(0, 49, 48);// declares a Uart object called Serial using instance 0 of Apollo3 UART peripherals with RX on pin 49 and TX on pin 48 (note, you specify *pins* not Apollo3 pads. This uses the variant's pin map to determine the Apollo3 pad) diff --git a/variants/SparkFun_Ambiq_SBL/config/variant.h b/variants/SparkFun_Ambiq_SBL/config/variant.h new file mode 100644 index 00000000..87c6aeb2 --- /dev/null +++ b/variants/SparkFun_Ambiq_SBL/config/variant.h @@ -0,0 +1,53 @@ +/* +Copyright (c) 2019 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#ifndef _AP3_VARIANT_H_ +#define _AP3_VARIANT_H_ + +#include "Arduino.h" + +#define AP3_VARIANT_NUM_PINS (50) + +// Pin map declaration +extern const ap3_gpio_pad_t ap3_variant_pinmap[AP3_VARIANT_NUM_PINS]; + +// Uart declarations +class Uart; // Forward declaration of Uart +extern Uart Serial; + +// Wire defines +#define WIRE_INTERFACES_COUNT 2 + +#define WireQwiic Wire // Giving Wire an alias of "WireQwiic" in case people want to use it +#define AP3_Wire_IOM 4 // Secify that Wire uses IOMaster instance 4 + +#define WireAccel Wire1 +#define AP3_Wire1_IOM 3 + +// SPI Defines +#define SPI_INTERFACES_COUNT 1 + +#define AP3_SPI_IOM 0 // Speciy that SPI uses IOMaster 0 +#define AP3_SPI_DUP ap3_spi_full_duplex // Specify that SPI is full-duplex (as opposed to ap3_spi_tx_only or ap3_spi_rx_only) + +#define LED_BUILTIN 46 + +#endif // _AP3_VARIANT_H_ \ No newline at end of file diff --git a/variants/SparkFun_Ambiq_SBL/linker_scripts/gcc/flash_with_bootloader.ld b/variants/SparkFun_Ambiq_SBL/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 00000000..c6d2441b --- /dev/null +++ b/variants/SparkFun_Ambiq_SBL/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * blank_slate.ld - Linker script for applications using startup_gnu.c + * + *****************************************************************************/ +ENTRY(Reset_Handler) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K /*Start code after the Ambiq SBL rather than SparkFun ABL*/ + SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K +} + +SECTIONS +{ + .text : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) + KEEP(*(.patch)) + *(.text) + *(.text*) + + . = ALIGN(4); + __init_array_start = .; + KEEP(*(.init_array)) /* C++ constructors */ + KEEP(*(.ctors)) /* and vtable init */ + __init_array_end = .; + + *(.rodata) + *(.rodata*) + . = ALIGN(4); + _etext = .; + } > FLASH + + /* User stack section initialized by startup code. */ + .stack (NOLOAD): + { + . = ALIGN(8); + *(.stack) + *(.stack*) + . = ALIGN(8); + } > SRAM + + .data : + { + . = ALIGN(4); + _sdata = .; + *(.data) + *(.data*) + . = ALIGN(4); + _edata = .; + } > SRAM AT>FLASH + + /* used by startup to initialize data */ + _init_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _sbss = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } > SRAM + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/variants/SparkFun_Ambiq_SBL/startup/startup_gcc.c b/variants/SparkFun_Ambiq_SBL/startup/startup_gcc.c new file mode 100644 index 00000000..3c5d02b2 --- /dev/null +++ b/variants/SparkFun_Ambiq_SBL/startup/startup_gcc.c @@ -0,0 +1,392 @@ +//***************************************************************************** +// +//! @file startup_gcc.c +//! +//! @brief Definitions for interrupt handlers, the vector table, and the stack. +// +//***************************************************************************** + +//***************************************************************************** +// +// Copyright (c) 2018, Ambiq Micro +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// Third party software included in this distribution is subject to the +// additional license terms as defined in the /docs/licenses directory. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// This is part of revision v1.2.12-1330-gad755f6e5 of the AmbiqSuite Development Package. +// +//***************************************************************************** + +#include +#include "am_mcu_apollo.h" // Defines AM_CMSIS_REGS + +//***************************************************************************** +// +// Forward declaration of interrupt handlers. +// +//***************************************************************************** +extern void Reset_Handler(void) __attribute ((naked)); +#if AM_CMSIS_REGS +extern void NMI_Handler(void) __attribute ((weak)); +extern void HardFault_Handler(void) __attribute ((weak)); +extern void MemManage_Handler(void) __attribute ((weak, alias ("HardFault_Handler"))); +extern void BusFault_Handler(void) __attribute ((weak, alias ("HardFault_Handler"))); +extern void UsageFault_Handler(void) __attribute ((weak, alias ("HardFault_Handler"))); +extern void SecureFault_Handler(void) __attribute ((weak)); +extern void SVC_Handler(void) __attribute ((weak, alias ("am_default_isr"))); +extern void DebugMon_Handler(void) __attribute ((weak, alias ("am_default_isr"))); +extern void PendSV_Handler(void) __attribute ((weak, alias ("am_default_isr"))); +extern void SysTick_Handler(void) __attribute ((weak, alias ("am_default_isr"))); +#else // AM_CMSIS_REGS +extern void am_nmi_isr(void) __attribute ((weak)); +extern void am_fault_isr(void) __attribute ((weak)); +extern void am_mpufault_isr(void) __attribute ((weak, alias ("am_fault_isr"))); +extern void am_busfault_isr(void) __attribute ((weak, alias ("am_fault_isr"))); +extern void am_usagefault_isr(void) __attribute ((weak, alias ("am_fault_isr"))); +extern void am_svcall_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_debugmon_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_pendsv_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_systick_isr(void) __attribute ((weak, alias ("am_default_isr"))); +#endif // AM_CMSIS_REGS + +extern void am_brownout_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_watchdog_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_rtc_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_vcomp_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_ioslave_ios_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_ioslave_acc_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_iomaster0_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_iomaster1_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_iomaster2_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_iomaster3_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_iomaster4_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_iomaster5_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_ble_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_gpio_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_ctimer_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_uart_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_uart1_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_scard_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_adc_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_pdm_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_mspi_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr0_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr1_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr2_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr3_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr4_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr5_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr6_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_stimer_cmpr7_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_clkgen_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software0_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software1_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software2_isr(void) __attribute ((weak, alias ("am_default_isr"))); +extern void am_software3_isr(void) __attribute ((weak, alias ("am_default_isr"))); + +extern void am_default_isr(void) __attribute ((weak)); + +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +__attribute__ ((section(".stack"))) +static uint32_t g_pui32Stack[1024]; + +//***************************************************************************** +// +// The vector table. Note that the proper constructs must be placed on this to +// ensure that it ends up at physical address 0x0000.0000. +// +// Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and +// am_usagefault_isr does not work if am_fault_isr is defined externally. +// Therefore, we'll explicitly use am_fault_isr in the table for those vectors. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (* const g_am_pfnVectors[])(void) = +{ + (void (*)(void))((uint32_t)g_pui32Stack + sizeof(g_pui32Stack)), + // The initial stack pointer +#if AM_CMSIS_REGS + Reset_Handler, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + HardFault_Handler, // The MemManage_Handler + HardFault_Handler, // The BusFault_Handler + HardFault_Handler, // The UsageFault_Handler + SecureFault_Handler, // The SecureFault_Handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler +#else // AM_CMSIS_REGS + am_reset_isr, // The reset handler + am_nmi_isr, // The NMI handler + am_fault_isr, // The hard fault handler + am_fault_isr, // The MPU fault handler + am_fault_isr, // The bus fault handler + am_fault_isr, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + am_svcall_isr, // SVCall handle + am_debugmon_isr, // Debug monitor handler + 0, // Reserved + am_pendsv_isr, // The PendSV handler + am_systick_isr, // The SysTick handler +#endif // AM_CMSIS_REGS + + // + // Peripheral Interrupts + // + am_brownout_isr, // 0: Brownout (rstgen) + am_watchdog_isr, // 1: Watchdog + am_rtc_isr, // 2: RTC + am_vcomp_isr, // 3: Voltage Comparator + am_ioslave_ios_isr, // 4: I/O Slave general + am_ioslave_acc_isr, // 5: I/O Slave access + am_iomaster0_isr, // 6: I/O Master 0 + am_iomaster1_isr, // 7: I/O Master 1 + am_iomaster2_isr, // 8: I/O Master 2 + am_iomaster3_isr, // 9: I/O Master 3 + am_iomaster4_isr, // 10: I/O Master 4 + am_iomaster5_isr, // 11: I/O Master 5 + am_ble_isr, // 12: BLEIF + am_gpio_isr, // 13: GPIO + am_ctimer_isr, // 14: CTIMER + am_uart_isr, // 15: UART0 + am_uart1_isr, // 16: UART1 + am_scard_isr, // 17: SCARD + am_adc_isr, // 18: ADC + am_pdm_isr, // 19: PDM + am_mspi_isr, // 20: MSPI + am_default_isr, // 21: reserved + am_stimer_isr, // 22: SYSTEM TIMER + am_stimer_cmpr0_isr, // 23: SYSTEM TIMER COMPARE0 + am_stimer_cmpr1_isr, // 24: SYSTEM TIMER COMPARE1 + am_stimer_cmpr2_isr, // 25: SYSTEM TIMER COMPARE2 + am_stimer_cmpr3_isr, // 26: SYSTEM TIMER COMPARE3 + am_stimer_cmpr4_isr, // 27: SYSTEM TIMER COMPARE4 + am_stimer_cmpr5_isr, // 28: SYSTEM TIMER COMPARE5 + am_stimer_cmpr6_isr, // 29: SYSTEM TIMER COMPARE6 + am_stimer_cmpr7_isr, // 30: SYSTEM TIMER COMPARE7 + am_clkgen_isr, // 31: CLKGEN + am_software0_isr, // 32: SOFTWARE0 + am_software1_isr, // 33: SOFTWARE1 + am_software2_isr, // 34: SOFTWARE2 + am_software3_isr // 35: SOFTWARE3 +}; + +//****************************************************************************** +// +// Place code immediately following vector table. +// +//****************************************************************************** +//****************************************************************************** +// +// The Patch table. +// +//****************************************************************************** +__attribute__ ((section(".patch"))) +uint32_t const __Patchable[] = +{ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern uint32_t _etext; +extern uint32_t _sdata; +extern uint32_t _edata; +extern uint32_t _sbss; +extern uint32_t _ebss; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied entry() routine is called. +// +//***************************************************************************** +#if defined(__GNUC_STDC_INLINE__) +void +Reset_Handler(void) +{ + // + // Set the vector table pointer. + // + __asm(" ldr r0, =0xE000ED08\n" + " ldr r1, =g_am_pfnVectors\n" + " str r1, [r0]"); + + // + // Set the stack pointer. + // + __asm(" ldr sp, [r1]"); +#ifndef NOFPU + // + // Enable the FPU. + // + __asm("ldr r0, =0xE000ED88\n" + "ldr r1,[r0]\n" + "orr r1,#(0xF << 20)\n" + "str r1,[r0]\n" + "dsb\n" + "isb\n"); +#endif + // + // Copy the data segment initializers from flash to SRAM. + // + __asm(" ldr r0, =_init_data\n" + " ldr r1, =_sdata\n" + " ldr r2, =_edata\n" + "copy_loop:\n" + " ldr r3, [r0], #4\n" + " str r3, [r1], #4\n" + " cmp r1, r2\n" + " blt copy_loop\n"); + // + // Zero fill the bss segment. + // + __asm(" ldr r0, =_sbss\n" + " ldr r1, =_ebss\n" + " mov r2, #0\n" + "zero_loop:\n" + " cmp r0, r1\n" + " it lt\n" + " strlt r2, [r0], #4\n" + " blt zero_loop"); + + // + // Call the application's entry point. + // + main(); + + // + // If main returns then execute a break point instruction + // + __asm(" bkpt "); +} +#else +#error GNU STDC inline not supported. +#endif + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +void +#if AM_CMSIS_REGS +NMI_Handler(void) +#else // AM_CMSIS_REGS +am_nmi_isr(void) +#endif // AM_CMSIS_REGS +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +void +#if AM_CMSIS_REGS +HardFault_Handler(void) +#else // AM_CMSIS_REGS +am_fault_isr(void) +#endif // AM_CMSIS_REGS +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +void +am_default_isr(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} diff --git a/variants/SparkFun_Artemis/linker_scripts/gcc/flash_with_bootloader.ld b/variants/SparkFun_Artemis/linker_scripts/gcc/flash_with_bootloader.ld index 1d51321b..69a6cde1 100644 --- a/variants/SparkFun_Artemis/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/SparkFun_Artemis/linker_scripts/gcc/flash_with_bootloader.ld @@ -7,7 +7,7 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K + FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 960K /*Modified from 0xC000 to work with SparkFun ABL*/ SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K } diff --git a/variants/SparkFun_BlackBoard_Artemis/linker_scripts/gcc/flash_with_bootloader.ld b/variants/SparkFun_BlackBoard_Artemis/linker_scripts/gcc/flash_with_bootloader.ld index 1d51321b..69a6cde1 100644 --- a/variants/SparkFun_BlackBoard_Artemis/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/SparkFun_BlackBoard_Artemis/linker_scripts/gcc/flash_with_bootloader.ld @@ -7,7 +7,7 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K + FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 960K /*Modified from 0xC000 to work with SparkFun ABL*/ SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K } diff --git a/variants/SparkFun_BlackBoard_Artemis_Mega/linker_scripts/gcc/flash_with_bootloader.ld b/variants/SparkFun_BlackBoard_Artemis_Mega/linker_scripts/gcc/flash_with_bootloader.ld index 1d51321b..69a6cde1 100644 --- a/variants/SparkFun_BlackBoard_Artemis_Mega/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/SparkFun_BlackBoard_Artemis_Mega/linker_scripts/gcc/flash_with_bootloader.ld @@ -7,7 +7,7 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K + FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 960K /*Modified from 0xC000 to work with SparkFun ABL*/ SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K } diff --git a/variants/SparkFun_BlackBoard_Artemis_Nano/linker_scripts/gcc/flash_with_bootloader.ld b/variants/SparkFun_BlackBoard_Artemis_Nano/linker_scripts/gcc/flash_with_bootloader.ld index 1d51321b..69a6cde1 100644 --- a/variants/SparkFun_BlackBoard_Artemis_Nano/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/SparkFun_BlackBoard_Artemis_Nano/linker_scripts/gcc/flash_with_bootloader.ld @@ -7,7 +7,7 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K + FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 960K /*Modified from 0xC000 to work with SparkFun ABL*/ SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K } diff --git a/variants/SparkFun_Edge_V2/linker_scripts/gcc/flash_with_bootloader.ld b/variants/SparkFun_Edge_V2/linker_scripts/gcc/flash_with_bootloader.ld index 1d51321b..69a6cde1 100644 --- a/variants/SparkFun_Edge_V2/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/SparkFun_Edge_V2/linker_scripts/gcc/flash_with_bootloader.ld @@ -7,7 +7,7 @@ ENTRY(Reset_Handler) MEMORY { - FLASH (rx) : ORIGIN = 0x0000C000, LENGTH = 960K + FLASH (rx) : ORIGIN = 0x00010000, LENGTH = 960K /*Modified from 0xC000 to work with SparkFun ABL*/ SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K }