Commit a433e31c authored by Federico Vaga's avatar Federico Vaga

bootloader: add Silicon Labs bootloader AN0042

This is just a copy of the Silicon Labs bootloader (AN0042).
Signed-off-by: 's avatarFederico Vaga <federico.vaga@gmail.com>
parent 0b4ee8ca
Build instructions.
============================================================
1. Make sure that #define BL_DEBUG and #define SIMULATE_SWDCLK_PIN_HI
in config.h are not active (comment them out).
2. Build release build of subproject bootld first.
Make sure optimize options "High" and "Size" are selected.
2 warnings from the linker is expected.
3. Convert the binary output from the bootld build to a h-file
for inclusion in the bootldld sub project:
Execute the following in the project "src" directory:
bin2h.exe ../iar/bootld/Release/Exe/bootld.bin ../src/bootld.h -v bootloader
4. Build release build of subproject bootldld.
Make sure optimize options "High" and "Size" are selected.
1 warning from the compiler is expected.
The binary from this build (bootldld.bin) is the actual bootloader.
\ No newline at end of file
[Version]
Signature="$WINDOWS NT$"
Class=Ports
ClassGUID={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%EMAS%
DriverVer=06/21/2006,6.1.7601.17514
[Manufacturer]
%EMAS%=DeviceList, NT, NTAMD64, NTIA64
;------------------------------------------------------------------------------
[DeviceList]
%CDCDEVICE%=DriverInstall,USB\VID_2544&PID_0003
[DeviceList.NT]
%CDCDEVICE%=DriverInstall,USB\VID_2544&PID_0003
[DeviceList.NTAMD64]
%CDCDEVICE%=DriverInstall,USB\VID_2544&PID_0003
[DeviceList.NTIA64]
%CDCDEVICE%=DriverInstall,USB\VID_2544&PID_0003
;------------------------------------------------------------------------------
[DriverInstall]
Include=mdmcpq.inf
CopyFiles=FakeModemCopyFileSection
AddReg=LowerFilterAddReg,SerialPropPageAddReg
[DriverInstall.Services]
Include=mdmcpq.inf
AddService = usbser, 0x00000002, LowerFilter_Service_Inst
[SerialPropPageAddReg]
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
;------------------------------------------------------------------------------
[Strings]
EMAS = "Energy Micro AS"
CDCDEVICE = "EFM32 USB CDC Serial port"
SERVICE = "USB CDC Serial Port Driver"
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x20000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20008000;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { section .intvec };
place in RAM_region { readonly, readwrite , block CSTACK };
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = (0x00000000+0x00004000-1);
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = (0x20000000+0x00008000-1);
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
keep { section .intvec };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK };
Copyright Statement and Disclaimer
Copyright (c) 2003 Jon Ripley. All rights reserved.
Redistribution and use in binary form, without modification is permitted
provided that the following conditions are met:
1. 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.
2. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Jon Ripley.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 REGENTS 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.
-------------------------------------------------------------------------------
Program : bin2h
Purpose : Convert binary data to a C Header file
Author : (C) Jon Ripley, 2002
Version : 0.01 (26th November 2002)
-------------------------------------------------------------------------------
bin2h vsn 0.01 (26 Nov 2002) (C) Jon Ripley
Usage: bin2h <input> <output> [options]
Options:-
[-i] <input> Input file name
[-o] <output> Output file name
-v <name> Name of C/C++ variable
-c <number> Number of columns of output
-u Output uppercase hex values
-h Display this help text
-l Display the licence for this program
-b Beep when command is completed
-q <command> Command to execute on exit
Contact : mailto:jon@jonripley.com
Web : http://jonripley.com/
autobaud.h,28
#define _AUTOBAUD_H34,1723
config.h,797
#define CONFIG_H35,1758
#define EP_DATA_OUT 48,2240
#define EP_DATA_IN 49,2318
#define EP_NOTIFY 50,2396
#define PIN_LOOP_INTERVAL 53,2556
#define BOOTLOADER_USART 56,2630
#define BOOTLOADER_USART_CLOCK 57,2672
#define BOOTLOADER_USART_LOCATION 58,2730
#define AUTOBAUD_TIMER 62,2930
#define AUTOBAUD_TIMER_CHANNEL 63,2972
#define AUTOBAUD_TIMER_LOCATION 64,3009
#define AUTOBAUD_TIMER_IRQn 65,3070
#define AUTOBAUD_TIMER_CLOCK 66,3117
#define AUTOBAUD_TIMER_INT_MASK 67,3175
#define AUTOBAUD_TIMER_ROUTE 68,3224
#define AUTOBAUD_TIMER_IRQHANDLER 69,3278
#define SWDCLK_PIN_IS_HI(71,3333
#define SWDCLK_PIN_IS_LO(72,3404
#define BOOTLOADER_SIZE 75,3524
#define MAX_SIZE_OF_FLASH 78,3638
#define MASSERASE_BLOCK_SIZE 81,3741
__STATIC_INLINE void CONFIG_UsartGpioSetup(84,3880
xmodem.h,453
#define _XMODEM_H34,1712
#define XMODEM_SOH 36,1733
#define XMODEM_EOT 37,1770
#define XMODEM_ACK 38,1807
#define XMODEM_NAK 39,1844
#define XMODEM_CAN 40,1882
#define XMODEM_NCG 41,1920
#define XMODEM_DATA_SIZE 43,1960
uint8_t padding;47,2020
uint8_t header;48,2091
uint8_t packetNumber;49,2110
uint8_t packetNumberC;50,2135
uint8_t data[data51,2161
uint8_t crcHigh;52,2196
uint8_t crcLow;53,2216
} XMODEM_packet;54,2235
xmodem.c,209
#define ALIGNMENT(43,1852
uint8_t rawPacket[rawPacket48,2023
uint8_t rawPacket[rawPacket50,2108
uint8_t rawPacket[rawPacket52,2222
static int VerifyPacketChecksum(63,2728
int XMODEM_download(100,3728
usbconfig.h,215
#define __USBCONFIG_H34,1758
#define USB_DEVICE42,1850
#define NUM_EP_USED 49,2268
#define NUM_APP_TIMERS 56,2689
#define USER_PUTCHAR 67,3260
#define DEBUG_USB_API70,3371
#define USB_USE_PRINTF73,3436
autobaud.c,296
#define SAMPLE_MAX 40,1827
static volatile int currentSample 42,1851
static volatile uint16_t samples[samples43,1891
void AUTOBAUD_TIMER_IRQHANDLER(50,2235
static uint32_t EstimateBaudRate(73,2929
void AUTOBAUD_start(103,3921
void AUTOBAUD_stop(138,5033
bool AUTOBAUD_completed(155,5567
retargetdebug.h,34
#define __RETARGETDEBUG_H34,1733
bootldio.h,28
#define _BOOTLDIO_H34,1730
retargetdebug.c,448
#define RETARGET_IRQ_NAME 44,1926
#define RETARGET_CLK 45,1975
#define RETARGET_IRQn 46,2019
#define RETARGET_UART 47,2062
#define RETARGET_TX 48,2097
#define RETARGET_RX 49,2134
#define RETARGET_LOCATION 50,2171
#define RETARGET_TXPORT 51,2225
#define RETARGET_TXPIN 52,2263
#define RETARGET_RXPORT 53,2294
#define RETARGET_RXPIN 54,2332
void RETARGET_SerialInit(59,2561
int RETARGET_ReadChar(94,3855
int RETARGET_WriteChar(105,4170
boot.h,24
#define _BOOT_H34,1700
bootldio.c,496
#define USB_BUF_SIZ 41,1845
static bool useUsb 43,1872
static uint32_t usbXferCnt;47,1945
static volatile bool usbXferDone;48,1984
static USB_Status_TypeDef usbXferStatus;49,2024
static int UsbDataXferred(56,2337
void BOOTLDIO_setMode(75,2913
bool BOOTLDIO_usbMode(87,3247
void BOOTLDIO_printHex(99,3563
uint8_t BOOTLDIO_rxByte(135,4272
bool BOOTLDIO_getPacket(168,5198
int BOOTLDIO_txByte(202,6023
void BOOTLDIO_printString(225,6721
void BOOTLDIO_usartInit(252,7364
loader.c,18
int main(44,2004
cdc.c,421
bool CDC_Configured 38,1739
EFM32_PACK_START(42,1927
uint32_t dwDTERate;45,1969
uint8_t bCharFormat;46,2046
uint8_t bParityType;47,2123
uint8_t bDataBits;48,2200
uint8_t dummy;49,2277
} __attribute__ ((packed)) cdcLineCoding_TypeDef;50,2358
EFM32_PACK_END(51,2409
cdcLineCoding_TypeDef __attribute__ ((aligned(4))) cdcLineCoding 59,2581
EFM32_PACK_END(63,2678
int CDC_SetupCmd(86,3468
flash.c,372
DMA_DESCRIPTOR_TypeDef descr;42,1949
DMA_DESCRIPTOR_TypeDef descr 44,2006
DMA_DESCRIPTOR_TypeDef descr 46,2094
uint32_t flashSize,51,2199
uint32_t flashSize, flashPageSize;51,2199
void FLASH_CalcPageSize(58,2445
void FLASH_init(80,3062
void FLASH_writeWord(109,4222
void FLASH_writeBlock(153,6057
void FLASH_eraseOneBlock(213,8629
void FLASH_massErase(248,9753
crc.h,23
#define _CRC_H34,1716
bootld.h,36
char bootloader[bootloader34,1667
boot.c,118
bool BOOT_checkFirmwareIsValid(44,2059
__asm void BOOT_jump(60,2498
void BOOT_jump(70,2671
void BOOT_boot(87,3096
crc.c,27
uint16_t CRC_calc(59,2640
descriptors.h,300
EFM32_ALIGN(34,1717
#define CONFIG_DESCSIZE 53,2298
EFM32_ALIGN(61,2745
static const void * const strings[strings165,8187
static uint8_t bufferingMultiplier[bufferingMultiplier175,8457
static const USBD_Callbacks_TypeDef callbacks 177,8532
static const USBD_Init_TypeDef initstruct 186,8748
main.c,779
#define BULK_EP_SIZE 49,1977
#define BOOTLOADER_VERSION_STRING 52,2109
#define USER_PAGE_START 54,2182
#define USER_PAGE_END 55,2218
#define LOCK_PAGE_START 56,2254
#define LOCK_PAGE_END 57,2290
#define DEBUG_LOCK_WORD 59,2328
__no_init uint32_t bootloaderCRC;81,3062
static const uint8_t crcString[crcString89,3315
static const uint8_t newLineString[newLineString90,3368
static const uint8_t readyString[readyString91,3416
static const uint8_t okString[okString92,3473
static const uint8_t failString[failString93,3527
static const uint8_t unknownString[unknownString94,3583
int main(99,3826
static void commandlineLoop(224,7184
static void verify(360,10951
static void Disconnect(371,11357
void RTC_IRQHandler(397,12004
static void StartRTC(406,12321
flash.h,24
#define FLASH_H34,1711
cdc.h,0
/**************************************************************************//**
* @file autobaud.c
* @brief Bootloader autobaud functions.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "autobaud.h"
#include "em_device.h"
#include "em_cmu.h"
#include "em_usb.h"
#include "xmodem.h"
#include "bootldio.h"
#define SAMPLE_MAX 6
static volatile int currentSample = 0;
static volatile uint16_t samples[ SAMPLE_MAX ];
/**************************************************************************//**
* @brief
* AUTOBAUD_TIMER interrupt handler. This function stores the current value of the
* timer in the samples array.
*****************************************************************************/
void AUTOBAUD_TIMER_IRQHANDLER( void )
{
uint32_t period;
/* Clear CC flag */
AUTOBAUD_TIMER->IFC = AUTOBAUD_TIMER_INT_MASK;
/* Store CC value in samples array */
if ( currentSample < SAMPLE_MAX )
{
period = AUTOBAUD_TIMER->CC[AUTOBAUD_TIMER_CHANNEL].CCV;
samples[ currentSample++ ] = period;
}
}
/**************************************************************************//**
* @brief
* This function uses the samples array to estimate the baudrate.
* Assumes that HF clock is 48MHz and that the TIMER is not prescaled.
*
* @return
* Measured baudrate.
*****************************************************************************/
static uint32_t EstimateBaudRate( void )
{
int i;
uint16_t timeDiff;
uint32_t periodSum = 0;
/*
* Calculate the periods. Discard the first (false) sample value.
* Accumulate period values.
*/
for (i = 2; i < currentSample; i++)
{
timeDiff = samples[ i ];
timeDiff -= samples[ i-1 ];
periodSum += timeDiff;
}
return ( CMU_ClockFreqGet( cmuClock_HFPER ) * 2 * (currentSample - 2) ) / periodSum;
}
/**************************************************************************//**
* @brief
* This function sets up AUTOBAUD_TIMER to estimate the needed CLKDIV needed for
* BOOTLOADER_USART. It does this by using compare channel
* AUTOBAUD_TIMER_CHANNEL and registering how many HF clock cycles occur
* between rising edges.
*
* This assumes that AUTOBAUD_TIMER AUTOBAUD_TIMER_CHANNEL overlaps with the
* BOOTLOADER_USART RX pin.
*****************************************************************************/
void AUTOBAUD_start( void )
{
USB_PUTS( "Starting autobaud.\r\n" );
/* Setup pins for USART */
CONFIG_UsartGpioSetup();
/* Set a high top value to avoid overflow */
AUTOBAUD_TIMER->TOP = UINT32_MAX;
/* Set up compare channel. Trigger on rising edge and capture value. */
AUTOBAUD_TIMER->CC[AUTOBAUD_TIMER_CHANNEL].CTRL =
TIMER_CC_CTRL_MODE_INPUTCAPTURE | TIMER_CC_CTRL_ICEDGE_RISING;
/* Set up AUTOBAUD_TIMER to location AUTOBAUD_TIMER_LOCATION */
AUTOBAUD_TIMER->ROUTE = AUTOBAUD_TIMER_LOCATION | AUTOBAUD_TIMER_ROUTE;
/* Clear all timer interrupt flags */
AUTOBAUD_TIMER->IFC = 0xFFFFFFFF;
/* Enable interrupt on channel capture */
AUTOBAUD_TIMER->IEN = AUTOBAUD_TIMER_INT_MASK;
/* Enable interrupts */
NVIC_EnableIRQ( AUTOBAUD_TIMER_IRQn );
/* Start the timer */
AUTOBAUD_TIMER->CMD = TIMER_CMD_START;
}
/**************************************************************************//**
* @brief
* This function stops AUTOBAUD_TIMER.
*****************************************************************************/
void AUTOBAUD_stop( void )
{
/* Disable interrupts in Cortex */
NVIC_DisableIRQ( AUTOBAUD_TIMER_IRQn );
/* Disable routing of TIMER. */
AUTOBAUD_TIMER->ROUTE = _TIMER_ROUTE_RESETVALUE;
}
/**************************************************************************//**
* @brief
* This function checks for autobaud completion.
*
* @return
* true on succesful autobaud completion.
* false if autobaud not yet completed.
*****************************************************************************/
bool AUTOBAUD_completed( void )
{
uint32_t baudRate, clkdiv;
if ( currentSample < SAMPLE_MAX )
return false;
AUTOBAUD_stop();
baudRate = EstimateBaudRate();
clkdiv = 4 * CMU_ClockFreqGet( cmuClock_HFPER );
clkdiv /= 16 * baudRate;
clkdiv -= 4;
clkdiv *= 64;
/* Initialize the USART */
BOOTLDIO_usartInit( clkdiv );
USB_PUTS( "Autobaud complete.\r\n" );
USB_PRINTF( "Measured baudrate is %d\r\n", baudRate );
USB_PRINTF( "New USART clkdiv is %d\r\n ", clkdiv );
return true;
}
/**************************************************************************//**
* @file autobaud.h
* @brief Autobaud estimation for BOOTLOADER_USART
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef _AUTOBAUD_H
#define _AUTOBAUD_H
#include <stdbool.h>
void AUTOBAUD_start(void);
void AUTOBAUD_stop( void );
bool AUTOBAUD_completed(void);
#endif
/**************************************************************************//**
* @file boot.c
* @brief Boot Loader
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdbool.h>
#include "em_device.h"
#include "boot.h"
#include "em_usb.h"
/**************************************************************************//**
* @brief Checks to see if the reset vector of the application is valid
* @return false if the firmware is not valid, true if it is.
*****************************************************************************/
bool BOOT_checkFirmwareIsValid(void)
{
uint32_t pc;
pc = *((uint32_t *) BOOTLOADER_SIZE + 1);
if (pc < MAX_SIZE_OF_FLASH)
return true;
return false;
}
/**************************************************************************//**
* @brief This function sets up the Cortex M-3 with a new SP and PC.
*****************************************************************************/
#if defined ( __CC_ARM )
__asm void BOOT_jump(uint32_t sp, uint32_t pc)
{
/* Set new MSP, PSP based on SP (r0)*/
msr msp, r0
msr psp, r0
/* Jump to PC (r1)*/
mov pc, r1
}
#else
void BOOT_jump(uint32_t sp, uint32_t pc)
{
(void) sp;
(void) pc;
/* Set new MSP, PSP based on SP (r0)*/
__asm("msr msp, r0");
__asm("msr psp, r0");
/* Jump to PC (r1)*/
__asm("mov pc, r1");
}
#endif
/**************************************************************************//**
* @brief Boots the application
*****************************************************************************/
void BOOT_boot(void)
{
uint32_t pc, sp;
/* Reset all used registers to their default value. */
/* Disable all interrupts. */
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
/* Disable USB */
USBD_Stop();
/* Reset memory system controller settings. */
MSC->READCTRL = _MSC_READCTRL_RESETVALUE;
MSC->WRITECTRL = _MSC_WRITECTRL_RESETVALUE;
MSC->LOCK = 0;
/* Reset GPIO settings. */
GPIO->ROUTE = _GPIO_ROUTE_RESETVALUE;
GPIO->P[4].MODEH = _GPIO_P_MODEH_RESETVALUE;
GPIO->P[4].DOUT = _GPIO_P_DOUT_RESETVALUE;
GPIO->P[5].MODEL = _GPIO_P_MODEL_RESETVALUE;
GPIO->P[5].DOUT = _GPIO_P_DOUT_RESETVALUE;
/* Reset DMA controller settings. */
DMA->CONFIG = _DMA_CONFIG_RESETVALUE;
DMA->CTRLBASE = _DMA_CTRLBASE_RESETVALUE;
DMA->CH[0].CTRL = _DMA_CH_CTRL_RESETVALUE;
DMA->CHENC = 0xFFFFFFFF;
/* Reset TIMER0 settings. */
TIMER0->CMD = TIMER_CMD_STOP;
TIMER0->TOP = _TIMER_TOP_RESETVALUE;
TIMER0->CTRL = _TIMER_CTRL_RESETVALUE;
TIMER0->CC[0].CTRL = _TIMER_CC_CTRL_RESETVALUE;
/* Reset TIMER1 settings. */
AUTOBAUD_TIMER->CMD = TIMER_CMD_STOP;
AUTOBAUD_TIMER->TOP = _TIMER_TOP_RESETVALUE;
AUTOBAUD_TIMER->IEN = _TIMER_IEN_RESETVALUE;
AUTOBAUD_TIMER->IFC = 0xFFFFFFFF;
AUTOBAUD_TIMER->CC[0].CTRL = _TIMER_CC_CTRL_RESETVALUE;
/* Reset RTC settings. */
RTC->IEN = _RTC_IEN_RESETVALUE;
RTC->COMP0 = _RTC_COMP0_RESETVALUE;
RTC->CTRL = _RTC_CTRL_RESETVALUE;
/* Reset UART settings. */
BOOTLOADER_USART->ROUTE = _USART_ROUTE_RESETVALUE;
BOOTLOADER_USART->CLKDIV = _USART_CLKDIV_RESETVALUE;
BOOTLOADER_USART->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS;
/* Wait for LF peripheral syncronization. */
while (RTC->SYNCBUSY & _RTC_SYNCBUSY_MASK);
while (CMU->SYNCBUSY & CMU_SYNCBUSY_LFACLKEN0);
/* Switch to default cpu clock. */
CMU->CMD = CMU_CMD_HFCLKSEL_HFRCO;
CMU->OSCENCMD = CMU_OSCENCMD_HFXODIS | CMU_OSCENCMD_LFRCODIS;
/* Reset clock registers used. */
CMU->HFCORECLKEN0 = _CMU_HFCORECLKEN0_RESETVALUE;
CMU->HFPERCLKDIV = _CMU_HFPERCLKDIV_RESETVALUE;
CMU->HFPERCLKEN0 = _CMU_HFPERCLKEN0_RESETVALUE;
CMU->LFCLKSEL = _CMU_LFCLKSEL_RESETVALUE;
CMU->LFACLKEN0 = _CMU_LFACLKEN0_RESETVALUE;
/* Set new vector table pointer */
SCB->VTOR = (uint32_t)BOOTLOADER_SIZE;
/* Read new SP and PC from vector table */
sp = *((uint32_t *)BOOTLOADER_SIZE );
pc = *((uint32_t *)BOOTLOADER_SIZE + 1);
BOOT_jump(sp, pc);
}
/**************************************************************************//**
* @file boot.h
* @brief Bootloader boot functions
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef _BOOT_H
#define _BOOT_H
void BOOT_boot(void);
bool BOOT_checkFirmwareIsValid(void);
void BOOT_jump(uint32_t sp, uint32_t pc);
#endif
This diff is collapsed.
/**************************************************************************//**
* @file bootldio.c
* @brief IO code, USART or USB, for the EFM32 bootloader
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdbool.h>
#include "em_device.h"
#include "em_usb.h"
#include "xmodem.h"
#include "bootldio.h"
#include "config.h"
#define USB_BUF_SIZ 256
static bool useUsb = false;
STATIC_UBUF( usbBuffer, USB_BUF_SIZ );
static uint32_t usbXferCnt;
static volatile bool usbXferDone;
static USB_Status_TypeDef usbXferStatus;
/**************************************************************************//**
* @brief
* Callback function called whenever a packet with data has been
* transferred on USB.
*****************************************************************************/
static int UsbDataXferred( USB_Status_TypeDef status,
uint32_t xferred, uint32_t remaining )
{
(void)remaining; /* Unused parameter */
usbXferStatus = status;
usbXferCnt = xferred;
usbXferDone = true;
return USB_STATUS_OK;
}
/***************************************************************************//**
* @brief
* Set I/O in correct mode.
*
* @param[in] usbMode
* True if USB shall be used, USART otherwise.
******************************************************************************/
void BOOTLDIO_setMode( bool usb )
{
useUsb = usb;
}
/***************************************************************************//**
* @brief
* Get current I/O mode.
*
* @return
* True if USB is current I/O mode, false if USART.
******************************************************************************/
bool BOOTLDIO_usbMode( void )
{
return useUsb;
}
/***************************************************************************//**
* @brief
* Prints an int in hex.
*
* @param integer
* The integer to be printed.
******************************************************************************/
void BOOTLDIO_printHex( uint32_t integer )
{
uint8_t c;
int i, j, digit;
for ( i = 7, j = 0; i >= 0; i--, j++ )
{
digit = (integer >> (i * 4)) & 0xf;
if (digit < 10)
{
c = digit + 0x30;
}
else
{
c = digit + 0x37;
}
if ( useUsb )
{
usbBuffer[ j ] = c;
}
else
{
BOOTLDIO_txByte(c);
}
}
if ( useUsb )
{
usbBuffer[ j ] = '\0';
BOOTLDIO_printString( usbBuffer );
}
}
/**************************************************************************//**
* @brief Get single byte from USART or USB
*****************************************************************************/
uint8_t BOOTLDIO_rxByte( void )
{
uint8_t retVal;
uint32_t timer = 2000000;
if ( useUsb )
{
usbXferDone = false;
USBD_Read( EP_DATA_OUT, usbBuffer, USB_BUF_SIZ, UsbDataXferred );
while ( !usbXferDone ){}
retVal = usbXferStatus == USB_STATUS_OK ? usbBuffer[0] : 0;
}
else
{
while (!(BOOTLOADER_USART->STATUS & USART_STATUS_RXDATAV) && --timer ){}
retVal = timer > 0 ? (uint8_t)BOOTLOADER_USART->RXDATA : 0;
}
return retVal;
}
/**************************************************************************//**
* @brief Get an XMODEM packet from USB with optional timeout.
*
* @param[in] p
* Pointer to XMODEM storage space.
*
* @param[in] timeout
* Transmission timeout in milliseconds, no timeout if zero.
*
* @return
* True if a transmission took place.
*****************************************************************************/
bool BOOTLDIO_getPacket( XMODEM_packet *p, int timeout )
{
usbXferDone = false;
USBD_Read( EP_DATA_OUT, usbBuffer, USB_BUF_SIZ, UsbDataXferred );
if ( timeout )
{
while ( !usbXferDone && --timeout )
{
USBTIMER_DelayMs( 1 );
}
if ( timeout <= 0 )
{
USBD_AbortTransfer( EP_DATA_OUT );
return false;
}
}
else
{
while ( !usbXferDone ){}
}
/*
* Copy data at p+1 so that data payload becomes even aligned.
* See definition of XMODEM_packet.
*/
memcpy( (uint8_t*)p + 1, usbBuffer, usbXferCnt );
return true;
}
/**************************************************************************//**
* @brief Transmit single byte to USART or USB
*****************************************************************************/
int BOOTLDIO_txByte( uint8_t data )
{
if ( useUsb )
{
usbBuffer[ 0 ] = data;
usbXferDone = false;
USBD_Write( EP_DATA_IN, usbBuffer, 1, UsbDataXferred );
while ( !usbXferDone ){}
return usbXferStatus == USB_STATUS_OK ? (int)data : 0;
}
else
{
/* Check that transmit buffer is empty */
while (!(BOOTLOADER_USART->STATUS & USART_STATUS_TXBL)){}
BOOTLOADER_USART->TXDATA = (uint32_t) data;
}
return (int)data;
}
/**************************************************************************//**
* @brief Transmit null-terminated string to USART or USB
*****************************************************************************/
void BOOTLDIO_printString( const uint8_t *string )
{
int len;
if ( useUsb )
{
len = strlen( (char*)string );
memcpy( usbBuffer, string, len );
usbXferDone = false;
USBD_Write( EP_DATA_IN, usbBuffer, len, UsbDataXferred );
while ( !usbXferDone ){}
}
else
{
while (*string != 0)
{
BOOTLDIO_txByte(*string++);
}
}
}
/**************************************************************************//**
* @brief Intializes BOOTLOADER_USART
*
* @param clkdiv
* The clock divisor to use.
*****************************************************************************/
void BOOTLDIO_usartInit( uint32_t clkdiv )
{
/* Configure BOOTLOADER_USART */
/* USART default to 1 stop bit, no parity, 8 data bits, so not
* explicitly set */
/* Set the clock division */
BOOTLOADER_USART->CLKDIV = clkdiv;
/* Enable RX and TX pins and set location 0 */
BOOTLOADER_USART->ROUTE = BOOTLOADER_USART_LOCATION |
USART_ROUTE_RXPEN | USART_ROUTE_TXPEN;
/* Clear RX/TX buffers */
BOOTLOADER_USART->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
/* Enable RX/TX */
BOOTLOADER_USART->CMD = USART_CMD_RXEN | USART_CMD_TXEN;
}
/**************************************************************************//**
* @file bootldio.h
* @brief IO code, USART or USB, for the EFM32 bootloader
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef _BOOTLDIO_H
#define _BOOTLDIO_H
void BOOTLDIO_printHex( uint32_t integer );
int BOOTLDIO_txByte( uint8_t data );
uint8_t BOOTLDIO_rxByte( void );
void BOOTLDIO_printString( const uint8_t *string );
void BOOTLDIO_usartInit( uint32_t clkdiv );
void BOOTLDIO_setMode( bool usb );
bool BOOTLDIO_usbMode( void );
bool BOOTLDIO_getPacket( XMODEM_packet *p, int timeout );
#endif
/**************************************************************************//**
* @file cdc.c
* @brief CDC source file
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_device.h"
#include "em_usb.h"
#include "cdc.h"
bool CDC_Configured = false;
/* The serial port LINE CODING data structure, used to carry information */
/* about serial port baudrate, parity etc. between host and device. */
EFM32_PACK_START( 1 )
typedef struct
{
uint32_t dwDTERate; /** Baudrate */
uint8_t bCharFormat; /** Stop bits, 0=1 1=1.5 2=2 */
uint8_t bParityType; /** 0=None 1=Odd 2=Even 3=Mark 4=Space */
uint8_t bDataBits; /** 5, 6, 7, 8 or 16 */
uint8_t dummy; /** To ensure size is a multiple of 4 bytes.*/
} __attribute__ ((packed)) cdcLineCoding_TypeDef;
EFM32_PACK_END()
/*
* The LineCoding variable must be 4-byte aligned as it is used as USB
* transmit and receive buffer
*/
EFM32_ALIGN(4)
EFM32_PACK_START( 1 )
cdcLineCoding_TypeDef __attribute__ ((aligned(4))) cdcLineCoding =
{
115200, 0, 0, 8, 0
};
EFM32_PACK_END()
/**************************************************************************//**
* Called each time the USB device state is changed.
* Starts CDC operation when device has been configured by USB host.
*****************************************************************************/
void CDC_StateChange( USBD_State_TypeDef oldState, USBD_State_TypeDef newState )
{
if ( newState == USBD_STATE_CONFIGURED )
{
CDC_Configured = true;
}
else
{
CDC_Configured = false;
}
}
/**************************************************************************//**
* Called each time the USB host sends a SETUP command.
* Implements CDC class specific commands.
*****************************************************************************/
int CDC_SetupCmd( const USB_Setup_TypeDef *setup )
{
int retVal = USB_STATUS_REQ_UNHANDLED;
if ( ( setup->Type == USB_SETUP_TYPE_CLASS ) &&
( setup->Recipient == USB_SETUP_RECIPIENT_INTERFACE ) )
{
switch ( setup->bRequest )
{
case USB_CDC_GETLINECODING:
/********************/
if ( ( setup->wValue == 0 ) &&
( setup->wIndex == 0 ) && /* Interface no. */
( setup->wLength == 7 ) && /* Length of cdcLineCoding */
( setup->Direction == USB_SETUP_DIR_IN ) )
{
/* Send current settings to USB host. */
USBD_Write( 0, (void*)&cdcLineCoding, 7, NULL );
retVal = USB_STATUS_OK;
}
break;
case USB_CDC_SETLINECODING:
/********************/
if ( ( setup->wValue == 0 ) &&
( setup->wIndex == 0 ) && /* Interface no. */
( setup->wLength == 7 ) && /* Length of cdcLineCoding */
( setup->Direction != USB_SETUP_DIR_IN ) )
{
/* Get new settings from USB host. */
USBD_Read( 0, (void*)&cdcLineCoding, 7, NULL );
retVal = USB_STATUS_OK;
}
break;
case USB_CDC_SETCTRLLINESTATE:
/********************/
if ( ( setup->wIndex == 0 ) && /* Interface no. */
( setup->wLength == 0 ) ) /* No data */
{
/* Do nothing ( Non compliant behaviour !! ) */
retVal = USB_STATUS_OK;
}
break;
}
}
return retVal;
}
/**************************************************************************//**
* @file cdc.h
* @brief CDC header file
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
extern bool CDC_Configured;
int CDC_SetupCmd( const USB_Setup_TypeDef *setup );
void CDC_StateChange( USBD_State_TypeDef oldState, USBD_State_TypeDef newState );
/**************************************************************************//**
* @file config.h
* @brief Bootloader Configuration.
* This file defines how the bootloader is set up.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef CONFIG_H
#define CONFIG_H
/************ DEBUG #define's ******************************************/
/** This #define pulls in printf etc. Undef when making release build. */
//#define BL_DEBUG
/** This #define simulates that the SWDCLK pin is pulled high.
** Undef when making release build. */
//#define SIMULATE_SWDCLK_PIN_HI
/************ DEBUG #define's end **************************************/
/** Define USB endpoint addresses */
#define EP_DATA_OUT 0x01 /* Endpoint for USB data reception. */
#define EP_DATA_IN 0x81 /* Endpoint for USB data transmission. */
#define EP_NOTIFY 0x82 /* The notification endpoint (not used). */
/** Number of milliseconds between each consecutive polling of the SWD pins */
#define PIN_LOOP_INTERVAL 250
/** USART used for communication. */
#define BOOTLOADER_USART USART0
#define BOOTLOADER_USART_CLOCK CMU_HFPERCLKEN0_USART0
#define BOOTLOADER_USART_LOCATION USART_ROUTE_LOCATION_LOC0
/** TIMER1 is used for autobaud. The channel and location must match the
** RX line of BOOTLOADER_USART for this to work properly. */
#define AUTOBAUD_TIMER TIMER1
#define AUTOBAUD_TIMER_CHANNEL 1
#define AUTOBAUD_TIMER_LOCATION TIMER_ROUTE_LOCATION_LOC1
#define AUTOBAUD_TIMER_IRQn TIMER1_IRQn
#define AUTOBAUD_TIMER_CLOCK CMU_HFPERCLKEN0_TIMER1
#define AUTOBAUD_TIMER_INT_MASK TIMER_IFC_CC1
#define AUTOBAUD_TIMER_ROUTE TIMER_ROUTE_CC1PEN
#define AUTOBAUD_TIMER_IRQHANDLER TIMER1_IRQHandler
#define SWDCLK_PIN_IS_HI() ( ( GPIO->P[5].DIN & 0x1 ) == 0x1 )
#define SWDCLK_PIN_IS_LO() ( ( GPIO->P[5].DIN & 0x1 ) == 0x0 )
/** The size of the bootloader flash image */
#define BOOTLOADER_SIZE (16*1024) /* 16 KB */
/** The maximum flash size of any EFM32 part */
#define MAX_SIZE_OF_FLASH (1024*1024) /* 1 MB */
/** The size of a mass erase block */
#define MASSERASE_BLOCK_SIZE (512*1024) /* 512 KB */
/** This function sets up GPIO for the USART used in the bootloader. */
__STATIC_INLINE void CONFIG_UsartGpioSetup(void)
{
/* Use USART0 location 0
* 0 : TX - Pin E10, RX - Pin E11
* Configure GPIO pins LOCATION 1 as push pull (TX)
* and input (RX)
* To avoid false start, configure output as high
*/
GPIO->P[4].DOUT = (1 << 10);
GPIO->P[4].MODEH = GPIO_P_MODEH_MODE10_PUSHPULL | GPIO_P_MODEH_MODE11_INPUT;
}
#endif
/**************************************************************************//**
* @file crc.c
* @brief CRC calculation routines
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "crc.h"
#include "em_device.h"
/**************************************************************************//**
* @brief
* This function calculates the CRC-16-CCIT checksum of a memory range.
*
* @note
* This implementation uses an initial value of 0, while some implementations
* of CRC-16-CCIT uses an initial value of 0xFFFF. If you wish to
* precalculate the CRC before uploading the binary to the bootloader you
* can use this function. However, keep in mind that the 'v' and 'c' commands
* computes the crc of the entire flash, so any bytes not used by your
* application will have the value 0xFF.
*
* @param start
* Pointer to the start of the memory block
*
* @param end
* Pointer to the end of the block. This byte is not included in the computed
* CRC.
*
* @return
* The computed CRC value.
*****************************************************************************/
uint16_t CRC_calc(uint8_t *start, uint8_t *end)
{
uint16_t crc = 0x0;
uint8_t *data;
for (data = start; data < end; data++)
{
crc = (crc >> 8) | (crc << 8);
crc ^= *data;
crc ^= (crc & 0xff) >> 4;
crc ^= crc << 12;
crc ^= (crc & 0xff) << 5;
}
return crc;
}
/**************************************************************************//**
* @file crc.h
* @brief CRC16 routines for XMODEM and verification.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef _CRC_H
#define _CRC_H
#include <stdint.h>
uint16_t CRC_calc(uint8_t *start, uint8_t *end);
#endif
/***************************************************************************//**
* @file descriptors.h
* @brief USB descriptors for HID keyboard example project.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
EFM32_ALIGN(4)
static const USB_DeviceDescriptor_TypeDef deviceDesc __attribute__ ((aligned(4)))=
{
.bLength = USB_DEVICE_DESCSIZE,
.bDescriptorType = USB_DEVICE_DESCRIPTOR,
.bcdUSB = 0x0200,
.bDeviceClass = USB_CLASS_CDC,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = 0x2544,
.idProduct = 0x0003,
.bcdDevice = 0x0000,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 0,
.bNumConfigurations = 1
};
#define CONFIG_DESCSIZE ( USB_CONFIG_DESCSIZE + \
(USB_INTERFACE_DESCSIZE * 2) + \
(USB_ENDPOINT_DESCSIZE * NUM_EP_USED) + \
USB_CDC_HEADER_FND_DESCSIZE + \
USB_CDC_CALLMNG_FND_DESCSIZE + \
USB_CDC_ACM_FND_DESCSIZE + \
5 )
EFM32_ALIGN(4)
static const uint8_t configDesc[] __attribute__ ((aligned(4)))=
{
/*** Configuration descriptor ***/
USB_CONFIG_DESCSIZE, /* bLength */
USB_CONFIG_DESCRIPTOR, /* bDescriptorType */
CONFIG_DESCSIZE, /* wTotalLength (LSB) */
USB_CONFIG_DESCSIZE>>8, /* wTotalLength (MSB) */
2, /* bNumInterfaces */
1, /* bConfigurationValue */
0, /* iConfiguration */
CONFIG_DESC_BM_RESERVED_D7 | /* bmAttrib: Self powered */
CONFIG_DESC_BM_SELFPOWERED,
CONFIG_DESC_MAXPOWER_mA( 100 ),/* bMaxPower: 100 mA */
/*** Communication Class Interface descriptor (interface no. 0) ***/
USB_INTERFACE_DESCSIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR,/* bDescriptorType */
0, /* bInterfaceNumber */
0, /* bAlternateSetting */
1, /* bNumEndpoints */
USB_CLASS_CDC, /* bInterfaceClass */
USB_CLASS_CDC_ACM, /* bInterfaceSubClass */
0, /* bInterfaceProtocol */
0, /* iInterface */
/*** CDC Header Functional descriptor ***/
USB_CDC_HEADER_FND_DESCSIZE, /* bFunctionLength */
USB_CS_INTERFACE_DESCRIPTOR, /* bDescriptorType */
USB_CLASS_CDC_HFN, /* bDescriptorSubtype */
0x20, /* bcdCDC spec.no LSB */
0x01, /* bcdCDC spec.no MSB */
/*** CDC Call Management Functional descriptor ***/
USB_CDC_CALLMNG_FND_DESCSIZE, /* bFunctionLength */
USB_CS_INTERFACE_DESCRIPTOR, /* bDescriptorType */
USB_CLASS_CDC_CMNGFN, /* bDescriptorSubtype */
0, /* bmCapabilities */
1, /* bDataInterface */
/*** CDC Abstract Control Management Functional descriptor ***/
USB_CDC_ACM_FND_DESCSIZE, /* bFunctionLength */
USB_CS_INTERFACE_DESCRIPTOR, /* bDescriptorType */
USB_CLASS_CDC_ACMFN, /* bDescriptorSubtype */
0x02, /* bmCapabilities */
/* The capabilities that this configuration supports: */
/* D7..D4: RESERVED (Reset to zero) */
/* D3: 1 - Device supports the notification Network_Connection. */
/* D2: 1 - Device supports the request Send_Break */
/* D1: 1 - Device supports the request combination of Set_Line_Coding, */
/* Set_Control_Line_State, Get_Line_Coding, and the */
/* notification Serial_State. */
/* D0: 1 - Device supports the request combination of Set_Comm_Feature, */
/* Clear_Comm_Feature, and Get_Comm_Feature. */
/*** CDC Union Functional descriptor ***/
5, /* bFunctionLength */
USB_CS_INTERFACE_DESCRIPTOR, /* bDescriptorType */
USB_CLASS_CDC_UNIONFN, /* bDescriptorSubtype */
0, /* bControlInterface, itf. no. 0 */
1, /* bSubordinateInterface0, itf. no. 1 */
/*** CDC Notification endpoint descriptor ***/
USB_ENDPOINT_DESCSIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR,/* bDescriptorType */
EP_NOTIFY, /* bEndpointAddress (IN) */
USB_EPTYPE_INTR, /* bmAttributes */
BULK_EP_SIZE, /* wMaxPacketSize (LSB) */
0, /* wMaxPacketSize (MSB) */
0xFF, /* bInterval */
/*** Data Class Interface descriptor (interface no. 1) ***/
USB_INTERFACE_DESCSIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR,/* bDescriptorType */
1, /* bInterfaceNumber */
0, /* bAlternateSetting */
2, /* bNumEndpoints */
USB_CLASS_CDC_DATA, /* bInterfaceClass */
0, /* bInterfaceSubClass */
0, /* bInterfaceProtocol */
0, /* iInterface */
/*** CDC Data interface endpoint descriptors ***/
USB_ENDPOINT_DESCSIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR,/* bDescriptorType */
EP_DATA_IN, /* bEndpointAddress (IN) */
USB_EPTYPE_BULK, /* bmAttributes */
BULK_EP_SIZE, /* wMaxPacketSize (LSB) */
0, /* wMaxPacketSize (MSB) */
0, /* bInterval */
USB_ENDPOINT_DESCSIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR,/* bDescriptorType */
EP_DATA_OUT, /* bEndpointAddress (OUT)*/
USB_EPTYPE_BULK, /* bmAttributes */
BULK_EP_SIZE, /* wMaxPacketSize (LSB) */
0, /* wMaxPacketSize (MSB) */
0 /* bInterval */
};
STATIC_CONST_STRING_DESC_LANGID( langID, 0x04, 0x09 );
STATIC_CONST_STRING_DESC( iManufacturer, L"Energy Micro AS" );
STATIC_CONST_STRING_DESC( iProduct , L"EFM32 USB CDC serial port device" );
static const void * const strings[] =
{
&langID,
&iManufacturer,
&iProduct,
};
/* Endpoint buffer sizes */
/* 1 = single buffer, 2 = double buffering, 3 = triple buffering ... */
/* Use double buffering on the BULK endpoints. */
static uint8_t bufferingMultiplier[ NUM_EP_USED + 1 ] = { 1, 1, 2, 2 };
static const USBD_Callbacks_TypeDef callbacks =
{
.usbReset = NULL,
.usbStateChange = CDC_StateChange,
.setupCmd = CDC_SetupCmd,
.isSelfPowered = NULL,
.sofInt = NULL
};
static const USBD_Init_TypeDef initstruct =
{
.deviceDescriptor = &deviceDesc,
.configDescriptor = configDesc,
.stringDescriptors = strings,
.numberOfStrings = sizeof(strings)/sizeof(void*),
.callbacks = &callbacks,
.bufferingMultiplier = bufferingMultiplier
};
This diff is collapsed.
/**************************************************************************//**
* @file flash.h
* @brief Bootloader flash writing functions.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef FLASH_H
#define FLASH_H
/*
* Flash programming hardware interface
*
*/
/* Helper functions */
void FLASH_writeWord(uint32_t address, uint32_t data);
void FLASH_writeBlock(void *block_start,
uint32_t offset_into_block,
uint32_t count,
uint8_t const *buffer);
void FLASH_eraseOneBlock(uint32_t blockStart);
void FLASH_massErase( uint32_t eraseCmd );
void FLASH_init(void);
void FLASH_CalcPageSize(void);
extern uint32_t flashSize;
extern uint32_t flashPageSize;
#endif
/**************************************************************************//**
* @file loader.c
* @brief USB/USART0 bootloader 1. level loader.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <string.h>
#include <stdbool.h>
#include "em_device.h"
#include "boot.h"
const
#include "bootld.h"
/**************************************************************************//**
* The main entry point.
*****************************************************************************/
int main(void)
{
__set_MSP( ( 0x20000000 + sizeof( bootloader ) + 0x400 ) & 0xFFFFFFF0 );
/* Load the entire bootloader into SRAM. */
memcpy( (void*)0x20000000, bootloader, sizeof( bootloader ) );
/* Start executing the bootloader. */
BOOT_jump( *(uint32_t*)0x20000000, *(uint32_t*)0x20000004 );
}
This diff is collapsed.
/***************************************************************************//**
* @file retargetdebug.c
* @brief Provide stdio retargeting to UART or USB CDC for debugging purposes.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdio.h>
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "config.h"
#include "retargetdebug.h"
#if defined( BL_DEBUG )
#define RETARGET_IRQ_NAME USART0_RX_IRQHandler
#define RETARGET_CLK cmuClock_USART0
#define RETARGET_IRQn USART0_RX_IRQn
#define RETARGET_UART USART0
#define RETARGET_TX USART_Tx
#define RETARGET_RX USART_Rx
#define RETARGET_LOCATION USART_ROUTE_LOCATION_LOC0
#define RETARGET_TXPORT gpioPortE
#define RETARGET_TXPIN 10
#define RETARGET_RXPORT gpioPortE
#define RETARGET_RXPIN 11
/**************************************************************************//**
* @brief Intializes UART/LEUART
*****************************************************************************/
void RETARGET_SerialInit(void)
{
/* Configure GPIO pins */
CMU_ClockEnable(cmuClock_GPIO, true);
/* To avoid false start, configure output as high */
GPIO_PinModeSet(RETARGET_TXPORT, RETARGET_TXPIN, gpioModePushPull, 1);
//GPIO_PinModeSet(RETARGET_RXPORT, RETARGET_RXPIN, gpioModeInput, 0);
USART_TypeDef *usart = RETARGET_UART;
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
/* Enable peripheral clocks */
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(RETARGET_CLK, true);
/* Configure USART for basic async operation */
init.enable = usartDisable;
USART_InitAsync(usart, &init);
/* Enable pins at correct location */
usart->ROUTE = /*USART_ROUTE_RXPEN |*/ USART_ROUTE_TXPEN | RETARGET_LOCATION;
/* Finally enable it */
USART_Enable(usart, usartEnable);
#if !defined( __CROSSWORKS_ARM ) && defined( __GNUC__ )
setvbuf( stdout, NULL, _IONBF, 0 ); /*Set unbuffered mode for stdout (newlib)*/
#endif
}
/**************************************************************************//**
* @brief Receive a byte from USART/LEUART and put into global buffer
* @return -1 on failure, or positive character integer on sucesss
*****************************************************************************/
int RETARGET_ReadChar(void)
{
int c = -1;
return c;
}
/**************************************************************************//**
* @brief Transmit single byte to USART/LEUART
* @param data Character to transmit
*****************************************************************************/
int RETARGET_WriteChar(char c)
{
RETARGET_TX(RETARGET_UART, c);
return c;
}
#endif
/**************************************************************************//**
* @file retargetdebug.h
* @brief I/O retarget prototypes and definitions
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __RETARGETDEBUG_H
#define __RETARGETDEBUG_H
#if defined( BL_DEBUG )
void RETARGET_SerialInit(void);
int RETARGET_ReadChar(void);
int RETARGET_WriteChar(char c);
#endif
#endif
/***************************************************************************//**
* @file usbconfig.h
* @brief USB protocol stack library, application supplied configuration options.
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __USBCONFIG_H
#define __USBCONFIG_H
#include "config.h"
#ifdef __cplusplus
extern "C" {
#endif
#define USB_DEVICE
/****************************************************************************
** **
** Specify number of endpoints used (in addition to EP0). **
** **
*****************************************************************************/
#define NUM_EP_USED 3
/****************************************************************************
** **
** Specify number of application timers you need. **
** **
*****************************************************************************/
#define NUM_APP_TIMERS 0
/****************************************************************************
** **
** Configure serial port debug output. **
** **
*****************************************************************************/
#if defined( BL_DEBUG )
/* Define a function for transmitting a single char on the serial port. */
extern int RETARGET_WriteChar(char c);
#define USER_PUTCHAR RETARGET_WriteChar
/* Debug USB API functions (illegal input parameters etc.) */
#define DEBUG_USB_API
/* Include the printf function. */
#define USB_USE_PRINTF
#endif
#ifdef __cplusplus
}
#endif
#endif /* __USBCONFIG_H */
/**************************************************************************//**
* @file xmodem.c
* @brief XMODEM protocol
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_device.h"
#include "em_common.h"
#include "xmodem.h"
#include "bootldio.h"
#include "flash.h"
#include "crc.h"
#include "config.h"
#include "em_usb.h"
#define ALIGNMENT(base,align) (((base)+((align)-1))&(~((align)-1)))
/* Packet storage. Double buffered version. */
#if defined (__ICCARM__)
#pragma data_alignment=4
uint8_t rawPacket[2][ALIGNMENT(sizeof(XMODEM_packet),4)];
#elif defined (__CC_ARM)
uint8_t rawPacket[2][ALIGNMENT(sizeof(XMODEM_packet),4)] __attribute__ ((aligned(4)));
#elif defined (__GNUC__)
uint8_t rawPacket[2][ALIGNMENT(sizeof(XMODEM_packet),4)] __attribute__ ((aligned(4)));
#else
#error Undefined toolkit, need to define alignment
#endif
/**************************************************************************//**
* @brief Verifies checksum, packet numbering and
* @param pkt The packet to verify
* @param sequenceNumber The current sequence number.
* @returns -1 on packet error, 0 otherwise
*****************************************************************************/
static int VerifyPacketChecksum(XMODEM_packet *pkt, int sequenceNumber)
{
uint16_t packetCRC;
uint16_t calculatedCRC;
/* Check the packet number integrity */
if (pkt->packetNumber + pkt->packetNumberC != 255)
{
return -1;
}
/* Check that the packet number matches the excpected number */
if (pkt->packetNumber != (sequenceNumber % 256))
{
return -1;
}
calculatedCRC = CRC_calc((uint8_t *) pkt->data, (uint8_t *) &(pkt->crcHigh));
packetCRC = pkt->crcHigh << 8 | pkt->crcLow;
/* Check the CRC value */
if (calculatedCRC != packetCRC)
{
return -1;
}
return 0;
}
/**************************************************************************//**
* @brief Starts a XMODEM download.
*
* @param baseAddress
* The address to start writing from
*
* @param endAddress
* The last address. This is only used for clearing the flash
*****************************************************************************/
int XMODEM_download(uint32_t baseAddress, uint32_t endAddress)
{
XMODEM_packet *pkt;
uint32_t i;
uint32_t addr;
uint32_t sequenceNumber = 1;
/* Erase flash */
addr = baseAddress;
/* Do first 512K block. */
/* Check if it is possible to mass erase first block. */
if ( ( addr == 0 ) && ( endAddress >= MASSERASE_BLOCK_SIZE ) )
{
FLASH_massErase( MSC_WRITECMD_ERASEMAIN0 );
addr += MASSERASE_BLOCK_SIZE;
}
else
{
while ( addr < MASSERASE_BLOCK_SIZE )
{
FLASH_eraseOneBlock( addr );
addr += flashPageSize;
}
}
/* Do second 512K block. */
if ( flashSize > MASSERASE_BLOCK_SIZE )
{
/* Mass erase possible ? */
if ( ( addr == MASSERASE_BLOCK_SIZE ) &&
( endAddress >= 2 * MASSERASE_BLOCK_SIZE ) )
{
FLASH_massErase( MSC_WRITECMD_ERASEMAIN1 );
}
else
{
while ( addr < 2 * MASSERASE_BLOCK_SIZE )
{
FLASH_eraseOneBlock( addr );
addr += flashPageSize;
}
}
}
/*
* Send one start transmission packet. Wait for a response. If there is no
* response, we resend the start transmission packet.
* Note: There is a fairly long delay between retransmissions (~6 s).
*/
pkt = (XMODEM_packet*)rawPacket[ sequenceNumber ];
while (1)
{
BOOTLDIO_txByte(XMODEM_NCG);
if ( BOOTLDIO_usbMode() )
{
if ( BOOTLDIO_getPacket( pkt, 6000 ) )
{
goto usb_loop_entry;
}
}
else
{
for (i = 0; i < 20000000; i++)
{
if (BOOTLOADER_USART->STATUS & USART_STATUS_RXDATAV)
{
goto xmodem_transfer;
}
}
}
}
xmodem_transfer:
while (1)
{
/* Swap buffer for packet buffer */
pkt = (XMODEM_packet*)rawPacket[ sequenceNumber & 1 ];
if ( BOOTLDIO_usbMode() )
{
BOOTLDIO_getPacket( pkt, 0 );
}
else
{
/* Fetch the first byte of the packet explicitly, as it defines the
* rest of the packet */
pkt->header = BOOTLDIO_rxByte();
}
usb_loop_entry:
/* Check for end of transfer */
if (pkt->header == XMODEM_EOT)
{
/* Acknowledge End of transfer */
BOOTLDIO_txByte(XMODEM_ACK);
break;
}
/* If the header is not a start of header (SOH), then cancel
* the transfer. */
if (pkt->header != XMODEM_SOH)
{
return -1;
}
if ( !BOOTLDIO_usbMode() )
{
/* Fill the remaining bytes packet */
/* Byte 0 is padding, byte 1 is header */
for ( i = 2; i < sizeof(XMODEM_packet); i++ )
{
*(((uint8_t *) pkt) + i) = BOOTLDIO_rxByte();
}
}
if ( VerifyPacketChecksum( pkt, sequenceNumber ) != 0 )
{
/* On a malformed packet, we send a NAK, and start over */
BOOTLDIO_txByte(XMODEM_NAK);
continue;
}
/* Write data to flash */
FLASH_writeBlock((void *) baseAddress,
(sequenceNumber - 1) * XMODEM_DATA_SIZE,
XMODEM_DATA_SIZE,
(uint8_t const *) pkt->data);
sequenceNumber++;
/* Send ACK */
BOOTLDIO_txByte(XMODEM_ACK);
}
/* Wait for previous DMA transfer completion */
while (DMA->CHENS & DMA_CHENS_CH0ENS){}
/* Wait for last flash programming operation from previous transfer */
while ((MSC->STATUS & MSC_STATUS_BUSY)){}
return 0;
}
/**************************************************************************//**
* @file xmodem.h
* @brief XMODEM prototypes and definitions
* @author Silicon Labs
* @version 1.10
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef _XMODEM_H
#define _XMODEM_H
#define XMODEM_SOH 1
#define XMODEM_EOT 4
#define XMODEM_ACK 6
#define XMODEM_NAK 21
#define XMODEM_CAN 24
#define XMODEM_NCG 67
#define XMODEM_DATA_SIZE 128
typedef struct
{
uint8_t padding; /* Padding to make sure data is 32 bit aligned. */
uint8_t header;
uint8_t packetNumber;
uint8_t packetNumberC;
uint8_t data[XMODEM_DATA_SIZE];
uint8_t crcHigh;
uint8_t crcLow;
} XMODEM_packet;
int XMODEM_download(uint32_t baseAddress, uint32_t endAddress);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment