From c351d60d912c121b3c4e22b8b53e5d946bb5f748 Mon Sep 17 00:00:00 2001 From: TC Wan Date: Thu, 23 Dec 2010 18:30:11 +0800 Subject: checkin wip for communications support Start implementing USB communications support --- Debugger/debug_comm.S | 161 +++++++++++++++++++++++++++++++++++++++++++++++- Debugger/debug_macros.h | 17 +++++ Debugger/debug_stub.S | 11 ++-- Debugger/debug_stub.h | 17 ++++- 4 files changed, 197 insertions(+), 9 deletions(-) diff --git a/Debugger/debug_comm.S b/Debugger/debug_comm.S index 857c3ea..872ddc6 100644 --- a/Debugger/debug_comm.S +++ b/Debugger/debug_comm.S @@ -13,9 +13,36 @@ * */ + +#define __NXOS__ /* Temporarily hardcoded in file */ + #define __ASSEMBLY__ #include "debug_stub.h" +#ifdef __NXOS__ +#include "usb.h" +#else +#include "c_comm.h" +#endif + +.bss +.align 4 + +debug_InUSBBuf: + .space USB_BUFSIZE,0 +debug_OutUSBBuf: + .space USB_BUFSIZE,0 + +debug_msgRxBufPtr: + .word 0x0 +debug_msgTxBufPtr: + .word 0x0 + +debug_segmentRxNum: /* Current Rx Segment Number */ + .word 0x0 +debug_segmentTxNum: /* Current Tx Segment Number */ + .word 0x0 + .data .align 4 @@ -248,15 +275,108 @@ _exit_conv_ascii2byte: * a Message interface has been defined. This can still call getChar() and putChar() subroutines * if so desired, but it'll be a purely internal matter. * + * Message Format + * Since we need to use EP1&2 (Bulk channels) to communicate with the PC Host, the messages should + * follow the NXT Direct Commands message structure (this will allow for interoperability with NXT Firmware + * in addition to NxOS). The maximum length of any USB communications via the Bulk channel is 64 bytes. + * There is a one byte Telegram Type field which identifies the type of telegram, followed by the + * Telegram header and actual message. + * + * [The GDB Message Format is derived from the MESSAGEWRITE Direct Command format] + * The LEGO Mindstorms Communications Protocol Direct Commands GDB Message format (including all headers) + * is as follows: + * + * GDB Command + * =========== + * Byte 0: Telegram Type Field (0x00 Direct Command, Response required) | USB Channel Header + * Byte 1: Command Field (0xF0: GDB command) | NXT Command Header + * Byte 2: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) | + * Byte 3: Telegram Size (Len of USB Buffer - 4, max is MSG_SEGMENTSIZE) | + * Byte 4-N: Message data | GDB Command + * + * The GDB Command (of size M) has the following format: + * Offset 0: '$' + * Offset 1: GDB Command char + * Offset 2 - (M-4): Command packet info + * Offset M-3: '#' + * Offset M-2: MSB of Checksum + * Offset M-1: LSB of Checksum + * + * The maximum size of a GDB Command packet is MSGBUF_SIZE - 5 ('$', '#', 2 byte checksum, trailing NULL char) + * + * GDB Response + * ============ + * Byte 0: Telegram Type Field (0x02 Response) | USB Channel Header + * Byte 1: Command Field (0xF1: GDB response) | NXT Command Header + * Byte 2: Segment No (1-255, 0: Last Segment; limit is MSG_NUMSEGMENTS) | + * Byte 3: Telegram Size (Len of USB Buffer - 4, max is MSG_SEGMENTSIZE) | + * Byte 4-N: Message data | GDB Response + * + * The GDB Response (of size M) has the following format: + * Offset 0: '+' or '-' Command Received Status + * Offset 1: '$' + * Offset 2 - (M-4): Response packet info + * Offset M-3: '#' + * Offset M-2: MSB of Checksum + * Offset M-1: LSB of Checksum + * + * The maximum size of a GDB Response packet is MSGBUF_SIZE - 6 ('-'/'+', '$', '#', 2 byte checksum, trailing NULL char) + * + * Note: The Telegram Size is the actual size of the Message Data portion + * (i.e., excludes the four header bytes, includes the GDB Command/Response Packet trailing NULL character + * in the last segment) */ + + .global dbg__comm_init +/* dbg__comm_init + * Initialize communications channel. + * On Entry: + * R0: MSG Rx Buf Pointer + * R1: MSG Tx Buf Pointer + */ + +dbg__comm_init: +#ifdef __NXOS__ + stmfd sp!, {lr} + ldr r2, =debug_msgRxBufPtr + stmia r2, {r0,r1} /* Assume that the 2 pointers are consecutive */ + bl _dbg__usbbuf_reset + ldmfd sp!, {pc} + +_dbg__usbbuf_reset: + stmfd sp!, {lr} + ldr r0, =debug_InUSBBuf + ldr r1, #USB_BUFSIZE + ldr r2, =nx_usb_read + bl r2 + ldmfd sp!, {pc} +#else + /* FIXME: NXT Firmware support */ + bx lr +#endif + .global dbg__hasDebugMsg /* dbg__hasDebugMsg * Checks for pending Debugger Message (Non-Blocking). * On exit: - * r0: Boolean (0: no pending message, 1: has pending message) + * r0: !0: (Availale Debugger Message Size), 0: no pending message + * r1: message segment number */ dbg__hasDebugMsg: +#ifdef __NXOS__ + stmfd sp!, {lr} + ldr r0, =nx_usb_data_read + bl r2 /* Number of bytes read in R0 */ + /* Note: The return value is the USB Buffer Size, includes NXT Direct Command Header */ + /* FIXME: Need to check command type etc. before accepting it as a valid Debugger message */ + ldr r2, =debug_InUSBBuf + ldrb r0, [r2, #USB_NXT_TELEGRAMSIZE_OFFSET] + ldrb r1, [r2, #USB_NXT_SEGNUM_OFFSET] + ldmfd sp!, {pc} +#else + /* FIXME: NXT Firmware support */ bx lr +#endif .global dbg__getDebugMsg /* dbg__getDebugMsg @@ -269,8 +389,47 @@ dbg__hasDebugMsg: * (NULL if message error) * */ + /* FIXME: This does not handle multiple segments currently, we just assume that everything is in one segment */ dbg__getDebugMsg: +#ifdef __NXOS__ + stmfd sp!, {lr} + bl dbg__hasDebugMsg + cmp r0, #0 + ble _exit_getDebugMsg /* Zero length message, skip */ + teq r1, #0 + bne _exit_getDebugMsg /* Don't process segmented messages for now */ + +_copy_msg_from_usbbuf: + /* FIXME: handle multiple segments */ + ldr r1, =debug_InUSBBuf + ldrb r2, [r1, #USB_GDBMSG_START] + mov r3, #MSGBUF_STARTCHAR + teq r2, r3 + bne _exit_getDebugMsg /* Debugger Message does not have valid start char '$' */ + ldrb r2, [r1, r0] + cmp r2, #0 /* Check for NULL (in last segment) */ + bne _exit_getDebugMsg /* Debugger Message does not have valid terminating NULL char */ + sub r3, r0, #USB_GDBMSG_CHKSUMOFFSET /* Message Length - 4 = '#' offset */ + ldrb r2, [r1, r3] + mov r3, #MSGBUF_CHKSUMCHAR + teq r2, r3 + bne _exit_getDebugMsg /* Debugger Message does not have valid checksum char */ + + /* FIXME: Perform Checksum verification */ + + mov r3, r0 /* Setup size param for memcpy macro */ + ldr r2, =debug_msgRxBufPtr + ldr r2, [r2] + add r1, r1, #USB_GDBMSG_START + _dbg_memcpy r2, r1, r3 + /* FIXME: Need to check command type etc. before accepting it as a valid Debugger message */ +_exit_getDebugMsg: + bl _dbg__usbbuf_reset /* Next USB telegram transaction */ + ldmfd sp!, {pc} +#else + /* FIXME: NXT Firmware support */ bx lr +#endif .global dbg__putDebugMsg /* dbg__putDebugMsg diff --git a/Debugger/debug_macros.h b/Debugger/debug_macros.h index 416022e..f66e42c 100644 --- a/Debugger/debug_macros.h +++ b/Debugger/debug_macros.h @@ -91,6 +91,23 @@ sub \deststrptr, \deststrptr, #1 /* Adjust Destination string pointer to point at NULL character */ .endm +/* _dbg_memcpy + * _dbg_stpcpy macro + * On entry: + * deststrptr: Destination string [Cannot be R0] + * sourcestrptr: Source string [Cannot be R0] + * sizereg: Number of bytes to copy [Cannot be R0] + * On exit: + * deststrptr: Pointer to NULL character in destination string + * R0: destroyed + */ + .macro _dbg_memcpy deststrptr, sourcestrptr, sizereg +1: ldrb r0, [\sourcestrptr], #1 + strb r0, [\deststrptr], #1 + subs \sizereg, \sizereg, #1 + bne 1b + .endm + /* _dbg_outputMsgValidResponse * Return Message with valid response ('+$') * On exit: diff --git a/Debugger/debug_stub.S b/Debugger/debug_stub.S index 8448a46..4ebe6f3 100644 --- a/Debugger/debug_stub.S +++ b/Debugger/debug_stub.S @@ -341,13 +341,14 @@ debug_armComplexCCTable: dbg__bkpt_init: stmfd sp!, {lr} bl _dbg__clear_breakpoints - mov r0, #0 + mov r2, #0 ldr r1, =debug_curr_breakpoint - str r0, [r1] - ldr r1, =debug_InMsgBuf - strb r0, [r1] + str r2, [r1] + ldr r0, =debug_InMsgBuf + strb r2, [r0] ldr r1, =debug_OutMsgBuf - strb r0, [r1] + strb r2, [r1] + bl dbg__comm_init /* Pass R0: Rx Buffer, R1: Tx Buffer to comm submodule */ /* FIXME: Initialize other stuff here */ _dbg_setstate DBG_INIT diff --git a/Debugger/debug_stub.h b/Debugger/debug_stub.h index c3a71c4..e79f0de 100644 --- a/Debugger/debug_stub.h +++ b/Debugger/debug_stub.h @@ -36,10 +36,20 @@ * High Speed Device 64 1024 1024 512 */ -#define USB_BUFSIZE 64 -#define USB_NUMDATAPKTS 3 /* For packet transfers */ +#define USB_BUFSIZE 64 /* USB Buffer size for AT91SAM7S */ + +#define USB_NXT_TELEGRAMTYPE_OFFSET 0 /* NXT Direct Command/Response Header */ +#define USB_NXT_COMMAND_OFFSET 1 +#define USB_NXT_SEGNUM_OFFSET 2 +#define USB_NXT_TELEGRAMSIZE_OFFSET 3 + +#define USB_GDBMSG_START 4 /* Offset into USB Telegram buffer */ +#define USB_GDBMSG_CHKSUMOFFSET 4 /* to be subtracted from USB_NXT_TELEGRAMSIZE_OFFSET */ + +#define MSG_NUMSEGMENTS 3 /* For packet transfers */ +#define MSG_SEGMENTSIZE (USB_BUFSIZE - USB_GDBMSG_START) /* 60 bytes per segment */ +#define MSGBUF_SIZE (MSG_SEGMENTSIZE*MSG_NUMSEGMENTS) /* Debug Message Buffer Size, 60 x 3 = 180 chars = ~80 bytes of actual data */ -#define MSGBUF_SIZE (USB_BUFSIZE*USB_NUMDATAPKTS) /* Debug Message Buffer Size, 64 x 3 = 192 chars = ~90 bytes */ #define MSGBUF_STARTCHAR '$' #define MSGBUF_ACKCHAR '+' #define MSGBUF_NAKCHAR '-' @@ -47,6 +57,7 @@ #define MSGBUF_SIGCHAR 'S' #define MSGBUF_CPSRREG '!' #define MSGBUF_SETCHAR '=' +#define MSGBUF_CHKSUMCHAR '#' #define MSGBUF_CMDINDEX_OUTOFRANGE_VAL -1 /*@}*/ -- cgit v1.2.3