diff --git a/bootloader/clubdance_v2_bootloader.X/nbproject/configurations.xml b/bootloader/clubdance_v2_bootloader.X/nbproject/configurations.xml
index 114dc98..b5b21b5 100644
--- a/bootloader/clubdance_v2_bootloader.X/nbproject/configurations.xml
+++ b/bootloader/clubdance_v2_bootloader.X/nbproject/configurations.xml
@@ -20,6 +20,7 @@
../../common_src/system.c
+ ../../common_src/memory.h
../src/usb_events.c
../src/main.c
../src/bootloader.c
+ ../src/VectorRemap.asm
-
-
-
-
+
+
+
+
@@ -178,6 +180,7 @@
value="Press to browse for a specific firmware version"/>
+
diff --git a/bootloader/src/VectorRemap.asm b/bootloader/src/VectorRemap.asm
new file mode 100644
index 0000000..ab932ba
--- /dev/null
+++ b/bootloader/src/VectorRemap.asm
@@ -0,0 +1,35 @@
+;/*******************************************************************************
+;Copyright 2016 Microchip Technology Inc. (www.microchip.com)
+;
+;Licensed under the Apache License, Version 2.0 (the "License");
+;you may not use this file except in compliance with the License.
+;You may obtain a copy of the License at
+;
+; http://www.apache.org/licenses/LICENSE-2.0
+;
+;Unless required by applicable law or agreed to in writing, software
+;distributed under the License is distributed on an "AS IS" BASIS,
+;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;See the License for the specific language governing permissions and
+;limitations under the License.
+;
+;To request to license the code under the MLA license (www.microchip.com/mla_license),
+;please contact mla_licensing@microchip.com
+;*******************************************************************************/
+
+ ;//High priority interrupt vector remapping
+ PSECT HiVector,class=CODE,delta=1,abs
+ org 0x08
+ goto 0x1C08 ;Resides at 0x0008 (hardware high priority interrupt vector), and causes PC to jump to 0x1C08 upon a high priority interrupt event
+
+
+ ;//Low priority interrupt vector remapping, as well as bootloader mode absolute
+ ;//entry point (located at 0x001C).
+ PSECT LoVector,class=CODE,delta=1,abs
+ org 0x18
+ goto 0x1C18 ;Resides at 0x0018 (hardware low priority interrupt vector), and causes PC to jump to 0x1C18 upon a low priority interrupt event
+ goto 0x30 ;Resides at 0x001C //Serves as absolute entry point from application program into the bootloader mode
+
+
+
+ end
\ No newline at end of file
diff --git a/bootloader/src/bootloader.c b/bootloader/src/bootloader.c
index b4c6b14..74f2125 100644
--- a/bootloader/src/bootloader.c
+++ b/bootloader/src/bootloader.c
@@ -152,8 +152,8 @@ unsigned char BufferedDataIndex;
uint24_t ProgrammedPointer;
unsigned char ConfigsLockValue;
-USB_VOLATILE USB_HANDLE txHandle = 0;
-USB_VOLATILE USB_HANDLE rxHandle = 0;
+USB_VOLATILE USB_HANDLE txHandle;
+USB_VOLATILE USB_HANDLE rxHandle;
void WriteFlashBlock(void);
void WriteConfigBits(void);
@@ -173,7 +173,8 @@ void UserInit(void)
ConfigsLockValue = 1;
USBEnableEndpoint(HID_EP, USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
- rxHandle = HIDRxPacket(HID_EP, (char *)&PacketFromPC, USB_PACKET_SIZE);
+ rxHandle = HIDRxPacket(HID_EP, (uint8_t *)&PacketFromPC, USB_PACKET_SIZE);
+ txHandle = 0;
}
/******************************************************************************
@@ -219,7 +220,7 @@ void ProcessIO(void)
{
//We received a new command from the host. Copy the OUT packet from
//the host into a local buffer for processing.
- rxHandle = HIDRxPacket(HID_EP, (char *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
+ rxHandle = HIDRxPacket(HID_EP, (uint8_t *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
//HIDRxReport((char *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
BootState = NOT_IDLE; //Set flag letting state machine know it has a command that needs processing.
@@ -263,7 +264,7 @@ void ProcessIO(void)
//Init pad bytes to 0x00... Already done after we received the QUERY_DEVICE command (just after calling HIDRxReport()).
//Now send the packet to the USB host software, assuming the USB endpoint is available/ready to accept new data.
- txHandle = HIDTxPacket(HID_EP, (char *)&PacketToPC, USB_PACKET_SIZE);
+ txHandle = HIDTxPacket(HID_EP, (uint8_t *)&PacketToPC, USB_PACKET_SIZE);
BootState = IDLE;
}
break;
@@ -279,7 +280,6 @@ void ProcessIO(void)
//First erase main program flash memory
for(ErasePageTracker = START_PAGE_TO_ERASE; ErasePageTracker < (unsigned int)(MAX_PAGE_TO_ERASE + 1); ErasePageTracker++)
{
- ClearWatchdog();
#ifdef __XC8__
TBLPTRU = 0x00;
TBLPTRH = (uint8_t)((uint24_t)ErasePageTracker >> 2);
@@ -390,7 +390,7 @@ void ProcessIO(void)
//data over so it can get sent to the USB host software.
if(!HIDTxHandleBusy(txHandle))
{
- HIDTxPacket(HID_OUT_EP, (char *)&PacketToPC, USB_PACKET_SIZE);
+ txHandle = HIDTxPacket(HID_EP, (uint8_t *)&PacketToPC, USB_PACKET_SIZE);
BootState = IDLE;
}
break;
@@ -428,7 +428,7 @@ void ProcessIO(void)
//Now actually command USB to send the packet to the host
if(!HIDTxHandleBusy(txHandle))
{
- HIDTxPacket(HID_OUT_EP, (char *)&PacketToPC, USB_PACKET_SIZE);
+ txHandle = HIDTxPacket(HID_EP, (uint8_t *)&PacketToPC, USB_PACKET_SIZE);
BootState = IDLE; //Packet will be sent, go back to idle state ready for next command from host
}
break;
@@ -509,7 +509,6 @@ void SignFlash(void)
if((i % WRITE_BLOCK_SIZE) == 0)
{
//The write latches are full, time to program the block.
- ClearWatchdog();
EECON1 = 0xA4; //Write to flash on next WR = 1 operation
UnlockAndActivate(CORRECT_UNLOCK_KEY);
}
@@ -574,8 +573,10 @@ void WriteFlashBlock(void) //Use to write blocks of data to flash.
static unsigned char CorrectionFactor;
static const uint8_t* pROM;
+
+ uint24_t romPtrAddress = ProgrammedPointer - BufferedDataIndex;
- pROM = (const uint8_t*)((uint8_t)ProgrammedPointer - BufferedDataIndex);
+ pROM = (const uint8_t*)romPtrAddress;
TBLPTRU = 0x00;
TBLPTRH = (uint8_t)((uint16_t)pROM >> 8);
TBLPTRL = (uint8_t)pROM;
@@ -776,18 +777,6 @@ void UnlockAndActivate(unsigned char UnlockKey)
EECON1bits.WREN = 0; //Good practice now to clear the WREN bit, as further protection against any accidental activation of self write/erase operations.
}
-//Helper function to reduce code size when built with C18. The ClrWdt() is an
-//inline assembly macro, and on the C18 compiler, if you execute an inline asm
-//instruction in a C function, it prevents the compiler from implementing
-//optimizations to that particular function (since the compiler doesn't know what
-//the user did in the inline asm). Therefore, inline asm is more efficient if
-//implemented outside of large C functions, when using C18.
-void ClearWatchdog(void)
-{
- ClrWdt();
-}
-
-
//Note: The ClrWdt() and "_asm tblrdpostinc _endasm" are inline assembly language
//instructions. The ClearWatchdog() and TableReadPostIncrement() functions are
//theoretically extraneous, since the operations being accomplished could be
diff --git a/bootloader/src/bootloader.h b/bootloader/src/bootloader.h
index 31419b1..b645b6b 100644
--- a/bootloader/src/bootloader.h
+++ b/bootloader/src/bootloader.h
@@ -29,9 +29,6 @@
void UserInit(void);
void ProcessIO(void);
-void ClearWatchdog(void);
-void DisableUSBandExecuteLongDelay(void);
-
//Vector remapping/absolute address constants
#define REMAPPED_APPLICATION_RESET_VECTOR 0x1C00
diff --git a/bootloader/src/main.c b/bootloader/src/main.c
index 655e914..3143471 100644
--- a/bootloader/src/main.c
+++ b/bootloader/src/main.c
@@ -9,22 +9,75 @@
#include "usb.h"
#include "bootloader.h"
-void main(void) {
- //UserInit();
+/* Private prototypes */
+void main(void);
+void BootMain(void);
+
+const unsigned int FlashSignatureWord __at(APP_SIGNATURE_ADDRESS) = APP_SIGNATURE_VALUE;
+
+void main(void)
+{
+ //BootMain();
+ /**
+ * TODO: implement hardware IO-based method for forcing entry into bootloader
+ */
+ // normal operation: verify the firmware signature is valid. if it isn't enter
+ // bootloader (fw update) mode so valid firmware can be flashed
+//DoFlashSignatureCheck:
+ //Check if the application region flash signature is valid
+ if(*(const unsigned int*)APP_SIGNATURE_ADDRESS == APP_SIGNATURE_VALUE)
+ {
+ //The flash signature was valid, implying the previous
+ //erase/program/verify operation was a success.
+
+ //Also make sure the first WORD of program memory in the app space
+ //is not blank, meaning there is an application image programmed into the device.
+ if(*(const unsigned int*)REMAPPED_APPLICATION_RESET_VECTOR != 0xFFFF)
+ {
+ //Go ahead and jump out of bootloader mode into the application run mode
+ #asm
+ goto REMAPPED_APPLICATION_RESET_VECTOR
+ #endasm
+ }
+ }
+ //else the application image is missing or corrupt. In this case, we
+ //need to stay in the bootloader mode, so the user has the ability to
+ //try (again) to re-program a valid application image into the device.
+
+ BootMain();
+}
+
+void BootMain(void) __at(0x30)
+{
+ //Make sure interrupts are disabled for this code (could still be on,
+ //if the application firmware jumped into the bootloader via software methods)
+ INTCON = 0x00;
+
+ //Clear the stack pointer, in case the user application jumped into
+ //bootloader mode with excessive junk on the call stack
+ STKPTR = 0x00;
+
+ // End of the important parts of the C initializer. This bootloader firmware does not use
+ // any C initialized user variables (idata memory sections). Therefore, the above is all
+ // the initialization that is required.
+
// initialize the USB framework
USBDeviceInit();
USBDeviceAttach();
+ // initialize the bootloader
+ UserInit();
+
+ //Execute main loop
while(1)
{
+ //Need to call USBDeviceTasks() periodically. This function takes care of
+ //processing non-USB application related USB packets (ex: "Chapter 9"
+ //packets associated with USB enumeration)
USBDeviceTasks();
- // do nothing if: not connected to USB host, or the host put us in suspend state
- if((USBGetDeviceState() < CONFIGURED_STATE) | USBIsDeviceSuspended())
- continue;
-
- // run application specific tasks
- ProcessIO();
- }
-}
+ ProcessIO(); //This is where all the actual bootloader related data transfer/self programming takes
+ //place see ProcessIO() function in the BootPIC[xxxx].c file.
+ }//end while
+}
\ No newline at end of file
diff --git a/common_src/memory.h b/common_src/memory.h
new file mode 100644
index 0000000..469c7c2
--- /dev/null
+++ b/common_src/memory.h
@@ -0,0 +1,37 @@
+/*************************************************************************
+ * Copyright (C) 2019 by Justin Byers
+ *
+ * This file is part of clubdance_v2.
+ *
+ * clubdance_v2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * clubdance_v2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with clubdance_v2. If not, see .
+ *************************************************************************/
+
+/**
+ * @file memory.
+ * @author Justin Byers
+ * @date August 11, 2019
+ * @brief
+ *
+ */
+#ifndef MEMORY_
+#define MEMORY_
+
+#define APP_FW_MEMORY_OFFSET 0x2000
+
+#define BOOTLOADER_ENTRYPOINT 0x001C
+
+#define APP_FW_VERSION_ADDRESS (APP_FW_MEMORY_OFFSET + 0x0016)
+
+#endif /* MEMORY_ */
+
diff --git a/firmware/clubdance_v2.X/nbproject/configurations.xml b/firmware/clubdance_v2.X/nbproject/configurations.xml
index cfca5da..3e2dab7 100644
--- a/firmware/clubdance_v2.X/nbproject/configurations.xml
+++ b/firmware/clubdance_v2.X/nbproject/configurations.xml
@@ -20,6 +20,7 @@
../../common_src/system.c
+ ../../common_src/memory.h
-
+
@@ -107,14 +108,14 @@
-
+
-
+
-
+
@@ -129,7 +130,7 @@
-
+
@@ -140,7 +141,7 @@
-
+
@@ -251,6 +252,7 @@
+ ../../bootloader/clubdance_v2_bootloader.X/dist/default/production/clubdance_v2_bootloader.X.production.hex
false
false
diff --git a/firmware/src/main.c b/firmware/src/main.c
index d9e8566..f450dfa 100644
--- a/firmware/src/main.c
+++ b/firmware/src/main.c
@@ -22,16 +22,17 @@
* @date 6 Aug 2019
* @brief USB interface to 6-sensor DDR pads.
*/
+const unsigned int VersionWord __at(0x1C16) = 0x0100;
#pragma warning disable 1510
#include "usb.h"
#include "padhal.h"
#include "dancepad.h"
-#ifdef LINK_FOR_BOOTLOADER
+//#ifdef LINK_FOR_BOOTLOADER
// only define this if building fw to be used with the bootloader
-const unsigned int VersionWord __at(0x1416) = 0x0100;
-#endif
+
+//#endif
void main(void)
{