fix(dap): Fix timing problems in the SPI
This commit is contained in:
		
							parent
							
								
									1f30a57c78
								
							
						
					
					
						commit
						f9db957170
					
				
							
								
								
									
										18
									
								
								README.md
								
								
								
								
							
							
						
						
									
										18
									
								
								README.md
								
								
								
								
							|  | @ -180,6 +180,24 @@ When you select max clock, we will take the following actions: | ||||||
| 
 | 
 | ||||||
| > Note that the most significant speed constraint of this project is still the TCP connection speed. | > Note that the most significant speed constraint of this project is still the TCP connection speed. | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | ## For OpenOCD user | ||||||
|  | 
 | ||||||
|  | This project was originally designed to run on Keil, but now you can also perform firmware flash on OpenOCD. | ||||||
|  | 
 | ||||||
|  | Note that if you want to use a 40MHz SPI acceleration, you need to specify the speed after the target device is connected, otherwise it will fail with the beginning. | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | # Run before approaching the flash command | ||||||
|  | > adapter speed 10000 | ||||||
|  | 
 | ||||||
|  | # > halt | ||||||
|  | # > flash write_image [erase] [unlock] filename [offset] [type] | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > Keil's timing handling is somewhat different from OpenOCD's. For example, OpenOCD lacks the SWD line reset sequence before reading the `IDCODE` registers. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| ## Develop | ## Develop | ||||||
| 
 | 
 | ||||||
| 0.  Check other branches to know the latest development progress. | 0.  Check other branches to know the latest development progress. | ||||||
|  |  | ||||||
|  | @ -329,10 +329,11 @@ __STATIC_INLINE void PORT_JTAG_SETUP(void) | ||||||
|  */ |  */ | ||||||
| __STATIC_INLINE void PORT_SWD_SETUP(void) | __STATIC_INLINE void PORT_SWD_SETUP(void) | ||||||
| { | { | ||||||
|   // At this stage we do not consider whether to use SPI or GPIO.
 |  | ||||||
|   // We will switch to the specific mode when setting the transfer rate.
 |   // We will switch to the specific mode when setting the transfer rate.
 | ||||||
|   DAP_SPI_Init(); | 
 | ||||||
|   DAP_SPI_Disable(); |   // Now we need to set it to ordinary GPIO mode. In most implementations,
 | ||||||
|  |   // the DAP will then read the status of the PIN via the `SWJ_PIN` command.
 | ||||||
|  |   DAP_SPI_Deinit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  |  | ||||||
|  | @ -264,6 +264,9 @@ static uint32_t DAP_ResetTarget(uint8_t *response) { | ||||||
| //             number of bytes in request (upper 16 bits)
 | //             number of bytes in request (upper 16 bits)
 | ||||||
| static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) { | static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) { | ||||||
| #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) | #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) | ||||||
|  |   if (SWD_TransferSpeed == kTransfer_SPI) | ||||||
|  |     DAP_SPI_Deinit(); | ||||||
|  | 
 | ||||||
|   uint32_t value; |   uint32_t value; | ||||||
|   uint32_t select; |   uint32_t select; | ||||||
|   uint32_t wait; |   uint32_t wait; | ||||||
|  | @ -356,6 +359,9 @@ static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) { | ||||||
|   *response = 0U; |   *response = 0U; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |   if (SWD_TransferSpeed == kTransfer_SPI) // restore
 | ||||||
|  |     DAP_SPI_Init(); | ||||||
|  | 
 | ||||||
|   return ((6U << 16) | 1U); |   return ((6U << 16) | 1U); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -505,15 +511,16 @@ static uint32_t DAP_SWD_Sequence(const uint8_t *request, uint8_t *response) { | ||||||
|     } |     } | ||||||
|     count = (count + 7U) / 8U; |     count = (count + 7U) / 8U; | ||||||
| #if (DAP_SWD != 0) | #if (DAP_SWD != 0) | ||||||
|     if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { |     ////FIXME: ?
 | ||||||
|       PIN_SWDIO_OUT_DISABLE(); |     // if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
 | ||||||
|     } else { |     //   PIN_SWDIO_OUT_DISABLE();
 | ||||||
|       PIN_SWDIO_OUT_ENABLE(); |     // } else {
 | ||||||
|     } |     //   PIN_SWDIO_OUT_ENABLE();
 | ||||||
|  |     // }
 | ||||||
|     SWD_Sequence(sequence_info, request, response); |     SWD_Sequence(sequence_info, request, response); | ||||||
|     if (sequence_count == 0U) { |     // if (sequence_count == 0U) {
 | ||||||
|       PIN_SWDIO_OUT_ENABLE(); |     //   PIN_SWDIO_OUT_ENABLE();
 | ||||||
|     } |     // }
 | ||||||
| #endif | #endif | ||||||
|     if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { |     if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { | ||||||
|       request_count++; |       request_count++; | ||||||
|  |  | ||||||
|  | @ -37,6 +37,11 @@ typedef enum { | ||||||
|  */ |  */ | ||||||
| void DAP_SPI_Init() | void DAP_SPI_Init() | ||||||
| { | { | ||||||
|  |     // The driving of GPIO should be stopped,
 | ||||||
|  |     // otherwise SPI has potential timing issues (This issue has been identified in OpenOCD)
 | ||||||
|  |     GPIO.out_w1tc = (0x1 << 13); | ||||||
|  |     GPIO.out_w1tc = (0x1 << 14); | ||||||
|  | 
 | ||||||
|     // Disable flash operation mode
 |     // Disable flash operation mode
 | ||||||
|     DAP_SPI.user.flash_mode = false; |     DAP_SPI.user.flash_mode = false; | ||||||
| 
 | 
 | ||||||
|  | @ -145,6 +150,9 @@ __FORCEINLINE void DAP_SPI_Deinit() | ||||||
|     GPIO.enable_w1tc |= (0x1 << 12); |     GPIO.enable_w1tc |= (0x1 << 12); | ||||||
| #endif // (USE_SPI_SIO != 1)
 | #endif // (USE_SPI_SIO != 1)
 | ||||||
| 
 | 
 | ||||||
|  |     // enable SWCLK output
 | ||||||
|  |     GPIO.enable_w1ts |= (0x01 << 14); | ||||||
|  | 
 | ||||||
|     gpio_pin_reg_t pin_reg; |     gpio_pin_reg_t pin_reg; | ||||||
|     GPIO.enable_w1ts |= (0x1 << 13); |     GPIO.enable_w1ts |= (0x1 << 13); | ||||||
|     GPIO.pin[13].driver = 1; // OD output
 |     GPIO.pin[13].driver = 1; // OD output
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue