kind of works for writing flash. IMPORTANT ISSUE - the memory usage output given by the linker for program size used DOES NOT equal the actual flash space used when programming. INVESTIGATE: did I set a memory space that doesn't lie on a page boundary? or do I just need to increase the flash space allocated to the bootloader

This commit is contained in:
2019-08-11 21:39:11 -04:00
parent 5ab4eceb88
commit 5c2d710bc2
8 changed files with 165 additions and 48 deletions

View File

@@ -20,6 +20,7 @@
</logicalFolder>
</logicalFolder>
<itemPath>../../common_src/system.c</itemPath>
<itemPath>../../common_src/memory.h</itemPath>
</logicalFolder>
<logicalFolder name="HeaderFiles"
displayName="Header Files"
@@ -38,6 +39,7 @@
<itemPath>../src/usb_events.c</itemPath>
<itemPath>../src/main.c</itemPath>
<itemPath>../src/bootloader.c</itemPath>
<itemPath>../src/VectorRemap.asm</itemPath>
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
@@ -140,10 +142,10 @@
<property key="code-model-rom" value="default,-1C00-7FFF"/>
<property key="create-html-files" value="false"/>
<property key="data-model-ram" value=""/>
<property key="data-model-size-of-double" value="24"/>
<property key="data-model-size-of-double-gcc" value="short-double"/>
<property key="data-model-size-of-float" value="24"/>
<property key="data-model-size-of-float-gcc" value="short-float"/>
<property key="data-model-size-of-double" value="32"/>
<property key="data-model-size-of-double-gcc" value="no-short-double"/>
<property key="data-model-size-of-float" value="32"/>
<property key="data-model-size-of-float-gcc" value="no-short-float"/>
<property key="display-class-usage" value="false"/>
<property key="display-hex-usage" value="false"/>
<property key="display-overall-usage" value="true"/>
@@ -178,6 +180,7 @@
value="Press to browse for a specific firmware version"/>
<property key="ToolFirmwareOption.UseLatestFirmware" value="true"/>
<property key="debugoptions.useswbreakpoints" value="false"/>
<property key="firmware.download.all" value="false"/>
<property key="hwtoolclock.frcindebug" value="false"/>
<property key="memories.aux" value="false"/>
<property key="memories.bootflash" value="true"/>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

37
common_src/memory.h Normal file
View File

@@ -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 <https://www.gnu.org/licenses/>.
*************************************************************************/
/**
* @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_ */

View File

@@ -20,6 +20,7 @@
</logicalFolder>
</logicalFolder>
<itemPath>../../common_src/system.c</itemPath>
<itemPath>../../common_src/memory.h</itemPath>
</logicalFolder>
<logicalFolder name="HeaderFiles"
displayName="Header Files"
@@ -99,7 +100,7 @@
<property key="default-bitfield-type" value="true"/>
<property key="default-char-type" value="true"/>
<property key="define-macros" value="LINK_FOR_BOOTLOADER"/>
<property key="disable-optimizations" value="true"/>
<property key="disable-optimizations" value="false"/>
<property key="extra-include-directories"
value="..\src;..\..\common_src\framework\usb\inc"/>
<property key="favor-optimization-for" value="-speed,+space"/>
@@ -107,14 +108,14 @@
<property key="garbage-collect-functions" value="true"/>
<property key="identifier-length" value="255"/>
<property key="local-generation" value="false"/>
<property key="operation-mode" value="free"/>
<property key="operation-mode" value="pro"/>
<property key="opt-xc8-compiler-strict_ansi" value="false"/>
<property key="optimization-assembler" value="true"/>
<property key="optimization-assembler-files" value="true"/>
<property key="optimization-assembler-files" value="false"/>
<property key="optimization-debug" value="false"/>
<property key="optimization-invariant-enable" value="false"/>
<property key="optimization-invariant-value" value="16"/>
<property key="optimization-level" value="-O0"/>
<property key="optimization-level" value="-Os"/>
<property key="optimization-speed" value="false"/>
<property key="optimization-stable-enable" value="false"/>
<property key="pack-struct" value="true"/>
@@ -129,7 +130,7 @@
</HI-TECH-COMP>
<HI-TECH-LINK>
<property key="additional-options-checksum" value=""/>
<property key="additional-options-code-offset" value="1400"/>
<property key="additional-options-code-offset" value="1C00"/>
<property key="additional-options-command-line" value=""/>
<property key="additional-options-errata" value=""/>
<property key="additional-options-extend-address" value="false"/>
@@ -140,7 +141,7 @@
<property key="calibrate-oscillator-value" value="0x3400"/>
<property key="clear-bss" value="true"/>
<property key="code-model-external" value="wordwrite"/>
<property key="code-model-rom" value="default,-0-13FF,-1406-1407,-1416-1417"/>
<property key="code-model-rom" value="default,-0-1BFF,-1C06-1C07,-1C16-1C17"/>
<property key="create-html-files" value="false"/>
<property key="data-model-ram" value=""/>
<property key="data-model-size-of-double" value="32"/>
@@ -251,6 +252,7 @@
<archiverTool>
</archiverTool>
<loading>
<loadableFile>../../bootloader/clubdance_v2_bootloader.X/dist/default/production/clubdance_v2_bootloader.X.production.hex</loadableFile>
<useAlternateLoadableFile>false</useAlternateLoadableFile>
<parseOnProdLoad>false</parseOnProdLoad>
<alternateLoadableFile></alternateLoadableFile>

View File

@@ -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)
{