diff --git a/orbtrace/debug/cmsis_dap.py b/orbtrace/debug/cmsis_dap.py index 60a425a..e4d83eb 100644 --- a/orbtrace/debug/cmsis_dap.py +++ b/orbtrace/debug/cmsis_dap.py @@ -205,7 +205,7 @@ def __init__(self, streamIn, streamOut, dbgif, v2Indication): # Support for DAP_Transfer_Block self.tfB_txb = Signal(4) # TFR Block State machine index (12 states) - self.Bretries = Signal(16) # Retry counter for WAIT + self.Bretries = Signal(16) # Retry counter for WAIT self.transferBCount = Signal(16) # Number of transfers 1..65535 self.readBDelay = Signal() # We are doing a posted read self.readBIgnore = Signal() # Don't swallow this data, we're starting to post @@ -213,7 +213,7 @@ def __init__(self, streamIn, streamOut, dbgif, v2Indication): # Support for RESP_Transfer_Complete self.txb = Signal(4) # Transfer complete state machine (8 states) self.transferCCount = Signal(16) # Number of transfers 1..65535 - + # CMSIS-DAP Configuration info self.waitRetry = Signal(16,reset=4096) # Number of transfer retries after WAIT response self.matchRetry = Signal(16,reset=16) # Number of retries on reads with Value Match in DAP_Transfer @@ -290,7 +290,7 @@ def RESP_Connect_Setup(self, m): m.d.sync += [ self.txBlock.word_select(0,16).eq(Cat(self.rxBlock.word_select(0,8),C(1,8))), self.dbgif.command.eq(CMD_SET_SWD), - self.isJTAG.eq(0), + self.isJTAG.eq(0), self.txLen.eq(2), self.dbgif.go.eq(1) ] @@ -302,7 +302,7 @@ def RESP_Connect_Setup(self, m): m.d.sync += [ self.txBlock.word_select(0,16).eq(Cat(self.rxBlock.word_select(0,8),C(2,8))), self.dbgif.command.eq(CMD_SET_JTAG), - self.isJTAG.eq(1), + self.isJTAG.eq(1), self.txLen.eq(2), self.dbgif.go.eq(1) ] @@ -487,7 +487,7 @@ def RESP_JTAG_Configure_Setup(self, m): m.d.sync += [ self.dbgif.command.eq( CMD_SET_JTAG_CFG ), self.jtag_ircount.eq(0), - self.dbgif.dev.eq(self.rxBlock.bit_select(8,3)-1) + self.dbgif.dev.eq(self.rxBlock.bit_select(8,4)-1) ] m.next='JTAG_Configure_PROCESS'; @@ -568,7 +568,7 @@ def RESP_Transfer_Setup(self, m): # Filter for case someone tries to send us no transfers to perform # in which case we send back a good ack! with m.If(self.rxBlock.bit_select(16,8)!=0): - m.next = 'DAP_Transfer_PROCESS'; + m.next = 'DAP_Transfer_PROCESS' with m.Else(): m.d.sync += [ self.txBlock.word_select(2,8).eq(C(1,8)), @@ -576,7 +576,7 @@ def RESP_Transfer_Setup(self, m): ] m.next = 'RESPOND' - + def RESP_Transfer_Process(self, m): m.d.comb += self.tfrram.dat_w.eq(self.dbgif.dread) @@ -602,7 +602,7 @@ def RESP_Transfer_Process(self, m): m.d.sync += [ self.tfr_txb.eq(6), self.tfrReq.eq(0x0e), - self.readDelay.eq(0), + self.readDelay.eq(0), ] with m.Else(): # Otherwise progress to the exit states @@ -617,11 +617,10 @@ def RESP_Transfer_Process(self, m): m.d.sync += self.busy.eq(0) with m.Else(): # We are consuming this event, so count it - with m.If(self.transferTCount): - m.d.sync += self.transferTCount.eq(self.transferTCount-1) + m.d.sync += self.transferTCount.eq(self.transferTCount-1) # This is a good transaction from the stream, so record the fact it's in flow m.d.sync += self.txBlock.word_select(1,8).eq(self.txBlock.word_select(1,8)+1) - + # Check to see if readDelay continues... # Rule for JTAG is any read, for SWD it's any AP read # If it doesn't then we need to collect these data before progressing @@ -649,11 +648,11 @@ def RESP_Transfer_Process(self, m): self.readIgnore.eq((~self.readDelay) & ((self.isJTAG & (self.tfrReq.bit_select(1,1))) | ((~self.isJTAG) & (self.tfrReq.bit_select(0,2)==3)))) ] - + # ..and now go do the read or write as appropriate with m.If ((~self.tfrReq.bit_select(1,1)) | self.tfrReq.bit_select(4,1) | - self.tfrReq.bit_select(5,1) ): + self.tfrReq.bit_select(5,1) ): # Need to collect the value m.d.sync += self.tfr_txb.eq(2) with m.Else(): @@ -742,7 +741,7 @@ def RESP_Transfer_Process(self, m): m.d.sync += self.tfrram.adr.eq(self.tfrram.adr+1) m.d.sync += self.tfr_txb.eq(0) - + # Transfer completed, start sending data back ----------------------------------------- with m.Case(10,11,12): with m.If(self.streamIn.ready): @@ -760,7 +759,7 @@ def RESP_Transfer_Process(self, m): self.txb.eq(0), self.txedLen.eq((self.tfrram.adr*4)+3) # Record length of data to be returned ] - + # ---------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------- def RESP_TransferBlock_Setup(self, m): @@ -772,7 +771,7 @@ def RESP_TransferBlock_Setup(self, m): m.d.sync += [ # DAP Index is 1 byte in, transfer count is dealt with at the end - self.dbgif.dev.eq(self.rxBlock.bit_select(13,3)), + self.dbgif.dev.eq(self.rxBlock.bit_select(8,3)), self.tfrram.adr.eq(0), # We will not read back the first word immediately if we're in JTAG read @@ -904,7 +903,7 @@ def RESP_TransferBlock_Process(self, m): # ---------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------- - + def RESP_Transfer_Complete(self, m): # Complete the process of returning data collected via either Transfer_Process or # TransferBlock_Process. Data count to be transferred is inferred by ram address and diff --git a/verilog/dbgIF.v b/verilog/dbgIF.v index 8721674..07d6d52 100644 --- a/verilog/dbgIF.v +++ b/verilog/dbgIF.v @@ -188,6 +188,7 @@ module dbgIF #(parameter CLK_FREQ=100000000, parameter DEFAULT_SWCLK=1000000, pa // JTAG Related reg [2:0] ndevs; // Number of devices in JTAG chain + reg [3:0] current_dev; // The currently selected device reg [29:0] irlenx; // Length of each IR-1, 5x5 bits reg [3:0] ir; // Last written ir contents @@ -252,12 +253,12 @@ module dbgIF #(parameter CLK_FREQ=100000000, parameter DEFAULT_SWCLK=1000000, pa (active_mode==MODE_JTAG)?jtag_tms: local_swdo; assign jtag_tdo = tdo_swo; - + assign jtag_wr = 1'b1; assign tdi = ((dbg_state==ST_DBG_IDLE) || (active_mode==MODE_SWJ))?pinw_tdi :(active_mode==MODE_JTAG)?jtag_tdi :1'b1; - + assign swwr = ((dbg_state==ST_DBG_IDLE) || (active_mode==MODE_SWJ))?pinw_swwr :(active_mode==MODE_SWD)?swd_swwr :(active_mode==MODE_JTAG)?jtag_wr @@ -343,7 +344,7 @@ module dbgIF #(parameter CLK_FREQ=100000000, parameter DEFAULT_SWCLK=1000000, pa ); assign pinw_swclk = pinsin[8+0] ?pinsin[0]:1'b1; - + //////////////////////////////////////////////////////////////////////////////////////////////////////// always @(posedge clk, posedge rst) @@ -357,6 +358,7 @@ module dbgIF #(parameter CLK_FREQ=100000000, parameter DEFAULT_SWCLK=1000000, pa ir <= JTAG_BYPASS; idleCycles <= MIN_IDLE_CYCLES; turnaround <= 0; + current_dev <= 4'b1000; end else begin @@ -369,19 +371,19 @@ module dbgIF #(parameter CLK_FREQ=100000000, parameter DEFAULT_SWCLK=1000000, pa pinw_tdi <= pinsin[8+2]?pinsin[2]:1; pinw_swwr <= pinsin[8+4]?pinsin[4]:0; pinw_swdo <= pinsin[8+1]?pinsin[1]:0; - + // Run the clock, and edge detection cdivcount <= cdivcount?cdivcount-1:clkDiv; risingedge <= 0; fallingedge <= 0; - + if (cdivcount==0) begin risingedge <= ~root_tgtclk; fallingedge <= root_tgtclk; root_tgtclk <= ~root_tgtclk; end - + // The usecs counter can run all of the time, it's independent usecsdiv<=usecsdiv?usecsdiv-1:TICKS_PER_USEC-1; @@ -439,11 +441,15 @@ module dbgIF #(parameter CLK_FREQ=100000000, parameter DEFAULT_SWCLK=1000000, pa CMD_TRANSACT: // Execute transaction on target interface -------------------------- if (fallingedge) begin - if ((commanded_mode==MODE_JTAG) && (ir!= (apndp?JTAG_APACC:JTAG_DPACC))) + // If we're in JTAG mode and either the device changed, or the IR state needed + // changed, then update the IR chain value + if ((commanded_mode==MODE_JTAG) && ((current_dev!=dev) || + (ir!= (apndp?JTAG_APACC:JTAG_DPACC)))) begin // Before we go any further we have to setup the right IR to write to jtag_cmd <= JTAG_CMD_IR; JTAG_trans_os <= 1'b1; + current_dev <= dev; end else begin diff --git a/verilog/jtagIF.v b/verilog/jtagIF.v index a6da07a..0c53f07 100644 --- a/verilog/jtagIF.v +++ b/verilog/jtagIF.v @@ -68,7 +68,6 @@ module jtagIF ( parameter ST_JTAG_IDDATA = 3; // Getting ID data parameter ST_JTAG_WRITEIR = 5; // Writing IR parameter ST_JTAG_TRANSFER = 6; // Performing Data Transfer - assign idle = (jtag_state==ST_JTAG_IDLE); // ======================================================================================================== @@ -138,7 +137,7 @@ module jtagIF ( endcase // case (cmd) end end // case: ST_JTAG_IDLE - + // ============================================================================================== ST_JTAG_TRANSFER: // TRANSFER Supporting State ================================================== begin @@ -146,7 +145,7 @@ module jtagIF ( tmsbits <= 6'b000100; // 6'b000001; tmscount <= 3; next_state <= ST_JTAG_IDLE; - + if (falling) // Write Host -> Device ------------------------------------------------------- begin if (devcount!=dev) @@ -156,28 +155,30 @@ module jtagIF ( 0: tdi<=rnw; 1: tdi<=addr32[0]; 2: tdi<=addr32[1]; - + default: tdi <= rnw?1'b1:dwrite[windex]; endcase // case (tdxcount) - - if ((devcount==ndevs)) - tms <= 1'b1; + + // If we're on the last device + if ((devcount==ndevs) && ((34==tdxcount) || (devcount!=dev))) + // Signal EXIT1-DR + tms <= 1'b1; end - + if (rising) // Read Device -> Host -------------------------------------------------------- begin tdxcount <= tdxcount+1; windex <= windex+1; - + case (tdxcount) 0: ack[0]<=tdo; 1: ack[1]<=tdo; - 2: + 2: begin ack[2]<=tdo; windex<=0; - + // If ack is wait then abort if ({tdo,ack[1],ack[0]}!=2) begin @@ -187,7 +188,7 @@ module jtagIF ( end default: dread[windex] <= tdo; endcase // case (tdxcount) - + // In bypass for every device except the target, so only 1 bit if ((devcount!=dev) || (34==tdxcount)) begin @@ -201,18 +202,18 @@ module jtagIF ( end end // if (rising) end - + // ============================================================================================== ST_JTAG_IDDATA: // READID Supporting States ===================================================== begin if (falling) tdi <= ((devcount==dev) & (rnw==0))?dwrite[tdxcount]:1'b0; - + if (rising) begin tdxcount <= tdxcount+1; dread[tdxcount] <= tdo; - + // For ID read it's always 32 bits... if (5'h1f==tdxcount) begin @@ -236,7 +237,7 @@ module jtagIF ( if (falling) jtag_state <= ST_JTAG_TMSOUT; end - + // ============================================================================================== ST_JTAG_WRITEIR: // SETIR Supporting states ===================================================== begin @@ -247,18 +248,18 @@ module jtagIF ( if (falling) begin tdi <= (devcount==dev)?ir[tdxcount]:1'b1; - + // If we are on the last bit then signal tms to leave if ((devcount==ndevs) && (tdxcount[4:0]+1 == irlenx[ 5*devcount +:5 ] )) tms <= 1'b1; end - + if (rising) begin tdxcount <= tdxcount+1; - + if ( tdxcount[4:0]+1 == irlenx[ 5*devcount +:5 ] ) - + begin if (devcount==ndevs) jtag_state <= ST_JTAG_TMSOUT; @@ -270,7 +271,7 @@ module jtagIF ( end end end // case: ST_JTAG_WRITEIR - + // ============================================================================================== ST_JTAG_TMSOUT: // clock out defined tms bits =================================================== begin @@ -288,4 +289,3 @@ module jtagIF ( endcase // case (jtag_state) end // always @ (posedge clk) endmodule // jtagIF -