aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/armdebug/Debugger/debug_comm.S
diff options
context:
space:
mode:
Diffstat (limited to 'AT91SAM7S256/armdebug/Debugger/debug_comm.S')
-rw-r--r--AT91SAM7S256/armdebug/Debugger/debug_comm.S481
1 files changed, 36 insertions, 445 deletions
diff --git a/AT91SAM7S256/armdebug/Debugger/debug_comm.S b/AT91SAM7S256/armdebug/Debugger/debug_comm.S
index 821d0c8..570fedc 100644
--- a/AT91SAM7S256/armdebug/Debugger/debug_comm.S
+++ b/AT91SAM7S256/armdebug/Debugger/debug_comm.S
@@ -22,6 +22,22 @@
#include "debug_internals.h"
#include "debug_comm.h"
+ /* Hexutils function references */
+ .extern hex2char
+ .extern char2hex
+ .extern byte2ascii
+ .extern halfword2ascii_be
+ .extern halfword2ascii_le
+ .extern word2ascii_be
+ .extern word2ascii_le
+ .extern ascii2hex_varlen_be
+ .extern ascii2byte
+ .extern ascii2halfword_be
+ .extern ascii2halfword_le
+ .extern ascii2word_be
+ .extern ascii2word_le
+
+
.bss
.align 4
@@ -46,10 +62,11 @@ debug_msgTxBuf_AppendPtr:
debug_segmentRxNum: /* Current Rx Segment Number */
.word 0x0
-/* Incoming Message Length and Comm Channel is now common to both NxOS and NXT Firmware */
debug_nxtMsgLength: /* NXT Firmware Received Message Length */
.word 0x0
+/* Comm Channel is now common to both NxOS and NXT Firmware */
+ .global debug_nxtCommChannel
debug_nxtCommChannel:
.word 0x0
@@ -61,443 +78,9 @@ debug_nxtCommChannel:
nxt_commcmd_header:
.byte NXT_GDBMSG_TELEGRAMTYPE, 0x00, 0x00 /* padded to 3 bytes */
-hex2char_lut:
- .ascii "0123456789ABCDEF"
-
-/* Macros
- */
-
-
-/* _hex2char_lut
- * Internal routine to intialize the LUT address pointer
- */
- .macro _hex2char_lut addrptr
- ldr \addrptr, =hex2char_lut
- .endm
-
-/* _hex2char_cont
- * Internal routine that assumes that the LUT has been loaded.
- * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the
- * ASCII equivalent in in the same register(7:0)
- * The second parameter is the LUT address pointer register to use (assumed to be initialized)
- * WARNING: Assumes that the value in register is sanity checked before invoking macro
- */
- .macro _hex2char_cont reg, addrptr
- ldrb \reg, [\addrptr, \reg]
- .endm
-
-/* _hex2char
- * This macro accepts a byte sized hex value as a parameter register(7:0) and returns the
- * ASCII equivalent in in the same register(7:0)
- * The second parameter is the LUT address pointer register to use (register content is destroyed)
- * WARNING: Assumes that the value in register is sanity checked before invoking macro
- */
- .macro _hex2char reg, addrptr
- _hex2char_lut \addrptr
- _hex2char_cont \reg, \addrptr
- .endm
-
-/* _char2hex
- * This macro accepts an ASCII char as a parameter register(7:0) and returns the
- * equivalent byte sized hex value in in the same register(7:0)
- * WARNING: Assumes that the char in register is a valid hex char before invoking macro
- */
- .macro _char2hex reg
- cmp \reg, #'A' /* If Alpha */
- bichs \reg, \reg, #ASCII_LOWER2UPPER_MASK /* Convert to Uppercase */
- subhs \reg, \reg, #7 /* Adjustment to allow for subtraction with 0x30 */
- sub \reg, \reg, #0x30 /* get final hex value */
- .endm
-
-
.code 32
.text
.align 4
-
-
-/* Utility Routines
- * GDB requires command parameters to be specified as Big Endian values.
- * However, the read/write register command expect the register contents to be specified in target byte order.
- * Hence we need both versions of multibyte conversion routines for word sized values.
- */
-
-/* hex2char
- * This routine accepts a byte sized hex value in R0(7:0) and returns the
- * ASCII equivalent in R0(7:0)
- */
- .global hex2char
-
-hex2char:
- stmfd sp!, {r1,lr}
- and r0, #NIBBLE0 /* make sure that input is sane */
- _hex2char r0, r1
- ldmfd sp!, {r1,pc}
-
-/* char2hex
- * This routine accepts an ASCII character in R0(7:0) and returns the
- * equivalent byte sized hex value in R0(7:0).
- * It accepts lowercase and uppercase ASCII Hex char inputs.
- * Invalid inputs return -1 as the value
-* On entry:
- * R0: ASCII character
- * On exit:
- * R0: Hex value
- */
- .global char2hex
-
-char2hex:
- and r0, r0, #BYTE0 /* make sure that input is sane */
- cmp r0, #'0'
- blo char2hex_error
- cmp r0, #'9'
- bls perform_char2hex
- cmp r0, #'A'
- blo char2hex_error
- cmp r0, #'F'
- bls perform_char2hex
- cmp r0, #'a'
- blo char2hex_error
- cmp r0, #'f'
- bhi char2hex_error
- /* Validated Hex Char */
-perform_char2hex:
- _char2hex r0 /* Return hex value in R0 */
- bx lr
-
-char2hex_error:
- mov r0, #-1 /* Set Return value to Error value */
- bx lr
-
-/* byte2ascii_cont
- * (Shared routine, does not perform sanity checks)
- * On entry:
- * R0: ASCII buffer pointer
- * R1[7:0]: byte value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Destroyed
- *
- * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1,
- * and stores the ASCII equivalent byte value in the buffer pointed to by R0.
- * Note: On return, R0 points to next empty char slot in buffer
- */
-byte2ascii_cont:
- stmfd sp!, {r2,r3,r4, lr}
- lsl r2, r1, #24 /* Keep copy of input byte value R1[7:0], shifted to MSB R2[31:24] */
- mov r4, #2 /* Loop counter */
- _hex2char_lut r3 /* initialize LUT pointer */
-1: ror r2, r2, #28 /* Rotate MSNibble R2[31:28] into LSNibble position R2[3:0] */
- and r1, r2, #NIBBLE0 /* Mask out everything else, store Nibble in R1 */
- _hex2char_cont r1, r3 /* Convert nibble to ASCII char */
- strb r1, [r0], #1
- subs r4, r4, #1 /* decrement loop counter */
- bne 1b
- ldmfd sp!, {r2,r3,r4, pc}
-
-/* byte2ascii
- * On entry:
- * R0: ASCII buffer pointer
- * R1[7:0]: Byte value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Original Address of Buffer
- *
- * This routine accepts an ASCII buffer pointer in R0 and a byte value in R1,
- * and stores the ASCII equivalent byte value in the buffer pointed to by R0.
- * Note: On return, R0 points to the next empty char slot in buffer
- */
- .global byte2ascii
-
-byte2ascii:
- stmfd sp!, {r0, lr} /* Keep ASCII buffer pointer */
- and r1, #BYTE0 /* sanitize input */
- bl byte2ascii_cont
- ldmfd sp!, {r1, pc} /* return original string pointer in R1 */
-
-/* halfword2ascii_be
- * Big Endian version of halfword2ascii conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * R1[15:0]: Halfword value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Original Address of Buffer
- *
- * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1,
- * and stores the ASCII equivalent halfword value in the buffer pointed to by R0.
- * Note: On return, R0 points to the next empty char slot in buffer
- */
- .global halfword2ascii_be
-halfword2ascii_be:
- stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
- mov r3, #2 /* Loop Counter */
- mov r2, r1, lsl #16 /* copy of input halfword value R1[15:0], shifted to MSH R2[31:16] */
- b _conv_byte2ascii_be /* goto Byte conversion loop */
-
-/* halfword2ascii_le
- * Little Endian version of halfword2ascii conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * R1[15:0]: Halfword value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Original Address of Buffer
- *
- * This routine accepts an ASCII buffer pointer in R0 and a halfword value in R1,
- * and stores the ASCII equivalent halfword value in the buffer pointed to by R0.
- * Note: On return, R0 points to the next empty char slot in buffer
- */
- .global halfword2ascii_le
-halfword2ascii_le:
- stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
- mov r3, #2 /* Loop Counter */
- b _conv_byte2ascii_le /* goto Byte conversion loop */
-
-
-/* word2ascii_be
- * Big Endian version of word2ascii conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * R1[31:0]: Word value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Original Address of Buffer
- *
- * This routine accepts an ASCII buffer pointer in R0 and a word value in R1,
- * and stores the ASCII equivalent word value in the buffer pointed to by R0.
- * Note: On return, R0 points to the next empty char slot in buffer
- */
- .global word2ascii_be
-word2ascii_be:
- stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
- mov r2, r1 /* copy of input word value R1[31:0] */
- mov r3, #4 /* Loop Counter */
-
- /* Fall through to byte coversion loop */
-
-
-/* Big Endian Multibyte Convert: Rotate then convert */
-_conv_byte2ascii_be:
- ror r2, r2, #24 /* Rotate MSB R2[31:24] into LSB position R2[7:0] */
- and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */
- bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */
- subs r3, r3, #1
- bne _conv_byte2ascii_be
- ldmfd sp!, {r1,r2,r3, pc}
-
-/* word2ascii_le
- * Little Endian version of word2ascii conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * R1[31:0]: Word value
- * On exit:
- * R0: Address of next empty char slot in buffer
- * R1: Original Address of Buffer
- *
- * This routine accepts an ASCII buffer pointer in R0 and a word value in R1,
- * and stores the ASCII equivalent word value in the buffer pointed to by R0.
- * Note: On return, R0 points to the next empty char slot in buffer
- */
- .global word2ascii_le
-word2ascii_le:
- stmfd sp!, {r0,r2,r3, lr} /* Keep ASCII buffer pointer */
- mov r2, r1 /* copy of input word value R1[31:0] */
- mov r3, #4 /* Loop Counter */
-
- /* Fall through to byte coversion loop */
-
-/* Little Endian Multibyte Convert: Convert then rotate */
-_conv_byte2ascii_le:
- and r1, r2, #BYTE0 /* Copy byte value in R2[7:0] into R1 */
- bl byte2ascii_cont /* R0: next ASCII buffer location pointer, R1: destroyed */
- ror r2, r2, #8 /* Rotate LSB+1 R2[15:8] into LSB position R2[7:0] */
- subs r3, r3, #1
- bne _conv_byte2ascii_le
- ldmfd sp!, {r1,r2,r3, pc}
-
-
-/* ascii2hex_varlen_be
- * Big Endian version of ascii2hex_varlen conversion routine
- * (There is no Little Endian Version)
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0: Hex value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the hex value in R0 for up to 8 Hex characters.
- * Note: On return, R1 points to the ASCII buffer location after the hex value chars.
- */
- .global ascii2hex_varlen_be
-
-ascii2hex_varlen_be:
- stmfd sp!, {r2,r3, lr}
- mov r3, #CMD_REG_REGPARAMLEN /* Set max count to 8 (Max Register size) */
- mov r1, r0 /* Use R1 as ASCII buffer pointer */
- mov r2, #0 /* Initialize Cummulative Results */
-2: ldrb r0, [r1] /* Load ASCII char for Hex Value */
- bl char2hex /* on return, hex value in R0, -1 for error */
- cmp r0, #-1
- beq _exit_ascii2hex_varlen
- orr r2, r0, r2, lsl #4 /* combined byte value */
- subs r3, r3, #1 /* Decrement Counter */
- add r1, r1, #1 /* Go to next char slot */
- bne 2b
-_exit_ascii2hex_varlen:
- mov r0, r2 /* Return results in R0 */
- ldmfd sp!, {r2,r3, pc}
-
-
-/* ascii2byte
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0[7:0]: Byte value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the byte value in R0[7:0].
- * Note: On return, R1 points to the ASCII buffer location after the current 2 chars.
- * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
- * otherwise it will return invalid results.
- */
- .global ascii2byte
-
-ascii2byte:
- stmfd sp!, {r2, lr}
- mov r1, r0 /* Use R1 as ASCII buffer pointer */
- ldrb r0, [r1], #1 /* Load ASCII char for MSN */
- bl char2hex /* on return, hex value in R0, -1 for error (ignored) */
- mov r2, r0, lsl #4 /* Intermediate Results register */
- ldrb r0, [r1], #1 /* Load ASCII char for LSN */
- bl char2hex /* on return, hex value in R0, -1 for error (ignored) */
- orr r0, r2, r0 /* combined byte value */
- ldmfd sp!, {r2, pc}
-
-/* ascii2halfword_be
- * Big Endian version of ascii2halfword conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0[15:0]: Halfword value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the Halfword value in R0[15:0].
- * Note: On return, R1 points to the ASCII buffer location after the current 4 chars.
- * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
- * otherwise it will return invalid results.
- */
- .global ascii2halfword_be
-
-ascii2halfword_be:
- stmfd sp!, {r2,r3, lr}
- mov r3, #2 /* Loop counter */
- b _conv_ascii2byte_be
-
-/* ascii2halfword_le
- * Little Endian version of ascii2halfword conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0[15:0]: Halfword value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the Halfword value in R0[15:0].
- * Note: On return, R1 points to the ASCII buffer location after the current 4 chars.
- * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
- * otherwise it will return invalid results.
- */
- .global ascii2halfword_le
-
-ascii2halfword_le:
- stmfd sp!, {r2,r3, lr}
- mov r3, #2 /* Loop counter */
- b _conv_ascii2byte_le
-
-
-/* ascii2word_be
- * Big Endian version of ascii2word conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0[31:0]: Word value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the word value in R0[31:0].
- * Note: On return, R1 points to the ASCII buffer location after the current 8 chars.
- * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
- * otherwise it will return invalid results.
- */
- .global ascii2word_be
-
-ascii2word_be:
- stmfd sp!, {r2,r3, lr}
- mov r3, #4 /* Loop counter */
-
- /* Fall through to byte coversion loop */
-
-_conv_ascii2byte_be:
- teq r0, #0
- beq _exit_conv_ascii2byte_be /* exit if NULL pointer in R0 */
- mov r2, #0 /* Initialize Cummulative value */
-2: bl ascii2byte
- orr r2, r0, r2, lsl #8 /* Merge current byte with cummulative value */
- mov r0, r1 /* Copy next char pointer to R0 for next byte */
- subs r3, r3, #1
- bne 2b
- mov r0, r2 /* Copy it to R0 as return value */
-
-_exit_conv_ascii2byte_be:
- ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */
-
-/* ascii2word_le
- * Litle Endian version of ascii2word conversion routine
- * On entry:
- * R0: ASCII buffer pointer
- * On exit:
- * R0[31:0]: Word value
- * R1: Address of next char slot in buffer
- *
- * This routine accepts an ASCII buffer pointer in R0,
- * and returns the word value in R0[31:0].
- * Note: On return, R1 points to the ASCII buffer location after the current 8 chars.
- * WARNING: This routine assumes that the input buffer was sanitized and contains valid Hex chars,
- * otherwise it will return invalid results.
- */
- .global ascii2word_le
-
-ascii2word_le:
- stmfd sp!, {r2,r3, lr}
- mov r3, #4 /* Loop counter */
-
- /* Fall through to byte coversion loop */
-
-_conv_ascii2byte_le:
- teq r0, #0
- beq _exit_conv_ascii2byte_le /* exit if NULL pointer in R0 */
- push {r3} /* Need to keep couter for final value adjustment */
- mov r2, #0 /* Initialize Cummulative value */
-2: bl ascii2byte
- orr r2, r0, r2, ror #8 /* Merge current byte with cummulative value */
- mov r0, r1 /* Copy next char pointer to R0 for next byte */
- subs r3, r3, #1
- bne 2b
- /* Cummulative value done, need to rotate it into the correct position for return value */
- pop {r3} /* retrieve counter */
- rsb r3, r3, #5 /* 5 - count */
- lsl r3, r3, #3 /* [(5-count) x 8] bits to rotate */
- mov r0, r2, ror r3 /* Copy it to R0 as return value */
-
-_exit_conv_ascii2byte_le:
- ldmfd sp!, {r2,r3, pc} /* return hex value in R0 */
-
-
-
-
/* Debugger Communications Routines
* It does not make sense to pass information from the Debugger Module to the Comm. link one character
* at a time, especially if we're not using a native serial interface (e.g., EIA-232). Consequently
@@ -577,24 +160,26 @@ dbg__comm_init:
str r0, [r1, #NXTCOMMCHANNEL_OFFSET] /* Clear NXT Channel on INIT */
ldmfd sp!, {pc}
-_dbg__comm_readbuf_reset:
#ifdef __NXOS__
+_dbg__comm_readbuf_reset:
stmfd sp!, {lr}
ldr r0, =debug_InCommBuf
mov r1, #USB_BUFSIZE
- ldr r2, =nx_usb_read
+ ldr r2, =fantom_init
mov lr, pc
bx r2
+#if 0
ldr r1, =debug_nxtMsgLength
mov r0, #0
str r0, [r1] /* Clear NxOS Received Message Length */
+#endif
ldmfd sp!, {pc}
#else
+_dbg__comm_readbuf_reset:
ldr r1, =debug_nxtMsgLength
mov r0, #0
str r0, [r1] /* Clear NXT Received Message Length */
bx lr
-#endif
.global dbg__copyNxtDebugMsg
/* dbg__copyNxtDebugMsg
@@ -616,6 +201,7 @@ dbg__copyNxtDebugMsg:
*/
_dbg_memcpy r1, r0, r2, r3 /* r3: scratch register */
bx lr
+#endif
/* _dbg_reset_msgTxBuf_AppendPtr
* Internal variable to reset pointers.
@@ -638,7 +224,7 @@ _dbg_reset_msgTxBuf_AppendPtr:
_dbg__commHasMsg:
stmfd sp!, {lr}
#ifdef __NXOS__
- ldr r2, =nx_usb_data_read
+ ldr r2, =nx_usb_fantom_data_read
mov lr,pc
bx r2 /* Number of bytes read in R0 */
/* Note: The return value in R0 is the Comm Buffer Size, includes NXT Direct Command Header */
@@ -662,7 +248,8 @@ _dbg__commHasMsg:
b _exit_dbg__commHasMsg
invalid_CommMsg:
- mov r0, #0
+ bl _dbg__comm_readbuf_reset /* Next Comm telegram transaction */
+ mov r0, #0
_exit_dbg__commHasMsg:
ldmfd sp!, {pc}
@@ -837,9 +424,11 @@ _dbg__sendCommMsg:
mov r4, r0 /* Keep Comm Buffer length in R4 */
#ifdef __NXOS__
/* Check USB bus status, transmit message if possible */
- bl nx_usb_is_connected /* R0 = True if USB is ready */
- cmp r0, #TRUE
- bne _exit_dbg__sendCommMsg
+ bl nx_usb_is_connected /* R0 = TRUE (#1) if USB is ready */
+ teq r0, #0 /* FALSE == #0;
+ We can't check for True condition since values
+ used by C-Compiler & ARMDEBUG are different */
+ beq _dbg__sendCommMsgFailed
/* Actual transmission (blocking) */
ldr r0, =debug_OutCommBuf /* data pointer parameter */
@@ -847,9 +436,11 @@ _dbg__sendCommMsg:
bl nx_usb_write
1: bl nx_usb_data_written /* R0 = True if data has been sent */
- cmp r0, #TRUE
+ teq r0, #0 /* FALSE == #0;
+ We can't check for True condition since values
+ used by C-Compiler & ARMDEBUG are different */
/* FIXME: implement timeout */
- bne 1b /* Busy Wait Loop */
+ beq 1b /* Busy Wait Loop */
#else
ldr r0, =debug_nxtCommChannel
ldr r0, [r0] /* Get Channel Enum */