├── .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 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 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 | --------------------------------------------------------------------------------