├── .gitignore
├── README.md
├── .project
├── LICENSE
├── .settings
├── org.eclipse.cdt.core.prefs
└── language.settings.xml
├── user
├── Makefile
└── user_main.c
├── driver
├── intr_config.c
├── Makefile
├── io_config.c
├── gpio.c
├── uart.c
└── i2s.c
├── include
├── user_config.h
├── i2s.h
├── uart.h
├── pwm.h
└── gpio.h
├── Makefile
├── utils
├── gen_appbin.py
└── esptool32.py
└── .cproject
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 | .output
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # esp32_playground
2 | Somewhere to put the esp32 code I am playing with.
3 |
4 | # Topics investigated thus far
5 | * Blink using a Task
6 | * Wifi config
7 | * Temp sensor read
8 | * Passing task parameter using *pvParameters
9 |
10 | # Setup
11 | 1. Get SDK running from here: https://github.com/espressif/ESP32_RTOS_SDK
12 | 2. Install Eclipse
13 | 3. Clone repo
14 | 4. You may need to edit BIN_PATH and SDK_PATH in C/C++ Build / Environment within Eclipse
15 |
16 | # Usage
17 | * Change wifi settings in /Incudes/user_config.h
18 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | esp32_blink
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.core.ccnature
24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
26 |
27 |
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Chris Fraser
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.cdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/BIN_PATH/delimiter=\:
3 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/BIN_PATH/operation=replace
4 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/BIN_PATH/value=${HOME}/workspace/ESP32_BIN
5 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/PATH/delimiter=\:
6 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/PATH/operation=replace
7 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/PATH/value=/opt/Espressif/crosstool-NG/builds/xtensa-esp108-elf/bin\:${PATH}
8 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/SDK_PATH/delimiter=\:
9 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/SDK_PATH/operation=replace
10 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/SDK_PATH/value=${HOME}/workspace/ESP32_RTOS_SDK
11 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/append=true
12 | environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1640058030/appendContributed=true
13 |
--------------------------------------------------------------------------------
/user/Makefile:
--------------------------------------------------------------------------------
1 |
2 | #############################################################
3 | # Required variables for each makefile
4 | # Discard this section from all parent makefiles
5 | # Expected variables (with automatic defaults):
6 | # CSRCS (all "C" files in the dir)
7 | # SUBDIRS (all subdirs with a Makefile)
8 | # GEN_LIBS - list of libs to be generated ()
9 | # GEN_IMAGES - list of images to be generated ()
10 | # COMPONENTS_xxx - a list of libs/objs in the form
11 | # subdir/lib to be extracted and rolled up into
12 | # a generated lib/image xxx.a ()
13 | #
14 | ifndef PDIR
15 | GEN_LIBS = libuser.a
16 | endif
17 |
18 |
19 | #############################################################
20 | # Configuration i.e. compile options etc.
21 | # Target specific stuff (defines etc.) goes in here!
22 | # Generally values applying to a tree are captured in the
23 | # makefile at its root level - these are then overridden
24 | # for a subtree within the makefile rooted therein
25 | #
26 | #DEFINES +=
27 |
28 | #############################################################
29 | # Recursion Magic - Don't touch this!!
30 | #
31 | # Each subtree potentially has an include directory
32 | # corresponding to the common APIs applicable to modules
33 | # rooted at that subtree. Accordingly, the INCLUDE PATH
34 | # of a module can only contain the include directories up
35 | # its parent path, and not its siblings
36 | #
37 | # Required for each makefile to inherit from the parent
38 | #
39 |
40 | INCLUDES := $(INCLUDES) -I $(PDIR)include
41 | INCLUDES += -I ./
42 | PDIR := ../$(PDIR)
43 | sinclude $(PDIR)Makefile
44 |
45 |
--------------------------------------------------------------------------------
/driver/intr_config.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 | #include "espressif/esp_common.h"
25 |
26 | void intr_matrix_set(uint32 model_num, uint32 intr_num)
27 | {
28 | uint32 addr = INTR_MAP_REG_A + (model_num / 6) * 4;
29 | uint32 shift = (model_num % 6) * 5;
30 |
31 | if (shift >= 15) {
32 | shift++;
33 | }
34 |
35 | SET_PERI_REG_BITS(addr, 0x1f, intr_num, shift);//0x80
36 | }
37 |
--------------------------------------------------------------------------------
/include/user_config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #ifndef __USER_CONFIG_H__
26 | #define __USER_CONFIG_H__
27 |
28 |
29 | // WiFi Config
30 | #define SSID "yourssid"
31 | #define PASSWORD "**********"
32 |
33 | // LED pin
34 | // Connect led+ to pin below
35 | // Ensure that the resistor keeps current below 6mA
36 | #define LEDPIN 22
37 |
38 | #endif
39 |
40 |
--------------------------------------------------------------------------------
/driver/Makefile:
--------------------------------------------------------------------------------
1 |
2 | #############################################################
3 | # Required variables for each makefile
4 | # Discard this section from all parent makefiles
5 | # Expected variables (with automatic defaults):
6 | # CSRCS (all "C" files in the dir)
7 | # SUBDIRS (all subdirs with a Makefile)
8 | # GEN_LIBS - list of libs to be generated ()
9 | # GEN_IMAGES - list of images to be generated ()
10 | # COMPONENTS_xxx - a list of libs/objs in the form
11 | # subdir/lib to be extracted and rolled up into
12 | # a generated lib/image xxx.a ()
13 | #
14 | ifndef PDIR
15 |
16 | GEN_LIBS = libdriver.a
17 |
18 | endif
19 |
20 |
21 | #############################################################
22 | # Configuration i.e. compile options etc.
23 | # Target specific stuff (defines etc.) goes in here!
24 | # Generally values applying to a tree are captured in the
25 | # makefile at its root level - these are then overridden
26 | # for a subtree within the makefile rooted therein
27 | #
28 | #DEFINES +=
29 |
30 | #############################################################
31 | # Recursion Magic - Don't touch this!!
32 | #
33 | # Each subtree potentially has an include directory
34 | # corresponding to the common APIs applicable to modules
35 | # rooted at that subtree. Accordingly, the INCLUDE PATH
36 | # of a module can only contain the include directories up
37 | # its parent path, and not its siblings
38 | #
39 | # Required for each makefile to inherit from the parent
40 | #
41 |
42 | INCLUDES := $(INCLUDES) -I $(PDIR)include
43 | INCLUDES += -I ./
44 | INCLUDES += -I ../freertos/include
45 | INCLUDES += -I ../../rom/include
46 | INCLUDES += -I ../../include/ets
47 | PDIR := ../$(PDIR)
48 | sinclude $(PDIR)Makefile
49 |
50 |
--------------------------------------------------------------------------------
/.settings/language.settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/driver/io_config.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #include "espressif/esp_common.h"
26 | #include "freertos/portmacro.h"
27 | #include "gpio.h"
28 |
29 | /*
30 | * set gpio input to a signal
31 | * one gpio can input to several signals
32 | * If gpio == 0x30, cancel input to the signal, input 0 to signal
33 | * If gpio == 0x38, cancel input to the signal, input 1 to signal, for I2C pad
34 | */
35 | void gpio_matrix_in(uint32 gpio, uint32 signal_idx)
36 | {
37 | uint32 addr = GPIO_FUNC_IN_SEL0 + ((signal_idx / 5) * 4);
38 | uint32 shift = (signal_idx % 5) * 6;
39 |
40 | portENTER_CRITICAL();
41 |
42 | SET_PERI_REG_BITS(addr, 0x3f, gpio, shift);//0x30 0 0x38 1
43 |
44 | if ((signal_idx < 6) || ((signal_idx < 16) && (signal_idx > 7)) || ((signal_idx < 19) && (signal_idx > 16)) || ((signal_idx < 69) && (signal_idx > 62))) {
45 | SET_PERI_REG_MASK(SIG_FUNC_IN_SEL, 1 << signal_idx);
46 | }
47 |
48 | portEXIT_CRITICAL();
49 | }
50 |
51 | /*
52 | * set signal output to gpio
53 | * one signal can output to several gpios
54 | * If signal_idx == 0x80, cancel output put to the gpio
55 | */
56 | #define INVALID_SIGNAL 0x80
57 | void gpio_matrix_out(uint32 gpio, uint32 signal_idx)
58 | {
59 | uint32 addr = GPIO_FUNC_OUT_SEL0 + ((gpio / 4) * 4);
60 | uint32 shift = (gpio % 4) * 8;
61 | uint32 pin_reg;
62 |
63 | if (gpio >= GPIO_PIN_COUNT) {
64 | return;
65 | }
66 |
67 | portENTER_CRITICAL();
68 |
69 | if (gpio < 32) {
70 | pin_reg = GPIO_REG_READ(GPIO_ENABLE);
71 |
72 | if (INVALID_SIGNAL == signal_idx) {
73 | pin_reg &= ~(1 << gpio);
74 | } else {
75 | pin_reg |= (1 << gpio);
76 | }
77 |
78 | GPIO_REG_WRITE(GPIO_ENABLE, pin_reg);
79 | } else {
80 | pin_reg = GPIO_REG_READ(GPIO_ENABLE1);
81 |
82 | if (INVALID_SIGNAL == signal_idx) {
83 | pin_reg &= ~(1 << (gpio - 32));
84 | } else {
85 | pin_reg |= (1 << (gpio - 32));
86 | }
87 |
88 | GPIO_REG_WRITE(GPIO_ENABLE1, pin_reg);
89 | }
90 |
91 | SET_PERI_REG_BITS(addr, 0xff, signal_idx, shift);//0x80
92 |
93 | portEXIT_CRITICAL();
94 | }
95 |
--------------------------------------------------------------------------------
/include/i2s.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #ifndef I2S_H
26 | #define I2S_H
27 |
28 | #ifdef __cplusplus
29 | extern "C" {
30 | #endif
31 |
32 | /** \defgroup Driver_APIs Driver APIs
33 | * @brief Driver APIs
34 | */
35 |
36 | /** @addtogroup Driver_APIs
37 | * @{
38 | */
39 |
40 | /** \defgroup I2S_Driver_APIs I2S Driver APIs
41 | * @brief I2S driver APIs
42 | */
43 |
44 | /** @addtogroup I2S_Driver_APIs
45 | * @{
46 | */
47 |
48 | //#define GPIO_PIN_REG_4 (PERIPHS_IO_MUX + 0x48)
49 | //#define GPIO_PIN_REG_0 (PERIPHS_IO_MUX + 0x44)
50 |
51 | #define TX_MASTER 0
52 | #define TX_SLAVE 1
53 | #define RX_MASTER 2
54 | #define RX_SLAVE 3
55 |
56 | struct sdio_queue {
57 | uint32 blocksize: 12;
58 | uint32 datalen : 12;
59 | uint32 unused : 5;
60 | uint32 sub_sof : 1;
61 | uint32 eof : 1;
62 | uint32 owner : 1;
63 |
64 | uint32 buf_ptr;
65 | uint32 next_link_ptr;
66 | };
67 |
68 | #define ETS_SLC_INTR_ENABLE() xt_ints_on(1 << ETS_SLC_INUM)
69 |
70 | #define CONF_RXLINK_ADDR(addr) CLEAR_PERI_REG_MASK(I2SRX_LINK, I2S_I2S_RXLINK_ADDR);\
71 | SET_PERI_REG_MASK(I2SRX_LINK, ((uint32)(addr)) & I2S_I2S_RXLINK_ADDR)
72 | #define CONF_TXLINK_ADDR(addr) CLEAR_PERI_REG_MASK(I2STX_LINK, I2S_I2S_TXLINK_ADDR);\
73 | SET_PERI_REG_MASK(I2STX_LINK, ((uint32)(addr)) & I2S_I2S_TXLINK_ADDR)
74 |
75 | #define START_RXLINK() SET_PERI_REG_MASK(I2SRX_LINK, I2S_I2S_RXLINK_START)
76 | #define START_TXLINK() SET_PERI_REG_MASK(I2STX_LINK, I2S_I2S_TXLINK_START)
77 |
78 | /**
79 | * @brief GPIO initialization, including config DATA, WS and BCK GPIO pin.
80 | *
81 | * @attention This API can be called only once per mode.
82 | *
83 | * @param uint8 mode : i2s mode select between TX_MASTER, TX_SLAVE, RX_MASTER, RX_SLAVE;
84 | *
85 | * @return null
86 | */
87 | void i2s_GPIO_init(uint8 mode);
88 |
89 | /**
90 | * @brief I2S module initialization, including FIFO, M/S mode, data format, clock frequency.
91 | *
92 | * @attention This API can be called only once per mode.
93 | *
94 | * @param null
95 | *
96 | * @return null
97 | */
98 | void i2s_init(void);
99 |
100 | /**
101 | * @brief DMA module initialization, including DMA mode and interrupt.
102 | *
103 | * @attention This API can be called only once per mode.
104 | *
105 | * @param null
106 | *
107 | * @return null
108 | */
109 | void slc_init(void);
110 |
111 | /**
112 | * @brief Process data received/treansmitted when interrupt occurs.
113 | *
114 | * @attention This API can be called only once per mode.
115 | *
116 | * @param void *para: pointer to parameter
117 | *
118 | * @return null
119 | */
120 | void slc_isr(void *para);
121 |
122 | /**
123 | * @brief Create DMA buffer descriptors.
124 | *
125 | * @param uint8 own : select the owner of the current link to be either software or hardware
126 | * @param uint8 eof : mark for end of file
127 | * @param uint8 sub_sof : mark for sub start of file
128 | * @param uint16 size : the actual size of the buffer
129 | * @param uint16 length : the total size of the buffer
130 | * @param uint32* buf_ptr : the start address of the buffer
131 | * @param struct sdio_queue* nxt_ptr : the address of the next descriptor
132 | * @param struct sdio_queue* i2s_queue : the address of the current descriptor
133 | *
134 | * @return null
135 | */
136 | void create_one_link(uint8 own, uint8 eof, uint8 sub_sof, uint16 size, uint16 length,
137 | uint32 *buf_ptr, struct sdio_queue *nxt_ptr, struct sdio_queue *i2s_queue);
138 |
139 | /**
140 | * @brief Functional DEMO for i2s module.
141 | *
142 | * @param null
143 | *
144 | * @return null
145 | */
146 | void i2s_test(void);
147 |
148 | /**
149 | * @}
150 | */
151 |
152 | /**
153 | * @}
154 | */
155 |
156 | #ifdef __cplusplus
157 | }
158 | #endif
159 |
160 | #endif
161 |
--------------------------------------------------------------------------------
/user/user_main.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by: Chris Fraser (@thegwa)
3 | * Email: hellochrisfrasercoza
4 | * License: MIT
5 | *
6 | * Blink
7 | * Step 1: Flash an LED
8 | * Step 2: ...
9 | * Step 3: Profit
10 | */
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | // Config
17 | #include "user_config.h"
18 |
19 | // Drivers
20 | #include
21 |
22 | static int statusLedInterval = 5000;
23 |
24 | // Wifi Callback handler
25 | void wifi_event_handler_cb(System_Event_t *event);
26 |
27 | /* wifiConfigTask to setup wifi config */
28 | void wifiConfigTask(void *p) {
29 |
30 | if (wifi_get_opmode() != STATION_MODE)
31 | {
32 | os_printf("Wifi not in Station Mode... Resetting.");
33 | wifi_set_opmode(STATION_MODE);
34 | wifi_station_set_auto_connect(false);
35 | vTaskDelay(1000 / portTICK_RATE_MS);
36 | system_restart();
37 | }
38 |
39 | if (wifi_station_get_auto_connect())
40 | {
41 | os_printf("Wifi set to auto connect... Resetting.");
42 | wifi_station_set_auto_connect(false);
43 | system_restart();
44 | }
45 |
46 | os_printf("Wifi correctly configured.");
47 |
48 | vTaskDelete(NULL);
49 | }
50 |
51 | /* wifiConfigTask to setup wifi config */
52 | void wifiConnectTask(void *p) {
53 |
54 | wifi_set_event_handler_cb(wifi_event_handler_cb);
55 | int count = 0;
56 | while(!wifi_station_connect()){
57 | if( count++ > 10){
58 | os_printf("Setting wifi credentials");
59 | // set AP parameter
60 | struct station_config config;
61 |
62 | bzero(&config, sizeof(struct station_config));
63 | sprintf(config.ssid, SSID);
64 | sprintf(config.password, PASSWORD);
65 | wifi_station_set_config(&config);
66 |
67 | wifi_station_connect();
68 |
69 | break;
70 | }
71 |
72 | vTaskDelay(250 / portTICK_RATE_MS);
73 | }
74 |
75 | vTaskDelete(NULL);
76 | }
77 |
78 | void wifi_event_handler_cb(System_Event_t *event)
79 | {
80 | if (event == NULL) {
81 | os_printf("No event\n");
82 | return;
83 | }
84 |
85 | Event_Info_u event_info = event->event_info;
86 | switch (event->event_id) {
87 | case EVENT_STAMODE_SCAN_DONE:
88 | os_printf("ESP32 station finish scanning AP\n");
89 | break;
90 | case EVENT_STAMODE_CONNECTED:
91 | os_printf("ESP32 station connected to AP\n");
92 |
93 | Event_StaMode_Connected_t c = event_info.connected;
94 | os_printf("SSID: %s\n",c.ssid);
95 |
96 | statusLedInterval = 100;
97 | break;
98 | case EVENT_STAMODE_DISCONNECTED:
99 | os_printf("ESP32 station disconnected to AP\n");
100 | break;
101 | case EVENT_STAMODE_AUTHMODE_CHANGE:
102 | os_printf("The auth mode of AP connected by ESP32 station changed\n");
103 | break;
104 | case EVENT_STAMODE_GOT_IP:
105 | os_printf("ESP32 station got IP from connected AP\n");
106 | statusLedInterval = 1000;
107 | break;
108 | case EVENT_STAMODE_DHCP_TIMEOUT:
109 | os_printf("ESP32 station dhcp client got IP timeout\n");
110 | break;
111 | case EVENT_SOFTAPMODE_STACONNECTED:
112 | os_printf("A station connected to ESP32 soft-AP\n");
113 | break;
114 | case EVENT_SOFTAPMODE_STADISCONNECTED:
115 | os_printf("A station disconnected to ESP32 soft-AP\n");
116 | break;
117 | case EVENT_SOFTAPMODE_PROBEREQRECVED:
118 | os_printf("Receive probe request packet in soft-AP interface\n");
119 | break;
120 | case EVENT_MAX:
121 | os_printf("EVENT_MAX\n");
122 | break;
123 | default:
124 | break;
125 | }
126 | }
127 |
128 | // blinkTask for LED
129 | void blinkTask(void *p) {
130 | while (1) {
131 | //printf("PIN:%i ON\n", LEDPIN);
132 | // Set the pin to high
133 | GPIO_OUTPUT_SET(LEDPIN, 1);
134 |
135 | // For some reason FreeRTOS has a tick rate of 100Hz
136 | // Dividing by portTICK_RATE_MS fixes ms values
137 | vTaskDelay(statusLedInterval / portTICK_RATE_MS);
138 |
139 | //printf("PIN:%i OFF\n", LEDPIN);
140 | // Set the pin to low
141 | GPIO_OUTPUT_SET(LEDPIN, 0);
142 | vTaskDelay(statusLedInterval / portTICK_RATE_MS);
143 | }
144 | }
145 |
146 | // tempReadTask for internal sensor
147 | void tempReadTask(void *p) {
148 |
149 | int* delay = (int*)p;
150 |
151 | while (1) {
152 | printf("Temp: %d\n", temperature_sensor_read() );
153 |
154 | vTaskDelay(*delay / portTICK_RATE_MS);
155 | }
156 | }
157 |
158 | // "main" method
159 | void user_init(void) {
160 | // Print out some interesting things
161 | printf("SDK version:%s\n", system_get_sdk_version());
162 | printf("CPU running at %dMHz\n", system_get_cpu_freq());
163 | printf("Free Heap size: %d\n", system_get_free_heap_size());
164 | system_print_meminfo();
165 |
166 | printf("Starting wifiConfigTask");
167 | printf("==================================================================\n");
168 | // Create the wifiConfig Task
169 | xTaskCreate(wifiConfigTask, (signed char * )"wifiConfigTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
170 |
171 | printf("Starting wifiConnectTask");
172 | printf("==================================================================\n");
173 | // Create the wifiConmect Task
174 | xTaskCreate(wifiConnectTask, (signed char * )"wifiConnectTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
175 |
176 | printf("Starting blinkTask");
177 | printf("==================================================================\n");
178 |
179 | // Create the blink task
180 | xTaskCreate(blinkTask, (signed char * )"blinkTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
181 |
182 | printf("Starting tempReadTask");
183 | printf("==================================================================\n");
184 | static int tempInterval = 5000; // interval to pass to the tempReadTask via *pvParameters
185 |
186 | // Create the tempRead Task
187 | xTaskCreate(tempReadTask, (signed char * )"tempReadTask", configMINIMAL_STACK_SIZE, &tempInterval, 1, NULL);
188 | }
189 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #############################################################
2 | # Required variables for each makefile
3 | # Discard this section from all parent makefiles
4 | # Expected variables (with automatic defaults):
5 | # CSRCS (all "C" files in the dir)
6 | # SUBDIRS (all subdirs with a Makefile)
7 | # GEN_LIBS - list of libs to be generated ()
8 | # GEN_IMAGES - list of object file images to be generated ()
9 | # GEN_BINS - list of binaries to be generated ()
10 | # COMPONENTS_xxx - a list of libs/objs in the form
11 | # subdir/lib to be extracted and rolled up into
12 | # a generated lib/image xxx.a ()
13 | #
14 |
15 | TARGET = eagle
16 | #FLAVOR = release
17 | FLAVOR = debug
18 |
19 | #EXTRA_CCFLAGS += -u
20 |
21 | # esptool path and port
22 | ESPTOOL ?= utils/esptool32.py
23 | ESPPORT ?= /dev/ttyUSB0
24 | # Baud rate for programmer
25 | BAUD ?= 230400
26 |
27 | # SPI_SPEED = 40, 26, 20, 80
28 | SPI_SPEED ?= 40
29 | # SPI_MODE: qio, qout, dio, dout
30 | SPI_MODE ?= qio
31 | # SPI_SIZE_MAP
32 | # 0 : 512 KB (256 KB + 256 KB)
33 | # 1 : 256 KB
34 | # 2 : 1024 KB (512 KB + 512 KB)
35 | # 3 : 2048 KB (512 KB + 512 KB)
36 | # 4 : 4096 KB (512 KB + 512 KB)
37 | # 5 : 2048 KB (1024 KB + 1024 KB)
38 | # 6 : 4096 KB (1024 KB + 1024 KB)
39 | SPI_SIZE_MAP ?= 1
40 |
41 | ifeq ($(SPI_SPEED), 26.7)
42 | freqdiv = 1
43 | flashimageoptions = -ff 26m
44 | else
45 | ifeq ($(SPI_SPEED), 20)
46 | freqdiv = 2
47 | flashimageoptions = -ff 20m
48 | else
49 | ifeq ($(SPI_SPEED), 80)
50 | freqdiv = 15
51 | flashimageoptions = -ff 80m
52 | else
53 | freqdiv = 0
54 | flashimageoptions = -ff 40m
55 | endif
56 | endif
57 | endif
58 |
59 | ifeq ($(SPI_MODE), QOUT)
60 | mode = 1
61 | flashimageoptions += -fm qout
62 | else
63 | ifeq ($(SPI_MODE), DIO)
64 | mode = 2
65 | flashimageoptions += -fm dio
66 | else
67 | ifeq ($(SPI_MODE), DOUT)
68 | mode = 3
69 | flashimageoptions += -fm dout
70 | else
71 | mode = 0
72 | flashimageoptions += -fm qio
73 | endif
74 | endif
75 | endif
76 |
77 | ifeq ($(SPI_SIZE_MAP), 1)
78 | size_map = 1
79 | flash = 256
80 | flashimageoptions += -fs 2m
81 | blankaddr = 0xFC000
82 | else
83 | ifeq ($(SPI_SIZE_MAP), 2)
84 | size_map = 2
85 | flash = 1024
86 | flashimageoptions += -fs 8m
87 | blankaddr = 0xFE000
88 | else
89 | ifeq ($(SPI_SIZE_MAP), 3)
90 | size_map = 3
91 | flash = 2048
92 | flashimageoptions += -fs 16m
93 | blankaddr = 0x1FE000
94 | else
95 | ifeq ($(SPI_SIZE_MAP), 4)
96 | size_map = 4
97 | flash = 4096
98 | flashimageoptions += -fs 32m
99 | blankaddr = 0x3FE000
100 | else
101 | ifeq ($(SPI_SIZE_MAP), 5)
102 | size_map = 5
103 | flash = 2048
104 | flashimageoptions += -fs 16m
105 | blankaddr = 0x1FE000
106 | else
107 | ifeq ($(SPI_SIZE_MAP), 6)
108 | size_map = 6
109 | flash = 4096
110 | flashimageoptions += -fs 32m
111 | blankaddr = 0x3FE000
112 | else
113 | size_map = 0
114 | flash = 512
115 | flashimageoptions += -fs 4m
116 | blankaddr = 0x7E000
117 | endif
118 | endif
119 | endif
120 | endif
121 | endif
122 | endif
123 |
124 | ifndef PDIR # {
125 | GEN_IMAGES= eagle.app.v7.out
126 | GEN_BINS= eagle.app.v7.bin
127 | SPECIAL_MKTARGETS=$(APP_MKTARGETS)
128 | SUBDIRS= \
129 | driver \
130 | user
131 |
132 | endif # } PDIR
133 |
134 | LDDIR = $(SDK_PATH)/ld
135 |
136 | CCFLAGS += -Os
137 |
138 | TARGET_LDFLAGS = \
139 | -nostdlib \
140 | -Wl,-EL \
141 | --longcalls \
142 | --text-section-literals
143 |
144 | ifeq ($(FLAVOR),debug)
145 | TARGET_LDFLAGS += -g -O2
146 | endif
147 |
148 | ifeq ($(FLAVOR),release)
149 | TARGET_LDFLAGS += -g -O0
150 | endif
151 |
152 | COMPONENTS_eagle.app.v7 = \
153 | driver/libdriver.a \
154 | user/libuser.a
155 |
156 | LINKFLAGS_eagle.app.v7 = \
157 | -L$(SDK_PATH)/lib \
158 | -nostdlib \
159 | -T$(LD_FILE) \
160 | -Wl,--no-check-sections \
161 | -u call_user_start \
162 | -Wl,-static \
163 | -Wl,--start-group \
164 | -lc \
165 | -lgcc \
166 | -lhal \
167 | -lm \
168 | -lcrypto \
169 | -lfreertos \
170 | -llwip \
171 | -lmain \
172 | -lnet80211 \
173 | -lphy \
174 | -lpp \
175 | -lrtc \
176 | -lwpa \
177 | $(DEP_LIBS_eagle.app.v7)\
178 | -Wl,--end-group
179 |
180 | DEPENDS_eagle.app.v7 = $(LD_FILE)
181 |
182 | #############################################################
183 | # Configuration i.e. compile options etc.
184 | # Target specific stuff (defines etc.) goes in here!
185 | # Generally values applying to a tree are captured in the
186 | # makefile at its root level - these are then overridden
187 | # for a subtree within the makefile rooted therein
188 | #
189 |
190 | #UNIVERSAL_TARGET_DEFINES = \
191 |
192 | # Other potential configuration flags include:
193 | # -DTXRX_TXBUF_DEBUG
194 | # -DTXRX_RXBUF_DEBUG
195 | # -DWLAN_CONFIG_CCX
196 | CONFIGURATION_DEFINES = -DICACHE_FLASH
197 |
198 | DEFINES += \
199 | $(UNIVERSAL_TARGET_DEFINES) \
200 | $(CONFIGURATION_DEFINES)
201 |
202 | DDEFINES += \
203 | $(UNIVERSAL_TARGET_DEFINES) \
204 | $(CONFIGURATION_DEFINES)
205 |
206 |
207 | #############################################################
208 | # Recursion Magic - Don't touch this!!
209 | #
210 | # Each subtree potentially has an include directory
211 | # corresponding to the common APIs applicable to modules
212 | # rooted at that subtree. Accordingly, the INCLUDE PATH
213 | # of a module can only contain the include directories up
214 | # its parent path, and not its siblings
215 | #
216 | # Required for each makefile to inherit from the parent
217 | #
218 |
219 | INCLUDES := $(INCLUDES) -I $(PDIR)include
220 | sinclude $(SDK_PATH)/Makefile
221 |
222 | .PHONY: checkpath
223 | checkpath:
224 | @if test -z $(SDK_PATH); then \
225 | echo "Please export SDK_PATH firstly!!!"; \
226 | exit 1; \
227 | else \
228 | if test ! -d $(SDK_PATH)/include/espressif/esp32; then \
229 | echo "$(SDK_PATH) is not a ESP32_RTOS_SDK path, please check!!!"; \
230 | exit 1; \
231 | fi; \
232 | fi; \
233 | echo "$(SDK_PATH) is all good." \
234 |
235 | flash: all
236 | python $(ESPTOOL) -p $(ESPPORT) -b $(BAUD) write_flash $(flashimageoptions) 0x00000 $(SDK_PATH)/bin/boot.bin 0x04000 $(BIN_PATH)/irom1.bin 0x40000 $(BIN_PATH)/irom0_flash.bin $(blankaddr) $(SDK_PATH)/bin/blank.bin
237 |
238 | rebuild: clean all
239 |
240 |
--------------------------------------------------------------------------------
/include/uart.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #ifndef __UART_H__
26 | #define __UART_H__
27 |
28 | #ifdef __cplusplus
29 | extern "C" {
30 | #endif
31 |
32 | #define ETS_UART_INTR_ENABLE() xt_ints_on(1 << ETS_UART_INUM)
33 | #define ETS_UART_INTR_DISABLE() xt_ints_off(1 << ETS_UART_INUM)
34 | #define UART_INTR_MASK 0x1ff
35 | #define UART_LINE_INV_MASK (0x3f << 19)
36 |
37 | typedef enum {
38 | UART_WordLength_5b = 0x0,
39 | UART_WordLength_6b = 0x1,
40 | UART_WordLength_7b = 0x2,
41 | UART_WordLength_8b = 0x3
42 | } UART_WordLength;
43 |
44 | typedef enum {
45 | USART_StopBits_1 = 0x1,
46 | USART_StopBits_1_5 = 0x2,
47 | USART_StopBits_2 = 0x3,
48 | } UART_StopBits;
49 |
50 | typedef enum {
51 | UART0 = 0x0,
52 | UART1 = 0x1,
53 | } UART_Port;
54 |
55 | typedef enum {
56 | USART_Parity_None = 0x2,
57 | USART_Parity_Even = 0x0,
58 | USART_Parity_Odd = 0x1
59 | } UART_ParityMode;
60 |
61 | typedef enum {
62 | PARITY_DIS = 0x0,
63 | PARITY_EN = 0x2
64 | } UartExistParity;
65 |
66 | typedef enum {
67 | BIT_RATE_300 = 300,
68 | BIT_RATE_600 = 600,
69 | BIT_RATE_1200 = 1200,
70 | BIT_RATE_2400 = 2400,
71 | BIT_RATE_4800 = 4800,
72 | BIT_RATE_9600 = 9600,
73 | BIT_RATE_19200 = 19200,
74 | BIT_RATE_38400 = 38400,
75 | BIT_RATE_57600 = 57600,
76 | BIT_RATE_74880 = 74880,
77 | BIT_RATE_115200 = 115200,
78 | BIT_RATE_230400 = 230400,
79 | BIT_RATE_460800 = 460800,
80 | BIT_RATE_921600 = 921600,
81 | BIT_RATE_1843200 = 1843200,
82 | BIT_RATE_3686400 = 3686400,
83 | } UART_BautRate; //you can add any rate you need in this range
84 |
85 | typedef enum {
86 | USART_HardwareFlowControl_None = 0x0,
87 | USART_HardwareFlowControl_RTS = 0x1,
88 | USART_HardwareFlowControl_CTS = 0x2,
89 | USART_HardwareFlowControl_CTS_RTS = 0x3
90 | } UART_HwFlowCtrl;
91 |
92 | typedef enum {
93 | UART_None_Inverse = 0x0,
94 | UART_Rxd_Inverse = UART_RXD_INV,
95 | UART_CTS_Inverse = UART_CTS_INV,
96 | UART_Txd_Inverse = UART_TXD_INV,
97 | UART_RTS_Inverse = UART_RTS_INV,
98 | } UART_LineLevelInverse;
99 |
100 | typedef struct {
101 | UART_BautRate baud_rate;
102 | UART_WordLength data_bits;
103 | UART_ParityMode parity; // chip size in byte
104 | UART_StopBits stop_bits;
105 | UART_HwFlowCtrl flow_ctrl;
106 | uint8 UART_RxFlowThresh ;
107 | uint32 UART_InverseMask;
108 | } UART_ConfigTypeDef;
109 |
110 | typedef struct {
111 | uint32 UART_IntrEnMask;
112 | uint8 UART_RX_TimeOutIntrThresh;
113 | uint8 UART_TX_FifoEmptyIntrThresh;
114 | uint8 UART_RX_FifoFullIntrThresh;
115 | } UART_IntrConfTypeDef;
116 |
117 | //=======================================
118 |
119 | /** \defgroup Driver_APIs Driver APIs
120 | * @brief Driver APIs
121 | */
122 |
123 | /** @addtogroup Driver_APIs
124 | * @{
125 | */
126 |
127 | /** \defgroup UART_Driver_APIs UART Driver APIs
128 | * @brief UART driver APIs
129 | */
130 |
131 | /** @addtogroup UART_Driver_APIs
132 | * @{
133 | */
134 |
135 |
136 | /**
137 | * @brief Set UART baud rate.
138 | *
139 | * Example : uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));
140 | *
141 | * @param UART_Port uart_no : UART0 or UART1
142 | * @param uint16 div : frequency divider
143 | *
144 | * @return null
145 | */
146 | void uart_div_modify(UART_Port uart_no, uint16 div);
147 |
148 | /**
149 | * @brief Wait uart tx fifo empty, do not use it if tx flow control enabled.
150 | *
151 | * @param UART_Port uart_no : UART0 or UART1
152 | *
153 | * @return null
154 | */
155 | void UART_WaitTxFifoEmpty(UART_Port uart_no); //do not use if tx flow control enabled
156 |
157 | /**
158 | * @brief Clear uart tx fifo and rx fifo.
159 | *
160 | * @param UART_Port uart_no : UART0 or UART1
161 | *
162 | * @return null
163 | */
164 | void UART_ResetFifo(UART_Port uart_no);
165 |
166 | /**
167 | * @brief Clear uart interrupt flags.
168 | *
169 | * @param UART_Port uart_no : UART0 or UART1
170 | * @param uint32 clr_mask : To clear the interrupt bits
171 | *
172 | * @return null
173 | */
174 | void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask);
175 |
176 | /**
177 | * @brief Enable uart interrupts .
178 | *
179 | * @param UART_Port uart_no : UART0 or UART1
180 | * @param uint32 ena_mask : To enable the interrupt bits
181 | *
182 | * @return null
183 | */
184 | void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask);
185 |
186 | /**
187 | * @brief Register an application-specific interrupt handler for Uarts interrupts.
188 | *
189 | * @param void *fn : interrupt handler for Uart interrupts.
190 | * @param void *arg : interrupt handler's arg.
191 | *
192 | * @return null
193 | */
194 | void UART_intr_handler_register(void *fn, void *arg);
195 |
196 | /**
197 | * @brief Config from which serial output printf function.
198 | *
199 | * @param UART_Port uart_no : UART0 or UART1
200 | *
201 | * @return null
202 | */
203 | void UART_SetPrintPort(UART_Port uart_no);
204 |
205 | /**
206 | * @brief Config Common parameters of serial ports.
207 | *
208 | * @param UART_Port uart_no : UART0 or UART1
209 | * @param UART_ConfigTypeDef *pUARTConfig : parameters structure
210 | *
211 | * @return null
212 | */
213 | void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig);
214 |
215 | /**
216 | * @brief Config types of uarts.
217 | *
218 | * @param UART_Port uart_no : UART0 or UART1
219 | * @param UART_IntrConfTypeDef *pUARTIntrConf : parameters structure
220 | *
221 | * @return null
222 | */
223 | void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf);
224 |
225 | /**
226 | * @brief Config the length of the uart communication data bits.
227 | *
228 | * @param UART_Port uart_no : UART0 or UART1
229 | * @param UART_WordLength len : the length of the uart communication data bits
230 | *
231 | * @return null
232 | */
233 | void UART_SetWordLength(UART_Port uart_no, UART_WordLength len);
234 |
235 | /**
236 | * @brief Config the length of the uart communication stop bits.
237 | *
238 | * @param UART_Port uart_no : UART0 or UART1
239 | * @param UART_StopBits bit_num : the length uart communication stop bits
240 | *
241 | * @return null
242 | */
243 | void UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num);
244 |
245 | /**
246 | * @brief Configure whether to open the parity.
247 | *
248 | * @param UART_Port uart_no : UART0 or UART1
249 | * @param UART_ParityMode Parity_mode : the enum of uart parity configuration
250 | *
251 | * @return null
252 | */
253 | void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) ;
254 |
255 | /**
256 | * @brief Configure the Baud rate.
257 | *
258 | * @param UART_Port uart_no : UART0 or UART1
259 | * @param uint32 baud_rate : the Baud rate
260 | *
261 | * @return null
262 | */
263 | void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate);
264 |
265 | /**
266 | * @brief Configure Hardware flow control.
267 | *
268 | * @param UART_Port uart_no : UART0 or UART1
269 | * @param UART_HwFlowCtrl flow_ctrl : Hardware flow control mode
270 | * @param uint8 rx_thresh : threshold of Hardware flow control
271 | *
272 | * @return null
273 | */
274 | void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh);
275 |
276 | /**
277 | * @brief Configure trigging signal of uarts.
278 | *
279 | * @param UART_Port uart_no : UART0 or UART1
280 | * @param UART_LineLevelInverse inverse_mask : Choose need to flip the IO
281 | *
282 | * @return null
283 | */
284 | void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) ;
285 |
286 | /**
287 | * @brief An example illustrates how to configure the serial port.
288 | *
289 | * @param null
290 | *
291 | * @return null
292 | */
293 | void uart_init_new(void);
294 |
295 | /**
296 | * @}
297 | */
298 |
299 | /**
300 | * @}
301 | */
302 |
303 | #ifdef __cplusplus
304 | }
305 | #endif
306 |
307 | #endif
308 |
--------------------------------------------------------------------------------
/utils/gen_appbin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # File : gen_appbin.py
4 | # This file is part of Espressif's generate bin script.
5 | # Copyright (C) 2013 - 2016, Espressif Systems
6 | #
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of version 3 of the GNU General Public License as
9 | # published by the Free Software Foundation.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License along
17 | # with this program. If not, see .
18 |
19 | """This file is part of Espressif's generate bin script.
20 | argv[1] is elf file name
21 | argv[2] is version num"""
22 |
23 | import string
24 | import sys
25 | import os
26 | import re
27 | import binascii
28 | import struct
29 | import zlib
30 |
31 |
32 | TEXT_ADDRESS = 0x40040000
33 | # app_entry = 0
34 | # data_address = 0x3ffb0000
35 | # data_end = 0x40000000
36 | # text_end = 0x40120000
37 |
38 | CHECKSUM_INIT = 0xEF
39 |
40 | chk_sum = CHECKSUM_INIT
41 | blocks = 0
42 | flash_blocks = 0
43 |
44 | def write_file(file_name,data):
45 | if file_name is None:
46 | print 'file_name cannot be none\n'
47 | sys.exit(0)
48 |
49 | fp = open(file_name,'ab')
50 |
51 | if fp:
52 | fp.seek(0,os.SEEK_END)
53 | fp.write(data)
54 | fp.close()
55 | else:
56 | print '%s write fail\n'%(file_name)
57 |
58 | def combine_bin(file_name,dest_file_name,start_offset_addr,need_chk):
59 | global chk_sum
60 |
61 | if dest_file_name is None:
62 | print 'dest_file_name cannot be none\n'
63 | sys.exit(0)
64 |
65 | if file_name:
66 | fp = open(file_name,'rb')
67 | if fp:
68 | ########## write text ##########
69 | fp.seek(0,os.SEEK_END)
70 | data_len = fp.tell()
71 | if data_len:
72 | if need_chk:
73 | tmp_len = (data_len + 3) & (~3)
74 | else:
75 | tmp_len = (data_len + 15) & (~15)
76 | data_bin = struct.pack(' eagle.app.sym'
169 | else :
170 | cmd = 'xtensa-esp108-elf-nm -g ' + elf_file + ' > eagle.app.sym'
171 |
172 | os.system(cmd)
173 |
174 | fp = file('./eagle.app.sym')
175 | if fp is None:
176 | print "open sym file error\n"
177 | sys.exit(0)
178 |
179 | lines = fp.readlines()
180 | fp.close()
181 |
182 | entry_addr = None
183 | p = re.compile('(\w*)(\sT\s)(call_user_start)$')
184 | for line in lines:
185 | m = p.search(line)
186 | if m != None:
187 | entry_addr = m.group(1)
188 |
189 |
190 | if entry_addr is None:
191 | print 'no entry point!!'
192 | sys.exit(0)
193 |
194 | data_start_addr = '0'
195 | p = re.compile('(\w*)(\sA\s)(_data_start)$')
196 | for line in lines:
197 | m = p.search(line)
198 | if m != None:
199 | data_start_addr = m.group(1)
200 |
201 |
202 | rodata_start_addr = '0'
203 | p = re.compile('(\w*)(\sA\s)(_rodata_start)$')
204 | for line in lines:
205 | m = p.search(line)
206 | if m != None:
207 | rodata_start_addr = m.group(1)
208 |
209 | if os.path.getsize(text_bin_name):
210 | blocks = blocks + 1
211 | if os.path.getsize(data_bin_name):
212 | blocks = blocks + 1
213 | if os.path.getsize(rodata_bin_name):
214 | blocks = blocks + 1
215 |
216 | fp1 = open(irom1text_bin_name,'rb')
217 | fp1.seek(0,os.SEEK_END)
218 | Dcache_data_len = fp1.tell()
219 | # print data_len
220 | if Dcache_data_len :
221 | Dcache_data_len = struct.pack('> 8)+chr((all_bin_crc & 0x00FF0000) >> 16)+chr((all_bin_crc & 0xFF000000) >> 24))
283 | icache_file = open(flash_bin_name, "rb")
284 | if int(os.path.getsize(irom1text_bin_name)):
285 | Dcache_bin_len = (int(os.path.getsize(irom1text_bin_name)) + 16 +15 ) &(~15)
286 | #print Dcache_bin_len
287 | icache_file.seek(Dcache_bin_len ,0)
288 | open(Icache_flash_bin_name, "wb").write(icache_file.read())
289 | cmd = 'rm eagle.app.sym'
290 | os.system(cmd)
291 |
292 | if __name__=='__main__':
293 | gen_appbin()
294 |
--------------------------------------------------------------------------------
/include/pwm.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 |
26 | #ifndef __PWM_H__
27 | #define __PWM_H__
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | //#include "Ledc_reg.h"
34 | //#include "ets_sys.h"
35 | //#include "eagle_soc.h"
36 |
37 |
38 | /** \defgroup Driver_APIs Driver APIs
39 | * @brief Driver APIs
40 | */
41 |
42 | /** @addtogroup Driver_APIs
43 | * @{
44 | */
45 |
46 | /** \defgroup PWM_Driver_APIs PWM Driver APIs
47 | * @brief PWM driver APIs
48 | */
49 |
50 | /** @addtogroup PWM_Driver_APIs
51 | * @{
52 | */
53 |
54 | #define PWM_CHANNEL_NUM_MAX 8
55 |
56 | #define TIMER0 0
57 | #define TIMER1 1
58 | #define TIMER2 2
59 | #define TIMER3 3
60 |
61 | #define CHANNEL0 0
62 | #define CHANNEL1 1
63 | #define CHANNEL2 2
64 | #define CHANNEL3 3
65 | #define CHANNEL4 4
66 | #define CHANNEL5 5
67 | #define CHANNEL6 6
68 | #define CHANNEL7 7
69 |
70 | #define OUTPUT_LOW 0
71 | #define OUTPUT_HIGH 1
72 |
73 | #define REF_TICK_CLK 0
74 | #define APB_CLK 1
75 |
76 | struct pwm_param {
77 | uint32 period;
78 | uint32 freq;
79 | uint32 duty[PWM_CHANNEL_NUM_MAX]; //PWM_CHANNEL<=8
80 | };
81 |
82 | /**
83 | * @brief PWM function initialization, including GPIO, frequency and duty cycle.
84 | *
85 | * @attention This API can be called only once.
86 | *
87 | * @param uint32 period : pwm frequency
88 | * @param uint32 *duty : duty cycle
89 | * @param uint32 pwm_channel_num : PWM channel number
90 | * @param uint32 (*pin_info_list)[3] : GPIO parameter of PWM channel, it is a pointer
91 | * of n x 3 array which defines GPIO register, IO
92 | * reuse of corresponding pin and GPIO number.
93 | *
94 | * @return null
95 | */
96 | void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32(*pin_info_list)[3]);
97 |
98 | /**
99 | * @brief Set the duty cycle of a PWM channel.
100 | *
101 | * Set the time that high level signal will last, duty depends on period,
102 | * the maximum value can be period *1000 / 45.
103 | * For example, 1KHz PWM, duty range is 0~22222
104 | *
105 | * @attention After set configuration, pwm_start needs to be called to take effect.
106 | *
107 | * @param uint32 duty : duty cycle
108 | * @param uint8 channel : PWM channel number
109 | *
110 | * @return null
111 | */
112 | void pwm_set_duty(uint32 duty, uint8 channel);
113 |
114 | /**
115 | * @brief Get the duty cycle of a PWM channel.
116 | *
117 | * Duty cycle will be (duty * 45)/(period *1000).
118 | *
119 | * @param uint8 channel : PWM channel number
120 | *
121 | * @return Duty cycle of PWM output.
122 | */
123 | uint32 pwm_get_duty(uint8 channel);
124 |
125 | /**
126 | * @brief Set PWM period, unit : us.
127 | *
128 | * For example, for 1KHz PWM, period is 1000 us.
129 | *
130 | * @attention After set configuration, pwm_start needs to be called to take effect.
131 | *
132 | * @param uint32 period : PWM period, unit : us.
133 | *
134 | * @return null
135 | */
136 | void pwm_set_period(uint32 period);
137 |
138 | /**
139 | * @brief Get PWM period, unit : us.
140 | *
141 | * @param null
142 | *
143 | * @return PWM period, unit : us.
144 | */
145 | uint32 pwm_get_period(void);
146 |
147 | /**
148 | * @brief Starts PWM.
149 | *
150 | * @attention This function needs to be called after PWM configuration is changed.
151 | *
152 | * @param null
153 | *
154 | * @return null
155 | */
156 | void pwm_start(void);
157 |
158 | /**
159 | * @brief Set high_speed channel base clock.
160 | *
161 | * @param uint8 timer_sel : timer to set
162 | * @param uint8 apb_clk_sel : pick clock source for timer
163 | *
164 | * @return null
165 | */
166 | void ledc_set_base_hclk(uint8 timer_sel, uint8 apb_clk_sel);
167 |
168 | /**
169 | * @brief Set low_speed channel base clock.
170 | *
171 | * @param uint8 timer_sel : timer to set
172 | * @param uint8 apb_clk_sel :pick clock source for timer
173 | *
174 | * @return null
175 | */
176 | void ledc_set_base_lclk(uint8 timer_sel, uint8 apb_clk_sel);
177 |
178 | /**
179 | * @brief Set high_speed channel frequency.
180 | *
181 | * frequency=base_clk_frequency*div_num*(2^timer_lim)/256
182 | *
183 | * @param uint8 timer_sel : timer to set
184 | * @param uint32 div_num : set first divider
185 | * @param uint8 timer_lim : set second divider
186 | *
187 | * @return null
188 | */
189 | void ledc_set_hperiod(uint8 timer_sel, uint32 div_num, uint8 timer_lim);
190 |
191 | /**
192 | * @brief Set low_speed channel frequency.
193 | *
194 | * frequency=base_clk_frequency*div_num*(2^timer_lim)/256
195 | *
196 | * @param uint8 timer_sel : timer to set
197 | * @param uint32 div_num : set first divider
198 | * @param uint8 timer_lim : set second divider
199 | *
200 | * @return null
201 | */
202 | void ledc_set_lperiod(uint8 timer_sel, uint32 div_num, uint8 timer_lim);
203 |
204 | /**
205 | * @brief Select one timer for one low_speed channel.
206 | *
207 | * @param uint8 chan_num : channel to pick
208 | * @param uint8 timer_sel : timer to set
209 | *
210 | * @return null
211 | */
212 | void ledc_set_ltimer(uint8 chan_num, uint8 timer_sel);
213 |
214 | /**
215 | * @brief Select one timer for one high_speed channel.
216 | *
217 | * @param uint8 chan_num : channel to pick
218 | * @param uint8 timer_sel : timer to set
219 | *
220 | * @return null
221 | */
222 | void ledc_set_htimer(uint8 chan_num, uint8 timer_sel);
223 |
224 | /**
225 | * @brief Set high_speed channel output (as high or low) when idle.
226 | *
227 | * @param uint8 chan_num : channel to pick
228 | * @param uint8 idle_level : choose output as high or low
229 | *
230 | * @return null
231 | */
232 | void ledc_set_idle_hlevel(uint8 chan_num, uint8 idle_level);
233 |
234 | /**
235 | * @brief Set low_speed channel output (as high or low) when idle.
236 | *
237 | * @param uint8 chan_num : channel to pick
238 | * @param uint8 idle_level : choose output as high or low
239 | *
240 | * @return null
241 | */
242 | void ledc_set_idle_llevel(uint8 chan_num, uint8 idle_level);
243 |
244 | /**
245 | * @brief Set high_speed channel duty.
246 | *
247 | * @param uint8 chan_num : 8 channels in total,value from 0~7
248 | * @param uint32 hpoint_val : output high when counter equals this value
249 | * @param uint32 duty_val : output low after counter equals this value
250 | * @param uint8 increase : 1 - increase duty ratio, 0 - decrease duty ratio
251 | * @param uint16 duty_num : generate interrupt after duty_num * duty_cycle outputs
252 | * @param uint16 duty_cycle : increase or decrease duty ratio every duty_cycle outputs
253 | * @param uint16 duty_scale : the range of changing on duty ratio
254 | *
255 | * @return null
256 | */
257 | void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 increase, uint16 duty_num, uint16 duty_cycle, uint16 duty_scale);
258 |
259 | /**
260 | * @brief Set low_speed channel duty.
261 | *
262 | * @param uint8 chan_num : 8 channels in total, value from 0~7
263 | * @param uint32 hpoint_val : output high when counter equals this value
264 | * @param uint32 duty_val : output low after counter equals this value
265 | * @param uint8 increase : 1 - increase duty ratio, 0 - decrease duty ratio
266 | * @param uint16 duty_num : generate interrupt after duty_num * duty_cycle outputs
267 | * @param uint16 duty_cycle : increase or decrease duty ratio every duty_cycle outputs
268 | * @param uint16 duty_scale : the range of changing on duty ratio
269 | *
270 | * @return null
271 | */
272 | void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 increase, uint16 duty_num, uint16 duty_cycle, uint16 duty_scale);
273 |
274 | /**
275 | * @brief Enable one high_speed channel.
276 | *
277 | * @param uint8 chan_num : channel to pick
278 | *
279 | * @return null
280 | */
281 | void ledc_hstart(uint8 chan_num);
282 |
283 | /**
284 | * @brief Enable one low_speed channel.
285 | *
286 | * @param uint8 chan_num : channel to pick
287 | *
288 | * @return null
289 | */
290 | void ledc_lstart(uint8 chan_num);
291 |
292 | /**
293 | * @brief Pause one of the timers for high_speed channel.
294 | *
295 | * @param uint8 timer_sel : timer to set
296 | *
297 | * @return null
298 | */
299 | void ledc_timer_hpause(uint8 timer_sel);
300 |
301 | /**
302 | * @brief Pause one of the timers for low_speed channel.
303 | *
304 | * @param uint8 timer_sel : timer to set
305 | *
306 | * @return null
307 | */
308 | void ledc_timer_lpause(uint8 timer_sel);
309 |
310 | /**
311 | * @brief Unpause one of the timers for high_speed channel.
312 | *
313 | * @param uint8 timer_sel : timer to set
314 | *
315 | * @return null
316 | */
317 | void ledc_timer_hunpause(uint8 timer_sel);
318 |
319 | /**
320 | * @brief Unpause one of the timers for low_speed channel.
321 | *
322 | * @param uint8 timer_sel : timer to set
323 | *
324 | * @return null
325 | */
326 | void ledc_timer_lunpause(uint8 timer_sel);
327 |
328 | /**
329 | * @brief Stop one of the timers for high_speed channel.
330 | *
331 | * @param uint8 timer_sel : timer to set
332 | *
333 | * @return null
334 | */
335 | void ledc_timer_hstop(uint8 timer_sel);
336 |
337 | /**
338 | * @brief Stop one of the timers for low_speed channel.
339 | *
340 | * @param uint8 timer_sel : timer to set
341 | *
342 | * @return null
343 | */
344 | void ledc_timer_lstop(uint8 timer_sel);
345 |
346 | /**
347 | * @}
348 | */
349 |
350 | /**
351 | * @}
352 | */
353 |
354 | #ifdef __cplusplus
355 | }
356 |
357 | #endif
358 |
359 | #endif
360 |
--------------------------------------------------------------------------------
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
83 |
84 |
85 |
86 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | make
141 |
142 | all
143 | true
144 | true
145 | true
146 |
147 |
148 | make
149 |
150 | clean
151 | true
152 | true
153 | true
154 |
155 |
156 | make
157 |
158 | checkpath
159 | true
160 | true
161 | true
162 |
163 |
164 | make
165 | flash
166 | true
167 | true
168 | true
169 |
170 |
171 | make
172 |
173 | rebuild
174 | true
175 | true
176 | true
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/driver/gpio.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #include "espressif/esp_common.h"
26 | #include "freertos/portmacro.h"
27 | #include "freertos/xtensa_api.h"
28 | #include "gpio.h"
29 | #include
30 |
31 | const uint32 GPIO_PIN_REG[40] = {
32 | GPIO_PIN_REG_0,
33 | GPIO_PIN_REG_1,
34 | GPIO_PIN_REG_2,
35 | GPIO_PIN_REG_3,
36 | GPIO_PIN_REG_4,
37 | GPIO_PIN_REG_5,
38 | GPIO_PIN_REG_6,
39 | GPIO_PIN_REG_7,
40 | GPIO_PIN_REG_8,
41 | GPIO_PIN_REG_9,
42 | GPIO_PIN_REG_10,
43 | GPIO_PIN_REG_11,
44 | GPIO_PIN_REG_12,
45 | GPIO_PIN_REG_13,
46 | GPIO_PIN_REG_14,
47 | GPIO_PIN_REG_15,
48 | GPIO_PIN_REG_16,
49 | GPIO_PIN_REG_17,
50 | GPIO_PIN_REG_18,
51 | GPIO_PIN_REG_19,
52 | GPIO_PIN_REG_20,
53 | GPIO_PIN_REG_21,
54 | GPIO_PIN_REG_22,
55 | GPIO_PIN_REG_23,
56 | 0,
57 | GPIO_PIN_REG_25,
58 | GPIO_PIN_REG_26,
59 | GPIO_PIN_REG_27,
60 | 0,
61 | 0,
62 | 0,
63 | 0,
64 | GPIO_PIN_REG_32,
65 | GPIO_PIN_REG_33,
66 | GPIO_PIN_REG_34,
67 | GPIO_PIN_REG_35,
68 | GPIO_PIN_REG_36,
69 | GPIO_PIN_REG_37,
70 | GPIO_PIN_REG_38,
71 | GPIO_PIN_REG_39
72 | };
73 |
74 | const uint8 intr_gpio_signals[] = {
75 | PCNT_SIG_CH0_IN0_IDX,
76 | PCNT_SIG_CH0_IN1_IDX,
77 | PCNT_SIG_CH0_IN2_IDX,
78 | PCNT_SIG_CH0_IN3_IDX,
79 | PCNT_SIG_CH0_IN4_IDX,
80 | PCNT_SIG_CH0_IN5_IDX,
81 | PCNT_SIG_CH0_IN6_IDX,
82 | PCNT_SIG_CH0_IN7_IDX
83 | };
84 |
85 | uint8 intr_gpio_nums[8];
86 |
87 | static void gpio_intr_reset(uint32 intr_num, uint8 reset)
88 | {
89 | if (intr_num > 7) {
90 | return;
91 | }
92 |
93 | //bit PCNT_CNT_PAUSE_U0-7
94 | CLEAR_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2 + 1));
95 |
96 | //bit PCNT_PLUS_CNT_RST_U0-7
97 | if (reset) {
98 | SET_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2));
99 | } else {
100 | CLEAR_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2));
101 | }
102 | }
103 |
104 | static void gpio_intr_init(uint32 intr_num, GPIO_INT_TYPE intr_type)
105 | {
106 | uint32 cfg0_addr = PCNT_U0_CONF0 + (intr_num * 12);
107 | uint32 cfg1_addr = PCNT_U0_CONF1 + (intr_num * 12);
108 | uint32 cfg2_addr = PCNT_U0_CONF2 + (intr_num * 12);
109 |
110 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_LCTRL_MODE_U0, 0, PCNT_CH1_LCTRL_MODE_U0_S);
111 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_HCTRL_MODE_U0, 0, PCNT_CH1_HCTRL_MODE_U0_S);
112 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_POS_MODE_U0, 0, PCNT_CH1_POS_MODE_U0_S);
113 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH1_NEG_MODE_U0, 0, PCNT_CH1_NEG_MODE_U0_S);
114 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_LCTRL_MODE_U0, 0, PCNT_CH0_LCTRL_MODE_U0_S);
115 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_HCTRL_MODE_U0, 0, PCNT_CH0_HCTRL_MODE_U0_S);
116 |
117 | if (intr_type == GPIO_PIN_INTR_NEGEDGE) {
118 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 0, PCNT_CH0_POS_MODE_U0_S);
119 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 1, PCNT_CH0_NEG_MODE_U0_S);
120 | } else if (intr_type == GPIO_PIN_INTR_POSEDGE) {
121 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 1, PCNT_CH0_POS_MODE_U0_S);
122 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 0, PCNT_CH0_NEG_MODE_U0_S);
123 | } else if (intr_type == GPIO_PIN_INTR_ANYEDGE) {
124 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 1, PCNT_CH0_POS_MODE_U0_S);
125 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 1, PCNT_CH0_NEG_MODE_U0_S);
126 | } else {
127 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 0, PCNT_CH0_POS_MODE_U0_S);
128 | SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 0, PCNT_CH0_NEG_MODE_U0_S);
129 | }
130 |
131 | SET_PERI_REG_BITS(cfg1_addr, PCNT_CNT_THRES0_U0, 1, PCNT_CNT_THRES0_U0_S);
132 | SET_PERI_REG_BITS(cfg2_addr, PCNT_CNT_L_LIM_U0, 10, PCNT_CNT_L_LIM_U0_S);
133 | SET_PERI_REG_BITS(cfg2_addr, PCNT_CNT_H_LIM_U0, 10, PCNT_CNT_H_LIM_U0_S);
134 | CLEAR_PERI_REG_MASK(cfg0_addr, (PCNT_THR_THRES1_EN_U0 | PCNT_THR_L_LIM_EN_U0
135 | | PCNT_THR_H_LIM_EN_U0 | PCNT_THR_ZERO_EN_U0 | PCNT_FILTER_EN_U0));
136 |
137 | SET_PERI_REG_MASK(cfg0_addr, PCNT_THR_THRES0_EN_U0);
138 | SET_PERI_REG_MASK(PCNT_INT_ENA, BIT(intr_num));
139 | }
140 |
141 | //intr_num only support 0-7
142 | void gpio_intr_config(uint32 gpio_num, uint32 intr_num, GPIO_INT_TYPE intr_type)
143 | {
144 | if (intr_num >= sizeof(intr_gpio_nums)) {
145 | return;
146 | }
147 |
148 | gpio_intr_reset(intr_num, 1);
149 | intr_gpio_nums[intr_num] = gpio_num;
150 | gpio_matrix_in(0x30, intr_gpio_signals[intr_num]);
151 | gpio_matrix_in(intr_gpio_nums[intr_num], intr_gpio_signals[intr_num]);
152 | gpio_intr_init(intr_num, intr_type);
153 | gpio_intr_reset(intr_num, 0);
154 | }
155 |
156 | void gpio_intr_disable(uint32 intr_num)
157 | {
158 | uint32 cfg0_addr = PCNT_U0_CONF0 + (intr_num * 12);
159 | gpio_intr_reset(intr_num, 1);
160 | CLEAR_PERI_REG_MASK(cfg0_addr, PCNT_THR_THRES0_EN_U0);
161 | CLEAR_PERI_REG_MASK(PCNT_INT_ENA, BIT(intr_num));
162 | }
163 |
164 | static void gpio_intr_clear(uint32 intr_num)
165 | {
166 | SET_PERI_REG_MASK(PCNT_INT_CLR, BIT(intr_num));
167 | gpio_intr_reset(intr_num, 1);
168 | gpio_intr_reset(intr_num, 0);
169 | }
170 |
171 | void gpio_intr_process(void)
172 | {
173 | uint32 intr_status;
174 | int intr_num;
175 | uint8 gpio_num;
176 | intr_status = READ_PERI_REG(PCNT_INT_ST);
177 |
178 | while ((intr_num = __builtin_ctz(intr_status)) >= 0) {
179 | intr_status &= ~BIT(intr_num);
180 | gpio_num = intr_gpio_nums[intr_num];
181 | gpio_intr_clear(intr_num);
182 |
183 | switch (gpio_num) {
184 | default:
185 | printf("gpio %d intr come\n", gpio_num);
186 | break;
187 | }
188 | }
189 | }
190 |
191 | void gpio_config(GPIO_ConfigTypeDef *pGPIOConfig)
192 | {
193 | uint32 gpio_pin_mask = pGPIOConfig->GPIO_Pin;
194 | uint32 gpio_pin_mask_high = pGPIOConfig->GPIO_Pin_high;
195 | uint32 io_reg;
196 | uint8 io_num = 0;
197 | uint32 pin_reg;
198 | uint32 bit_valid;
199 |
200 | if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Input) {
201 | GPIO_AS_INPUT(gpio_pin_mask);
202 | GPIO_AS_INPUT_HIGH(gpio_pin_mask_high);
203 | } else if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Output) {
204 | GPIO_AS_OUTPUT(gpio_pin_mask);
205 | GPIO_AS_OUTPUT_HIGH(gpio_pin_mask_high);
206 | }
207 |
208 | do {
209 | bit_valid = (io_num >= 32 ? (gpio_pin_mask_high & (0x1 << (io_num - 32))) : (gpio_pin_mask & (0x1 << io_num)));
210 |
211 | if (bit_valid && (io_reg = GPIO_PIN_REG[io_num])) {
212 | if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Input) {
213 | SET_PERI_REG_MASK(io_reg, FUN_IE);
214 | }
215 |
216 | //for ESP32 function 2 of every pad is allways GPIO func
217 | PIN_FUNC_SELECT(io_reg, 2);
218 |
219 | if (pGPIOConfig->GPIO_Pullup) {
220 | PIN_PULLUP_EN(io_reg);
221 | } else {
222 | PIN_PULLUP_DIS(io_reg);
223 | }
224 |
225 | if (pGPIOConfig->GPIO_Pulldown) {
226 | PIN_PULLDWN_EN(io_reg);
227 | } else {
228 | PIN_PULLDWN_DIS(io_reg);
229 | }
230 |
231 | if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Out_OD) {
232 | portENTER_CRITICAL();
233 |
234 | pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(io_num));
235 | //pin_reg &= (~GPIO_GPIO_PIN0_PAD_DRIVER);
236 | pin_reg |= GPIO_GPIO_PIN0_PAD_DRIVER;
237 | GPIO_REG_WRITE(GPIO_PIN_ADDR(io_num), pin_reg);
238 |
239 | portEXIT_CRITICAL();
240 | }
241 |
242 | gpio_pin_intr_state_set(io_num, pGPIOConfig->GPIO_IntrType);
243 | }
244 |
245 | io_num++;
246 | } while (io_num < GPIO_PIN_COUNT);
247 | }
248 |
249 | void gpio_output_sigmadelta_enable(uint32 gpio_num, uint32 sigma_num, uint32 prescale)
250 | {
251 | if (sigma_num >= 8) {
252 | return;
253 | }
254 |
255 | SET_PERI_REG_BITS(SIGMADELTA0 + sigma_num * 4, SIGMADELTA_SD0_PRESCALE, prescale, SIGMADELTA_SD0_PRESCALE_S);
256 | gpio_matrix_out(gpio_num, GPIO_SD0_OUT_IDX + sigma_num);
257 | }
258 |
259 | void gpio_output_sigmadelta_disable(uint32 gpio_num)
260 | {
261 | gpio_matrix_out(gpio_num, 0x80);
262 | }
263 |
264 | /*
265 | * Change GPIO pin output by setting, clearing, or disabling pins.
266 | * In general, it is expected that a bit will be set in at most one
267 | * of these masks. If a bit is clear in all masks, the output state
268 | * remains unchanged.
269 | *
270 | * There is no particular ordering guaranteed; so if the order of
271 | * writes is significant, calling code should divide a single call
272 | * into multiple calls.
273 | *
274 | * This function only config GPIO0-GPIO31, If you want to config GPIO32-GPIO39, use gpio_output_conf_high
275 | *
276 | */
277 | void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask)
278 | {
279 | GPIO_REG_WRITE(GPIO_OUT_W1TS, set_mask);
280 | GPIO_REG_WRITE(GPIO_OUT_W1TC, clear_mask);
281 | GPIO_REG_WRITE(GPIO_ENABLE_W1TS, enable_mask);
282 | GPIO_REG_WRITE(GPIO_ENABLE_W1TC, disable_mask);
283 | }
284 |
285 | /*
286 | * Change GPIO pin output by setting, clearing, or disabling pins.
287 | * In general, it is expected that a bit will be set in at most one
288 | * of these masks. If a bit is clear in all masks, the output state
289 | * remains unchanged.
290 | *
291 | * There is no particular ordering guaranteed; so if the order of
292 | * writes is significant, calling code should divide a single call
293 | * into multiple calls.
294 | *
295 | * This function only config GPIO32-GPIO39, If you want to config GPIO0-GPIO31, use gpio_output_conf
296 | *
297 | */
298 | void gpio_output_conf_high(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask)
299 | {
300 | GPIO_REG_WRITE(GPIO_OUT1_W1TS, set_mask);
301 | GPIO_REG_WRITE(GPIO_OUT1_W1TC, clear_mask);
302 | GPIO_REG_WRITE(GPIO_ENABLE1_W1TS, enable_mask);
303 | GPIO_REG_WRITE(GPIO_ENABLE1_W1TC, disable_mask);
304 | }
305 |
306 | /*
307 | * Sample the value of GPIO input pins and returns a bitmask.
308 | *
309 | * Only GPIO0-GPIO31
310 | */
311 | uint32 gpio_input_get(void)
312 | {
313 | return GPIO_REG_READ(GPIO_IN);
314 | }
315 |
316 | /*
317 | * Sample the value of GPIO input pins and returns a bitmask.
318 | *
319 | * Only GPIO32-GPIO39
320 | */
321 | uint32 gpio_input_get_high(void)
322 | {
323 | return GPIO_REG_READ(GPIO_IN1);
324 | }
325 |
326 | /*
327 | * Register an application-specific interrupt handler for GPIO pin
328 | * interrupts. Once the interrupt handler is called, it will not
329 | * be called again until after a call to gpio_intr_ack. Any GPIO
330 | * interrupts that occur during the interim are masked.
331 | *
332 | * The application-specific handler is called with a mask of
333 | * pending GPIO interrupts. After processing pin interrupts, the
334 | * application-specific handler may wish to use gpio_intr_pending
335 | * to check for any additional pending interrupts before it returns.
336 | */
337 | void gpio_intr_handler_register(void *fn, void *arg)
338 | {
339 | intr_matrix_set(HW_GPIO_INUM, ETS_GPIO_INUM);
340 | xt_set_interrupt_handler(ETS_GPIO_INUM, fn, arg);
341 | }
342 |
343 | // we do not support sleep by now
344 | #if 0
345 | /*
346 | only highlevel and lowlevel intr can use for wakeup
347 | */
348 | void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state)
349 | {
350 | uint32 pin_reg;
351 |
352 | if ((intr_state == GPIO_PIN_INTR_LOLEVEL) || (intr_state == GPIO_PIN_INTR_HILEVEL)) {
353 | portENTER_CRITICAL();
354 |
355 | pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(i));
356 | pin_reg &= (~GPIO_PIN_INT_TYPE_MASK);
357 | pin_reg |= (intr_state << GPIO_PIN_INT_TYPE_LSB);
358 | pin_reg |= GPIO_PIN_WAKEUP_ENABLE_SET(GPIO_WAKEUP_ENABLE);
359 | GPIO_REG_WRITE(GPIO_PIN_ADDR(i), pin_reg);
360 |
361 | portEXIT_CRITICAL();
362 | }
363 | }
364 |
365 | void gpio_pin_wakeup_disable(void)
366 | {
367 | uint8 i;
368 | uint32 pin_reg;
369 |
370 | for (i = 0; i < GPIO_PIN_COUNT; i++) {
371 | pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(i));
372 |
373 | if (pin_reg & GPIO_PIN_WAKEUP_ENABLE_MASK) {
374 | pin_reg &= (~GPIO_PIN_INT_TYPE_MASK);
375 | pin_reg |= (GPIO_PIN_INTR_DISABLE << GPIO_PIN_INT_TYPE_LSB);
376 | pin_reg &= ~(GPIO_PIN_WAKEUP_ENABLE_SET(GPIO_WAKEUP_ENABLE));
377 | GPIO_REG_WRITE(GPIO_PIN_ADDR(i), pin_reg);
378 | }
379 | }
380 | }
381 | #endif
382 |
383 | void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state)
384 | {
385 | uint32 pin_reg;
386 |
387 | portENTER_CRITICAL();
388 |
389 | pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(i));
390 | pin_reg &= (~GPIO_PIN_INT_TYPE_MASK);
391 | pin_reg |= (intr_state << GPIO_PIN_INT_TYPE_LSB);
392 | pin_reg &= (~GPIO_GPIO_PIN0_INT_ENA);
393 | pin_reg |= (BIT(2) << GPIO_GPIO_PIN0_INT_ENA_S);
394 | GPIO_REG_WRITE(GPIO_PIN_ADDR(i), pin_reg);
395 |
396 | portEXIT_CRITICAL();
397 | }
398 |
--------------------------------------------------------------------------------
/driver/uart.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #include "freertos/FreeRTOS.h"
26 | #include "freertos/task.h"
27 | #include "freertos/queue.h"
28 | #include "freertos/xtensa_api.h"
29 |
30 | #include "espressif/esp_common.h"
31 | #include "uart.h"
32 | #include "gpio.h"
33 | #include
34 |
35 | enum {
36 | UART_EVENT_RX_CHAR,
37 | UART_EVENT_MAX
38 | };
39 |
40 | typedef struct _os_event_ {
41 | uint32 event;
42 | uint32 param;
43 | } os_event_t;
44 |
45 | xTaskHandle xUartTaskHandle;
46 | xQueueHandle xQueueUart;
47 |
48 | LOCAL STATUS uart_tx_one_char(uint8 uart, uint8 TxChar)
49 | {
50 | while (true) {
51 | uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
52 |
53 | if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
54 | break;
55 | }
56 | }
57 |
58 | WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
59 | return OK;
60 | }
61 |
62 | LOCAL void uart1_write_char(char c)
63 | {
64 | if (c == '\n') {
65 | uart_tx_one_char(UART1, '\r');
66 | uart_tx_one_char(UART1, '\n');
67 | } else if (c == '\r') {
68 | } else {
69 | uart_tx_one_char(UART1, c);
70 | }
71 | }
72 |
73 | LOCAL void uart0_write_char(char c)
74 | {
75 | if (c == '\n') {
76 | uart_tx_one_char(UART0, '\r');
77 | uart_tx_one_char(UART0, '\n');
78 | } else if (c == '\r') {
79 | } else {
80 | uart_tx_one_char(UART0, c);
81 | }
82 | }
83 |
84 | #if 0
85 | LOCAL void uart_rx_intr_handler_ssc(void)
86 | {
87 | /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
88 | * uart1 and uart0 respectively
89 | */
90 | os_event_t e;
91 | portBASE_TYPE xHigherPriorityTaskWoken;
92 |
93 | uint8 RcvChar;
94 | uint8 uart_no = 0;
95 |
96 | if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) {
97 | return;
98 | }
99 |
100 | RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
101 |
102 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
103 |
104 | e.event = UART_EVENT_RX_CHAR;
105 | e.param = RcvChar;
106 |
107 | xQueueSendFromISR(xQueueUart, (void *)&e, &xHigherPriorityTaskWoken);
108 | portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
109 | }
110 |
111 | LOCAL void uart_config(uint8 uart_no, UartDevice *uart)
112 | {
113 | if (uart_no == UART1) {
114 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_SD_DATA3_U1TXD);
115 | } else {
116 | /* rcv_buff size if 0x100 */
117 | _xt_isr_attach(ETS_UART_INUM, uart_rx_intr_handler_ssc);
118 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
119 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, PERIPHS_IO_MUX_SD_DATA3_U);
120 | }
121 |
122 | uart_div_modify(uart_no, UART_CLK_FREQ / (uart->baut_rate));
123 |
124 | WRITE_PERI_REG(UART_CONF0(uart_no), uart->exist_parity
125 | | uart->parity
126 | | (uart->stop_bits << UART_STOP_BIT_NUM_S)
127 | | (uart->data_bits << UART_BIT_NUM_S));
128 |
129 | //clear rx and tx fifo,not ready
130 | SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
131 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
132 |
133 | if (uart_no == UART0) {
134 | //set rx fifo trigger
135 | WRITE_PERI_REG(UART_CONF1(uart_no),
136 | ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));
137 | } else {
138 | WRITE_PERI_REG(UART_CONF1(uart_no),
139 | ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));
140 | }
141 |
142 | //clear all interrupt
143 | WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
144 | //enable rx_interrupt
145 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA);
146 | }
147 | #endif
148 |
149 | void uart_task(void *pvParameters)
150 | {
151 | os_event_t e;
152 |
153 | for (;;) {
154 | if (xQueueReceive(xQueueUart, (void *)&e, (portTickType)portMAX_DELAY)) {
155 | switch (e.event) {
156 | case UART_EVENT_RX_CHAR:
157 | printf("%c", e.param);
158 | break;
159 |
160 | default:
161 | break;
162 | }
163 | }
164 | }
165 |
166 | vTaskDelete(NULL);
167 | }
168 |
169 | #if 0
170 | void uart_init(void)
171 | {
172 | while (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S));
173 |
174 | while (READ_PERI_REG(UART_STATUS(1)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S));
175 |
176 | UART_ConfigTypeDef uart;
177 |
178 | uart.baud_rate = BIT_RATE_115200;
179 | uart.data_bits = UART_WordLength_8b;
180 | uart.flow_ctrl = USART_HardwareFlowControl_None;
181 | // uart.exist_parity = PARITY_DIS;
182 | uart.parity = USART_Parity_None;
183 | uart.stop_bits = USART_StopBits_1;
184 |
185 | uart_config(UART0, &uart);
186 | uart_config(UART1, &uart);
187 |
188 | os_install_putc1(uart1_write_char);
189 |
190 | xt_ints_on(1 << ETS_UART_INUM);
191 |
192 | xQueueUart = xQueueCreate(32, sizeof(os_event_t));
193 |
194 | xTaskCreate(uart_task, (uint8 const *)"uTask", 512, NULL, tskIDLE_PRIORITY + 2, &xUartTaskHandle);
195 | }
196 | #endif
197 |
198 | //=================================================================
199 |
200 | void UART_SetWordLength(UART_Port uart_no, UART_WordLength len)
201 | {
202 | SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_BIT_NUM, len, UART_BIT_NUM_S);
203 | }
204 |
205 | void
206 | UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num)
207 | {
208 | SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_STOP_BIT_NUM, bit_num, UART_STOP_BIT_NUM_S);
209 | }
210 |
211 | void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask)
212 | {
213 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK);
214 | SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask);
215 | }
216 |
217 | void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode)
218 | {
219 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN);
220 |
221 | if (Parity_mode == USART_Parity_None) {
222 | } else {
223 | SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode | UART_PARITY_EN);
224 | }
225 | }
226 |
227 | void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate)
228 | {
229 | uart_div_modify(uart_no, UART_CLK_FREQ / baud_rate);
230 | }
231 |
232 | //only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set.
233 | void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh)
234 | {
235 | if (flow_ctrl & USART_HardwareFlowControl_RTS) {
236 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_MTDO_U0RTS);
237 | SET_PERI_REG_BITS(UART_CONF1(uart_no), UART_RX_FLOW_THRHD, rx_thresh, UART_RX_FLOW_THRHD_S);
238 | SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
239 | } else {
240 | CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
241 | }
242 |
243 | if (flow_ctrl & USART_HardwareFlowControl_CTS) {
244 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_MTCK_U0CTS);
245 | SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
246 | } else {
247 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
248 | }
249 | }
250 |
251 | void UART_WaitTxFifoEmpty(UART_Port uart_no) //do not use if tx flow control enabled
252 | {
253 | while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S));
254 | }
255 |
256 | void UART_ResetFifo(UART_Port uart_no)
257 | {
258 | SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
259 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
260 | }
261 |
262 | void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask)
263 | {
264 | WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask);
265 | }
266 |
267 | void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask)
268 | {
269 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask);
270 | }
271 |
272 | void UART_intr_handler_register(void *fn, void *arg)
273 | {
274 | xt_set_interrupt_handler(ETS_UART_INUM, fn, arg);
275 | }
276 |
277 | void UART_SetPrintPort(UART_Port uart_no)
278 | {
279 | if (uart_no == 1) {
280 | os_install_putc1(uart1_write_char);
281 | } else {
282 | os_install_putc1(uart0_write_char);
283 | }
284 | }
285 |
286 | void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig)
287 | {
288 | if (uart_no == UART1) {
289 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, FUNC_SD_DATA3_U1TXD);
290 | } else {
291 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
292 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
293 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
294 | }
295 |
296 | UART_SetFlowCtrl(uart_no, pUARTConfig->flow_ctrl, pUARTConfig->UART_RxFlowThresh);
297 | UART_SetBaudrate(uart_no, pUARTConfig->baud_rate);
298 |
299 | WRITE_PERI_REG(UART_CONF0(uart_no),
300 | ((pUARTConfig->parity == USART_Parity_None) ? 0x0 : (UART_PARITY_EN | pUARTConfig->parity))
301 | | (pUARTConfig->stop_bits << UART_STOP_BIT_NUM_S)
302 | | (pUARTConfig->data_bits << UART_BIT_NUM_S)
303 | | ((pUARTConfig->flow_ctrl & USART_HardwareFlowControl_CTS) ? UART_TX_FLOW_EN : 0x0)
304 | | pUARTConfig->UART_InverseMask | UART_TICK_REF_ALWAYS_ON);
305 |
306 | UART_ResetFifo(uart_no);
307 | }
308 |
309 | void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf)
310 | {
311 |
312 | uint32 reg_val = 0;
313 | UART_ClearIntrStatus(uart_no, UART_INTR_MASK);
314 | reg_val = READ_PERI_REG(UART_CONF1(uart_no));
315 |
316 | reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_TOUT_INT_ENA) ?
317 | ((((pUARTIntrConf->UART_RX_TimeOutIntrThresh)&UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN) : 0);
318 |
319 | reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_FULL_INT_ENA) ?
320 | (((pUARTIntrConf->UART_RX_FifoFullIntrThresh)&UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) : 0);
321 |
322 | reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_TXFIFO_EMPTY_INT_ENA) ?
323 | (((pUARTIntrConf->UART_TX_FifoEmptyIntrThresh)&UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) : 0);
324 |
325 | WRITE_PERI_REG(UART_CONF1(uart_no), reg_val);
326 | CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_INTR_MASK);
327 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), pUARTIntrConf->UART_IntrEnMask);
328 | }
329 |
330 | LOCAL void uart0_rx_intr_handler(void *para)
331 | {
332 | /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
333 | * uart1 and uart0 respectively
334 | */
335 | uint8 uart_no = UART0;//UartDev.buff_uart_no;
336 | uint8 fifo_len = 0;
337 | uint8 buf_idx = 0;
338 | //BaseType_t xHigherPriorityTaskWoken;
339 | uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ;
340 |
341 | while (uart_intr_status != 0x0) {
342 | if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) {
343 | os_printf_isr("FRM_ERR\r\n");
344 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
345 | } else if (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST)) {
346 | os_printf_isr("full\r\n");
347 | fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
348 | buf_idx = 0;
349 |
350 | while (buf_idx < fifo_len) {
351 | uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
352 | buf_idx++;
353 | }
354 |
355 | WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
356 | //CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
357 | //xQueueSendFromISR(QueUart,(&fifo_len),&xHigherPriorityTaskWoken) ;
358 | // portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
359 | //os_printf_isr("uart interrupt\n");
360 |
361 | } else if (UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST)) {
362 | os_printf_isr("tout\r\n");
363 | fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
364 | buf_idx = 0;
365 |
366 | while (buf_idx < fifo_len) {
367 | uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
368 | buf_idx++;
369 | }
370 |
371 | WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
372 | } else if (UART_TXFIFO_EMPTY_INT_ST == (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST)) {
373 | os_printf_isr("empty\n\r");
374 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
375 | CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
376 | } else if (UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)) {
377 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);
378 | os_printf_isr("RX OVF!!\r\n");
379 | } else {
380 | //skip
381 | }
382 |
383 | uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ;
384 | }
385 | }
386 |
387 | void uart_init_new(void)
388 | {
389 | UART_WaitTxFifoEmpty(UART0);
390 | UART_WaitTxFifoEmpty(UART1);
391 |
392 | UART_ConfigTypeDef uart_config;
393 | uart_config.baud_rate = BIT_RATE_115200;
394 | uart_config.data_bits = UART_WordLength_8b;
395 | uart_config.parity = USART_Parity_None;
396 | uart_config.stop_bits = USART_StopBits_1;
397 | uart_config.flow_ctrl = USART_HardwareFlowControl_None;
398 | uart_config.UART_RxFlowThresh = 120;
399 | uart_config.UART_InverseMask = UART_None_Inverse;
400 | UART_ParamConfig(UART0, &uart_config);
401 |
402 | UART_IntrConfTypeDef uart_intr;
403 | uart_intr.UART_IntrEnMask = UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_FULL_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA;
404 | uart_intr.UART_RX_FifoFullIntrThresh = 10;
405 | uart_intr.UART_RX_TimeOutIntrThresh = 2;
406 | uart_intr.UART_TX_FifoEmptyIntrThresh = 20;
407 | UART_IntrConfig(UART0, &uart_intr);
408 |
409 | UART_SetPrintPort(UART0);
410 | UART_intr_handler_register(uart0_rx_intr_handler, NULL);
411 | ETS_UART_INTR_ENABLE();
412 |
413 | /*
414 | UART_SetWordLength(UART0,UART_WordLength_8b);
415 | UART_SetStopBits(UART0,USART_StopBits_1);
416 | UART_SetParity(UART0,USART_Parity_None);
417 | UART_SetBaudrate(UART0,74880);
418 | UART_SetFlowCtrl(UART0,USART_HardwareFlowControl_None,0);
419 | */
420 |
421 | }
422 |
--------------------------------------------------------------------------------
/include/gpio.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 | #ifndef __GPIO_H__
26 | #define __GPIO_H__
27 |
28 | #ifdef __cplusplus
29 | extern "C" {
30 | #endif
31 |
32 | #define GPIO_Pin_0 (BIT(0)) /* Pin 0 selected */
33 | #define GPIO_Pin_1 (BIT(1)) /* Pin 1 selected */
34 | #define GPIO_Pin_2 (BIT(2)) /* Pin 2 selected */
35 | #define GPIO_Pin_3 (BIT(3)) /* Pin 3 selected */
36 | #define GPIO_Pin_4 (BIT(4)) /* Pin 4 selected */
37 | #define GPIO_Pin_5 (BIT(5)) /* Pin 5 selected */
38 | #define GPIO_Pin_6 (BIT(6)) /* Pin 6 selected */
39 | #define GPIO_Pin_7 (BIT(7)) /* Pin 7 selected */
40 | #define GPIO_Pin_8 (BIT(8)) /* Pin 8 selected */
41 | #define GPIO_Pin_9 (BIT(9)) /* Pin 9 selected */
42 | #define GPIO_Pin_10 (BIT(10)) /* Pin 10 selected */
43 | #define GPIO_Pin_11 (BIT(11)) /* Pin 11 selected */
44 | #define GPIO_Pin_12 (BIT(12)) /* Pin 12 selected */
45 | #define GPIO_Pin_13 (BIT(13)) /* Pin 13 selected */
46 | #define GPIO_Pin_14 (BIT(14)) /* Pin 14 selected */
47 | #define GPIO_Pin_15 (BIT(15)) /* Pin 15 selected */
48 | #define GPIO_Pin_16 (BIT(16)) /* Pin 16 selected */
49 | #define GPIO_Pin_17 (BIT(17)) /* Pin 17 selected */
50 | #define GPIO_Pin_18 (BIT(18)) /* Pin 18 selected */
51 | #define GPIO_Pin_19 (BIT(19)) /* Pin 19 selected */
52 | #define GPIO_Pin_20 (BIT(20)) /* Pin 20 selected */
53 | #define GPIO_Pin_21 (BIT(21)) /* Pin 21 selected */
54 | #define GPIO_Pin_22 (BIT(22)) /* Pin 22 selected */
55 | #define GPIO_Pin_23 (BIT(23)) /* Pin 23 selected */
56 | //#define GPIO_Pin_24 (BIT(24)) /* Pin 24 selected */
57 | #define GPIO_Pin_25 (BIT(25)) /* Pin 25 selected */
58 | #define GPIO_Pin_26 (BIT(26)) /* Pin 26 selected */
59 | #define GPIO_Pin_27 (BIT(27)) /* Pin 27 selected */
60 | //#define GPIO_Pin_28 (BIT(28)) /* Pin 28 selected */
61 | //#define GPIO_Pin_29 (BIT(29)) /* Pin 29 selected */
62 | //#define GPIO_Pin_30 (BIT(30)) /* Pin 30 selected */
63 | //#define GPIO_Pin_31 (BIT(31)) /* Pin 31 selected */
64 | #define GPIO_Pin_32 (BIT(0)) /* Pin 32 selected */
65 | #define GPIO_Pin_33 (BIT(1)) /* Pin 33 selected */
66 | #define GPIO_Pin_34 (BIT(2)) /* Pin 34 selected */
67 | #define GPIO_Pin_35 (BIT(3)) /* Pin 35 selected */
68 | #define GPIO_Pin_36 (BIT(4)) /* Pin 36 selected */
69 | #define GPIO_Pin_37 (BIT(5)) /* Pin 37 selected */
70 | #define GPIO_Pin_38 (BIT(6)) /* Pin 38 selected */
71 | #define GPIO_Pin_39 (BIT(7)) /* Pin 39 selected */
72 |
73 | #define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
74 | #define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
75 | #define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
76 | #define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
77 | #define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
78 | #define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
79 | #define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
80 | #define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
81 | #define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
82 | #define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
83 | #define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
84 | #define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
85 | #define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
86 | #define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
87 | #define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
88 | #define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
89 | #define GPIO_PIN_REG_16 PERIPHS_IO_MUX_GPIO16_U
90 | #define GPIO_PIN_REG_17 PERIPHS_IO_MUX_GPIO17_U
91 | #define GPIO_PIN_REG_18 PERIPHS_IO_MUX_GPIO18_U
92 | #define GPIO_PIN_REG_19 PERIPHS_IO_MUX_GPIO19_U
93 | #define GPIO_PIN_REG_20 PERIPHS_IO_MUX_GPIO20_U
94 | #define GPIO_PIN_REG_21 PERIPHS_IO_MUX_GPIO21_U
95 | #define GPIO_PIN_REG_22 PERIPHS_IO_MUX_GPIO22_U
96 | #define GPIO_PIN_REG_23 PERIPHS_IO_MUX_GPIO23_U
97 | #define GPIO_PIN_REG_25 PERIPHS_IO_MUX_GPIO25_U
98 | #define GPIO_PIN_REG_26 PERIPHS_IO_MUX_GPIO26_U
99 | #define GPIO_PIN_REG_27 PERIPHS_IO_MUX_GPIO27_U
100 | #define GPIO_PIN_REG_32 PERIPHS_IO_MUX_GPIO32_U
101 | #define GPIO_PIN_REG_33 PERIPHS_IO_MUX_GPIO33_U
102 | #define GPIO_PIN_REG_34 PERIPHS_IO_MUX_GPIO34_U
103 | #define GPIO_PIN_REG_35 PERIPHS_IO_MUX_GPIO35_U
104 | #define GPIO_PIN_REG_36 PERIPHS_IO_MUX_GPIO36_U
105 | #define GPIO_PIN_REG_37 PERIPHS_IO_MUX_GPIO37_U
106 | #define GPIO_PIN_REG_38 PERIPHS_IO_MUX_GPIO38_U
107 | #define GPIO_PIN_REG_39 PERIPHS_IO_MUX_GPIO39_U
108 |
109 | #define GPIO_REG_READ(reg) READ_PERI_REG(reg)
110 | #define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(reg, val)
111 | #define GPIO_PIN_COUNT 40
112 | #define GPIO_ID_PIN0 0
113 | #define GPIO_ID_PIN(n) (GPIO_ID_PIN0 + (n))
114 | #define GPIO_PIN_ADDR(i) (GPIO_PIN0 + i * 4)
115 |
116 | #define GPIO_ID_IS_PIN_REGISTER(reg_id) \
117 | ((reg_id >= GPIO_ID_PIN0) && (reg_id <= GPIO_ID_PIN(GPIO_PIN_COUNT - 1)))
118 |
119 | #define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
120 |
121 | typedef enum {
122 | GPIO_PIN_INTR_DISABLE = 0, /**< disable GPIO interrupt */
123 | GPIO_PIN_INTR_POSEDGE = 1, /**< GPIO interrupt type : rising edge */
124 | GPIO_PIN_INTR_NEGEDGE = 2, /**< GPIO interrupt type : falling edge */
125 | GPIO_PIN_INTR_ANYEDGE = 3, /**< GPIO interrupt type : bothe rising and falling edge */
126 | } GPIO_INT_TYPE;
127 |
128 | typedef enum {
129 | GPIO_Mode_Input = 0x0, /**< GPIO mode : Input */
130 | GPIO_Mode_Out_OD, /**< GPIO mode : Output_OD */
131 | GPIO_Mode_Output , /**< GPIO mode : Output */
132 | GPIO_Mode_Sigma_Delta , /**< GPIO mode : Sigma_Delta */
133 | } GPIOMode_TypeDef;
134 |
135 | typedef enum {
136 | GPIO_PullUp_DIS = 0x0, /**< disable GPIO pull up */
137 | GPIO_PullUp_EN = 0x1, /**< enable GPIO pull up */
138 | } GPIO_Pullup_IF;
139 |
140 | typedef enum {
141 | GPIO_PullDown_DIS = 0x0, /**< disable GPIO pull down */
142 | GPIO_PullDown_EN = 0x1, /**< enable GPIO pull down */
143 | } GPIO_Pulldown_IF;
144 |
145 | typedef struct {
146 | uint32 GPIO_Pin; /**< GPIO pin */
147 | uint32 GPIO_Pin_high; /**< GPIO pin */
148 | GPIOMode_TypeDef GPIO_Mode; /**< GPIO mode */
149 | GPIO_Pullup_IF GPIO_Pullup; /**< GPIO pullup */
150 | GPIO_Pulldown_IF GPIO_Pulldown; /**< GPIO pulldown */
151 | GPIO_INT_TYPE GPIO_IntrType; /**< GPIO interrupt type */
152 | } GPIO_ConfigTypeDef;
153 |
154 | /** \defgroup Driver_APIs Driver APIs
155 | * @brief Driver APIs
156 | */
157 |
158 | /** @addtogroup Driver_APIs
159 | * @{
160 | */
161 |
162 | /** \defgroup GPIO_Driver_APIs GPIO Driver APIs
163 | * @brief GPIO APIs
164 | */
165 |
166 | /** @addtogroup GPIO_Driver_APIs
167 | * @{
168 | */
169 |
170 | /**
171 | * @brief Set GPIO pin output level.
172 | *
173 | * @param gpio_no : The GPIO sequence number.
174 | * @param bit_value : GPIO pin output level.
175 | *
176 | * @return null
177 | */
178 | #define GPIO_OUTPUT_SET(gpio_no, bit_value) \
179 | ((gpio_no < 32) ? gpio_output_conf(bit_value << gpio_no, (bit_value ? 0 : 1) << gpio_no, 1 << gpio_no, 0) : \
180 | gpio_output_conf_high(bit_value << (gpio_no - 32), (bit_value ? 0 : 1) << (gpio_no - 32), 1 << (gpio_no - 32),0))
181 |
182 | /**
183 | * @brief Set GPIO pin output level,This function only config GPIO0-GPIO31 .
184 | *
185 | * @param gpio_bits : The GPIO bit number.
186 | * @param bit_value : GPIO pin output level.
187 | *
188 | * @return null
189 | */
190 | #define GPIO_OUTPUT(gpio_bits, bit_value) \
191 | if(bit_value) gpio_output_conf(gpio_bits, 0, gpio_bits, 0);\
192 | else gpio_output_conf(0, gpio_bits, gpio_bits, 0)
193 |
194 | /**
195 | * @brief Set GPIO pin output level,This function only config GPIO32-GPIO39.
196 | *
197 | * @param gpio_bits : The GPIO bit number.
198 | * @param bit_value : GPIO pin output level.
199 | *
200 | * @return null
201 | */
202 | #define GPIO_OUTPUT_HIGH(gpio_bits, bit_value) \
203 | if(bit_value) gpio_output_conf_high(gpio_bits, 0, gpio_bits, 0);\
204 | else gpio_output_conf_high(0, gpio_bits, gpio_bits, 0)
205 |
206 | /**
207 | * @brief Disable GPIO pin output.
208 | *
209 | * @param gpio_no : The GPIO sequence number.
210 | *
211 | * @return null
212 | */
213 | #define GPIO_DIS_OUTPUT(gpio_no) ((gpio_no < 32) ? \
214 | gpio_output_conf(0, 0, 0, 1 << gpio_no) : gpio_output_conf_high(0, 0, 0, 1 << gpio_no))
215 |
216 | /**
217 | * @brief Enable GPIO pin intput,This function only config GPIO0-GPIO31.
218 | *
219 | * @param gpio_bits : The GPIO bit number.
220 | *
221 | * @return null
222 | */
223 | #define GPIO_AS_INPUT(gpio_bits) gpio_output_conf(0, 0, 0, gpio_bits)
224 |
225 | /**
226 | * @brief Enable GPIO pin intput,This function only config GPIO32-GPIO39.
227 | *
228 | * @param gpio_bits : The GPIO bit number.
229 | *
230 | * @return null
231 | */
232 | #define GPIO_AS_INPUT_HIGH(gpio_bits) gpio_output_conf_high(0, 0, 0, gpio_bits)
233 |
234 | /**
235 | * @brief Enable GPIO pin output,This function only config GPIO0-GPIO31.
236 | *
237 | * @param gpio_bits : The GPIO bit number.
238 | *
239 | * @return null
240 | */
241 | #define GPIO_AS_OUTPUT(gpio_bits) gpio_output_conf(0, 0, gpio_bits, 0)
242 |
243 | /**
244 | * @brief Enable GPIO pin output,This function only config GPIO32-GPIO39.
245 | *
246 | * @param gpio_bits : The GPIO bit number.
247 | *
248 | * @return null
249 | */
250 | #define GPIO_AS_OUTPUT_HIGH(gpio_bits) gpio_output_conf_high(0, 0, gpio_bits, 0)
251 |
252 | /**
253 | * @brief GPIO init .
254 | *
255 | * @param pGPIOConfig : through this structure initialization GPIO.
256 | *
257 | * @return null
258 | */
259 | void gpio_config(GPIO_ConfigTypeDef *pGPIOConfig);
260 |
261 | /**
262 | * @brief Sample the level of GPIO input.
263 | *
264 | * @param gpio_no : The GPIO sequence number.
265 | *
266 | * @return the level of GPIO input
267 | */
268 | #define GPIO_INPUT_GET(gpio_no) ((gpio_no < 32) ? \
269 | ((gpio_input_get() >> gpio_no) & BIT0) : ((gpio_input_get_high() >> (gpio_no - 32)) & BIT0))
270 |
271 | /**
272 | * @brief Configure GPIO pins out or input.
273 | *
274 | * @param uint32 set_mask : Set the output for the high bit, the
275 | * corresponding bit is 1, the output of high,
276 | * the corresponding bit is 0, do not change the state.
277 | * @param uint32 set_mask : Set the output for the high bit, the
278 | * corresponding bit is 1, the output of low,
279 | * the corresponding bit is 0, do not change the state.
280 | * @param uint32 enable_mask : Enable Output
281 | * @param uint32 disable_mask : Enable Input
282 | *
283 | * @return null
284 | */
285 | void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask);
286 |
287 | /**
288 | * @brief Configure GPIO pins out or input.
289 | *
290 | * @param uint32 set_mask : Set the output for the high bit, the
291 | * corresponding bit is 1, the output of high,
292 | * the corresponding bit is 0, do not change the state.
293 | * @param uint32 set_mask : Set the output for the high bit, the
294 | * corresponding bit is 1, the output of low,
295 | * the corresponding bit is 0, do not change the state.
296 | * @param uint32 enable_mask : Enable Output
297 | * @param uint32 disable_mask : Enable Input
298 | *
299 | * @return null
300 | */
301 | void gpio_output_conf_high(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask);
302 |
303 | /**
304 | * @brief Register an application-specific interrupt handler for GPIO pin interrupts.
305 | *
306 | * @param void *fn : interrupt handler for GPIO pin interrupts.
307 | * @param void *arg : interrupt handler's arg
308 | *
309 | * @return null
310 | */
311 | void gpio_intr_handler_register(void *fn, void *arg);
312 |
313 | /**
314 | * @brief Configure GPIO wake up to light sleep,Only level way is effective.
315 | *
316 | * @param uint32 i : GPIO sequence number
317 | * @param GPIO_INT_TYPE intr_state : the level of wake up to light sleep
318 | *
319 | * @return null
320 | */
321 | void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state);
322 |
323 | /**
324 | * @brief Disable GPIO wake up to light sleep.
325 | *
326 | * @param null
327 | *
328 | * @return null
329 | */
330 | void gpio_pin_wakeup_disable(void);
331 |
332 | /**
333 | * @brief Config interrupt types of GPIO pin.
334 | *
335 | * @param uint32 i : The GPIO sequence number.
336 | * @param GPIO_INT_TYPE intr_state : GPIO interrupt types.
337 | *
338 | * @return null
339 | */
340 | void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state);
341 |
342 | /**
343 | * @brief Sample the value of GPIO input pins and returns a bitmask. This function only get the level GPIO0-GPIO31.
344 | *
345 | * @param null
346 | *
347 | * @return bitmask of GPIO pins input
348 | */
349 | uint32 gpio_input_get(void);
350 |
351 | /**
352 | * @brief Sample the value of GPIO input pins and returns a bitmask. This function only get the level GPIO32-GPIO39.
353 | *
354 | * @param null
355 | *
356 | * @return bitmask of GPIO pins input
357 | */
358 | uint32 gpio_input_get_high(void);
359 |
360 | /**
361 | * @brief Enable GPIO sigmadelta function.
362 | *
363 | * @param uint32 gpio_num : The GPIO sequence number.
364 | * @param uint32 sigma_num : the sigmadelta source sequence number 0-7.
365 | * @param uint32 prescale : Clock divide factor.
366 | *
367 | * @return null
368 | */
369 | void gpio_output_sigmadelta_enable(uint32 gpio_num, uint32 sigma_num, uint32 prescale);
370 |
371 | /**
372 | * @brief Disable GPIO sigmadelta function.
373 | *
374 | * @param uint32 gpio_num : The GPIO sequence number
375 | *
376 | * @return null
377 | */
378 | void gpio_output_sigmadelta_disable(uint32 gpio_num);
379 |
380 | /**
381 | * @brief Configure GPIO interrupr.
382 | *
383 | * @param uint32 gpio_num : The GPIO sequence number.
384 | * @param uint32 intr_num : the interrupt source sequence number 0-7.
385 | * @param GPIO_INT_TYPE intr_type : The type of interrupt.
386 | *
387 | * @return null
388 | */
389 | void gpio_intr_config(uint32 gpio_num, uint32 intr_num, GPIO_INT_TYPE intr_type);
390 |
391 | /**
392 | * @brief The GPIO interrupt function.
393 | *
394 | * @param null
395 | *
396 | * @return null
397 | */
398 | void gpio_intr_process(void);
399 |
400 | /**
401 | * @brief To bind GPIO input and a certain road input signal.
402 | *
403 | * @param uint32 gpio_num : The GPIO sequence number.
404 | * @param uint32 signal_idx : input signal sequence number.
405 | *
406 | * @return null
407 | */
408 | void gpio_matrix_in(uint32 gpio, uint32 signal_idx);
409 |
410 | /**
411 | * @brief To bind GPIO ouput and a certain road output signal.
412 | *
413 | * @param uint32 gpio_num : The GPIO sequence number.
414 | * @param uint32 signal_idx : out signal sequence number.
415 | *
416 | * @return null
417 | */
418 | void gpio_matrix_out(uint32 gpio, uint32 signal_idx);
419 |
420 | /**
421 | * @brief To bind mode interrupt and interrupt sequence number.
422 | *
423 | * @param uint32 model_num : The mode sequence number.
424 | * @param uint32 intr_num : interrupt sequence number.
425 | *
426 | * @return null
427 | */
428 | void intr_matrix_set(uint32 model_num, uint32 intr_num);
429 |
430 | /**
431 | * @}
432 | */
433 |
434 | /**
435 | * @}
436 | */
437 |
438 | #ifdef __cplusplus
439 | }
440 | #endif
441 |
442 | #endif
443 |
--------------------------------------------------------------------------------
/driver/i2s.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ESPRSSIF MIT License
3 | *
4 | * Copyright (c) 2015
5 | *
6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case,
7 | * it is free of charge, to any person obtaining a copy of this software and associated
8 | * documentation files (the "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11 | * to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all copies or
14 | * substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | */
24 |
25 |
26 | #include "freertos/FreeRTOS.h"
27 | #include "freertos/task.h"
28 | #include "freertos/queue.h"
29 | #include "freertos/xtensa_api.h"
30 | #include "espressif/esp_common.h"
31 | #include "i2s.h"
32 | #include "gpio.h"
33 | #include
34 |
35 | #define IIS_RX_BUF_LEN 512 //unit Byte
36 | #define IIS_TX_BUF_LEN 512 //unit Byte
37 | #define n 2
38 |
39 | #define RX_NUM 128 //unit word
40 | //#define
41 |
42 | uint32 i2s_rx_buff1[IIS_RX_BUF_LEN / 4];
43 | uint32 i2s_rx_buff2[IIS_RX_BUF_LEN / 4];
44 | uint32 i2s_tx_buff1[IIS_TX_BUF_LEN / 4];
45 | uint32 i2s_tx_buff2[IIS_TX_BUF_LEN / 4];
46 | uint32 i2s_tx_buff3[IIS_TX_BUF_LEN / 4];
47 |
48 | uint32 i2s_tx_test[IIS_TX_BUF_LEN * n];
49 | uint32 i2s_rx_test[IIS_TX_BUF_LEN * n];
50 |
51 | //uint32 i2s_tx_test_test[IIS_TX_BUF_LEN*n];
52 |
53 | int rx_buff1_cnt = 0;
54 | int rx_buff2_cnt = 0;
55 | int tx_cnt = 0;
56 |
57 | uint32 triang_tab1[IIS_RX_BUF_LEN / 2];
58 | uint32 triang_tab2[IIS_RX_BUF_LEN / 2];
59 |
60 | int8 tab_idx = 0;
61 |
62 | struct sdio_queue i2s_rx_queue1, i2s_rx_queue2, i2s_tx_queue1, i2s_tx_queue2, i2s_tx_queue3;
63 |
64 | //create fake audio data
65 | void generate_data(void)
66 | {
67 | uint16 i, j;
68 | uint32 val, val1;
69 | val = 0x100;
70 | val1 = 0x100;
71 |
72 | //generate data
73 |
74 | for (i = 0; i < 256; i++) {
75 | triang_tab1[i] = val;
76 | val += 0x100;
77 | }
78 |
79 | for (; i < 512; i++) {
80 | triang_tab2[i - 256] = val;
81 | val += 0x100;
82 | }
83 |
84 | for (j = 0; j < IIS_TX_BUF_LEN * n; j++) {
85 | i2s_rx_test[j] = val1;
86 | val1 += 0x100;
87 | }
88 | }
89 |
90 | //load data into buffer
91 | void load_buffer1_1(uint32 *buffer, uint32 buff_len)
92 | {
93 | uint32 i;
94 | uint32 *pbuff = buffer;
95 |
96 | for (i = 0; i < buff_len; i++) {
97 | *pbuff = triang_tab1[i];
98 | pbuff++;
99 | }
100 | }
101 |
102 | void load_buffer1_2(uint32 *buffer, uint32 buff_len)
103 | {
104 | uint32 i;
105 | uint32 *pbuff = buffer;
106 |
107 | for (i = 0; i < buff_len; i++) {
108 | *pbuff = triang_tab1[buff_len + i];
109 | pbuff++;
110 | }
111 | }
112 |
113 | void load_buffer2_1(uint32 *buffer, uint32 buff_len)
114 | {
115 | uint32 i;
116 | uint32 *pbuff = buffer;
117 |
118 | for (i = 0; i < buff_len; i++) {
119 | *pbuff = triang_tab2[i];
120 | pbuff++;
121 | }
122 | }
123 |
124 | void load_buffer2_2(uint32 *buffer, uint32 buff_len)
125 | {
126 | uint32 i;
127 | uint32 *pbuff = buffer;
128 |
129 | for (i = 0; i < buff_len; i++) {
130 | *pbuff = triang_tab2[buff_len + i];
131 | pbuff++;
132 | }
133 | }
134 |
135 | void clear_rx_buff(void)
136 | {
137 | uint32 i;
138 |
139 | for (i = 0; i < 128; i++) {
140 | i2s_tx_buff1[i] = 0;
141 | i2s_tx_buff2[i] = 0;
142 | i2s_tx_buff3[i] = 0;
143 | }
144 | }
145 |
146 | void copyarray(uint8 *dest, uint8 *src, uint32 nbyte)
147 | {
148 | int i;
149 |
150 | for (i = 0; i < nbyte; i++) {
151 | dest[i] = src[i];
152 | }
153 | }
154 |
155 | //create DMA buffer descriptors, unit of either size or length here is byte.
156 | //More details in I2S documents.
157 | void create_one_link(uint8 own, uint8 eof, uint8 sub_sof, uint16 size, uint16 length,
158 | uint32 *buf_ptr, struct sdio_queue *nxt_ptr, struct sdio_queue *i2s_queue)
159 | {
160 | unsigned int link_data0;
161 | unsigned int link_data1;
162 | unsigned int link_data2;
163 | unsigned int start_addr;
164 |
165 | i2s_queue->owner = own;
166 | i2s_queue->eof = eof;
167 | i2s_queue->sub_sof = sub_sof;
168 | i2s_queue->datalen = length;
169 | i2s_queue->blocksize = size;
170 | i2s_queue->buf_ptr = (uint32)buf_ptr;
171 | i2s_queue->next_link_ptr = (uint32)nxt_ptr;
172 | i2s_queue->unused = 0;
173 | }
174 |
175 | void i2s_GPIO_init(uint8 mode)
176 | {
177 | //GPIO_PIN_PAD_DRIVER
178 | CLEAR_PERI_REG_MASK(GPIO_PIN16, GPIO_GPIO_PIN19_PAD_DRIVER);
179 | CLEAR_PERI_REG_MASK(GPIO_PIN17, GPIO_GPIO_PIN20_PAD_DRIVER);
180 | CLEAR_PERI_REG_MASK(GPIO_PIN18, GPIO_GPIO_PIN21_PAD_DRIVER);
181 | CLEAR_PERI_REG_MASK(GPIO_PIN19, GPIO_GPIO_PIN19_PAD_DRIVER);
182 | CLEAR_PERI_REG_MASK(GPIO_PIN20, GPIO_GPIO_PIN20_PAD_DRIVER);
183 | CLEAR_PERI_REG_MASK(GPIO_PIN21, GPIO_GPIO_PIN21_PAD_DRIVER);
184 |
185 | if (mode == TX_MASTER) {
186 | //CONFIG I2S TX_master PIN FUNC
187 | //I2S0_TX module
188 | //I2S0_DATA_out-->GPIO_OUT_DATA[21]-->io_mux_core/GPIO21
189 | //I2S0_BCK_out/in-->GPIO_OUT_DATA[20]-->io_mux_core/GPIO20
190 | //I2S0_WS_out-->GPIO_OUT_DATA[19]-->io_mux_core/GPIO19
191 | SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL4, GPIO_GPIO_FUNC19_OUT_SEL, 25, GPIO_GPIO_FUNC19_OUT_SEL_S);
192 | SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL5, GPIO_GPIO_FUNC20_OUT_SEL, 24, GPIO_GPIO_FUNC20_OUT_SEL_S);
193 | SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL5, GPIO_GPIO_FUNC21_OUT_SEL, 23, GPIO_GPIO_FUNC21_OUT_SEL_S);
194 |
195 | WRITE_PERI_REG(0x60009074, FUN_PU);
196 | WRITE_PERI_REG(0x60009078, FUN_PU);
197 | WRITE_PERI_REG(0x6000907c, FUN_PU);
198 |
199 | //GPIO19_mcu_sel=0
200 | //GPIO20_mcu_sel=0
201 | //GPIO21_mcu_sel=0
202 | SET_PERI_REG_BITS(0x60009074, MCU_SEL, 0, MCU_SEL_S);
203 | SET_PERI_REG_BITS(0x60009078, MCU_SEL, 0, MCU_SEL_S);
204 | SET_PERI_REG_BITS(0x6000907c, MCU_SEL, 0, MCU_SEL_S);
205 |
206 | //SET_PERI_REG_BITS(0x60009074,FUN_DRV,3,FUN_DRV_S);
207 | //SET_PERI_REG_BITS(0x60009078,FUN_DRV,3,FUN_DRV_S);
208 | //SET_PERI_REG_BITS(0x6000907c,FUN_DRV,3,FUN_DRV_S);
209 |
210 | SET_PERI_REG_MASK(GPIO_ENABLE, BIT(19) | BIT(20) | BIT(21));
211 | } else if (mode == TX_SLAVE) {
212 | //I2S0_DATA_out-->GPIO_OUT_DATA[21]-->io_mux_core/GPIO21
213 | SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL5, GPIO_GPIO_FUNC21_OUT_SEL, 23, GPIO_GPIO_FUNC21_OUT_SEL_S);
214 |
215 | WRITE_PERI_REG(0x60009074, FUN_PU | FUN_IE);
216 | WRITE_PERI_REG(0x60009078, FUN_PU | FUN_IE);
217 | WRITE_PERI_REG(0x6000907c, FUN_PU);
218 |
219 | //I2S0_BCK_in
220 | //I2S0_WS_in
221 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL4, GPIO_GPIO_FUNC24_IN_SEL, 20, GPIO_GPIO_FUNC24_IN_SEL_S);
222 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5, GPIO_GPIO_FUNC25_IN_SEL, 19, GPIO_GPIO_FUNC25_IN_SEL_S);
223 |
224 | SET_PERI_REG_MASK(GPIO_ENABLE, BIT(21));
225 | CLEAR_PERI_REG_MASK(GPIO_ENABLE, BIT(19) | BIT(20));
226 | } else if (mode == RX_MASTER) {
227 | //I2S1_WS_out
228 | //I2S1_BCK_out
229 | SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL4, GPIO_GPIO_FUNC16_OUT_SEL, 28, GPIO_GPIO_FUNC16_OUT_SEL_S);
230 | SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL4, GPIO_GPIO_FUNC17_OUT_SEL, 27, GPIO_GPIO_FUNC17_OUT_SEL_S);
231 |
232 | WRITE_PERI_REG(0x6000904c, FUN_PU);
233 | WRITE_PERI_REG(0x60009050, FUN_PU);
234 | WRITE_PERI_REG(0x60009070, FUN_IE | FUN_PU);
235 |
236 | SET_PERI_REG_MASK(GPIO_ENABLE, BIT(16) | BIT(17));
237 | CLEAR_PERI_REG_MASK(GPIO_ENABLE, BIT(18));
238 |
239 | //I2S1_DATA_in
240 | //I2S1_WS_in
241 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5, GPIO_GPIO_FUNC26_IN_SEL, 18, GPIO_GPIO_FUNC26_IN_SEL_S);
242 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5, GPIO_GPIO_FUNC28_IN_SEL, 16, GPIO_GPIO_FUNC28_IN_SEL_S);
243 | } else if (mode == RX_SLAVE) {
244 | WRITE_PERI_REG(0x6000904c, FUN_IE | FUN_PU);
245 | WRITE_PERI_REG(0x60009050, FUN_IE | FUN_PU);
246 | WRITE_PERI_REG(0x60009070, FUN_IE | FUN_PU);
247 |
248 | CLEAR_PERI_REG_MASK(GPIO_ENABLE, BIT(16) | BIT(17) | BIT(18));
249 | //I2S1_DATA_in
250 | //I2S1_BCK_in
251 | //I2S1_WS_in
252 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5, GPIO_GPIO_FUNC26_IN_SEL, 18, GPIO_GPIO_FUNC26_IN_SEL_S);
253 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5, GPIO_GPIO_FUNC27_IN_SEL, 17, GPIO_GPIO_FUNC27_IN_SEL_S);
254 | SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5, GPIO_GPIO_FUNC28_IN_SEL, 16, GPIO_GPIO_FUNC28_IN_SEL_S);
255 | }
256 |
257 | //I2S0_DATA_in
258 | //I2S0_BCK_in
259 | //I2S0_WS_in
260 | //SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL4,GPIO_GPIO_FUNC23_IN_SEL,21,GPIO_GPIO_FUNC23_IN_SEL_S);
261 | //SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL4,GPIO_GPIO_FUNC24_IN_SEL,20,GPIO_GPIO_FUNC24_IN_SEL_S);
262 | //SET_PERI_REG_BITS(GPIO_FUNC_IN_SEL5,GPIO_GPIO_FUNC25_IN_SEL,19,GPIO_GPIO_FUNC25_IN_SEL_S);
263 |
264 | //CONFIG I2S RX PIN FUNC
265 | //I2S1 module
266 | //I2S1_DATA_in-->GPIO_OUT_DATA[18]-->io_mux_core/GPIO18
267 | //I2S1_BCK_out/in-->GPIO_OUT_DATA[17]-->io_mux_core/GPIO17
268 | //I2S1_WS_in-->GPIO_OUT_DATA[16]-->io_mux_core/GPIO16
269 | //SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL4,GPIO_GPIO_FUNC16_OUT_SEL,28,GPIO_GPIO_FUNC16_OUT_SEL_S);
270 | //SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL4,GPIO_GPIO_FUNC17_OUT_SEL,27,GPIO_GPIO_FUNC17_OUT_SEL_S);
271 | //SET_PERI_REG_BITS(GPIO_FUNC_OUT_SEL4,GPIO_GPIO_FUNC18_OUT_SEL,26,GPIO_GPIO_FUNC18_OUT_SEL_S);
272 |
273 | //GPIO_PIN_PAD_DRIVER
274 | //CLEAR_PERI_REG_MASK(GPIO_PIN16, GPIO_GPIO_PIN19_PAD_DRIVER);
275 | //CLEAR_PERI_REG_MASK(GPIO_PIN17, GPIO_GPIO_PIN20_PAD_DRIVER);
276 | //CLEAR_PERI_REG_MASK(GPIO_PIN18, GPIO_GPIO_PIN21_PAD_DRIVER);
277 | //WRITE_PERI_REG(GPIO_PIN19,0x4);
278 | //WRITE_PERI_REG(GPIO_PIN20,0x4);
279 |
280 | //GPIO16_mcu_sel=0
281 | //GPIO17_mcu_sel=0
282 | //GPIO18_mcu_sel=0
283 | //SET_PERI_REG_BITS(0x6000904c,MCU_SEL,0,MCU_SEL_S);
284 | //SET_PERI_REG_BITS(0x60009050,MCU_SEL,0,MCU_SEL_S);
285 | //SET_PERI_REG_BITS(0x60009070,MCU_SEL,0,MCU_SEL_S);
286 | }
287 |
288 | //Initialize the I2S module
289 | //More Registor details in I2S documents.
290 | void i2s_init(void)
291 | {
292 | //reset I2S
293 | CLEAR_PERI_REG_MASK(I2SCONF, I2S_I2S_RESET_MASK);
294 | SET_PERI_REG_MASK(I2SCONF, I2S_I2S_RESET_MASK);
295 | CLEAR_PERI_REG_MASK(I2SCONF, I2S_I2S_RESET_MASK);
296 |
297 | //Enable FIFO in i2s module
298 | SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);
299 |
300 | //set I2S_FIFO
301 | //set rx,tx data size, both are "24-bit full data discountinue" here
302 | SET_PERI_REG_BITS(I2S_FIFO_CONF, I2S_I2S_RX_FIFO_MOD, 2, I2S_I2S_RX_FIFO_MOD_S);
303 | SET_PERI_REG_BITS(I2S_FIFO_CONF, I2S_I2S_TX_FIFO_MOD, 2, I2S_I2S_TX_FIFO_MOD_S);
304 |
305 | //set I2S_CHAN
306 | //set rx,tx channel mode, both are "two channel" here
307 |
308 | SET_PERI_REG_BITS(I2S_FIFO_CONF, I2S_TX_CHAN_MOD, 0, I2S_TX_CHAN_MOD_S);
309 | SET_PERI_REG_BITS(I2S_FIFO_CONF, I2S_RX_CHAN_MOD, 0, I2S_RX_CHAN_MOD_S);
310 |
311 | //set RX eof num
312 | WRITE_PERI_REG(I2SRXEOF_NUM, RX_NUM);
313 |
314 | //trans master&rece slave mode,
315 | //MSB_shift,right_first,MSB_right,
316 | //use I2S clock divider to produce a 32KHz Sample Rate
317 | CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD |
318 | (I2S_BITS_MOD << I2S_BITS_MOD_S) |
319 | (I2S_BCK_DIV_NUM << I2S_BCK_DIV_NUM_S) |
320 | (I2S_CLKM_DIV_NUM << I2S_CLKM_DIV_NUM_S));
321 |
322 | SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST | I2S_MSB_RIGHT | I2S_RECE_SLAVE_MOD |
323 | I2S_RECE_MSB_SHIFT | I2S_TRANS_MSB_SHIFT |
324 | ((26 & I2S_BCK_DIV_NUM) << I2S_BCK_DIV_NUM_S) |
325 | ((4 & I2S_CLKM_DIV_NUM) << I2S_CLKM_DIV_NUM_S) |
326 | (8 << I2S_BITS_MOD_S));
327 |
328 | /*
329 | //trans slave&rece master mode,
330 | //MSB_shift,right_first,MSB_right,
331 | //use I2S clock divider to produce a 32KHz Sample Rate
332 | CLEAR_PERI_REG_MASK(I2SCONF, I2S_RECE_SLAVE_MOD|
333 | (I2S_BITS_MOD< 0
153 | self._port.setDTR(True ^ invert) # GPIO0 -> 0
154 | time.sleep(0.05)
155 | self._port.setRTS(False ^ invert) # RST -> 1
156 | time.sleep(0.1)
157 |
158 | self._first_flash_after_reset = True
159 |
160 | self._port.timeout = 0.3 # worst-case latency timer should be 255ms (probably <20ms)
161 | for _ in xrange(4):
162 | try:
163 | self._port.flushInput()
164 | self._port.flushOutput()
165 | self.sync()
166 | self._port.timeout = 5
167 | return
168 | except:
169 | time.sleep(0.05)
170 | self._port.setDTR(False ^ invert) # GPIO0 -> 1
171 | raise Exception('Failed to connect')
172 |
173 | """ Read memory address in target """
174 | def read_reg(self, addr):
175 | res = self.command(ESPROM.ESP_READ_REG, struct.pack('> 16) & 0xff) == 0:
265 | oui = (0x18, 0xfe, 0x34)
266 | elif ((mac1 >> 16) & 0xff) == 1:
267 | oui = (0xac, 0xd0, 0x74)
268 | else:
269 | raise Exception("Unknown OUI")
270 | return oui + ((mac1 >> 8) & 0xff, mac1 & 0xff, (mac0 >> 24) & 0xff)
271 |
272 | """ Read SPI flash manufacturer and device id """
273 | def flash_id(self):
274 | self.flash_begin(0, 0)
275 | self.write_reg(0x60000240, 0x0, 0xffffffff)
276 | self.write_reg(0x60000200, 0x10000000, 0xffffffff)
277 | flash_id = esp.read_reg(0x60000240)
278 | self.flash_finish(False)
279 | return flash_id
280 |
281 | """ Read SPI flash """
282 | def flash_read(self, offset, size, count = 1):
283 | # Create a custom stub
284 | stub = struct.pack(' 16:
344 | raise Exception('Invalid firmware image')
345 |
346 | for i in xrange(segments):
347 | (offset, size) = struct.unpack(' 0x40200000 or offset < 0x3ffe0000 or size > 65536:
349 | raise Exception('Suspicious segment 0x%x, length %d' % (offset, size))
350 | segment_data = f.read(size)
351 | if len(segment_data) < size:
352 | raise Exception('End of file reading segment 0x%x, length %d (actual length %d)' % (offset, size, len(segment_data)))
353 | self.segments.append((offset, size, segment_data))
354 |
355 | # Skip the padding. The checksum is stored in the last byte so that the
356 | # file is a multiple of 16 bytes.
357 | align = 15-(f.tell() % 16)
358 | f.seek(align, 1)
359 |
360 | self.checksum = ord(f.read(1))
361 |
362 | def add_segment(self, addr, data):
363 | # Data should be aligned on word boundary
364 | l = len(data)
365 | if l % 4:
366 | data += b"\x00" * (4 - l % 4)
367 | if l > 0:
368 | self.segments.append((addr, len(data), data))
369 |
370 | def save(self, filename):
371 | f = file(filename, 'wb')
372 | f.write(struct.pack(' 0:
571 | esp.mem_block(data[0:esp.ESP_RAM_BLOCK], seq)
572 | data = data[esp.ESP_RAM_BLOCK:]
573 | seq += 1
574 | print 'done!'
575 |
576 | print 'All segments done, executing at %08x' % image.entrypoint
577 | esp.mem_finish(image.entrypoint)
578 |
579 | elif args.operation == 'read_mem':
580 | print '0x%08x = 0x%08x' % (args.address, esp.read_reg(args.address))
581 |
582 | elif args.operation == 'write_mem':
583 | esp.write_reg(args.address, args.value, args.mask, 0)
584 | print 'Wrote %08x, mask %08x to %08x' % (args.value, args.mask, args.address)
585 |
586 | elif args.operation == 'dump_mem':
587 | f = file(args.filename, 'wb')
588 | for i in xrange(args.size/4):
589 | d = esp.read_reg(args.address+(i*4))
590 | f.write(struct.pack(' 0:
616 | print '\rWriting at 0x%08x... (%d %%)' % (address + seq*esp.ESP_FLASH_BLOCK, 100*(seq+1)/blocks),
617 | sys.stdout.flush()
618 | block = image[0:esp.ESP_FLASH_BLOCK]
619 | # Fix sflash config data
620 | if address == 0 and seq == 0 and block[0] == '\xe9':
621 | block = block[0:2] + flash_info + block[4:]
622 | # Pad the last block
623 | block = block + '\xff' * (esp.ESP_FLASH_BLOCK-len(block))
624 | esp.flash_block(block, seq)
625 | image = image[esp.ESP_FLASH_BLOCK:]
626 | seq += 1
627 | written += len(block)
628 | t = time.time() - t
629 | print '\rWrote %d bytes at 0x%08x in %.1f seconds (%.1f kbit/s)...' % (written, address, t, written / t * 8 / 1000)
630 | print '\nLeaving...'
631 | if args.flash_mode == 'dio':
632 | esp.flash_unlock_dio()
633 | else:
634 | esp.flash_begin(0, 0)
635 | esp.flash_finish(False)
636 |
637 | elif args.operation == 'run':
638 | esp.run()
639 |
640 | elif args.operation == 'image_info':
641 | image = ESPFirmwareImage(args.filename)
642 | print ('Entry point: %08x' % image.entrypoint) if image.entrypoint != 0 else 'Entry point not set'
643 | print '%d segments' % len(image.segments)
644 | print
645 | checksum = ESPROM.ESP_CHECKSUM_MAGIC
646 | for (idx, (offset, size, data)) in enumerate(image.segments):
647 | print 'Segment %d: %5d bytes at %08x' % (idx+1, size, offset)
648 | checksum = ESPROM.checksum(data, checksum)
649 | print
650 | print 'Checksum: %02x (%s)' % (image.checksum, 'valid' if image.checksum == checksum else 'invalid!')
651 |
652 | elif args.operation == 'make_image':
653 | image = ESPFirmwareImage()
654 | if len(args.segfile) == 0:
655 | raise Exception('No segments specified')
656 | if len(args.segfile) != len(args.segaddr):
657 | raise Exception('Number of specified files does not match number of specified addresses')
658 | for (seg, addr) in zip(args.segfile, args.segaddr):
659 | data = file(seg, 'rb').read()
660 | image.add_segment(addr, data)
661 | image.entrypoint = args.entrypoint
662 | image.save(args.output)
663 |
664 | elif args.operation == 'elf2image':
665 | if args.output is None:
666 | args.output = args.input + '-'
667 | e = ELFFile(args.input)
668 | image = ESPFirmwareImage()
669 | image.entrypoint = e.get_entry_point()
670 | for section, start in ((".text", "_text_start"), (".data", "_data_start"), (".rodata", "_rodata_start")):
671 | data = e.load_section(section)
672 | image.add_segment(e.get_symbol_addr(start), data)
673 |
674 | image.flash_mode = {'qio':0, 'qout':1, 'dio':2, 'dout': 3}[args.flash_mode]
675 | image.flash_size_freq = {'4m':0x00, '2m':0x10, '8m':0x20, '16m':0x30, '32m':0x40, '16m-c1': 0x50, '32m-c1':0x60, '32m-c2':0x70}[args.flash_size]
676 | image.flash_size_freq += {'40m':0, '26m':1, '20m':2, '80m': 0xf}[args.flash_freq]
677 |
678 | image.save(args.output + "0x00000.bin")
679 | data = e.load_section(".irom0.text")
680 | off = e.get_symbol_addr("_irom0_text_start") - 0x40200000
681 | assert off >= 0
682 | f = open(args.output + "0x%05x.bin" % off, "wb")
683 | f.write(data)
684 | f.close()
685 |
686 | elif args.operation == 'read_mac':
687 | mac = esp.read_mac()
688 | print 'MAC: %s' % ':'.join(map(lambda x: '%02x'%x, mac))
689 |
690 | elif args.operation == 'flash_id':
691 | flash_id = esp.flash_id()
692 | print 'Manufacturer: %02x' % (flash_id & 0xff)
693 | print 'Device: %02x%02x' % ((flash_id >> 8) & 0xff, (flash_id >> 16) & 0xff)
694 |
695 | elif args.operation == 'read_flash':
696 | print 'Please wait...'
697 | file(args.filename, 'wb').write(esp.flash_read(args.address, 1024, div_roundup(args.size, 1024))[:args.size])
698 |
699 | elif args.operation == 'erase_flash':
700 | esp.flash_erase()
701 |
--------------------------------------------------------------------------------