📄 bootloader.c
字号:
/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision: 2290 $
*/
/** @file
* This file contain parsing of USB commands
*
* @author Ole Saether
*
*/
#include <Nordic\reg24lu1.h>
#include <intrins.h>
#include "usb.h"
#include "bootloader.h"
#include "version.h"
#include "usb_cmds.h"
#include "flash.h"
#include "config.h"
#ifdef USE_USERCLASS
#pragma userclass (code = BOOTLOADER)
#pragma userclass (const = BOOTLOADER)
#endif
extern bool packet_received;
extern xdata volatile uint8_t in1buf[];
extern xdata volatile uint8_t out1buf[];
extern xdata volatile uint8_t in1bc;
static bool page_write;
static uint8_t nblock; // Holds the number of the current USB_EP1_SIZE bytes block
static uint8_t nblocks; // Holds number of the blocks programmed
static bool idata used_flash_pages[32]; // Holds which flash pages to erase
void parse_commands(void)
{
uint8_t count = 0;
if(page_write)
{
flash_bytes_write((uint16_t)nblock << 6, out1buf, USB_EP1_SIZE);
nblock++;
nblocks++;
in1buf[0] = 0;
count = 1;
if (nblocks == (FLASH_PAGE_SIZE/USB_EP1_SIZE))
{
page_write = false;
}
}
else
{
switch(out1buf[0])
{
case CMD_FIRMWARE_VERSION:
in1buf[0] = FW_VER_MAJOR;
in1buf[1] = FW_VER_MINOR;
count = 2;
break;
case CMD_FLASH_ERASE_PAGE:
flash_page_erase(out1buf[1]);
used_flash_pages[out1buf[1]] = false;
in1buf[0] = 0;
count = 1;
break;
case CMD_FLASH_PAGE_WRITE: // Eight 64 bytes bulk packets <- PC follow after this command
if (used_flash_pages[out1buf[1]])
{
flash_page_erase(out1buf[1]);
}
nblock = out1buf[1] << 3; // Multiply page number by 8 to get block number
nblocks = 0;
page_write = true;
in1buf[0] = 0;
count = 1;
break;
case CMD_FLASH_BLOCK_READ:
// Read one USB_EP1_SIZE bytes block from the address given
// by out1buf[1] << 6:
flash_bytes_read((uint16_t)out1buf[1]<<6, in1buf, USB_EP1_SIZE);
count = USB_EP1_SIZE;
break;
default:
break;
}
}
if (count > 0)
in1bc = count;
}
static void get_used_flash_pages(void)
{
uint8_t xdata *pb;
uint8_t i;
uint16_t j;
//
// Read through the whole flash to find out which flash
// pages that are in use. Store the result in the NUM_FLASH_PAGES
// sized array used_flash_pages[]:
for(i=0;i<NUM_FLASH_PAGES;i++)
{
used_flash_pages[i] = false;
pb = (uint8_t xdata *)(FLASH_PAGE_SIZE * (uint16_t)i);
for(j=0;j<FLASH_PAGE_SIZE;j++)
{
if(*pb != 0xff)
{
used_flash_pages[i] = true;
break;
}
pb++;
}
}
}
void bootloader(void)
{
EA = 0;
get_used_flash_pages();
usb_init();
packet_received = page_write = false;
//
// Enter an infinite loop waiting checking the USB interrupt flag and
// call the interrupt handler, usb_irq, when the flag is set. The interrupt
// handler will set the variable packet_received to true when a packet is
// received.
for(;;)
{
if (USBF)
{
USBF = 0;
usb_irq();
if(packet_received)
{
parse_commands();
packet_received = false;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -