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

📄 main_lpcusbboot.c

📁 NXP(原飞利浦)的LPC214X系列ARM上的USB在系统升级的源代码,极力推荐!!开发者主页: http://www.simonqian.com/en/LPCUSBBoot/
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
	LPC ISP protocol on a Serial Interface implemented on USB CDC class.
	This file is rewrited from main_serial.c
*/


#include <string.h>			// memcpy

#include "type.h"
#include "usbdebug.h"

#include "iap.h"

#include "console.h"
#include "usbapi.h"
#include "startup.h"

#include "serial_fifo.h"

#include "lpcisp.h"

#include "uu_codec.h"

#ifdef DEBUG
#define DBG_LEVEL				2
#else
#define DBG_LEVEL				0
#endif



// Chip related
#define LPCARM_MaxSect			26
#define LPCARM_MemTop			0x40008000
#define LPCARM_FlashSize		(512 * 1024)
// Bootloader related
#define Boot_Position_TOP		0		// bootloader located in the top of Flash(from 0x00000000)
#define Boot_Position_BOTTOM	1		// bootloader located in the bottom of Flash
#define Boot_Position			Boot_Position_TOP
#define Boot_Sect_Begin			0
#define Boot_Sect_Num			4
#define BOOT_START				0x00000000
#define APP_START				0x00004000





#define BAUD_RATE				115200

#define INT_IN_EP				0x81
#define BULK_OUT_EP				0x02
#define BULK_IN_EP				0x82

#define MAX_PACKET_SIZE			MAX_PACKET_SIZE0

#define CMD_LINE_LEN			MAX_PACKET_SIZE0

#define LE_WORD(x)				((x)&0xFF),((x)>>8)

// CDC definitions
#define CS_INTERFACE			0x24
#define CS_ENDPOINT				0x25

#define	SET_LINE_CODING			0x20
#define	GET_LINE_CODING			0x21
#define	SET_CONTROL_LINE_STATE	0x22

#define LPCARM_Unlock_Code		0x5A5A

// Boot Sector, MUST be protected
#define Boot_Sect_End			(Boot_Sect_Begin + Boot_Sect_Num - 1)

#if Boot_Position == Boot_Position_TOP
#	define APP_END				LPCARM_FlashSize
#	undef Boot_Sect_Begin
#	define Boot_Sect_Begin		0
#elif Boot_Position == Boot_Position_BOTTOM
#	define APP_END				BOOT_START
#else
#error "Boot_Position MUST be either Boot_Position_TOP or Boot_Position_BOTTOM"
#endif

// check
#if Boot_Sect_Num < 1
#error "Please give me some Flash for the Bootloader"
#endif
#if (Boot_Sect_End > LPCARM_MaxSect) || (APP_START >= LPCARM_FlashSize)
#error "R U kidding?"
#endif

// data structure for GET_LINE_CODING / SET_LINE_CODING class requests
typedef struct {
	U32		dwDTERate;
	U8		bCharFormat;
	U8		bParityType;
	U8		bDataBits;
} TLineCoding;

static TLineCoding LineCoding = {115200, 0, 0, 8};
static U8 abBulkBuf[MAX_PACKET_SIZE];
static U8 abClassReqData[8];

static U8 txdata[VCOM_FIFO_SIZE];
static U8 rxdata[VCOM_FIFO_SIZE];

static fifo_t txfifo;
static fifo_t rxfifo;

#define Sync_Mode_WaitSync		0
#define Sync_Mode_SendSync		1
#define Sync_Mode_WaitOSC		2
#define Sync_Mode_ReadOSC		3
#define Sync_Mode_Synced		4
static int Sync_Mode;
static int bUnlocked;
static int bChipEncrypted;

static int CDC_enable_echo = 0;

static const U8 abDescriptors[] = {

// device descriptor
	0x12,
	DESC_DEVICE,
	LE_WORD(0x0101),			// bcdUSB
	0x02,						// bDeviceClass
	0x00,						// bDeviceSubClass
	0x00,						// bDeviceProtocol
	MAX_PACKET_SIZE0,			// bMaxPacketSize
	LE_WORD(0xFFFF),			// idVendor
	LE_WORD(0x0005),			// idProduct
	LE_WORD(0x0100),			// bcdDevice
	0x01,						// iManufacturer
	0x02,						// iProduct
	0x03,						// iSerialNumber
	0x01,						// bNumConfigurations

// configuration descriptor
	0x09,
	DESC_CONFIGURATION,
	LE_WORD(67),				// wTotalLength
	0x02,						// bNumInterfaces
	0x01,						// bConfigurationValue
	0x00,						// iConfiguration
	0xC0,						// bmAttributes
	0x32,						// bMaxPower
// control class interface
	0x09,
	DESC_INTERFACE,
	0x00,						// bInterfaceNumber
	0x00,						// bAlternateSetting
	0x01,						// bNumEndPoints
	0x02,						// bInterfaceClass
	0x02,						// bInterfaceSubClass
	0x01,						// bInterfaceProtocol, linux requires value of 1 for the cdc_acm module
	0x00,						// iInterface
// header functional descriptor
	0x05,
	CS_INTERFACE,
	0x00,
	LE_WORD(0x0110),
// call management functional descriptor
	0x05,
	CS_INTERFACE,
	0x01,
	0x01,						// bmCapabilities = device handles call management
	0x01,						// bDataInterface
// ACM functional descriptor
	0x04,
	CS_INTERFACE,
	0x02,
	0x02,						// bmCapabilities
// union functional descriptor
	0x05,
	CS_INTERFACE,
	0x06,
	0x00,						// bMasterInterface
	0x01,						// bSlaveInterface0
// notification EP
	0x07,
	DESC_ENDPOINT,
	INT_IN_EP,					// bEndpointAddress
	0x03,						// bmAttributes = intr
	LE_WORD(8),					// wMaxPacketSize
	0x0A,						// bInterval
// data class interface descriptor
	0x09,
	DESC_INTERFACE,
	0x01,						// bInterfaceNumber
	0x00,						// bAlternateSetting
	0x02,						// bNumEndPoints
	0x0A,						// bInterfaceClass = data
	0x00,						// bInterfaceSubClass
	0x00,						// bInterfaceProtocol
	0x00,						// iInterface
// data EP OUT
	0x07,
	DESC_ENDPOINT,
	BULK_OUT_EP,				// bEndpointAddress
	0x02,						// bmAttributes = bulk
	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
	0x00,						// bInterval
// data EP in
	0x07,
	DESC_ENDPOINT,
	BULK_IN_EP,					// bEndpointAddress
	0x02,						// bmAttributes = bulk
	LE_WORD(MAX_PACKET_SIZE),	// wMaxPacketSize
	0x00,						// bInterval
	
	// string descriptors
	0x04,
	DESC_STRING,
	LE_WORD(0x0409),

	0x0E,
	DESC_STRING,
	'L', 0, 'P', 0, 'C', 0, 'U', 0, 'S', 0, 'B', 0,

	0x14,
	DESC_STRING,
	'U', 0, 'S', 0, 'B', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0,

	0x12,
	DESC_STRING,
	'D', 0, 'E', 0, 'A', 0, 'D', 0, 'C', 0, '0', 0, 'D', 0, 'E', 0,

// terminating zero
	0
};


/**
	Local function to handle bulk data
		
	@param [in] bEP
	@param [in] bEPStatus
 */
static void BulkIO(U8 bEP, U8 bEPStatus)
{
	int i, iLen;

	bEPStatus = bEPStatus;

	if(bEP & 0x80)
	{
		// Bulk IN
		if (fifo_avail(&txfifo) == 0) {
			// no more data, disable further NAK interrupts until next USB frame
			USBHwNakIntEnable(0);
			return;
		}

		// get bytes from transmit FIFO into intermediate buffer
		for (i = 0; i < MAX_PACKET_SIZE; i++) {
			if (!fifo_get(&txfifo, &abBulkBuf[i])) {
				break;
			}
		}
		iLen = i;
	
		// send over USB
		if (iLen > 0) {
			USBHwEPWrite(bEP, abBulkBuf, iLen);
		}
	}
	else
	{
		// Bulk OUT
		if (fifo_free(&rxfifo) < MAX_PACKET_SIZE) {
			// may not fit into fifo
			return;
		}

		// get data from USB into intermediate buffer
		iLen = USBHwEPRead(bEP, abBulkBuf, sizeof(abBulkBuf));
		for (i = 0; i < iLen; i++) {
			// put into FIFO
			if (!fifo_put(&rxfifo, abBulkBuf[i])) {
				// overflow... :(
				ASSERT(FALSE);
				break;
			}
		}
	}
}


/**
	Local function to handle the USB-CDC class requests
		
	@param [in] pSetup
	@param [out] piLen
	@param [out] ppbData
 */
static BOOL HandleClassRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
{
	switch (pSetup->bRequest) {

	// set line coding
	case SET_LINE_CODING:
#if DBG_LEVEL >= 3
DBG("SET_LINE_CODING\n");
#endif
		memcpy((U8 *)&LineCoding, *ppbData, 7);
		*piLen = 7;
#if DBG_LEVEL >= 3
DBG("dwDTERate=%u, bCharFormat=%u, bParityType=%u, bDataBits=%u\n",
	LineCoding.dwDTERate,
	LineCoding.bCharFormat,
	LineCoding.bParityType,
	LineCoding.bDataBits);
#endif

		Sync_Mode = Sync_Mode_WaitSync;
		CDC_enable_echo = 0;
		break;

	// get line coding
	case GET_LINE_CODING:
#if DBG_LEVEL >= 3
DBG("GET_LINE_CODING\n");
#endif
		*ppbData = (U8 *)&LineCoding;
		*piLen = 7;
		break;

	// set control line state
	case SET_CONTROL_LINE_STATE:
		// bit0 = DTR, bit = RTS
#if DBG_LEVEL >= 3
DBG("SET_CONTROL_LINE_STATE %X\n", pSetup->wValue);
#endif
		break;

	default:
		return FALSE;
	}
	return TRUE;
}


/**
	Initialises the VCOM port.
	Call this function before using VCOM_putchar or VCOM_getchar
 */
void VCOM_init(void)
{
	fifo_init(&txfifo, txdata);
	fifo_init(&rxfifo, rxdata);
}


/**
	Writes one character to VCOM port
	
	@param [in] c character to write
	@returns character written
 */
void VCOM_putchar(int c)
{
	while(!fifo_put(&txfifo, c))
		USBHwISR();

#if DBG_LEVEL >= 3
	DBG("putchar: 0x%02X\n", c);
#endif
}


/**
	Writes one string to VCOM port
	
	@param [in] s string to write
 */
void VCOM_putstr(char *s)
{
	while(*s)
		VCOM_putchar(*s++);
}


/**
	Writes one line to VCOM port
	
	@param [in] s string to write
 */
void VCOM_putln(char *s)
{
#if DBG_LEVEL >= 2
	DBG("putln: %s\n", s);
#endif

	VCOM_putstr(s);
	VCOM_putstr("\r\n");
}



/**
	Reads one character from VCOM port
	
	@returns character read
 */
int VCOM_getchar(void)
{
	U8 c;

	while (!fifo_get(&rxfifo, &c))
		USBHwISR();

#if DBG_LEVEL >= 3
	DBG("getchar: 0x%02X\n", c);
#endif

	if (CDC_enable_echo)
		VCOM_putchar(c);

	return c;
}


/**
	Reads one line from VCOM port

	@param [in] s buff to store data
	@param [in] iLen max length of data
	@returns length of string(\r\n is not included)
 */
int VCOM_getln(char *s, int iLen)
{
	int idx = 0;

	while ((*(s + idx) = VCOM_getchar()) != '\r') {
		if(Sync_Mode == Sync_Mode_WaitSync) {
			if (*(s + idx) == '?')
				Sync_Mode = Sync_Mode_SendSync;
			return 0;
		}
		if (*(s + idx) == 0x1B) {
			idx = 0;
#if DBG_LEVEL >= 2
			DBG("Aborted\n");
#endif
			continue;
		}
		if (idx < (iLen - 1))
			idx++;
		else
			return 0;
	}
	if (VCOM_getchar() != '\n') {
		return 0;
	}
	*(s + idx) = 0;

#if DBG_LEVEL >= 2
	DBG("getln: %s\n", s);
#endif

	return idx;
}


static void USBFrameHandler(U16 wFrame)
{
	wFrame = wFrame;

	if (fifo_avail(&txfifo) > 0) {
		// data available, enable NAK interrupt on bulk in
		USBHwNakIntEnable(INACK_BI);
	}
}












static int getNum(const char *s, U32 *num, char cEnd) {
	int i, ret = 0;
	U32 r = 1;

	*num = 0;

	while ((s[ret] != cEnd) && (s[ret] != '\0')) {
		ret++;
	}
	if (s[ret] != cEnd) {
		return 0;
	}

	i = ret - 1;
	while (i >= 0) {
		if ((s[i] < '0') || (s[i] > '9')) {
			return 0;
		}

		*num += (s[i] - '0') * r;
		r *= 10;
		i--;
	}

	return ret;
}


static int getPara(const char *s, U32 *Para, char cEnd) {
	if (s[0] != ' ') {
		return 0;
	}

	return getNum(s + 1, Para, cEnd) + 1;
}

static int parseParas(const char *s, int num, U32 *para, char cEnd) {
	int i, tmp, p = 0;

	for (i=0 ; i<num; i++) {
		if (i == (num - 1))
			tmp = getPara(&s[p], &para[i], cEnd);
		else
			tmp = getPara(&s[p], &para[i], ' ');
		p += tmp;
		if (!tmp)
			return 0;
	}

	return p;
}






int sprintf(char *out, const char *format, ...);
static U32 UU_chksum_val;
static int UU_getdata(int iLen, char *buf) {
	int i = 0, j, k,l = 0, n, resend_addr = 0;
	U32 chk_sum;
	char tmp[11], tmp_code[3];

	UU_chksum_val = 0;
	while(i < iLen) {
		n = (VCOM_getchar() - 0x20) & 0x3F;
		if((n < 1) || (n > 45))
			return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -