?? main_bootloader.c
字號:
/************************************************************************************************ * Project: USB AVR-ISP Bootloader * Author: Christian Ulrich
* Contact: christian at ullihome dot de
* * Creation Date: 2007-03-22 * Copyright: (c) 2007 by Christian Ulrich * License: GPLv2
*
*based on AVRUSBBoot by Thomas Fischl <tfischl@gmx.de>
***********************************************************************************************/
#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/wdt.h>#include <avr/boot.h>#include "config.h"
#include "usbdrv.h"
#define USBBOOT_FUNC_WRITE_EEP 4#define USBBOOT_FUNC_WRITE_PAGE 2#define USBBOOT_FUNC_LEAVE_BOOT 1#define USBBOOT_FUNC_GET_PAGESIZE 3
#define STATE_IDLE 0#define STATE_WRITE_PAGE 1
#define STATE_WRITE_EEP 2
static uchar replyBuffer[8];static uchar state = STATE_IDLE;static unsigned int page_address;static unsigned int page_offset;
void MAIN_tasks(void);
void (*jump_to_app)(void) = 0x0000;
void StartApplication()
{ cli(); boot_rww_enable(); GICR = (1 << IVCE); /* enable change of interrupt vectors */ GICR = (0 << IVSEL); /* move interrupts to application flash section */ jump_to_app();}
int main(void)
{
uchar i, j; //Jmp Opcode
if (!((pgm_read_byte(0) != 0xC0)||(PINC & (1<<PINC2))))
StartApplication(); /* activate pull-ups except on USB lines */ USB_CFG_IOPORT = (uchar)~((1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT)); /* all pins input except USB (-> USB reset) */#ifdef USB_CFG_PULLUP_IOPORT /* use usbDeviceConnect()/usbDeviceDisconnect() if available */ USBDDR = 0; /* we do RESET by deactivating pullup */ usbDeviceDisconnect();#else USBDDR = (1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT);#endif j = 0; while(--j){ /* USB Reset by device only required on Watchdog Reset */ i = 0; while(--i); /* delay >10ms for USB reset */ }#ifdef USB_CFG_PULLUP_IOPORT usbDeviceConnect();#else USBDDR = 0; /* remove USB reset condition */#endif
usbInit();
sei();
#ifndef USBASP_COMPATIBLE
DDRC = (1<<PC3)|(1<<PC4)|(1<<PC5);
PORTC &= ~(1<<PC3); //Green led on
PORTC &= ~(1<<PC4); //Green red off
PORTC |= (1<<PC5); //Green blue off
#else
DDRC = (1<<PC1)|(1<<PC3);
PORTC &= ~(1<<PC1); //Green led on
PORTC |= (1<<PC3); //Green red off
#endif
while(1)
usbPoll();
}
uint8_t usbFunctionSetup(uint8_t data[8]){
uchar len = 0; if (data[1] == USBBOOT_FUNC_LEAVE_BOOT)
{
StartApplication(); }
else if (data[1] == USBBOOT_FUNC_WRITE_PAGE)
{ state = STATE_WRITE_PAGE; page_address = (data[3] << 8) | data[2]; /* page address */ page_offset = 0; eeprom_busy_wait(); cli(); boot_page_erase(page_address); /* erase page */ sei(); boot_spm_busy_wait(); /* wait until page is erased */ len = 0xff; /* multiple out */ }
else if (data[1] == USBBOOT_FUNC_WRITE_EEP)
{ state = STATE_WRITE_EEP; page_address = (data[3] << 8) | data[2]; /* page address */ page_offset = 0; }
else if (data[1] == USBBOOT_FUNC_GET_PAGESIZE)
{ replyBuffer[0] = SPM_PAGESIZE >> 8; replyBuffer[1] = SPM_PAGESIZE & 0xff; len = 2; } usbMsgPtr = replyBuffer; return len;
}
uint8_t usbFunctionWrite( uint8_t *data, uint8_t len ){ uchar i; /* check if we are in correct state */ if ((state != STATE_WRITE_PAGE)||(state != STATE_WRITE_EEP)) return 0xff;
if (state == STATE_WRITE_PAGE)
{ for (i = 0; i < len; i+=2)
{ cli(); boot_page_fill(page_address + page_offset, data[i] | (data[i + 1] << 8)); sei(); page_offset += 2; /* check if we are at the end of a page */ if (page_offset >= SPM_PAGESIZE)
{ /* write page */ cli(); boot_page_write(page_address); sei(); boot_spm_busy_wait(); state = STATE_IDLE; return 1; }
}
}
else if (state == STATE_WRITE_EEP)
{
} return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -