⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootloader.c

📁 非常全的nrf2401设计资料
💻 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 + -