4646/**
4747 * RVSWD I/O is shared with SWD
4848 */
49- #define RVSWD_DIO_DIR_PORT SWDIO_DIR_PORT
50- #define RVSWD_DIO_PORT SWDIO_PORT
51- #define RVSWD_CLK_PORT SWCLK_PORT
52- #define RVSWD_DIO_DIR_PIN SWDIO_DIR_PIN
53- #define RVSWD_DIO_PIN SWDIO_PIN
54- #define RVSWD_CLK_PIN SWCLK_PIN
49+ #define RVSWD_DIO_PORT SWDIO_PORT
50+ #define RVSWD_DIO_PIN SWDIO_PIN
51+
52+ #define RVSWD_CLK_PORT SWCLK_PORT
53+ #define RVSWD_CLK_PIN SWCLK_PIN
5554
5655#define RVSWD_DIO_MODE_FLOAT SWDIO_MODE_FLOAT
5756#define RVSWD_DIO_MODE_DRIVE SWDIO_MODE_DRIVE
5857
58+ typedef enum rvswd_direction_t {
59+ RVSWD_DIRECTION_INPUT ,
60+ RVSWD_DIRECTION_OUTPUT
61+ } rvswd_direction_t ;
62+
5963rvswd_proc_s rvswd_proc ;
6064
6165static void rvswd_start (void ) __attribute__((optimize (3 )));
@@ -84,19 +88,21 @@ void rvswd_init(void)
8488 rvswd_proc .seq_out = rvswd_seq_out ;
8589}
8690
87- static void rvswd_set_dio_direction (bool output )
91+ static void rvswd_set_dio_direction (rvswd_direction_t direction )
8892{
8993 /* Do nothing if the direction is already set */
90- static bool current_direction = false;
91- if (output == current_direction )
94+ /* FIXME: this internal state may become invalid if the IO is modified elsewhere (e.g. SWD) */
95+ static rvswd_direction_t current_direction = RVSWD_DIRECTION_INPUT ;
96+ if (direction == current_direction )
9297 return ;
9398
9499 /* Change the direction */
95- if (output )
100+ if (direction == RVSWD_DIRECTION_OUTPUT ) {
96101 RVSWD_DIO_MODE_DRIVE ();
97- else
102+ } else {
98103 RVSWD_DIO_MODE_FLOAT ();
99- current_direction = output ;
104+ }
105+ current_direction = direction ;
100106}
101107
102108static void rvswd_start (void )
@@ -106,9 +112,9 @@ static void rvswd_start(void)
106112 */
107113
108114 /* Setup for the start sequence by setting the bus to the idle state */
109- rvswd_set_dio_direction (true);
115+ rvswd_set_dio_direction (RVSWD_DIRECTION_OUTPUT );
116+ gpio_set (RVSWD_DIO_PORT , RVSWD_DIO_PIN );
110117 gpio_set (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
111- gpio_set (RVSWD_DIO_DIR_PORT , RVSWD_DIO_PIN );
112118
113119 /* Ensure the bus is idle for a period */
114120 rvswd_hold_period ();
@@ -124,14 +130,9 @@ static void rvswd_stop(void)
124130 * DIO rising edge while CLK is idle high marks a STOP condition
125131 */
126132
127- /*
128- * Setup for the stop condition by driving the CLK and DIO low
129- *
130- * It is likely that the previous sequence left the CLK low already
131- * but a redundant low CLK set ensures we don't issue a start condition by mistake
132- */
133+ /* Setup for the stop condition by driving the CLK and DIO low */
133134 gpio_clear (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
134- rvswd_set_dio_direction (true );
135+ rvswd_set_dio_direction (RVSWD_DIRECTION_OUTPUT );
135136 gpio_clear (RVSWD_DIO_PORT , RVSWD_DIO_PIN );
136137
137138 /* Ensure setup for a period */
@@ -153,14 +154,16 @@ static uint32_t rvswd_seq_in_clk_delay(const size_t clock_cycles)
153154 gpio_clear (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
154155 rvswd_hold_period ();
155156
156- /* Sample the DIO line and raise the CLK, then hold for a period */
157+ /* Sample the DIO line and Raise the CLK, then hold for a period */
157158 value |= gpio_get (RVSWD_DIO_PORT , RVSWD_DIO_PIN ) ? (1U << (cycle - 1U )) : 0U ;
158159 gpio_set (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
159160 rvswd_hold_period ();
160161 }
161162
162- /* Leave the CLK low and return the value */
163- gpio_clear (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
163+ // /* Leave the CLK low and return the value */
164+ // gpio_clear(RVSWD_CLK_PORT, RVSWD_CLK_PIN);
165+
166+ /* Leave the CLK high and return the value */
164167 return value ;
165168}
166169
@@ -176,19 +179,19 @@ static uint32_t rvswd_seq_in_no_delay(const size_t clock_cycles)
176179 /* Sample the DIO line and raise the CLK */
177180 value |= gpio_get (RVSWD_DIO_PORT , RVSWD_DIO_PIN ) ? (1U << (cycle - 1U )) : 0U ;
178181 gpio_set (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
179-
180- __asm__("nop" ); /* Ensure there's time for the CLK to settle */
181182 }
182183
183- /* Leave the CLK low and return the value */
184- gpio_clear (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
184+ // /* Leave the CLK low and return the value */
185+ // gpio_clear(RVSWD_CLK_PORT, RVSWD_CLK_PIN);
186+
187+ /* Leave the CLK high and return the value */
185188 return value ;
186189}
187190
188191static uint32_t rvswd_seq_in (size_t clock_cycles )
189192{
190193 /* Set the DIO line to float to give control to the target */
191- rvswd_set_dio_direction (false );
194+ rvswd_set_dio_direction (RVSWD_DIRECTION_INPUT );
192195
193196 /* Delegate to the appropriate sequence in routine depending on the clock divider */
194197 if (target_clk_divider != UINT32_MAX )
@@ -211,8 +214,10 @@ static void rvswd_seq_out_clk_delay(const uint32_t dio_states, const size_t cloc
211214 rvswd_hold_period ();
212215 }
213216
214- /* Leave the CLK low */
215- gpio_clear (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
217+ // /* Leave the CLK low */
218+ // gpio_clear(RVSWD_CLK_PORT, RVSWD_CLK_PIN);
219+
220+ /* Leave the CLK high and return */
216221}
217222
218223static void rvswd_seq_out_no_delay (const uint32_t dio_states , const size_t clock_cycles )
@@ -227,14 +232,16 @@ static void rvswd_seq_out_no_delay(const uint32_t dio_states, const size_t clock
227232 gpio_set (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
228233 }
229234
230- /* Leave the CLK low */
231- gpio_clear (RVSWD_CLK_PORT , RVSWD_CLK_PIN );
235+ // /* Leave the CLK low */
236+ // gpio_clear(RVSWD_CLK_PORT, RVSWD_CLK_PIN);
237+
238+ /* Leave the CLK high and return */
232239}
233240
234241static void rvswd_seq_out (const uint32_t dio_states , const size_t clock_cycles )
235242{
236243 /* Set the DIO line to drive to give us control */
237- rvswd_set_dio_direction (true );
244+ rvswd_set_dio_direction (RVSWD_DIRECTION_OUTPUT );
238245
239246 /* Delegate to the appropriate sequence in routine depending on the clock divider */
240247 if (target_clk_divider != UINT32_MAX )
0 commit comments