API

The following is a description of each method, organized by software layer. The JTAG I/O Layer functions cannot be directly called by the user, but they are listed for reference. Commands that the user can enter are listed in the format that the user would type them into HyperTerminal. For commands that use numerical arguments, the user can choose whether to use base 10 or base 16. To use base 10, simply type the number in base 10 notation. To use hexadecimal, type "0x" before the argument. For example, to enter the number 64 in base ten, type "64". To enter it in hexadecimal, type "0x40".

JTAG I/O Layer

  • jtag_io(char tms, char tdi): Responsible for single state transitions in the JTAG state machine. First, the method ensures that TCK is low by clearing PORTC.2. While TCK is low, PORTC.3 and PORTC.5 are set appropriately based on the specified TMS and TDI inputs. A delay is inserted to ensure that the TMS and TDI signals are stable. Then, PORTC.2 is set high. On the rising edge of the TCK signal, the TMS and TDI signals are captured. After another delay, PORTC.2 is set low. After the falling edge of the TCK signal, TDO is captured. PINC.4 is read, and the TDO value is returned.
  • IRSCAN(int count, char* tdi): Used to shift data into the JTAG Instruction Register. The first argument indicates the length of the bit stream stored in the char array tdi. The tdi char array contains the bit stream specifying the data to shift in, LSB first. First, this method uses the jtag_io method to navigate to the Shift-IR state from the Run-Test/Idle state. Then, data is shifted in while remaining in the Shift-IR state. When the MSB of the data to enter is reached, the state changes to the Exit1-IR state. The state machine then uses the jtag_io method to return to the Run-Test/Idle state.
  • DRSCAN(int count, char* tdi): Used to shift data into and out of the JTAG Data Register. The first argument indicates the length of the bit stream stored in the char array tdi. The tdi char array contains the bit stream specifying the data to shift in, LSB first. First, this method uses the jtag_io method to navigate to the Shift-DR state from the Run-Test/Idle state. Then, data is shifted in while remaining in the Shift-DR state. When the MSB of the data to enter is reached, the state changes to the Exit1-DR state. The state machine then uses the jtag_io method to return to the Run-Test/Idle state.

JTAG Command Layer

  • break: Forces a break point in the target board by calling the force_break() method. IRSCAN is called with a count of 4 and a tdi data stream of [0,0,0,1]. 0x8 is the instruction code for the force break OCD specific JTAG instruction.
  • run: Resumes target board program execution after a breakpoint by calling the run() method. IRSCAN is called with a count of 4 and a tdi data stream of [1,0,0,1]. 0x9 is the instruction code for the run OCD specific JTAG instruction. Additionally, the method can also be used to exit reset mode if the reset command has previously entered. It does this by calling the exit_reset() method (See creset).
  • exec [arg2]: Executes a one-word AVR instruction with the opcode specified by arg2. This command calls the exec_AVR method, passing in arg2 as the opcode input. IRSCAN is called with a count of 4 and a tdi data stream of [0,1,0,1]. 0xA is the instruction code for OCD specific JTAG instruction used to execute AVR instructions. Next, DRSCAN is called with a count of 16 and a tdi stream specified by the input opcode. The user must determine the opcode to use this method. This method is mainly used for testing in early stages of development.
  • bypass [arg2]: Performs the Boundary Scan Bypass JTAG instruction. The TDI sequence to shift in is specified by arg2. First, IRSCAN is called with a count of 4 and a tdi data stream of [0,0,1,0]. 0x4 is the instruction code for the JTAG Bypass instruction. Next, DRSCAN is called to shift in the data stream specified by the user. Finally, the method prints the TDO stream shifted out with printTDO.
  • scanio: Performs a boundary scan. First, the scanio() method calls IRSCAN with a tdi data stream of [0,1,0,0]. 0x2 is the instruction code for the Boundary Scan Preload instruction. Next, DRSCAN is called with 57 zeroes of data. Next, IRSCAN is called with a data stream of [0,0,0,0]. 0x is the instruction code for the Boundary Scan Extest instruction. DRSCAN is called again with 57 zeroes of data. The boundary scan returns 57 bits on TDO, listing the values of the I/O pins and their control values. The value of the TDO stream is then printed with printTDO.
  • reset: Resets the target board by calling the reset_avr() method. IRSCAN is called with a tdi stream of [0,0,1,1]. 0xC is the instruction code for the Boundary Scan AVR_Reset instruction. Next, DRSCAN is called with a count of 1 and a single 1 for the data stream. This is required to activate the Reset Chain.
  • creset: Exits reset mode by calling the exit_reset() method. IRSCAN is called with a tdi stream of [0,0,1,1]. 0xC is the instruction code for the Boundary Scan AVR_Reset instruction. Next, DRSCAN is called with a count of 1 and a single 0 for the data stream. This is required to exit the Reset Chain.

OCD Function Layer

All of the OCD functions first call IRSCAN with a TDI sequence of [1,1,0,1]. This is the command to access the OCD registers. DRSCAN must then be called with a TDI sequence that specifies which of the 16 OCD registers to access, a read/write flag, and the data to write if the read/write flag is set to 1. When performing a read operation, the address of the register to read must be latched first. Latching is done in the Update-DR state, so DRSCAN must be called twice. The first time with a five bit data stream, containing the register number and a 0 for the read/write flag. Then, DRSCAN must be called again with a 21 bit data stream in TDI. Four bits for the register number, 1 for the read/write flag, and 16 zeros to shift into the Data Register so that the 16 bits in it can be shifted out on TDO.

Some of the OCD functions caused the PC to increment, so the PC is restored after each of these methods so the program could resume execution.

  • rocd [arg2]: Reads the contents of the OCD register specified by arg2, from 0 - 15. If the OCD is not enabled, the enable_OCD() method is first called. The readOCD method is then called, in which DRSCAN is called once to latch the address of the specified register, and again to read the contents of the register. The pertinent bits of the TDO stream are printed when this command is finished.
  • wocd [arg2] [arg3]: Writes data specified by arg3 to the OCD register specified by arg2, from 0 - 15. If the OCD is not enabled, the enable_OCD() method is first called. The writeOCD method is then called, in which DRSCAN is called with the appropriate sequence to write the specified data to the specified register.
  • b0 [arg2]: Sets up the OCD to break on the PC value specified with arg2 by calling the set_PSB0 method. First, the flag to enable PSB0 is set in the Break Control Register. Then, the value specified by the PC input is written to the PSB0 register. The PC value is shifted right by 1 because the PC values in the lss file are shifted one from the PC values that the PC instructions use.
  • c0: Disables the break on a PC value set with the b0 command. The clear_PSB0() method is called. The EN_PSB0 flag in the Break Control Register is cleared, and the contents of the PSB0 register are cleared.
  • b1 [arg2]: Sets up the OCD to break on the PC value specified with arg2 by calling the set_PSB1 method. First, the flag to enable PSB1 is set in the Break Control Register. Then, the value specified by the PC input is written to the PSB1 register. The PC value is shifted right by 1 because the PC values in the lss file are shifted one from the PC values that the PC instructions use.
  • c1: Disables the break on a PC value set with the b1 command. The clear_PSB1() method is called. The EN_PSB1 flag in the Break Control Register is cleared, and the contents of the PSB1 register are cleared.
  • b2 [arg2]: Enables the use of PDSB to break on the PC value specified with arg2. The pgm_PDBS method is called. The EN_PDSB, PDSB0, and PDSB1 flags are set in the Break Control Register. The addr input specifies the PC value to break on, and it is written to the PDSB register.
  • c2: Disables the use of PDSB to break on a PC value by calling the clear_pPDSB method. The EN_PDSB, PDSB0, and PDSB1 flags are cleared in the Break Control Register, and the contents of the PDSB register are cleared.
  • b3 [arg2]: Enables the use of PDMSB to break on the PC value specified with arg2. The pgm_PDMSB method is called. The EN_PDMSB, PDMSB0, and PDMSB1 flags are set in the Break Control Register. The addr input specifies the PC value to break on, and it is written to the PDMSB register.
  • c3: Disables the use of PDMSB to break on a PC value by calling the clear_pPDMSB method. The EN_PDMSB, PDMSB0, and PDMSB1 flags are cleared in the Break Control Register, and the contents of the PDMSB register are cleared.
  • bd0 [arg2]: Enables the use of PDSB to break on data access at the memory address specified by arg2. The data_PDSB method is called. First, the EN_PDSB and PDSB1 flags are set in the Break Control Register. The d_addr input specifies the address in memory of the data to break on. This value is written to the PDSB register.
  • cd0: Disables the break on data access at the memory address stored in PDSB by calling the clear_dPDSB method. First, the EN_PDSB and PDSB1 flags are cleared in the Break Control Register. The contents of the PDSB register are cleared.
  • bd1: Enables the use of PDMSB to break on data access at the memory address specified by arg2. The data_PDMSB method is called. First, the EN_PDMSB and PDMSB1 flags are set in the Break Control Register. The d_addr input specifies the address in memory of the data to break on. This value is written to the PDMSB register.
  • cd1: Disables the break on data access at the memory address stored in PDMSB by calling the clear_dPDMSB. First, the EN_PDMSB and PDMSB1 flags are cleared in the Break Control Register. The contents of the PDMSB register are cleared.
  • step: Enables single step breaking by setting the EN_STEP flag in the Break Control Register. Using this command, the user can step through the target board program one instruction at a time.
  • cstep: Disables single step breaking by clearing the EN_STEP flag in the Break Control Register.
  • stepf: Enables a break on change in program flow by setting the EN_FLOW flag in the Break Control Register. Using this command, the target board program will run until it encounters an instruction like a branch, jump, or ISR that changes program flow.
  • cflow: Disables the break on change in program flow by clearing the EN_FLOW flag in the Break Control Register.
  • runtimer: Enables timers to run during a break by setting the RUNTIMER flag in the Break Control Register.
  • clearall: Disables all break points. It clears the Break Control Register, PSB0, PSB1, PDSB, and PDMSB.
  • enocd: Enables the OCDR, which is used to communicate with the On-Chip Debugger. This command calls the enable_OCD() method, which is also called by the rocd and wocd commands if communication with the OCDR has not been enabled yet.
  • rocdr: Reads the contents of the OCDR. The contents of OCDR are printed on screen when this command is finished.

Assembly Function Layer

All assembly function layer methods execute AVR instructions. The first thing each method does is to call IRSCAN with [0,1,0,1] as the tdi stream, then they call DRSCAN with the appropriate opcode stored in the input stream. See the AVR Instruction Set for a description of each instruction and its corresponding opcode. Since execution of an AVR command causes the PC to increment, we restored the PC after execution of the AVR instruction. Some operations also made use of general purpose register 31 for temporary data storage. The contents of GPR 31 were stored and restored before and after execution of these instructions.

  • pc: This command prints the current PC value, retrieved by the read_PC() method, which uses a two word AVR instruction to read the PC. The PC value returned by the AVR instruction is right shifted by one bit to match the PC value reported in the lss file. This method actually returns the next PC, so we subtracted the PC increment to return the current value.
  • jump [arg2]: Jumps to the PC value specified by arg2 by calling the ijump method. The method indirectly changes the PC value using the Z register.
  • rjmp [arg2]: Calls the rjmp AVR instruction, which jumps to PC+k+1, where k is a signed integer specified by arg2.
  • sbi [arg2] [arg3]: Sets a single bit in an I/O register. The value of arg2 specifies which I/O register to use, from 0 to 31. The value of arg3 specifies which bit to set, from 0 to 7.
  • cbi [arg2] [arg3]: Clears a single bit in an I/O register. The value of arg2 specifies which I/O register to use, from 0 to 31. The value of arg3 specifies which bit to clear, from 0 to 7.
  • sbr [arg2] [arg3]: Sets the bits in the data register specified by arg2 to the value specified by arg3. This is done by performing a logical OR operation between the current contents of the register with the value. The value of arg2 ranges from 16 to 31, and arg3 ranges from 0 to 255.
  • cbr [arg2] [arg3]: Clears the bits in the data register specified by arg2 to the value specified by arg3. This is done by performing a logical AND operation between the current contents of the register with the complement of the value. The value of arg2 ranges from 16 to 31, and arg3 ranges from 0 to 255.
  • out [arg2] [arg3]: Outputs a value from the data register specified by arg2 to the I/O register specifies by arg3. The value of arg2 ranges from 0 to 31. The value of arg3 ranges from 0 to 63.
  • in [arg2] [arg3]: Inputs a value from the I/O register specified by arg3 into the data register specified by arg2. The value of arg3 ranges from 0 to 63. The value of arg2 ranges from 0 to 31.
  • sei: Sets the Global Interrupt Flag in the target board, enabling interrupts.
  • cli: Clears the Global Interrupt Flag in the target board, disabling interrupts.

User Command Layer

  • rreg [arg2]: Reads from the general purpose register specified by arg2, from 0 to 31. The contents of the register are printed on the screen.
  • wreg [arg2] [arg3]: Writes the immediate specified by arg3 into the general purpose register specified by arg2, from 0 to 31. This command performs a load immediate instruction and stores the immediate in the specified register.
  • rio [arg2]: Reads from the I/O register specified by arg2, from 0 to 63. This command uses the in instruction, and it prints the value read on screen.
  • wio [arg2] [arg3]: Writes the immediate specified by arg3 into the I/O register specified by arg2, from 0 to 63. This command uses the load immediate and out instructions.
  • rmem [arg2] [arg3]: Reads from memory. The value of arg2 specifies the base address to start reading from, and the value of arg3 specifies the number of bytes to read. If arg3 is not specified, the default size of 1 will be used. This command uses the ld instruction. When finished, each byte of memory read is printed on screen.
  • wmem [arg2] [arg3]: Writes the immediate specified by arg3 to the memory address specified by arg2. This command uses the ldi and st instructions.
  • restart: Restarts target board program execution by calling both the reset_avr and exit_reset JTAG methods.
  • resetd: Restarts program execution on both the debugger and the target board with by performing a jmp 0 assembler instruction.

Other Methods

  • addx [arg2] [arg3]: Prints the sum arg2 + arg3 in hex.
  • add [arg2] [arg3]: Prints the sum arg2 + arg3 in base 10.
  • subx [arg2] [arg3]: Prints the difference arg2 - arg3 in hex.
  • sub [arg2] [arg3]: Prints the difference arg2 - arg3 in base 10.
  • sr [arg2] [arg3]: Right shifts arg2 by arg3 and prints the result in hex.
  • sl [arg2] [arg3]: Left shifts arg2 by arg3 and prints the result in hex.
  • multx [arg2] [arg3]: Prints the product arg2 * arg3 in hex.
  • mult [arg2] [arg3]: Prints the product arg2 * arg3 in base 10.
  • divx [arg2] [arg3]: Prints the quotient arg2 / arg3 in hex.
  • div [arg2] [arg3]: Prints the quotient arg2 / arg3 in base 10.
  • ~ [arg2]: Negates arg2 and prints the result.
  • nop: Executes a 1 word nop instruction.
  • help [arg2]: Prints descriptions of the methods in the software layer specified by the user in arg2. The four possible values are "jtag", "ocd", "asm", and "user".