0
0
Fork 0

feat(esp32c3): Add support for esp32c3

This commit is contained in:
windowsair 2022-09-17 14:10:02 +08:00
parent 6d24440d7d
commit efdfec0362
16 changed files with 1674 additions and 135 deletions

View File

@ -1,4 +1,3 @@
test
<p align="center"><img src="https://user-images.githubusercontent.com/17078589/120061980-49274280-c092-11eb-9916-4965f6c48388.png"/></p>
![image](https://user-images.githubusercontent.com/17078589/107857220-05ecef00-6e68-11eb-9fa0-506b32052dba.png)
@ -30,6 +29,7 @@ For Keil users, we now also support [elaphureLink](https://github.com/windowsair
1. SoC Compatibility
- [x] ESP8266/8285
- [x] ESP32
- [x] ESP32C3
2. Debug Communication Mode
- [x] SWD
@ -43,7 +43,8 @@ For Keil users, we now also support [elaphureLink](https://github.com/windowsair
- [x] Uart TCP Bridge
5. More..
- [x] SWD protocol based on SPI acceleration
- [x] SWD protocol based on SPI acceleration (Up to 40MHz)
- [x] Support for [elaphureLink](https://github.com/windowsair/elaphureLink), fast Keil debug without drivers
- [x] ...
@ -138,8 +139,48 @@ There is built-in ipv4 only mDNS server. You can access the device using `dap.lo
| Other | |
|--------------------|---------------|
| LED\_WIFI\_STATUS | GPIO27 |
| Tx | GPIO10 |
| Rx | GPIO9 |
| Tx | GPIO23 |
| Rx | GPIO22 |
> Rx and Tx is used for uart bridge, not enabled by default.
</details>
<details>
<summary>ESP32C3</summary>
| SWD | |
|----------------|--------|
| SWCLK | GPIO6 |
| SWDIO | GPIO7 |
| TVCC | 3V3 |
| GND | GND |
--------------
| JTAG | |
|--------------------|---------|
| TCK | GPIO6 |
| TMS | GPIO7 |
| TDI | GPIO9 |
| TDO | GPIO8 |
| nTRST \(optional\) | GPIO4 |
| nRESET | GPIO5 |
| TVCC | 3V3 |
| GND | GND |
--------------
| Other | |
|--------------------|---------------|
| LED\_WIFI\_STATUS | GPIO10 |
| Tx | GPIO19 |
| Rx | GPIO18 |
> Rx and Tx is used for uart bridge, not enabled by default.
@ -204,11 +245,11 @@ python ./idf.py -p /dev/ttyS5 flash
<details>
<summary>ESP32</summary>
<summary>ESP32/ESP32C3</summary>
1. Get esp-idf
For now, please use esp-idf v4.2: https://github.com/espressif/esp-idf/releases/tag/v4.2
For now, please use esp-idf v4.4.2 : https://github.com/espressif/esp-idf/releases/tag/v4.4.2
2. Build & Flash
@ -239,7 +280,7 @@ idf.py -p /dev/ttyS5 flash
- Windows: [usbip-win](https://github.com/cezanne/usbip-win) .
- Linux: Distributed as part of the Linux kernel, but we have not yet tested on Linux platform, and the following instructions are all under Windows platform.
2. Start esp8266 and connect it to the device to be debugged
2. Start ESP chip and connect it to the device to be debugged
3. Connect it with usbip:
@ -247,12 +288,12 @@ idf.py -p /dev/ttyS5 flash
# HID Mode only
# for pre-compiled version on SourceForge
# or usbip old version
.\usbip.exe -D -a <your-esp8266-ip-address> 1-1
.\usbip.exe -D -a <your-esp-device-ip-address> 1-1
# 👉 Recommend
# HID Mode Or WinUSB Mode
# for usbip-win 0.3.0 kmdf ude
.\usbip.exe attach_ude -r <your-esp8266-ip-address> -b 1-1
.\usbip.exe attach_ude -r <your-esp-device-ip-address> -b 1-1
```
@ -330,7 +371,7 @@ When this project is updated, you can update the firmware over the air.
Visit the following website for OTA operations: [online OTA](http://corsacota.surge.sh/?address=dap.local:3241)
For most ESP8266 devices, you don't need to care about flash size. However, improper setting of the flash size may cause the OTA to fail. In this case, please change the flash size with `idf.py menuconfig`, or modify `sdkconfig`:
For most devices, you don't need to care about flash size. However, improper setting of the flash size may cause the OTA to fail. In this case, please change the flash size with `idf.py menuconfig`, or modify `sdkconfig`:
```
# Choose a flash size.
@ -378,7 +419,7 @@ Recv data <- TCP <- Uart Rx <- external devices
![uart_tcp_bridge](https://user-images.githubusercontent.com/17078589/150290065-05173965-8849-4452-ab7e-ec7649f46620.jpg)
When the TCP connection is established, bridge will try to resolve the text sent for the first time. When the text is a valid baud rate, bridge will switch to it.
When the TCP connection is established, bridge will try to resolve the text sent for the first packet. When the text is a valid baud rate, bridge will switch to it.
For example, sending the ASCII text `115200` will switch the baud rate to 115200.

View File

@ -1,3 +1,5 @@
<p align="center"><b>请注意:不同语言版本的翻译可能落后于项目的原始文档。请以原始文档为准。</b></p>
<p align="center"><img src="https://user-images.githubusercontent.com/17078589/120061980-49274280-c092-11eb-9916-4965f6c48388.png"/></p>
![image](https://user-images.githubusercontent.com/17078589/107857220-05ecef00-6e68-11eb-9fa0-506b32052dba.png)

View File

@ -59,6 +59,7 @@
#include "esp8266/include/esp8266/gpio_struct.h"
#include "esp8266/pin_mux_register.h"
#elif defined CONFIG_IDF_TARGET_ESP32
#elif defined CONFIG_IDF_TARGET_ESP32C3
#else
#error unknown hardware
#endif
@ -95,6 +96,9 @@ This information includes:
#elif defined CONFIG_IDF_TARGET_ESP32
#define CPU_CLOCK 240000000
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<240MHz
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define CPU_CLOCK 16000000
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz
#endif
@ -230,22 +234,32 @@ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
#define PIN_TDI 4
#define PIN_nTRST 0 // optional
#define PIN_nRESET 5
// LED_BUILTIN
#define PIN_LED_CONNECTED 2
// LED_BUILTIN
#define PIN_LED_CONNECTED _ // won't be used
#define PIN_LED_RUNNING _ // won't be used
#elif defined CONFIG_IDF_TARGET_ESP32
#define PIN_SWDIO 12 // SPI MISO
#define PIN_SWDIO_MOSI 13 // SPI MOSI
#define PIN_SWCLK 14
#define PIN_TDO 19 // device TDO -> Host Data Input ~~~(use RTC pin 16)~~~
#define PIN_TDO 19 // device TDO -> Host Data Input
#define PIN_TDI 18
#define PIN_nTRST 25 // optional
#define PIN_nRESET 26
// LED_BUILTIN
#define PIN_LED_CONNECTED 27
// LED_BUILTIN
#define PIN_LED_CONNECTED _ // won't be used
#define PIN_LED_RUNNING _ // won't be used
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define PIN_SWDIO _ // SPI MISO
#define PIN_SWDIO_MOSI 7 // SPI MOSI
#define PIN_SWCLK 6
#define PIN_TDO 8 // device TDO -> Host Data Input
#define PIN_TDI 9
#define PIN_nTRST 4 // optional
#define PIN_nRESET 5
#define PIN_LED_CONNECTED _ // won't be used
#define PIN_LED_RUNNING _ // won't be used
#endif
@ -380,6 +394,36 @@ __STATIC_INLINE void PORT_JTAG_SETUP(void)
GPIO_PULL_UP_ONLY_SET(PIN_nTRST);
GPIO_PULL_UP_ONLY_SET(PIN_nRESET);
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_INLINE void PORT_JTAG_SETUP(void)
{
// set TCK, TMS pin
// PIN_TDO output disable
GPIO.enable_w1tc.enable_w1tc = (0x1 << PIN_TDO);
// PIN_TDO input enable
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[PIN_TDO]);
// gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
GPIO.enable_w1ts.enable_w1ts = (0x1 << PIN_TDI);
GPIO.pin[PIN_TDI].pad_driver = 0;
REG_CLR_BIT(GPIO_PIN_MUX_REG[PIN_TDI], FUN_PD); // disable pull down
// gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
// gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
GPIO.enable_w1tc.enable_w1tc = (0x1 << PIN_nTRST);
GPIO.pin[PIN_nTRST].pad_driver = 1;
GPIO.enable_w1tc.enable_w1tc = (0x1 << PIN_nRESET);
GPIO.pin[PIN_nRESET].pad_driver = 1;
// gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
// gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
GPIO_PULL_UP_ONLY_SET(PIN_nTRST);
GPIO_PULL_UP_ONLY_SET(PIN_nRESET);
}
#endif
/**
@ -430,7 +474,7 @@ __STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void)
*/
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void)
{
GPIO.out_w1ts |= (0x1 << PIN_SWCLK);
GPIO_SET_LEVEL_HIGH(PIN_SWCLK);
}
/**
@ -440,7 +484,7 @@ __STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void)
*/
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void)
{
GPIO.out_w1tc |= (0x1 << PIN_SWCLK);
GPIO_SET_LEVEL_LOW(PIN_SWCLK);
}
// SWDIO/TMS Pin I/O --------------------------------------
@ -453,7 +497,7 @@ __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void)
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void)
{
// Note that we only use mosi in GPIO mode
return ((GPIO.in >> PIN_SWDIO_MOSI) & 0x1) ? 1 : 0;
return GPIO_GET_LEVEL(PIN_SWDIO_MOSI);
}
/**
@ -463,7 +507,7 @@ __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void)
*/
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void)
{
GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
GPIO_SET_LEVEL_HIGH(PIN_SWDIO_MOSI);
}
/**
@ -473,7 +517,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void)
*/
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void)
{
GPIO.out_w1tc |= (0x1 << PIN_SWDIO_MOSI);
GPIO_SET_LEVEL_LOW(PIN_SWDIO_MOSI);
}
/**
@ -484,7 +528,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void)
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void)
{
// Note that we only use mosi in GPIO mode
return ((GPIO.in >> PIN_SWDIO_MOSI) & 0x1) ? 1 : 0;
return GPIO_GET_LEVEL(PIN_SWDIO_MOSI);
}
/**
@ -503,13 +547,13 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit)
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI);
GPIO_SET_LEVEL_HIGH(PIN_SWDIO_MOSI);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_SWDIO_MOSI);
GPIO_SET_LEVEL_LOW(PIN_SWDIO_MOSI);
}
}
@ -546,6 +590,10 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void)
// Note that the input of esp32 is not always connected.
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[PIN_SWDIO_MOSI]);
GPIO.out_w1ts = (0x1 << PIN_SWDIO_MOSI);
#elif defined CONFIG_IDF_TARGET_ESP32C3
// Note that the input of esp32c3 is not always connected.
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[PIN_SWDIO_MOSI]);
GPIO.out_w1ts.out_w1ts = (0x1 << PIN_SWDIO_MOSI);
#endif
}
@ -558,7 +606,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void)
*/
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void)
{
return ((GPIO.in >> PIN_TDI) & 0x1) ? 1 : 0;
return GPIO_GET_LEVEL(PIN_TDI);
}
/**
@ -572,14 +620,12 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit)
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_TDI);
GPIO_SET_LEVEL_HIGH(PIN_TDI);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_TDI);
GPIO_SET_LEVEL_LOW(PIN_TDI);
}
}
@ -596,6 +642,8 @@ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void)
return READ_PERI_REG(RTC_GPIO_IN_DATA) & 0x1;
#elif defined CONFIG_IDF_TARGET_ESP32
return ((GPIO.in >> PIN_TDO) & 0x1) ? 1 : 0;
#elif defined CONFIG_IDF_TARGET_ESP32C3
return GPIO_GET_LEVEL(PIN_TDO);
#endif
}
@ -633,7 +681,7 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit)
*/
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void)
{
return ((GPIO.in >> PIN_nRESET) & 0x1) ? 1 : 0;
return GPIO_GET_LEVEL(PIN_nRESET);
}
/**
@ -650,12 +698,12 @@ __STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_nRESET);
GPIO_SET_LEVEL_HIGH(PIN_nRESET);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_nRESET);
GPIO_SET_LEVEL_LOW(PIN_nRESET);
}
}
@ -689,18 +737,7 @@ It is recommended to provide the following LEDs for status indication:
*/
__STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit)
{
#if (!defined USE_UART_BRIDGE || USE_UART_BRIDGE == 0)
if (bit)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_LED_CONNECTED);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_LED_CONNECTED);
}
#endif
(void)(bit);
}
/**
@ -712,6 +749,7 @@ __STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit)
*/
__STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit)
{
(void)(bit);
// if (bit)
// {
// //set bit
@ -774,20 +812,16 @@ __STATIC_INLINE void DAP_SETUP(void)
GPIO_FUNCTION_SET(PIN_TDI);
GPIO_FUNCTION_SET(PIN_nTRST);
GPIO_FUNCTION_SET(PIN_nRESET);
#if (!defined USE_UART_BRIDGE || USE_UART_BRIDGE == 0)
GPIO_FUNCTION_SET(PIN_LED_CONNECTED);
#endif
// GPIO_FUNCTION_SET(PIN_LED_RUNNING);
// Configure: LED as output (turned off)
#if (!defined USE_UART_BRIDGE || USE_UART_BRIDGE == 0)
GPIO_SET_DIRECTION_NORMAL_OUT(PIN_LED_CONNECTED);
#endif
// GPIO_SET_DIRECTION_NORMAL_OUT(PIN_LED_RUNNING);
LED_CONNECTED_OUT(0);
LED_RUNNING_OUT(0);
// LED_CONNECTED_OUT(0);
// LED_RUNNING_OUT(0);
PORT_OFF();
}

View File

@ -296,14 +296,15 @@ extern void DAP_Setup (void);
#define USE_ASSEMBLY 1
#if (USE_ASSEMBLY == 0)
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(uint32_t delay)
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(int32_t delay)
{
uint32_t count = delay;
int32_t count = delay;
while (--count)
;
}
#else
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(uint32_t delay)
#if defined CONFIG_IDF_TARGET_ESP8266 || CONFIG_IDF_TARGET_ESP32
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(int32_t delay)
{
__asm__ volatile(
"l_PINDELAYSLOW%=:"
@ -311,6 +312,16 @@ __STATIC_FORCEINLINE void PIN_DELAY_SLOW(uint32_t delay)
"BNEZ %[time], l_PINDELAYSLOW%=;"
: [time] "+r"(delay));
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_FORCEINLINE void PIN_DELAY_SLOW(int32_t delay)
{
__asm__ volatile(
"l_PINDELAYSLOW%=:"
"ADDI %[time], %[time], -1;"
"BNEZ %[time], l_PINDELAYSLOW%=;"
: [time] "+r"(delay));
}
#endif
#endif

View File

@ -28,6 +28,17 @@
#include "soc/soc/esp32/include/soc/spi_reg.h"
#endif
#include "hal/gpio_types.h"
#elif defined CONFIG_IDF_TARGET_ESP32C3
#include "soc/esp32c3/include/soc/gpio_struct.h"
#include "hal/esp32c3/include/hal/gpio_ll.h"
#include "hal/esp32c3/include/hal/clk_gate_ll.h"
#include "soc/esp32c3/include/soc/gpio_struct.h"
#include "soc/esp32c3/include/soc/dport_access.h"
#include "soc/esp32c3/include/soc/periph_defs.h"
#include "soc/esp32c3/include/soc/usb_serial_jtag_reg.h"
#include "soc/esp32c3/include/soc/io_mux_reg.h"
#include "soc/esp32c3/include/soc/spi_struct.h"
#include "soc/esp32c3/include/soc/spi_reg.h"
#else
#error unknown hardware
#endif

View File

@ -44,8 +44,18 @@ __STATIC_INLINE __UNUSED void GPIO_FUNCTION_SET(int io_num)
// Note that the index starts at 0, so we are using function 3.
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_num], PIN_FUNC_GPIO);
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_INLINE __UNUSED void GPIO_FUNCTION_SET(int io_num)
{
// Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function
if (io_num == IO_MUX_GPIO18_REG || io_num == IO_MUX_GPIO19_REG) {
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
}
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_num], PIN_FUNC_GPIO);
}
#endif
#ifdef CONFIG_IDF_TARGET_ESP8266
__STATIC_INLINE __UNUSED void GPIO_SET_DIRECTION_NORMAL_OUT(int io_num)
{
@ -60,18 +70,54 @@ __STATIC_INLINE __UNUSED void GPIO_SET_DIRECTION_NORMAL_OUT(int io_num)
// PP out
GPIO.pin[io_num].pad_driver = 0;
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_INLINE __UNUSED void GPIO_SET_DIRECTION_NORMAL_OUT(int io_num)
{
GPIO.enable_w1ts.enable_w1ts = (0x1 << io_num);
// PP out
GPIO.pin[io_num].pad_driver = 0;
}
#endif
#if defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
__STATIC_INLINE __UNUSED void GPIO_SET_LEVEL_HIGH(int io_num)
{
GPIO.out_w1ts |= (0x1 << io_num);
}
//FIXME: esp32
__STATIC_INLINE __UNUSED void GPIO_SET_LEVEL_LOW(int io_num)
{
GPIO.out_w1tc |= (0x1 << io_num);
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_INLINE __UNUSED void GPIO_SET_LEVEL_HIGH(int io_num)
{
gpio_ll_set_level(&GPIO, io_num, 1);
}
__STATIC_INLINE __UNUSED void GPIO_SET_LEVEL_LOW(int io_num)
{
gpio_ll_set_level(&GPIO, io_num, 0);
}
#endif
#if defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
__STATIC_INLINE __UNUSED int GPIO_GET_LEVEL(int io_num)
{
return ((GPIO.in >> io_num) & 0x1) ? 1 : 0;
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_INLINE __UNUSED int GPIO_GET_LEVEL(int io_num)
{
return gpio_ll_get_level(&GPIO, io_num);
}
#endif
__STATIC_INLINE __UNUSED void GPIO_SET_LEVEL_HIGH(int io_num)
{
GPIO.out_w1ts |= (0x1 << io_num);
}
#ifdef CONFIG_IDF_TARGET_ESP32
#if defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3
__STATIC_INLINE __UNUSED void GPIO_PULL_UP_ONLY_SET(int io_num)
{
// disable pull down
@ -82,12 +128,6 @@ __STATIC_INLINE __UNUSED void GPIO_PULL_UP_ONLY_SET(int io_num)
#endif
//FIXME: esp32
__STATIC_INLINE __UNUSED void GPIO_SET_LEVEL_LOW(int io_num)
{
GPIO.out_w1tc |= (0x1 << io_num);
}
// static void GPIO_SET_DIRECTION_NORMAL_IN(int io_num)
// {
// GPIO.enable_w1tc |= (0x1 << io_num);

View File

@ -238,7 +238,7 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
requestByte = constantBits | (((uint8_t)(request & 0xFU)) << 1U) | (ParityEvenUint8(request & 0xFU) << 5U);
/* For 4bit, Parity can be equivalent to 8bit with all 0 high bits */
#if (PRINT_SWD_PROTOCOL == 1)
#if (PRINT_SWD_PROTOCOL == 1)
switch (requestByte)
{
case 0xA5U:
@ -282,7 +282,7 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
os_printf("Unknown:%08x\r\n", requestByte);
break;
}
#endif
#endif
if (request & DAP_TRANSFER_RnW) {
/* Read data */
@ -304,11 +304,15 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
}
else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
////FIXME: esp32 // DAP_SPI_Fast_Cycle();
DAP_SPI_Generate_Cycle(1);
#if (PRINT_SWD_PROTOCOL == 1)
#if defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
DAP_SPI_Generate_Cycle(1);
#elif defined CONFIG_IDF_TARGET_ESP32C3
DAP_SPI_Fast_Cycle();
#endif
#if (PRINT_SWD_PROTOCOL == 1)
os_printf("WAIT\r\n");
#endif
#endif
// return DAP_TRANSFER_WAIT;
}
@ -322,9 +326,9 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
DAP_SPI_Disable();
PIN_SWDIO_TMS_SET();
#if (PRINT_SWD_PROTOCOL == 1)
#if (PRINT_SWD_PROTOCOL == 1)
os_printf("Protocol Error: Read\r\n");
#endif
#endif
}
return ((uint8_t)ack);
@ -352,9 +356,9 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
/* already turnaround. */
/* TODO: overrun transfer -> for read */
#if (PRINT_SWD_PROTOCOL == 1)
#if (PRINT_SWD_PROTOCOL == 1)
os_printf("WAIT\r\n");
#endif
#endif
}
else {
@ -368,9 +372,9 @@ static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) {
DAP_SPI_Disable();
PIN_SWDIO_TMS_SET();
#if (PRINT_SWD_PROTOCOL == 1)
#if (PRINT_SWD_PROTOCOL == 1)
os_printf("Protocol Error: Write\r\n");
#endif
#endif
}
return ((uint8_t)ack);

View File

@ -5,10 +5,11 @@
* @change: 2020-11-25 first version
* 2021-2-11 Support SWD sequence
* 2021-3-10 Support 3-wire SPI
* @version 0.3
* @date 2021-3-10
* 2022-9-15 Support ESP32C3
* @version 0.4
* @date 2022-9-15
*
* @copyright Copyright (c) 2021
* @copyright MIT License
*
*/
#include "sdkconfig.h"
@ -27,6 +28,8 @@
#define DAP_SPI SPI1
#elif defined CONFIG_IDF_TARGET_ESP32
#define DAP_SPI SPI2
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define DAP_SPI GPSPI2
#else
#error unknown hardware
#endif
@ -35,9 +38,31 @@
#ifdef CONFIG_IDF_TARGET_ESP8266
#define SET_MOSI_BIT_LEN(x) DAP_SPI.user1.usr_mosi_bitlen = x
#define SET_MISO_BIT_LEN(x) DAP_SPI.user1.usr_miso_bitlen = x
#define START_AND_WAIT_SPI_TRANSMISSION_DONE() \
do { \
DAP_SPI.cmd.usr = 1; \
while (DAP_SPI.cmd.usr) continue; \
} while(0)
#elif defined CONFIG_IDF_TARGET_ESP32
#define SET_MOSI_BIT_LEN(x) DAP_SPI.mosi_dlen.usr_mosi_dbitlen = x
#define SET_MISO_BIT_LEN(x) DAP_SPI.miso_dlen.usr_miso_dbitlen = x
#define START_AND_WAIT_SPI_TRANSMISSION_DONE() \
do { \
DAP_SPI.cmd.usr = 1; \
while (DAP_SPI.cmd.usr) continue; \
} while(0)
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define SET_MOSI_BIT_LEN(x) DAP_SPI.ms_dlen.ms_data_bitlen = x
#define SET_MISO_BIT_LEN(x) DAP_SPI.ms_dlen.ms_data_bitlen = x
#define START_AND_WAIT_SPI_TRANSMISSION_DONE() \
do { \
DAP_SPI.cmd.update = 1; \
while (DAP_SPI.cmd.update) continue; \
DAP_SPI.cmd.usr = 1; \
while (DAP_SPI.cmd.usr) continue; \
} while(0)
#endif
/**
@ -66,6 +91,7 @@ void DAP_SPI_WriteBits(const uint8_t count, const uint8_t *buf)
// have data to send
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user.usr_miso = 0;
SET_MOSI_BIT_LEN(count - 1);
// copy data to reg
switch (count)
@ -102,10 +128,7 @@ void DAP_SPI_WriteBits(const uint8_t count, const uint8_t *buf)
}
}
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}
@ -131,10 +154,7 @@ void DAP_SPI_ReadBits(const uint8_t count, uint8_t *buf) {
SET_MISO_BIT_LEN(count - 1U);
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for reading to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
#if (USE_SPI_SIO == 1)
DAP_SPI.user.sio = false;
@ -151,7 +171,7 @@ void DAP_SPI_ReadBits(const uint8_t count, uint8_t *buf) {
buf[i-1] = buf[i-1] & ((2 >> (count % 8)) - 1);
}
#if defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
/**
* @brief Step1: Packet Request
*
@ -179,10 +199,7 @@ __FORCEINLINE void DAP_SPI_Send_Header(const uint8_t packetHeaderData, uint8_t *
// copy data to reg
DAP_SPI.data_buf[0] = (packetHeaderData << 0) | (0U << 8) | (0U << 16) | (0U << 24);
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
#if (USE_SPI_SIO == 1)
DAP_SPI.user.sio = false;
@ -190,7 +207,41 @@ __FORCEINLINE void DAP_SPI_Send_Header(const uint8_t packetHeaderData, uint8_t *
dataBuf = DAP_SPI.data_buf[0];
*ack = (dataBuf >> 1) & 0b111;
} // defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
#elif defined CONFIG_IDF_TARGET_ESP32C3
__FORCEINLINE void DAP_SPI_Send_Header(const uint8_t packetHeaderData, uint8_t *ack, uint8_t TrnAfterACK)
{
uint32_t dataBuf;
// have data to send
DAP_SPI.user.usr_mosi = 0;
DAP_SPI.user.usr_command = 1;
DAP_SPI.user.usr_miso = 1;
// 8bits Header + 1 bit Trn(Before ACK) - 1(prescribed)
DAP_SPI.user2.usr_command_bitlen = 8U + 1U - 1U;
DAP_SPI.user2.usr_command_value = packetHeaderData;
#if (USE_SPI_SIO == 1)
DAP_SPI.user.sio = true;
#endif
// 3bits ACK + TrnAferACK - 1(prescribed)
SET_MISO_BIT_LEN(3U + TrnAfterACK - 1U);
START_AND_WAIT_SPI_TRANSMISSION_DONE();
#if (USE_SPI_SIO == 1)
DAP_SPI.user.sio = false;
#endif
DAP_SPI.user.usr_command = 0;
dataBuf = DAP_SPI.data_buf[0];
*ack = dataBuf & 0b111;
}
#endif
/**
@ -211,13 +262,10 @@ __FORCEINLINE void DAP_SPI_Read_Data(uint32_t *resData, uint8_t *resParity)
DAP_SPI.user.sio = true;
#endif
// 1 bit Trn(End) + 3bits ACK + 32bis data + 1bit parity - 1(prescribed)
// 1 bit Trn(End) + 32bis data + 1bit parity - 1(prescribed)
SET_MISO_BIT_LEN(1U + 32U + 1U - 1U);
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
#if (USE_SPI_SIO == 1)
DAP_SPI.user.sio = false;
@ -227,9 +275,10 @@ __FORCEINLINE void DAP_SPI_Read_Data(uint32_t *resData, uint8_t *resParity)
pU32Data[1] = DAP_SPI.data_buf[1];
*resData = (dataBuf >> 0U) & 0xFFFFFFFFU; // 32bits Response Data
*resParity = (dataBuf >> (0U + 32U)) & 1U; // 3bits ACK + 32bis data
*resParity = (dataBuf >> (0U + 32U)) & 1U; // 1bit parity
}
#if defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
/**
* @brief Step2: Write Data
*
@ -247,12 +296,26 @@ __FORCEINLINE void DAP_SPI_Write_Data(uint32_t data, uint8_t parity)
DAP_SPI.data_buf[0] = data;
DAP_SPI.data_buf[1] = parity;
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__FORCEINLINE void DAP_SPI_Write_Data(uint32_t data, uint8_t parity)
{
DAP_SPI.user.usr_mosi = 1;
DAP_SPI.user.usr_miso = 0;
// esp32c3 can not send 33 bits of data correctly, we need to send an additional bit
// that will not be recognized as the start bit.
SET_MOSI_BIT_LEN(32U + 1U + 1U - 1U);
DAP_SPI.data_buf[0] = data;
DAP_SPI.data_buf[1] = parity == 0 ? 0b00 : 0b01;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}
#endif
#if defined CONFIG_IDF_TARGET_ESP8266 || defined CONFIG_IDF_TARGET_ESP32
/**
* @brief Generate Clock Cycle
*
@ -267,14 +330,23 @@ __FORCEINLINE void DAP_SPI_Generate_Cycle(uint8_t num)
DAP_SPI.data_buf[0] = 0x00000000U;
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
// TODO: not wait?
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__FORCEINLINE void DAP_SPI_Generate_Cycle(uint8_t num)
{
//// TODO: It may take long time to generate just one clock
DAP_SPI.user.usr_mosi = 0;
DAP_SPI.user.usr_miso = 1;
#ifdef CONFIG_IDF_TARGET_ESP32
// esp32c3 can not send a single bit, therefore we use read operation instead.
SET_MISO_BIT_LEN(num - 1U);
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}
#endif
#if defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3
/**
* @brief Quickly generate 1 clock
*
@ -299,10 +371,7 @@ __FORCEINLINE void DAP_SPI_Protocol_Error_Read()
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}
@ -319,8 +388,5 @@ __FORCEINLINE void DAP_SPI_Protocol_Error_Write()
DAP_SPI.data_buf[0] = 0xFFFFFFFFU;
DAP_SPI.data_buf[1] = 0xFFFFFFFFU;
// Start transmission
DAP_SPI.cmd.usr = 1;
// Wait for sending to complete
while (DAP_SPI.cmd.usr) continue;
START_AND_WAIT_SPI_TRANSMISSION_DONE();
}

View File

@ -4,10 +4,11 @@
* @brief Switching between SPI mode and IO mode
* @change: 2020-11-25 first version
* 2021-2-11 Transmission mode switching test passed
* @version 0.2
* @date 2021-2-11
* 2022-9-15 Support ESP32C3
* @version 0.4
* @date 2021-9-15
*
* @copyright Copyright (c) 2021
* @copyright MIT License
*
*/
#include "sdkconfig.h"
@ -26,7 +27,8 @@
#define FUNC_SPI 1
#define SPI2_HOST 1
#define SPI_LL_RST_MASK (SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST)
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define DAP_SPI GPSPI2
#else
#error unknown hardware
#endif
@ -93,7 +95,7 @@ void DAP_SPI_Init()
// Enable soft reset
DAP_SPI.slave.sync_reset = true;
// Set the clock polarity and phase CPOL = CPHA = 0
// Set the clock polarity and phase CPOL = 1, CPHA = 0
DAP_SPI.pin.ck_idle_edge = 1; // HIGH while idle
DAP_SPI.user.ck_out_edge = 0;
@ -245,7 +247,7 @@ void DAP_SPI_Init()
DAP_SPI.ctrl2.miso_delay_num = 0;
// Set the clock polarity and phase CPOL = CPHA = 1
// Set the clock polarity and phase CPOL = 1, CPHA = 0
DAP_SPI.pin.ck_idle_edge = 1; // HIGH while idle
DAP_SPI.user.ck_out_edge = 0;
@ -253,6 +255,102 @@ void DAP_SPI_Init()
DAP_SPI.user.usr_command = 0;
DAP_SPI.user.usr_addr = 0;
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
void DAP_SPI_Init()
{
periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE);
// In esp32, the driving of GPIO should be stopped,
// otherwise there will be issue in the spi
GPIO.out_w1tc.out_w1tc = (0x1 << 6);
GPIO.out_w1tc.out_w1tc = (0x1 << 7);
// We will use IO_MUX to get the maximum speed.
GPIO.func_in_sel_cfg[FSPID_IN_IDX].sig_in_sel = 0; // IO_MUX direct connnect
PIN_INPUT_ENABLE(IO_MUX_GPIO7_REG); // MOSI
GPIO.func_out_sel_cfg[7].oen_sel = 0; // use output enable signal from peripheral
GPIO.func_out_sel_cfg[7].oen_inv_sel = 0; // do not invert the output value
PIN_FUNC_SELECT(IO_MUX_GPIO7_REG, FUNC_MTDO_FSPID);
GPIO.func_in_sel_cfg[FSPICLK_IN_IDX].sig_in_sel = 0;
PIN_INPUT_ENABLE(IO_MUX_GPIO6_REG); // SCLK
GPIO.func_out_sel_cfg[6].oen_sel = 0;
GPIO.func_out_sel_cfg[6].oen_inv_sel = 0;
PIN_FUNC_SELECT(IO_MUX_GPIO6_REG, FUNC_MTCK_FSPICLK);
// Not using DMA
// esp32c3 only
DAP_SPI.user.usr_conf_nxt = 0;
DAP_SPI.slave.usr_conf = 0;
DAP_SPI.dma_conf.dma_rx_ena = 0;
DAP_SPI.dma_conf.dma_tx_ena = 0;
// Set to Master mode
DAP_SPI.slave.slave_mode = false;
// use all 64 bytes of the buffer
DAP_SPI.user.usr_mosi_highpart = false;
DAP_SPI.user.usr_miso_highpart = false;
// Disable cs pin
DAP_SPI.user.cs_setup = false;
DAP_SPI.user.cs_hold = false;
// Disable CS signal
DAP_SPI.misc.cs0_dis = 1;
DAP_SPI.misc.cs1_dis = 1;
DAP_SPI.misc.cs2_dis = 1;
DAP_SPI.misc.cs3_dis = 1;
DAP_SPI.misc.cs4_dis = 1;
DAP_SPI.misc.cs5_dis = 1;
// Duplex transmit
DAP_SPI.user.doutdin = false; // half dulex
// Set data bit order
DAP_SPI.ctrl.wr_bit_order = 1; // SWD -> LSB
DAP_SPI.ctrl.rd_bit_order = 1; // SWD -> LSB
// Set dummy
DAP_SPI.user.usr_dummy = 0; // not use
// Set spi clk: 40Mhz 50% duty
// CLEAR_PERI_REG_MASK(PERIPHS_IO_MUX_CONF_U, SPI1_CLK_EQU_SYS_CLK);
// See esp32c3 TRM `SPI_CLOCK_REG`
DAP_SPI.clock.clk_equ_sysclk = false;
DAP_SPI.clock.clkdiv_pre = 0;
DAP_SPI.clock.clkcnt_n = SPI_40MHz_DIV - 1;
DAP_SPI.clock.clkcnt_h = SPI_40MHz_DIV / 2 - 1;
DAP_SPI.clock.clkcnt_l = SPI_40MHz_DIV - 1;
// MISO delay setting
DAP_SPI.user.rsck_i_edge = true;
DAP_SPI.din_mode.din0_mode = 0;
DAP_SPI.din_mode.din1_mode = 0;
DAP_SPI.din_mode.din2_mode = 0;
DAP_SPI.din_mode.din3_mode = 0;
DAP_SPI.din_num.din0_num = 0;
DAP_SPI.din_num.din1_num = 0;
DAP_SPI.din_num.din2_num = 0;
DAP_SPI.din_num.din3_num = 0;
// Set the clock polarity and phase CPOL = 1, CPHA = 0
DAP_SPI.misc.ck_idle_edge = 1; // HIGH while idle
DAP_SPI.user.ck_out_edge = 0;
// enable spi clock
DAP_SPI.clk_gate.clk_en = 1;
DAP_SPI.clk_gate.mst_clk_active = 1;
DAP_SPI.clk_gate.mst_clk_sel = 1;
// No command and addr for now
DAP_SPI.user.usr_command = 0;
DAP_SPI.user.usr_addr = 0;
}
#endif
@ -305,6 +403,19 @@ __FORCEINLINE void DAP_SPI_Deinit()
// disable MOSI pull up
// REG_CLR_BIT(GPIO_PIN_MUX_REG[13], FUN_PU);
}
#elif defined CONFIG_IDF_TARGET_ESP32C3
__FORCEINLINE void DAP_SPI_Deinit()
{
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[6], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[7], PIN_FUNC_GPIO); // MOSI
// enable SWCLK output
GPIO.enable_w1ts.enable_w1ts = (0x01 << 6);
// enable MOSI output & input
GPIO.enable_w1ts.enable_w1ts |= (0x1 << 7);
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[7]);
}
#endif
@ -328,7 +439,26 @@ __FORCEINLINE void DAP_SPI_Release()
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[14], PIN_FUNC_GPIO);
GPIO.enable_w1ts = (0x01 << 14);
}
#endif // CONFIG_IDF_TARGET_ESP32
#elif defined CONFIG_IDF_TARGET_ESP32C3
/**
* @brief Gain control of SPI
*
*/
__FORCEINLINE void DAP_SPI_Acquire()
{
PIN_FUNC_SELECT(IO_MUX_GPIO6_REG, FUNC_MTCK_FSPICLK);
}
/**
* @brief Release control of SPI
*
*/
__FORCEINLINE void DAP_SPI_Release()
{
PIN_FUNC_SELECT(IO_MUX_GPIO6_REG, FUNC_MTCK_GPIO6);
}
#endif
/**
* @brief Use SPI acclerate
*

@ -1 +1 @@
Subproject commit 98e9ffeb3b08e91743b147cf292dfd76259fc380
Subproject commit eecc603dc5db13aecd4253804d57f9a0a285bffa

View File

@ -10,6 +10,7 @@
#include <stdint.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "main/tcp_server.h"
#include "main/tcp_netconn.h"
#include "main/kcp_server.h"
@ -128,7 +129,14 @@ void app_main() {
// DAP handle task
xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &kDAPTaskHandle);
#if defined CONFIG_IDF_TARGET_ESP8266
#define UART_BRIDGE_TASK_STACK_SIZE 1024
#else
#define UART_BRIDGE_TASK_STACK_SIZE 2048
#endif
//// FIXME: potential stack overflow
#if (USE_UART_BRIDGE == 1)
xTaskCreate(uart_bridge_task, "uart_server", 1024, NULL, 2, NULL);
xTaskCreate(uart_bridge_task, "uart_server", UART_BRIDGE_TASK_STACK_SIZE, NULL, 2, NULL);
#endif
}

View File

@ -55,7 +55,7 @@ uint32_t get_timer_count()
#ifdef CONFIG_IDF_TARGET_ESP8266
return (uint32_t)frc2->count.data;
#elif defined CONFIG_IDF_TARGET_ESP32
#elif defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3
return 0;
#else
#error unknown hardware

View File

@ -59,6 +59,13 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#elif defined CONFIG_IDF_TARGET_ESP32
#define UART_BRIDGE_TX UART_NUM_2
#define UART_BRIDGE_RX UART_NUM_2
#define UART_BRIDGE_TX_PIN 23
#define UART_BRIDGE_RX_PIN 22
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define UART_BRIDGE_TX UART_NUM_1
#define UART_BRIDGE_RX UART_NUM_1
#define UART_BRIDGE_TX_PIN 19
#define UART_BRIDGE_RX_PIN 18 // PIN18 has 50000ns glitch during the power-up
#else
#error unknown hardware
#endif
@ -192,6 +199,10 @@ static void uart_bridge_setup() {
uart_driver_install(UART_BRIDGE_TX, 0, UART_BUF_SIZE, 0, NULL, 0); // TX only
}
#if defined CONFIG_IDF_TARGET_ESP32 || defined CONFIG_IDF_TARGET_ESP32C3
uart_set_pin(UART_BRIDGE_TX, UART_BRIDGE_TX_PIN, UART_BRIDGE_RX_PIN, -1, -1);
#endif
}
void uart_bridge_init() {

View File

@ -36,16 +36,16 @@ static struct {
#define DAP_IP_NETMASK 255, 255, 255, 0
//
#define USE_OTA 1
#define USE_OTA 0
#define USE_UART_BRIDGE 1
#define USE_UART_BRIDGE 0
#define UART_BRIDGE_PORT 1234
#define UART_BRIDGE_BAUDRATE 74880
//
// DO NOT CHANGE
#define USE_TCP_NETCONN 0
// DO NOT CHANGE
#define PORT 3240
#define CONFIG_EXAMPLE_IPV4 1
#define USE_KCP 0

View File

@ -21,6 +21,8 @@
#define PIN_LED_WIFI_STATUS 15
#elif defined CONFIG_IDF_TARGET_ESP32
#define PIN_LED_WIFI_STATUS 27
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define PIN_LED_WIFI_STATUS 10
#else
#error unknown hardware
#endif

1179
sdkconfig.defaults.esp32c3 Normal file

File diff suppressed because it is too large Load Diff