├── driver ├── easygpio │ ├── examples │ │ ├── dependencies │ │ │ ├── easygpio │ │ │ │ └── .keep │ │ │ └── stdout │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── include │ │ │ │ └── stdout │ │ │ │ │ ├── stdout.h │ │ │ │ │ └── uart_hw.h │ │ │ │ └── stdout.c │ │ ├── readgpio │ │ │ ├── localinclude │ │ │ │ └── .keep │ │ │ ├── include │ │ │ │ └── user_config.h │ │ │ ├── user │ │ │ │ └── user_main.c │ │ │ └── Makefile │ │ └── writegpio │ │ │ ├── localinclude │ │ │ └── .keep │ │ │ ├── include │ │ │ └── user_config.h │ │ │ ├── user │ │ │ └── user_main.c │ │ │ └── Makefile │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── include │ │ └── easygpio │ │ │ └── easygpio.h │ └── easygpio.c ├── pcd8544 │ ├── .gitignore │ ├── README.md │ ├── include │ │ └── pcd8544 │ │ │ └── pcd8544.h │ ├── Makefile │ └── pcd8544.c └── stdout │ ├── .gitignore │ ├── README.md │ ├── include │ └── stdout │ │ ├── stdout.h │ │ └── uart_hw.h │ └── stdout.c ├── mqtt ├── .gitignore ├── .gitmodules ├── include │ ├── user_config.h │ ├── mqtt_config.h │ └── driver │ │ ├── uart.h │ │ └── uart_register.h ├── mqtt │ ├── include │ │ ├── utils.h │ │ ├── typedef.h │ │ ├── debug.h │ │ ├── ringbuf.h │ │ ├── proto.h │ │ ├── queue.h │ │ ├── mqtt_msg.h │ │ └── mqtt.h │ ├── Makefile │ ├── ringbuf.c │ ├── queue.c │ ├── proto.c │ ├── utils.c │ └── mqtt_msg.c ├── modules │ ├── include │ │ ├── wifi.h │ │ └── config.h │ ├── Makefile │ ├── wifi.c │ └── config.c ├── .travis.yml ├── user │ ├── Makefile │ └── user_main.c ├── driver │ ├── Makefile │ └── uart.c ├── Makefile └── README.md ├── .gitignore ├── include └── user_config.h ├── user ├── Makefile └── user_main.c ├── Processing └── PublishToLcd │ └── PublishToLcd.pde ├── README.md └── Makefile /driver/easygpio/examples/dependencies/easygpio/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /driver/easygpio/examples/readgpio/localinclude/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /driver/easygpio/examples/writegpio/localinclude/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mqtt/.gitignore: -------------------------------------------------------------------------------- 1 | .cproject 2 | .project 3 | build/ 4 | firmware/ 5 | .settings/ 6 | .DS_Store -------------------------------------------------------------------------------- /driver/pcd8544/.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .cproject 3 | .settings 4 | build 5 | firmware 6 | 7 | -------------------------------------------------------------------------------- /driver/easygpio/examples/readgpio/include/user_config.h: -------------------------------------------------------------------------------- 1 | #ifndef __USER_CONFIG_H__ 2 | #define __USER_CONFIG_H__ 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /driver/easygpio/examples/writegpio/include/user_config.h: -------------------------------------------------------------------------------- 1 | #ifndef __USER_CONFIG_H__ 2 | #define __USER_CONFIG_H__ 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /mqtt/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tools/esptool"] 2 | path = tools/esptool 3 | url = https://github.com/themadinventor/esptool.git 4 | -------------------------------------------------------------------------------- /mqtt/include/user_config.h: -------------------------------------------------------------------------------- 1 | #ifndef __USER_CONFIG_H__ 2 | #define __USER_CONFIG_H__ 3 | 4 | #define USE_OPTIMIZE_PRINTF 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTILS_H_ 2 | #define _UTILS_H_ 3 | 4 | #include "c_types.h" 5 | 6 | uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s); 7 | uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip); 8 | uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str); 9 | #endif 10 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/typedef.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * Standard Types definition 4 | */ 5 | 6 | #ifndef _TYPE_DEF_H_ 7 | #define _TYPE_DEF_H_ 8 | 9 | typedef char I8; 10 | typedef unsigned char U8; 11 | typedef short I16; 12 | typedef unsigned short U16; 13 | typedef long I32; 14 | typedef unsigned long U32; 15 | typedef unsigned long long U64; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /mqtt/modules/include/wifi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi.h 3 | * 4 | * Created on: Dec 30, 2014 5 | * Author: Minh 6 | */ 7 | 8 | #ifndef USER_WIFI_H_ 9 | #define USER_WIFI_H_ 10 | #include "os_type.h" 11 | typedef void (*WifiCallback)(uint8_t); 12 | void ICACHE_FLASH_ATTR WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback cb); 13 | 14 | 15 | #endif /* USER_WIFI_H_ */ 16 | -------------------------------------------------------------------------------- /driver/stdout/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | -------------------------------------------------------------------------------- /driver/easygpio/examples/dependencies/stdout/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | -------------------------------------------------------------------------------- /driver/easygpio/.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse project files 2 | .cproject 3 | .project 4 | .settings 5 | 6 | # esp build files 7 | *.bin 8 | 9 | # Object files 10 | *.o 11 | *.ko 12 | *.obj 13 | *.elf 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * debug.h 3 | * 4 | * Created on: Dec 4, 2014 5 | * Author: Minh 6 | */ 7 | 8 | #ifndef USER_DEBUG_H_ 9 | #define USER_DEBUG_H_ 10 | 11 | #if defined(GLOBAL_DEBUG_ON) 12 | #define MQTT_DEBUG_ON 13 | #endif 14 | #if defined(MQTT_DEBUG_ON) 15 | #define INFO( format, ... ) os_printf( format, ## __VA_ARGS__ ) 16 | #else 17 | #define INFO( format, ... ) 18 | #endif 19 | // #ifndef INFO 20 | // #define INFO os_printf 21 | // #endif 22 | 23 | #endif /* USER_DEBUG_H_ */ 24 | -------------------------------------------------------------------------------- /driver/stdout/README.md: -------------------------------------------------------------------------------- 1 | # esp8266_stdout 2 | A clone of Jeroen Domburg's () stdout driver. 3 | It's an alternative uart driver that only uses the TX pin, so the RX pin is free for GPIO use. 4 | 5 | Needless to say, but this driver can only transmit. 6 | 7 | ###License: 8 | "THE BEER-WARE LICENSE" (Revision 42): 9 | Jeroen Domburg wrote this file. As long as you retain 10 | this notice you can do whatever you want with this stuff. If we meet some day, 11 | and you think this stuff is worth it, you can buy me a beer in return. 12 | 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # you can put your own user_config.h and mqtt_config.h here and git will not bother you about it 2 | localinclude/user_config.h 3 | localinclude/mqtt_config.h 4 | 5 | .project 6 | .cproject 7 | .settings 8 | firmware 9 | build 10 | # Object files 11 | *.o 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | 26 | # Shared objects (inc. Windows DLLs) 27 | *.dll 28 | *.so 29 | *.so.* 30 | *.dylib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app 36 | *.i*86 37 | *.x86_64 38 | *.hex 39 | -------------------------------------------------------------------------------- /driver/stdout/include/stdout/stdout.h: -------------------------------------------------------------------------------- 1 | //Stupid bit of code that does the bare minimum to make os_printf work. 2 | 3 | /* 4 | * ---------------------------------------------------------------------------- 5 | * "THE BEER-WARE LICENSE" (Revision 42): 6 | * Jeroen Domburg wrote this file. As long as you retain 7 | * this notice you can do whatever you want with this stuff. If we meet some day, 8 | * and you think this stuff is worth it, you can buy me a beer in return. 9 | * ---------------------------------------------------------------------------- 10 | */ 11 | 12 | void stdout_init(void); 13 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/ringbuf.h: -------------------------------------------------------------------------------- 1 | #ifndef _RING_BUF_H_ 2 | #define _RING_BUF_H_ 3 | 4 | #include 5 | #include 6 | #include "typedef.h" 7 | 8 | typedef struct{ 9 | U8* p_o; /**< Original pointer */ 10 | U8* volatile p_r; /**< Read pointer */ 11 | U8* volatile p_w; /**< Write pointer */ 12 | volatile I32 fill_cnt; /**< Number of filled slots */ 13 | I32 size; /**< Buffer size */ 14 | }RINGBUF; 15 | 16 | I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size); 17 | I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c); 18 | I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c); 19 | #endif 20 | -------------------------------------------------------------------------------- /driver/easygpio/examples/dependencies/stdout/README.md: -------------------------------------------------------------------------------- 1 | # esp8266_stdout 2 | A clone of Jeroen Domburg's () stdout driver. 3 | It's an alternative uart driver that only uses the TX pin, so the RX pin is free for GPIO use. 4 | 5 | Needless to say, but this driver can only transmit. 6 | 7 | ###License: 8 | "THE BEER-WARE LICENSE" (Revision 42): 9 | Jeroen Domburg wrote this file. As long as you retain 10 | this notice you can do whatever you want with this stuff. If we meet some day, 11 | and you think this stuff is worth it, you can buy me a beer in return. 12 | 13 | 14 | -------------------------------------------------------------------------------- /driver/easygpio/examples/dependencies/stdout/include/stdout/stdout.h: -------------------------------------------------------------------------------- 1 | //Stupid bit of code that does the bare minimum to make os_printf work. 2 | 3 | /* 4 | * ---------------------------------------------------------------------------- 5 | * "THE BEER-WARE LICENSE" (Revision 42): 6 | * Jeroen Domburg wrote this file. As long as you retain 7 | * this notice you can do whatever you want with this stuff. If we meet some day, 8 | * and you think this stuff is worth it, you can buy me a beer in return. 9 | * ---------------------------------------------------------------------------- 10 | */ 11 | 12 | void stdout_init(void); 13 | -------------------------------------------------------------------------------- /mqtt/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | before_install: 3 | - sudo apt-get -qq update 4 | - sudo apt-get install -y python-serial srecord 5 | install: 6 | - wget https://github.com/GeorgeHahn/nodemcu-firmware/raw/travis/tools/esp-open-sdk.tar.gz -O tools/esp-open-sdk.tar.gz 7 | - tar -zxvf tools/esp-open-sdk.tar.gz 8 | - export PATH=$PATH:$PWD/esp-open-sdk/sdk:$PWD/esp-open-sdk/xtensa-lx106-elf/bin 9 | - wget http://bbs.espressif.com/download/file.php?id=1046 -O tools/esp_iot_sdk_v1.5.1.zip 10 | - unzip tools/esp_iot_sdk_v1.5.1.zip 11 | script: 12 | - make all SDK_BASE="$PWD/esp_iot_sdk_v1.5.1" 13 | - cd firmware/ 14 | - file_name="esp_mqtt_v${TRAVIS_TAG}.${TRAVIS_BUILD_NUMBER}.bin" 15 | - srec_cat -output ${file_name} -binary 0x00000.bin -binary -fill 0xff 0x00000 0x40000 0x40000.bin -binary -offset 0x40000 16 | deploy: 17 | provider: releases 18 | api_key: 19 | file: "$TRAVIS_BUILD_DIR/firmware/${file_name}" 20 | skip_cleanup: true 21 | on: 22 | tags: true 23 | repo: tuanpmt/esp_mqtt 24 | -------------------------------------------------------------------------------- /include/user_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _USER_CONFIG_H_ 2 | #define _USER_CONFIG_H_ 3 | 4 | /* All of the mqtt settings are now moved to mqtt_config.h * */ 5 | 6 | // application configurations: 7 | #define PCD8544_RESET_PIN 4 //-1; This pin is now optional. 8 | // Set the PCD8544_RESET_PIN to negative value to disable the pin. 9 | // If you do disable it, you must tie LCD reset pin to esp reset via resistor. 10 | #define PCD8544_SCE_PIN 5 //-1; This pin is now optional. 11 | // Set PCD8544_SCE_PIN to negative value to disable the pin. 12 | // If you do disable it, you must tie LCD CE pin to GND via resistor. 13 | // dcPin, sdinPin and sclkPin can be used for other SPI devices if scePin is *NOT* disabled. 14 | #define PCD8544_DC_PIN 12 15 | #define PCD8544_SDIN_PIN 13 16 | #define PCD8544_SCLK_PIN 14 17 | #define PCD8544_CONTRAST 60 // the default contrast 18 | #endif 19 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/proto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: proto.h 3 | * Author: ThuHien 4 | * 5 | * Created on November 23, 2012, 8:57 AM 6 | */ 7 | 8 | #ifndef _PROTO_H_ 9 | #define _PROTO_H_ 10 | #include 11 | #include "typedef.h" 12 | #include "ringbuf.h" 13 | 14 | typedef void(PROTO_PARSE_CALLBACK)(); 15 | 16 | typedef struct{ 17 | U8 *buf; 18 | U16 bufSize; 19 | U16 dataLen; 20 | U8 isEsc; 21 | U8 isBegin; 22 | PROTO_PARSE_CALLBACK* callback; 23 | }PROTO_PARSER; 24 | 25 | I8 ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *completeCallback, U8 *buf, U16 bufSize); 26 | I8 ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, U8 *buf, U16 len); 27 | I16 ICACHE_FLASH_ATTR PROTO_Add(U8 *buf, const U8 *packet, I16 bufSize); 28 | I16 ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const U8 *packet, I16 len); 29 | I8 ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, U8 value); 30 | I16 ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF *rb, U8 *bufOut, U16* len, U16 maxBufLen); 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /driver/pcd8544/README.md: -------------------------------------------------------------------------------- 1 | # esp8266_pcd8544 2 | PCD8544 LCD driver for esp8266 (Nokia 5110 & 3110 display) 3 | 4 | This is a direct port of code found at [arduino playground.](http://playground.arduino.cc/Code/PCD8544) 5 | 6 | This git repository now only contains the the driver, the example code that used to be here is now moved to [pdc8544_example.](https://github.com/eadf/esp8266_pcd8544_example) 7 | 8 | Here is another example of how this module can be used: [esp_mqtt_lcd](https://github.com/eadf/esp_mqtt_lcd). 9 | 10 | Good news, the interface no longer requires 5 available GPIO outputs so an ESP-01 will indeed work. (But only if the RX pin of the esp is used.) 11 | 12 | The RST pin is optional, set it to a negative value and tie PCD8544 reset to ESP reset via a resistor. 13 | 14 | The CE pin is optional, set it to a negative value and tie PCD8544 CE pin to GND via a resistor. 15 | 16 | All of the pins are configurable, you just set the pins you want to use in the setting struct. 17 | 18 | I have tested this with sdk v0.9.5 and v0.9.4 (linux & mac makefile) 19 | 20 | -------------------------------------------------------------------------------- /mqtt/include/mqtt_config.h: -------------------------------------------------------------------------------- 1 | #ifndef __MQTT_CONFIG_H__ 2 | #define __MQTT_CONFIG_H__ 3 | 4 | #define CFG_HOLDER 0x00FF55A4 /* Change this value to load default configurations */ 5 | #define CFG_LOCATION 0x3C /* Please don't change or if you know what you doing */ 6 | #define MQTT_SSL_ENABLE 7 | 8 | /*DEFAULT CONFIGURATIONS*/ 9 | 10 | #define MQTT_HOST "192.168.1.100" //or "mqtt.yourdomain.com" 11 | #define MQTT_PORT 1883 12 | #define MQTT_BUF_SIZE 1024 13 | #define MQTT_KEEPALIVE 120 /*second*/ 14 | 15 | #define MQTT_CLIENT_ID "DVES_%08X" 16 | #define MQTT_USER "DVES_USER" 17 | #define MQTT_PASS "DVES_PASS" 18 | 19 | #define STA_SSID "DVES_HOME" 20 | #define STA_PASS "yourpassword" 21 | #define STA_TYPE AUTH_WPA2_PSK 22 | 23 | #define MQTT_RECONNECT_TIMEOUT 5 /*second*/ 24 | 25 | #define DEFAULT_SECURITY 0 26 | #define QUEUE_BUFFER_SIZE 2048 27 | 28 | #define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*/ 29 | //PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/ 30 | 31 | #endif // __MQTT_CONFIG_H__ -------------------------------------------------------------------------------- /driver/pcd8544/include/pcd8544/pcd8544.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pcd8544.h 3 | * 4 | * PCD8544 bit-banging driver ported from http://playground.arduino.cc/Code/PCD8544 5 | * 6 | * Created on: Jan 7, 2015 7 | * Author: Eadf 8 | */ 9 | 10 | #ifndef INCLUDE_DRIVER_PCD8544_H_ 11 | #define INCLUDE_DRIVER_PCD8544_H_ 12 | 13 | #include "c_types.h" 14 | 15 | // the number of chars per line 16 | #define PCD8544_LCD_CHARS_PER_LINE 12 17 | 18 | typedef struct { 19 | uint8_t lcdVop; 20 | uint8_t tempCoeff; 21 | uint8_t biasMode; 22 | bool inverse; 23 | 24 | int8_t resetPin; 25 | int8_t scePin; 26 | int8_t dcPin; 27 | int8_t sdinPin; 28 | int8_t sclkPin; 29 | } PCD8544_Settings; 30 | 31 | void PCD8544_lcdImage(uint8_t *image); 32 | void PCD8544_lcdClear(void); 33 | void PCD8544_lcdCharacter(char character); 34 | /** 35 | * Writes a null terminated string 36 | */ 37 | void PCD8544_lcdPrint(char *characters); 38 | /** 39 | * debug prints a binary to console 40 | */ 41 | void PCD8544_printBinary(uint32_t data); 42 | void PCD8544_gotoXY(int x, int y); 43 | void PCD8544_drawLine(void); 44 | /** 45 | * print ' ' a number of times, negative 'spaces' value prints nothing. 46 | */ 47 | void PCD8544_lcdPad(int16_t spaces); 48 | 49 | /** 50 | * Sets the contrast [0x00 - 0x7f]. 51 | * Useful, visible range is about 40-60. 52 | */ 53 | void PCD8544_setContrast(uint8_t val); 54 | 55 | void PCD8544_initLCD(PCD8544_Settings *settings); 56 | /** 57 | */ 58 | void PCD8544_init(PCD8544_Settings *settings); 59 | 60 | #endif /* INCLUDE_DRIVER_PCD8544_H_ */ 61 | -------------------------------------------------------------------------------- /mqtt/mqtt/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 = libmqtt.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 | -------------------------------------------------------------------------------- /mqtt/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 | -------------------------------------------------------------------------------- /mqtt/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 | GEN_LIBS = libdriver.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 | -------------------------------------------------------------------------------- /mqtt/modules/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 = libmqtt.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/easygpio/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 = libeasygpio.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/pcd8544/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 = libpcd8544.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 | -------------------------------------------------------------------------------- /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 | INCLUDES += -I ../../rom/include 43 | INCLUDES += -I ../../include/ets 44 | PDIR := ../$(PDIR) 45 | sinclude $(PDIR)Makefile 46 | 47 | -------------------------------------------------------------------------------- /mqtt/mqtt/ringbuf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * \file 3 | * Ring Buffer library 4 | */ 5 | 6 | #include "ringbuf.h" 7 | 8 | 9 | /** 10 | * \brief init a RINGBUF object 11 | * \param r pointer to a RINGBUF object 12 | * \param buf pointer to a byte array 13 | * \param size size of buf 14 | * \return 0 if successfull, otherwise failed 15 | */ 16 | I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size) 17 | { 18 | if(r == NULL || buf == NULL || size < 2) return -1; 19 | 20 | r->p_o = r->p_r = r->p_w = buf; 21 | r->fill_cnt = 0; 22 | r->size = size; 23 | 24 | return 0; 25 | } 26 | /** 27 | * \brief put a character into ring buffer 28 | * \param r pointer to a ringbuf object 29 | * \param c character to be put 30 | * \return 0 if successfull, otherwise failed 31 | */ 32 | I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c) 33 | { 34 | if(r->fill_cnt>=r->size)return -1; // ring buffer is full, this should be atomic operation 35 | 36 | 37 | r->fill_cnt++; // increase filled slots count, this should be atomic operation 38 | 39 | 40 | *r->p_w++ = c; // put character into buffer 41 | 42 | if(r->p_w >= r->p_o + r->size) // rollback if write pointer go pass 43 | r->p_w = r->p_o; // the physical boundary 44 | 45 | return 0; 46 | } 47 | /** 48 | * \brief get a character from ring buffer 49 | * \param r pointer to a ringbuf object 50 | * \param c read character 51 | * \return 0 if successfull, otherwise failed 52 | */ 53 | I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c) 54 | { 55 | if(r->fill_cnt<=0)return -1; // ring buffer is empty, this should be atomic operation 56 | 57 | 58 | r->fill_cnt--; // decrease filled slots count 59 | 60 | 61 | *c = *r->p_r++; // get the character out 62 | 63 | if(r->p_r >= r->p_o + r->size) // rollback if write pointer go pass 64 | r->p_r = r->p_o; // the physical boundary 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /driver/stdout/stdout.c: -------------------------------------------------------------------------------- 1 | //Stupid bit of code that does the bare minimum to make os_printf work. 2 | 3 | /* 4 | * ---------------------------------------------------------------------------- 5 | * "THE BEER-WARE LICENSE" (Revision 42): 6 | * Jeroen Domburg wrote this file. As long as you retain 7 | * this notice you can do whatever you want with this stuff. If we meet some day, 8 | * and you think this stuff is worth it, you can buy me a beer in return. 9 | * ---------------------------------------------------------------------------- 10 | */ 11 | #include "stdout/stdout.h" 12 | #include "ets_sys.h" 13 | #include "osapi.h" 14 | #include "stdout/uart_hw.h" 15 | 16 | static void ICACHE_FLASH_ATTR stdoutUartTxd(char c) { 17 | //Wait until there is room in the FIFO 18 | while (((READ_PERI_REG(UART_STATUS(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ; 19 | //Send the character 20 | WRITE_PERI_REG(UART_FIFO(0), c); 21 | } 22 | 23 | static void ICACHE_FLASH_ATTR stdoutPutchar(char c) { 24 | //convert \n -> \r\n 25 | if (c=='\n') stdoutUartTxd('\r'); 26 | stdoutUartTxd(c); 27 | } 28 | 29 | 30 | void ICACHE_FLASH_ATTR 31 | stdout_init() { 32 | //Enable TxD pin 33 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); 34 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); 35 | 36 | //Set baud rate and other serial parameters to 115200,n,8,1 37 | uart_div_modify(0, UART_CLK_FREQ/BIT_RATE_115200); 38 | WRITE_PERI_REG(UART_CONF0(0), (STICK_PARITY_DIS)|(ONE_STOP_BIT << UART_STOP_BIT_NUM_S)| \ 39 | (EIGHT_BITS << UART_BIT_NUM_S)); 40 | 41 | //Reset tx & rx fifo 42 | SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); 43 | CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); 44 | //Clear pending interrupts 45 | WRITE_PERI_REG(UART_INT_CLR(0), 0xffff); 46 | 47 | //Install our own putchar handler 48 | os_install_putc1((void *)stdoutPutchar); 49 | } 50 | -------------------------------------------------------------------------------- /driver/easygpio/examples/dependencies/stdout/stdout.c: -------------------------------------------------------------------------------- 1 | //Stupid bit of code that does the bare minimum to make os_printf work. 2 | 3 | /* 4 | * ---------------------------------------------------------------------------- 5 | * "THE BEER-WARE LICENSE" (Revision 42): 6 | * Jeroen Domburg wrote this file. As long as you retain 7 | * this notice you can do whatever you want with this stuff. If we meet some day, 8 | * and you think this stuff is worth it, you can buy me a beer in return. 9 | * ---------------------------------------------------------------------------- 10 | */ 11 | #include "stdout/stdout.h" 12 | #include "ets_sys.h" 13 | #include "osapi.h" 14 | #include "stdout/uart_hw.h" 15 | 16 | static void ICACHE_FLASH_ATTR stdoutUartTxd(char c) { 17 | //Wait until there is room in the FIFO 18 | while (((READ_PERI_REG(UART_STATUS(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ; 19 | //Send the character 20 | WRITE_PERI_REG(UART_FIFO(0), c); 21 | } 22 | 23 | static void ICACHE_FLASH_ATTR stdoutPutchar(char c) { 24 | //convert \n -> \r\n 25 | if (c=='\n') stdoutUartTxd('\r'); 26 | stdoutUartTxd(c); 27 | } 28 | 29 | 30 | void ICACHE_FLASH_ATTR 31 | stdout_init() { 32 | //Enable TxD pin 33 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); 34 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); 35 | 36 | //Set baud rate and other serial parameters to 115200,n,8,1 37 | uart_div_modify(0, UART_CLK_FREQ/BIT_RATE_115200); 38 | WRITE_PERI_REG(UART_CONF0(0), (STICK_PARITY_DIS)|(ONE_STOP_BIT << UART_STOP_BIT_NUM_S)| \ 39 | (EIGHT_BITS << UART_BIT_NUM_S)); 40 | 41 | //Reset tx & rx fifo 42 | SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); 43 | CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); 44 | //Clear pending interrupts 45 | WRITE_PERI_REG(UART_INT_CLR(0), 0xffff); 46 | 47 | //Install our own putchar handler 48 | os_install_putc1((void *)stdoutPutchar); 49 | } 50 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/queue.h: -------------------------------------------------------------------------------- 1 | /* str_queue.h -- 2 | * 3 | * Copyright (c) 2014-2015, Tuan PM 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef USER_QUEUE_H_ 32 | #define USER_QUEUE_H_ 33 | #include "os_type.h" 34 | #include "ringbuf.h" 35 | typedef struct { 36 | uint8_t *buf; 37 | RINGBUF rb; 38 | } QUEUE; 39 | 40 | void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize); 41 | int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len); 42 | int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE *queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen); 43 | BOOL ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE *queue); 44 | #endif /* USER_QUEUE_H_ */ 45 | -------------------------------------------------------------------------------- /mqtt/modules/include/config.h: -------------------------------------------------------------------------------- 1 | /* config.h 2 | * 3 | * Copyright (c) 2014-2015, Tuan PM 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef USER_CONFIG_H_ 32 | #define USER_CONFIG_H_ 33 | #include "os_type.h" 34 | #include "user_config.h" 35 | typedef struct{ 36 | uint32_t cfg_holder; 37 | uint8_t device_id[16]; 38 | 39 | uint8_t sta_ssid[64]; 40 | uint8_t sta_pwd[64]; 41 | uint32_t sta_type; 42 | 43 | uint8_t mqtt_host[64]; 44 | uint32_t mqtt_port; 45 | uint8_t mqtt_user[32]; 46 | uint8_t mqtt_pass[32]; 47 | uint32_t mqtt_keepalive; 48 | uint8_t security; 49 | } SYSCFG; 50 | 51 | typedef struct { 52 | uint8 flag; 53 | uint8 pad[3]; 54 | } SAVE_FLAG; 55 | 56 | void ICACHE_FLASH_ATTR CFG_Save(); 57 | void ICACHE_FLASH_ATTR CFG_Load(); 58 | 59 | extern SYSCFG sysCfg; 60 | 61 | #endif /* USER_CONFIG_H_ */ 62 | -------------------------------------------------------------------------------- /mqtt/mqtt/queue.c: -------------------------------------------------------------------------------- 1 | /* str_queue.c 2 | * 3 | * Copyright (c) 2014-2015, Tuan PM 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "queue.h" 31 | 32 | #include "user_interface.h" 33 | #include "osapi.h" 34 | #include "os_type.h" 35 | #include "mem.h" 36 | #include "proto.h" 37 | void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize) 38 | { 39 | queue->buf = (uint8_t*)os_zalloc(bufferSize); 40 | RINGBUF_Init(&queue->rb, queue->buf, bufferSize); 41 | } 42 | int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len) 43 | { 44 | return PROTO_AddRb(&queue->rb, buffer, len); 45 | } 46 | int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE *queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen) 47 | { 48 | 49 | return PROTO_ParseRb(&queue->rb, buffer, len, maxLen); 50 | } 51 | 52 | BOOL ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE *queue) 53 | { 54 | if(queue->rb.fill_cnt<=0) 55 | return TRUE; 56 | return FALSE; 57 | } 58 | -------------------------------------------------------------------------------- /mqtt/modules/wifi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi.c 3 | * 4 | * Created on: Dec 30, 2014 5 | * Author: Minh 6 | */ 7 | #include "wifi.h" 8 | #include "user_interface.h" 9 | #include "osapi.h" 10 | #include "espconn.h" 11 | #include "os_type.h" 12 | #include "mem.h" 13 | #include "mqtt_msg.h" 14 | #include "debug.h" 15 | #include "user_config.h" 16 | #include "config.h" 17 | 18 | static ETSTimer WiFiLinker; 19 | WifiCallback wifiCb = NULL; 20 | static uint8_t wifiStatus = STATION_IDLE, lastWifiStatus = STATION_IDLE; 21 | static void ICACHE_FLASH_ATTR wifi_check_ip(void *arg) 22 | { 23 | struct ip_info ipConfig; 24 | 25 | os_timer_disarm(&WiFiLinker); 26 | wifi_get_ip_info(STATION_IF, &ipConfig); 27 | wifiStatus = wifi_station_get_connect_status(); 28 | if (wifiStatus == STATION_GOT_IP && ipConfig.ip.addr != 0) 29 | { 30 | 31 | os_timer_setfn(&WiFiLinker, (os_timer_func_t *)wifi_check_ip, NULL); 32 | os_timer_arm(&WiFiLinker, 2000, 0); 33 | 34 | 35 | } 36 | else 37 | { 38 | if(wifi_station_get_connect_status() == STATION_WRONG_PASSWORD) 39 | { 40 | 41 | INFO("STATION_WRONG_PASSWORD\r\n"); 42 | wifi_station_connect(); 43 | 44 | 45 | } 46 | else if(wifi_station_get_connect_status() == STATION_NO_AP_FOUND) 47 | { 48 | 49 | INFO("STATION_NO_AP_FOUND\r\n"); 50 | wifi_station_connect(); 51 | 52 | 53 | } 54 | else if(wifi_station_get_connect_status() == STATION_CONNECT_FAIL) 55 | { 56 | 57 | INFO("STATION_CONNECT_FAIL\r\n"); 58 | wifi_station_connect(); 59 | 60 | } 61 | else 62 | { 63 | INFO("STATION_IDLE\r\n"); 64 | } 65 | 66 | os_timer_setfn(&WiFiLinker, (os_timer_func_t *)wifi_check_ip, NULL); 67 | os_timer_arm(&WiFiLinker, 500, 0); 68 | } 69 | if(wifiStatus != lastWifiStatus){ 70 | lastWifiStatus = wifiStatus; 71 | if(wifiCb) 72 | wifiCb(wifiStatus); 73 | } 74 | } 75 | 76 | void ICACHE_FLASH_ATTR WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback cb) 77 | { 78 | struct station_config stationConf; 79 | 80 | INFO("WIFI_INIT\r\n"); 81 | wifi_set_opmode_current(STATION_MODE); 82 | 83 | //wifi_station_set_auto_connect(FALSE); 84 | wifiCb = cb; 85 | 86 | os_memset(&stationConf, 0, sizeof(struct station_config)); 87 | 88 | os_sprintf(stationConf.ssid, "%s", ssid); 89 | os_sprintf(stationConf.password, "%s", pass); 90 | 91 | wifi_station_set_config_current(&stationConf); 92 | 93 | os_timer_disarm(&WiFiLinker); 94 | os_timer_setfn(&WiFiLinker, (os_timer_func_t *)wifi_check_ip, NULL); 95 | os_timer_arm(&WiFiLinker, 1000, 0); 96 | 97 | //wifi_station_set_auto_connect(TRUE); 98 | wifi_station_connect(); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /Processing/PublishToLcd/PublishToLcd.pde: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * A really simple processing app 4 | * Requires controlP5 and https://github.com/256dpi/processing-mqtt 5 | */ 6 | 7 | import mqtt.*; 8 | import controlP5.*; 9 | 10 | ControlP5 cp5; 11 | String mqttServer = "192.168.0.43"; 12 | 13 | MQTTClient client; 14 | 15 | void setup() { 16 | size(335,370); 17 | 18 | PFont font = createFont("arial",20); 19 | cp5 = new ControlP5(this); 20 | 21 | int yPos = 25; 22 | int yDelta = 40; 23 | for (int i=0; i<6; i++) { 24 | cp5.addTextfield("line" + i) 25 | .setPosition(20,yPos) 26 | .setSize(200,35) 27 | .setLabel("") 28 | .setFont(createFont("arial",20)) 29 | .setAutoClear(false) 30 | ; 31 | 32 | cp5.addBang("publishLine" + i) 33 | .setPosition(240,yPos) 34 | .setSize(80,35) 35 | .setLabel("send") 36 | .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER) 37 | ; 38 | yPos += yDelta; 39 | } 40 | 41 | yPos += 15; 42 | cp5.addTextfield("contrastField") 43 | .setPosition(20,yPos) 44 | .setSize(200,35) 45 | .setFont(createFont("arial",20)) 46 | .setAutoClear(false) 47 | ; 48 | 49 | cp5.addBang("publishContrast") 50 | .setPosition(240,yPos) 51 | .setSize(80,35) 52 | .setLabel("Set Contrast") 53 | .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER) 54 | ; 55 | textFont(font); 56 | 57 | client = new MQTTClient(this); 58 | client.connect("mqtt://" + mqttServer, "processing"); 59 | } 60 | 61 | void draw() {} 62 | 63 | public void publishLine0() { 64 | client.publish("/lcd0", cp5.get(Textfield.class,"line0").getText()); 65 | } 66 | 67 | public void publishLine1() { 68 | client.publish("/lcd1", cp5.get(Textfield.class,"line1").getText()); 69 | } 70 | 71 | public void publishLine2() { 72 | client.publish("/lcd2", cp5.get(Textfield.class,"line2").getText()); 73 | } 74 | 75 | public void publishLine3() { 76 | client.publish("/lcd3", cp5.get(Textfield.class,"line3").getText()); 77 | } 78 | 79 | public void publishLine4() { 80 | client.publish("/lcd4", cp5.get(Textfield.class,"line4").getText()); 81 | } 82 | 83 | public void publishLine5() { 84 | client.publish("/lcd5", cp5.get(Textfield.class,"line5").getText()); 85 | } 86 | 87 | public void publishContrast() { 88 | int contrast = int(cp5.get(Textfield.class,"contrastField").getText()); 89 | if (contrast < 55) { 90 | contrast = 55; 91 | } else if (contrast > 60) { 92 | contrast = 60; 93 | } 94 | cp5.get(Textfield.class,"contrastField").setText(""+contrast); 95 | client.publish("/lcd/contrast", ""+contrast); 96 | } -------------------------------------------------------------------------------- /mqtt/include/driver/uart.h: -------------------------------------------------------------------------------- 1 | #ifndef UART_APP_H 2 | #define UART_APP_H 3 | 4 | #include "uart_register.h" 5 | #include "eagle_soc.h" 6 | #include "c_types.h" 7 | 8 | #define RX_BUFF_SIZE 256 9 | #define TX_BUFF_SIZE 100 10 | #define UART0 0 11 | #define UART1 1 12 | 13 | typedef enum { 14 | FIVE_BITS = 0x0, 15 | SIX_BITS = 0x1, 16 | SEVEN_BITS = 0x2, 17 | EIGHT_BITS = 0x3 18 | } UartBitsNum4Char; 19 | 20 | typedef enum { 21 | ONE_STOP_BIT = 0, 22 | ONE_HALF_STOP_BIT = BIT2, 23 | TWO_STOP_BIT = BIT2 24 | } UartStopBitsNum; 25 | 26 | typedef enum { 27 | NONE_BITS = 0, 28 | ODD_BITS = 0, 29 | EVEN_BITS = BIT4 30 | } UartParityMode; 31 | 32 | typedef enum { 33 | STICK_PARITY_DIS = 0, 34 | STICK_PARITY_EN = BIT3 | BIT5 35 | } UartExistParity; 36 | 37 | typedef enum { 38 | BIT_RATE_9600 = 9600, 39 | BIT_RATE_19200 = 19200, 40 | BIT_RATE_38400 = 38400, 41 | BIT_RATE_57600 = 57600, 42 | BIT_RATE_74880 = 74880, 43 | BIT_RATE_115200 = 115200, 44 | BIT_RATE_230400 = 230400, 45 | BIT_RATE_256000 = 256000, 46 | BIT_RATE_460800 = 460800, 47 | BIT_RATE_921600 = 921600 48 | } UartBautRate; 49 | 50 | typedef enum { 51 | NONE_CTRL, 52 | HARDWARE_CTRL, 53 | XON_XOFF_CTRL 54 | } UartFlowCtrl; 55 | 56 | typedef enum { 57 | EMPTY, 58 | UNDER_WRITE, 59 | WRITE_OVER 60 | } RcvMsgBuffState; 61 | 62 | typedef struct { 63 | uint32 RcvBuffSize; 64 | uint8 *pRcvMsgBuff; 65 | uint8 *pWritePos; 66 | uint8 *pReadPos; 67 | uint8 TrigLvl; //JLU: may need to pad 68 | RcvMsgBuffState BuffState; 69 | } RcvMsgBuff; 70 | 71 | typedef struct { 72 | uint32 TrxBuffSize; 73 | uint8 *pTrxBuff; 74 | } TrxMsgBuff; 75 | 76 | typedef enum { 77 | BAUD_RATE_DET, 78 | WAIT_SYNC_FRM, 79 | SRCH_MSG_HEAD, 80 | RCV_MSG_BODY, 81 | RCV_ESC_CHAR, 82 | } RcvMsgState; 83 | 84 | typedef struct { 85 | UartBautRate baut_rate; 86 | UartBitsNum4Char data_bits; 87 | UartExistParity exist_parity; 88 | UartParityMode parity; // chip size in byte 89 | UartStopBitsNum stop_bits; 90 | UartFlowCtrl flow_ctrl; 91 | RcvMsgBuff rcv_buff; 92 | TrxMsgBuff trx_buff; 93 | RcvMsgState rcv_state; 94 | int received; 95 | int buff_uart_no; //indicate which uart use tx/rx buffer 96 | } UartDevice; 97 | 98 | void uart_init(UartBautRate uart0_br, UartBautRate uart1_br); 99 | void uart0_sendStr(const char *str); 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esp_mqtt_lcd 2 | 3 | ESP8266 displaying mqtt messages on a Nokia 5110 LCD 4 | 5 | I'm pulling in several git subtree modules : 6 | * [tuanpmt's exellent mqtt project: esp_mqtt](https://github.com/tuanpmt/esp_mqtt) 7 | * [esp8266_pcd8544](https://github.com/eadf/esp8266_pcd8544) the lcd driver 8 | * [esp8266_easygpio](https://github.com/eadf/esp8266_easygpio) makes it easy to change GPIO pins 9 | * [esp8266_stdout](https://github.com/eadf/esp8266_stdout) alternative UART implementation (required if you want to connect the lcd with only 3 pins) 10 | 11 | Good news, the interface no longer requires 5 available GPIO outputs so an ESP-01 will indeed work. (But only if the RX pin of the esp is used.) 12 | 13 | ##Usage 14 | To use this mqtt enabled LCD you can send text messages to these topics: 15 | * /lcd0 16 | * /lcd1 17 | * /lcd2 18 | * /lcd3 19 | * /lcd4 20 | * /lcd5 21 | 22 | Representing each row of the display. 23 | 24 | The LCD is also listening to these topics: 25 | * /lcd/clearscreen 26 | * /lcd/contrast 27 | 28 | You can also send messages to topics that are unique to each *esp*, look at the debug console for more info. 29 | 30 | ### Pin configuraton 31 | 32 | This is how the code is hooked up by default: 33 | 34 | PCD8544| ESP8266 35 | -------|------------------ 36 | RST Pin 1 | GPIO4 37 | CE Pin 2 | GPIO5 38 | DC Pin 3 | GPIO12 39 | Din Pin 4 | GPIO13 40 | Clk Pin 5 | GPIO14 41 | 42 | Some ESP-12 have GPIO4 & GPIO5 reversed. 43 | 44 | The RST pin is optional, set it to a negative value and tie PCD8544 reset to ESP reset via a resistor. 45 | 46 | The CE pin is optional, set it to a negative value and tie PCD8544 CE pin to GND via a resistor. 47 | 48 | All of the pins are configurable, you just set the pins you want to use in the setting struct. 49 | 50 | The makefile is copied from [esp_mqtt.](https://github.com/tuanpmt/esp_mqtt) 51 | 52 | ###Building and installing: 53 | 54 | First you need to install the sdk and the easy way of doing that is to use [esp_open_sdk.](https://github.com/pfalcon/esp-open-sdk) 55 | 56 | You can put that anywhere you like (/opt/local/esp-open-sdk, /esptools etc etc) 57 | 58 | Then you could create a small ```setenv.sh``` file, containing the location of your newly compiled sdk and other platform specific info; 59 | ``` 60 | export SDK_BASE=/opt/local/esp-open-sdk/sdk 61 | export PATH=${SDK_BASE}/../xtensa-lx106-elf/bin:${PATH} 62 | export ESPPORT=/dev/ttyO0 63 | ``` 64 | (or setup your IDE to do the same) 65 | 66 | You will have to edit the ```include/user_config.h``` file to suit your WiFi and mqtt settings. Alternatively you can copy ```include/user_config.h``` into ```localinclude/user_config.h``` and git will not bother you about modified files. 67 | 68 | To make a clean build, flash and connect to the esp console you just do this in a shell: 69 | ``` 70 | source setenv.sh # This is only needed once per session 71 | make clean && make test 72 | ``` 73 | 74 | You won't be needing esptool, the makefile only uses esptool.py (provided by esp-open-sdk) 75 | 76 | I have tested this with sdk 1.5.2, v0.9.5 and v0.9.4 (linux & mac) 77 | -------------------------------------------------------------------------------- /driver/easygpio/examples/readgpio/user/user_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, eadf (https://github.com/eadf) 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of Redis nor the names of its contributors may be used 14 | * to endorse or promote products derived from this software without 15 | * specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include "gpio.h" 33 | #include "easygpio/easygpio.h" 34 | #include "stdout/stdout.h" 35 | 36 | #define SAMPLE_PERIOD 750 // 750 ms 37 | static os_timer_t loop_timer; 38 | uint8_t pinsToTest[] = {0,2,3,4,5,12,13,14,15,16}; 39 | uint8_t pinsToTestLen = 10; 40 | 41 | static void ICACHE_FLASH_ATTR 42 | loop(void) { 43 | uint8_t i=0; 44 | for (i=0; ibuf = buf; 6 | parser->bufSize = bufSize; 7 | parser->dataLen = 0; 8 | parser->callback = completeCallback; 9 | parser->isEsc = 0; 10 | return 0; 11 | } 12 | 13 | I8 ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, U8 value) 14 | { 15 | switch(value){ 16 | case 0x7D: 17 | parser->isEsc = 1; 18 | break; 19 | 20 | case 0x7E: 21 | parser->dataLen = 0; 22 | parser->isEsc = 0; 23 | parser->isBegin = 1; 24 | break; 25 | 26 | case 0x7F: 27 | if (parser->callback != NULL) 28 | parser->callback(); 29 | parser->isBegin = 0; 30 | return 0; 31 | break; 32 | 33 | default: 34 | if(parser->isBegin == 0) break; 35 | 36 | if(parser->isEsc){ 37 | value ^= 0x20; 38 | parser->isEsc = 0; 39 | } 40 | 41 | if(parser->dataLen < parser->bufSize) 42 | parser->buf[parser->dataLen++] = value; 43 | 44 | break; 45 | } 46 | return -1; 47 | } 48 | 49 | I8 ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, U8 *buf, U16 len) 50 | { 51 | while(len--) 52 | PROTO_ParseByte(parser, *buf++); 53 | 54 | return 0; 55 | } 56 | I16 ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF* rb, U8 *bufOut, U16* len, U16 maxBufLen) 57 | { 58 | U8 c; 59 | 60 | PROTO_PARSER proto; 61 | PROTO_Init(&proto, NULL, bufOut, maxBufLen); 62 | while(RINGBUF_Get(rb, &c) == 0){ 63 | if(PROTO_ParseByte(&proto, c) == 0){ 64 | *len = proto.dataLen; 65 | return 0; 66 | } 67 | } 68 | return -1; 69 | } 70 | I16 ICACHE_FLASH_ATTR PROTO_Add(U8 *buf, const U8 *packet, I16 bufSize) 71 | { 72 | U16 i = 2; 73 | U16 len = *(U16*) packet; 74 | 75 | if (bufSize < 1) return -1; 76 | 77 | *buf++ = 0x7E; 78 | bufSize--; 79 | 80 | while (len--) { 81 | switch (*packet) { 82 | case 0x7D: 83 | case 0x7E: 84 | case 0x7F: 85 | if (bufSize < 2) return -1; 86 | *buf++ = 0x7D; 87 | *buf++ = *packet++ ^ 0x20; 88 | i += 2; 89 | bufSize -= 2; 90 | break; 91 | default: 92 | if (bufSize < 1) return -1; 93 | *buf++ = *packet++; 94 | i++; 95 | bufSize--; 96 | break; 97 | } 98 | } 99 | 100 | if (bufSize < 1) return -1; 101 | *buf++ = 0x7F; 102 | 103 | return i; 104 | } 105 | 106 | I16 ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const U8 *packet, I16 len) 107 | { 108 | U16 i = 2; 109 | if(RINGBUF_Put(rb, 0x7E) == -1) return -1; 110 | while (len--) { 111 | switch (*packet) { 112 | case 0x7D: 113 | case 0x7E: 114 | case 0x7F: 115 | if(RINGBUF_Put(rb, 0x7D) == -1) return -1; 116 | if(RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1; 117 | i += 2; 118 | break; 119 | default: 120 | if(RINGBUF_Put(rb, *packet++) == -1) return -1; 121 | i++; 122 | break; 123 | } 124 | } 125 | if(RINGBUF_Put(rb, 0x7F) == -1) return -1; 126 | 127 | return i; 128 | } 129 | 130 | -------------------------------------------------------------------------------- /driver/easygpio/examples/writegpio/user/user_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, eadf (https://github.com/eadf) 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of Redis nor the names of its contributors may be used 14 | * to endorse or promote products derived from this software without 15 | * specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include "gpio.h" 33 | #include "easygpio/easygpio.h" 34 | #include "stdout/stdout.h" 35 | 36 | #define SAMPLE_PERIOD 200 // 200 ms 37 | static os_timer_t dht22_timer; 38 | uint8_t pinsToTest[] = {0,2,4,5,12,13,14,15,16}; 39 | uint8_t pinsToTestLen = 9; 40 | 41 | static void ICACHE_FLASH_ATTR 42 | loop(void) { 43 | // set this shift-rotating pattern to anything you like 44 | static uint32_t shiftReg = 1;//0b101010101; 45 | uint8_t i=0; 46 | os_printf("Setting "); 47 | for (i=0; i> i) & 0x1; 49 | os_printf("GPIO%d=%d", pinsToTest[i], flag); 50 | easygpio_outputSet(pinsToTest[i], flag); 51 | //easygpio_outputEnable(pinsToTest[i], flag); 52 | if(i> 1); 62 | } 63 | 64 | void ICACHE_FLASH_ATTR 65 | setup(void) { 66 | uint8_t i=0; 67 | for (i=0; i 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | #include "ets_sys.h" 32 | #include "os_type.h" 33 | #include "mem.h" 34 | #include "osapi.h" 35 | #include "user_interface.h" 36 | 37 | #include "mqtt.h" 38 | #include "config.h" 39 | #include "user_config.h" 40 | #include "debug.h" 41 | 42 | SYSCFG sysCfg; 43 | SAVE_FLAG saveFlag; 44 | 45 | void ICACHE_FLASH_ATTR 46 | CFG_Save() 47 | { 48 | spi_flash_read((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE, 49 | (uint32 *)&saveFlag, sizeof(SAVE_FLAG)); 50 | 51 | if (saveFlag.flag == 0) { 52 | spi_flash_erase_sector(CFG_LOCATION + 1); 53 | spi_flash_write((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE, 54 | (uint32 *)&sysCfg, sizeof(SYSCFG)); 55 | saveFlag.flag = 1; 56 | spi_flash_erase_sector(CFG_LOCATION + 3); 57 | spi_flash_write((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE, 58 | (uint32 *)&saveFlag, sizeof(SAVE_FLAG)); 59 | } else { 60 | spi_flash_erase_sector(CFG_LOCATION + 0); 61 | spi_flash_write((CFG_LOCATION + 0) * SPI_FLASH_SEC_SIZE, 62 | (uint32 *)&sysCfg, sizeof(SYSCFG)); 63 | saveFlag.flag = 0; 64 | spi_flash_erase_sector(CFG_LOCATION + 3); 65 | spi_flash_write((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE, 66 | (uint32 *)&saveFlag, sizeof(SAVE_FLAG)); 67 | } 68 | } 69 | 70 | void ICACHE_FLASH_ATTR 71 | CFG_Load() 72 | { 73 | 74 | INFO("\r\nload ...\r\n"); 75 | spi_flash_read((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE, 76 | (uint32 *)&saveFlag, sizeof(SAVE_FLAG)); 77 | if (saveFlag.flag == 0) { 78 | spi_flash_read((CFG_LOCATION + 0) * SPI_FLASH_SEC_SIZE, 79 | (uint32 *)&sysCfg, sizeof(SYSCFG)); 80 | } else { 81 | spi_flash_read((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE, 82 | (uint32 *)&sysCfg, sizeof(SYSCFG)); 83 | } 84 | if(sysCfg.cfg_holder != CFG_HOLDER){ 85 | os_memset(&sysCfg, 0x00, sizeof sysCfg); 86 | 87 | 88 | sysCfg.cfg_holder = CFG_HOLDER; 89 | 90 | os_sprintf(sysCfg.sta_ssid, "%s", STA_SSID); 91 | os_sprintf(sysCfg.sta_pwd, "%s", STA_PASS); 92 | sysCfg.sta_type = STA_TYPE; 93 | 94 | os_sprintf(sysCfg.device_id, MQTT_CLIENT_ID, system_get_chip_id()); 95 | os_sprintf(sysCfg.mqtt_host, "%s", MQTT_HOST); 96 | sysCfg.mqtt_port = MQTT_PORT; 97 | os_sprintf(sysCfg.mqtt_user, "%s", MQTT_USER); 98 | os_sprintf(sysCfg.mqtt_pass, "%s", MQTT_PASS); 99 | 100 | sysCfg.security = DEFAULT_SECURITY; /* default non ssl */ 101 | 102 | sysCfg.mqtt_keepalive = MQTT_KEEPALIVE; 103 | 104 | INFO(" default configuration\r\n"); 105 | 106 | CFG_Save(); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /driver/easygpio/README.md: -------------------------------------------------------------------------------- 1 | # esp8266_easygpio 2 | An easy way of setting up esp8266 GPIO pins. 3 | 4 | I grew tired of juggling gpio pin numbers, gpio names and gpio functions. So i created this little helper library. 5 | 6 | To setup a pin as a GPIO input you can now just do this: 7 | 8 | ``` 9 | #include "easygpio/easygpio.h" 10 | ... 11 | bool easygpio_pinMode(0, EASYGPIO_NOPULL, EASYGPIO_INPUT); 12 | ``` 13 | 14 | Same thing with outputs: 15 | ``` 16 | bool easygpio_pinMode(1, EASYGPIO_NOPULL, EASYGPIO_OUTPUT); 17 | ``` 18 | pullStatus does not apply to output pins. 19 | 20 | You might still need the gpio_name and func. No problem: 21 | ``` 22 | bool easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func) 23 | ``` 24 | 25 | You can even setup an interrupt handler: 26 | ``` 27 | bool easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void* arg), void *interruptArg) 28 | ``` 29 | 30 | You can use the methods and macros defined in gpio.h (from the sdk) to access the 'standard' gpio pins (not GPIO16). 31 | ``` 32 | #include "gpio.h" 33 | ... 34 | GPIO_OUTPUT_SET(gpio_no, bit_value) // GPIO_OUTPUT_SET(0,1) sets gpio0 to high 35 | GPIO_DIS_OUTPUT(gpio_no) // GPIO_DIS_OUTPUT(2) turns off output on gpio2 36 | GPIO_INPUT_GET(gpio_no) // GPIO_INPUT_GET(12) returns the input value of gpio12 37 | ``` 38 | 39 | To access *all* of the pins in an uniform way you can use 40 | ``` 41 | uint8_t easygpio_inputGet(uint8_t gpio_pin); 42 | void easygpio_outputSet(uint8_t gpio_pin, uint8_t value); 43 | ``` 44 | However, you should not rely on that these methods will change input/output status of a pin (like the gpio.h macros does). 45 | 46 | e.g. if you call ```easygpio_outputSet``` on an input pin, the pin may or may not remain an input. This is because of performance and uniformity reasons. ```easygpio_outputSet(16,1)``` will never flip gpio16 to an output, and we can't have access methods with different semantics depending on pin number). 47 | 48 | So if you need to change the input/output mode of a pin on the fly, you can use ```easygpio_outputDisable()``` or ```easygpio_outputEnable()```. 49 | 50 | ###Available pins 51 | 52 | Pin number | Note 53 | -----------|------ 54 | GPIO0 | this pin selects bootmode [(pull up for *normal* boot)](https://github.com/esp8266/esp8266-wiki/wiki/Boot-Process#esp-boot-modes) 55 | GPIO1 | normally UART0 TX 56 | GPIO2 | this pin selects bootmode [(pull up for *normal* boot)](https://github.com/esp8266/esp8266-wiki/wiki/Boot-Process#esp-boot-modes) 57 | GPIO3 | normally UART0 RX (you can use [stdout](https://github.com/eadf/esp8266_stdout) to use it as GPIO) 58 | GPIO4 | sometimes mislabeled as GPIO5 (esp-12) 59 | GPIO5 | sometimes mislabeled as GPIO4 (esp-12) 60 | GPIO12 | 61 | GPIO13 | 62 | GPIO14 | 63 | GPIO15 | this pin selects bootmode [(pull down for *normal* boot)](https://github.com/esp8266/esp8266-wiki/wiki/Boot-Process#esp-boot-modes) 64 | GPIO16 | requires easygpio_inputGet() & easygpio_outputSet() access methods (no interrupt on this pin) 65 | 66 | All the GPIOs mentioned in ```easgle_soc.h``` are supported, but maybe we should not mess with the internal SPI pins for GPIO. 67 | 68 | ## Usage 69 | 70 | The project has been designed for easy reuse, just create a folder with these files in it ([git subtree](http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree) works great for that purpose). Then point your ```MODULES``` variable (or whatever subdirectory construct you use) in the ```Makefile``` to that folder . If you find yourself manually copying these individial .c and .h files - you're doing it wrong. 71 | 72 | See an example on how this library can be used [here](https://github.com/eadf/esp8266_digoleserial), [here](https://github.com/eadf/esp_mqtt_lcd), [here](https://github.com/eadf/esp8266_ping), [here](https://github.com/eadf/esp_mqtt_ports) - bha.. practically all of my esp projects uses it. 73 | 74 | ## Todo 75 | * Find the correct ```READ_PERI_REG()``` address for ```easygpio_inputGet()```, now it's simply using ```GPIO_INPUT_GET()``` 76 | 77 | ## Required: 78 | 79 | esp-open-sdk-1.5.2 or higher. 80 | 81 | I've successfully tested this with sdk v0.9.5 (linux & mac). 82 | -------------------------------------------------------------------------------- /mqtt/user/user_main.c: -------------------------------------------------------------------------------- 1 | /* main.c -- MQTT client example 2 | * 3 | * Copyright (c) 2014-2015, Tuan PM 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "ets_sys.h" 31 | #include "driver/uart.h" 32 | #include "osapi.h" 33 | #include "mqtt.h" 34 | #include "wifi.h" 35 | #include "config.h" 36 | #include "debug.h" 37 | #include "gpio.h" 38 | #include "user_interface.h" 39 | #include "mem.h" 40 | 41 | MQTT_Client mqttClient; 42 | 43 | void wifiConnectCb(uint8_t status) 44 | { 45 | if(status == STATION_GOT_IP){ 46 | MQTT_Connect(&mqttClient); 47 | } else { 48 | MQTT_Disconnect(&mqttClient); 49 | } 50 | } 51 | void mqttConnectedCb(uint32_t *args) 52 | { 53 | MQTT_Client* client = (MQTT_Client*)args; 54 | INFO("MQTT: Connected\r\n"); 55 | MQTT_Subscribe(client, "/mqtt/topic/0", 0); 56 | MQTT_Subscribe(client, "/mqtt/topic/1", 1); 57 | MQTT_Subscribe(client, "/mqtt/topic/2", 2); 58 | 59 | MQTT_Publish(client, "/mqtt/topic/0", "hello0", 6, 0, 0); 60 | MQTT_Publish(client, "/mqtt/topic/1", "hello1", 6, 1, 0); 61 | MQTT_Publish(client, "/mqtt/topic/2", "hello2", 6, 2, 0); 62 | 63 | } 64 | 65 | void mqttDisconnectedCb(uint32_t *args) 66 | { 67 | MQTT_Client* client = (MQTT_Client*)args; 68 | INFO("MQTT: Disconnected\r\n"); 69 | } 70 | 71 | void mqttPublishedCb(uint32_t *args) 72 | { 73 | MQTT_Client* client = (MQTT_Client*)args; 74 | INFO("MQTT: Published\r\n"); 75 | } 76 | 77 | void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) 78 | { 79 | char *topicBuf = (char*)os_zalloc(topic_len+1), 80 | *dataBuf = (char*)os_zalloc(data_len+1); 81 | 82 | MQTT_Client* client = (MQTT_Client*)args; 83 | 84 | os_memcpy(topicBuf, topic, topic_len); 85 | topicBuf[topic_len] = 0; 86 | 87 | os_memcpy(dataBuf, data, data_len); 88 | dataBuf[data_len] = 0; 89 | 90 | INFO("Receive topic: %s, data: %s \r\n", topicBuf, dataBuf); 91 | os_free(topicBuf); 92 | os_free(dataBuf); 93 | } 94 | 95 | 96 | void user_init(void) 97 | { 98 | uart_init(BIT_RATE_115200, BIT_RATE_115200); 99 | os_delay_us(1000000); 100 | 101 | CFG_Load(); 102 | 103 | MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.security); 104 | //MQTT_InitConnection(&mqttClient, "192.168.11.122", 1880, 0); 105 | 106 | MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive, 1); 107 | //MQTT_InitClient(&mqttClient, "client_id", "user", "pass", 120, 1); 108 | 109 | MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); 110 | MQTT_OnConnected(&mqttClient, mqttConnectedCb); 111 | MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb); 112 | MQTT_OnPublished(&mqttClient, mqttPublishedCb); 113 | MQTT_OnData(&mqttClient, mqttDataCb); 114 | 115 | WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb); 116 | 117 | INFO("\r\nSystem started ...\r\n"); 118 | } 119 | -------------------------------------------------------------------------------- /driver/easygpio/include/easygpio/easygpio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * easygpio.h 3 | * 4 | * Copyright (c) 2015, eadf (https://github.com/eadf) 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #ifndef EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ 33 | #define EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ 34 | 35 | #include "c_types.h" 36 | 37 | typedef enum { 38 | EASYGPIO_INPUT=0, 39 | EASYGPIO_OUTPUT=1 40 | } EasyGPIO_PinMode; 41 | 42 | typedef enum { 43 | EASYGPIO_PULLUP=3, 44 | EASYGPIO_NOPULL=4 45 | } EasyGPIO_PullStatus; 46 | 47 | /** 48 | * Returns the gpio name and func for a specific pin. 49 | */ 50 | bool easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func); 51 | 52 | /** 53 | * Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin. 54 | * The 'interruptArg' is the function argument that will be sent to your interruptHandler 55 | * (this way you can several interrupts with one interruptHandler) 56 | */ 57 | bool easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void *arg), void *interruptArg); 58 | 59 | /** 60 | * Deatach the interrupt handler from the 'gpio_pin' pin. 61 | */ 62 | bool easygpio_detachInterrupt(uint8_t gpio_pin); 63 | 64 | /** 65 | * Returns the number of active pins in the gpioMask. 66 | */ 67 | uint8_t easygpio_countBits(uint32_t gpioMask); 68 | 69 | /** 70 | * Sets the 'gpio_pin' pin as a GPIO and enables/disables the pull-up on that pin. 71 | * 'pullStatus' has no effect on output pins or GPIO16 72 | */ 73 | bool easygpio_pinMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, EasyGPIO_PinMode pinMode); 74 | 75 | /** 76 | * Enable or disable the internal pull up for a pin. 77 | */ 78 | bool easygpio_pullMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus); 79 | 80 | /** 81 | * Uniform way of getting GPIO input value. Handles GPIO 0-16. 82 | * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. 83 | * If you know that you won't be using GPIO16 then you'd better off by just using GPIO_INPUT_GET(). 84 | */ 85 | uint8_t easygpio_inputGet(uint8_t gpio_pin); 86 | 87 | /** 88 | * Uniform way of setting GPIO output value. Handles GPIO 0-16. 89 | * 90 | * You can not rely on that this function will switch the gpio to an output like GPIO_OUTPUT_SET does. 91 | * Use easygpio_outputEnable() to change an input gpio to output mode. 92 | */ 93 | void easygpio_outputSet(uint8_t gpio_pin, uint8_t value); 94 | 95 | /** 96 | * Uniform way of turning an output GPIO pin into input mode. Handles GPIO 0-16. 97 | * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. 98 | * This function does the same thing as GPIO_DIS_OUTPUT, but works on GPIO16 too. 99 | */ 100 | void easygpio_outputDisable(uint8_t gpio_pin); 101 | 102 | /** 103 | * Uniform way of turning an input GPIO pin into output mode. Handles GPIO 0-16. 104 | * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. 105 | * 106 | * This function: 107 | * - should only be used to convert a input pin into an output pin. 108 | * - is a little bit slower than easygpio_outputSet() so you should use that 109 | * function to just change output value. 110 | * - does the same thing as GPIO_OUTPUT_SET, but works on GPIO16 too. 111 | */ 112 | void easygpio_outputEnable(uint8_t gpio_pin, uint8_t value); 113 | 114 | #endif /* EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ */ 115 | -------------------------------------------------------------------------------- /mqtt/mqtt/utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Tuan PM 3 | * Email: tuanpm@live.com 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of the copyright holder nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "utils.h" 39 | 40 | 41 | uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str) 42 | { 43 | uint8_t segs = 0; /* Segment count. */ 44 | uint8_t chcnt = 0; /* Character count within segment. */ 45 | uint8_t accum = 0; /* Accumulator for segment. */ 46 | /* Catch NULL pointer. */ 47 | if (str == 0) 48 | return 0; 49 | /* Process every character in string. */ 50 | 51 | while (*str != '\0') { 52 | /* Segment changeover. */ 53 | 54 | if (*str == '.') { 55 | /* Must have some digits in segment. */ 56 | if (chcnt == 0) 57 | return 0; 58 | /* Limit number of segments. */ 59 | if (++segs == 4) 60 | return 0; 61 | /* Reset segment values and restart loop. */ 62 | chcnt = accum = 0; 63 | str++; 64 | continue; 65 | } 66 | 67 | /* Check numeric. */ 68 | if ((*str < '0') || (*str > '9')) 69 | return 0; 70 | 71 | /* Accumulate and check segment. */ 72 | 73 | if ((accum = accum * 10 + *str - '0') > 255) 74 | return 0; 75 | /* Advance other segment specific stuff and continue loop. */ 76 | 77 | chcnt++; 78 | str++; 79 | } 80 | 81 | /* Check enough segments and enough characters in last segment. */ 82 | 83 | if (segs != 3) 84 | return 0; 85 | if (chcnt == 0) 86 | return 0; 87 | /* Address okay. */ 88 | 89 | return 1; 90 | } 91 | uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip) 92 | { 93 | 94 | /* The count of the number of bytes processed. */ 95 | int i; 96 | /* A pointer to the next digit to process. */ 97 | const char * start; 98 | 99 | start = str; 100 | for (i = 0; i < 4; i++) { 101 | /* The digit being processed. */ 102 | char c; 103 | /* The value of this byte. */ 104 | int n = 0; 105 | while (1) { 106 | c = * start; 107 | start++; 108 | if (c >= '0' && c <= '9') { 109 | n *= 10; 110 | n += c - '0'; 111 | } 112 | /* We insist on stopping at "." if we are still parsing 113 | the first, second, or third numbers. If we have reached 114 | the end of the numbers, we will allow any character. */ 115 | else if ((i < 3 && c == '.') || i == 3) { 116 | break; 117 | } 118 | else { 119 | return 0; 120 | } 121 | } 122 | if (n >= 256) { 123 | return 0; 124 | } 125 | ((uint8_t*)ip)[i] = n; 126 | } 127 | return 1; 128 | 129 | } 130 | uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s) 131 | { 132 | uint32_t value = 0, digit; 133 | int8_t c; 134 | 135 | while((c = *s++)){ 136 | if('0' <= c && c <= '9') 137 | digit = c - '0'; 138 | else if('A' <= c && c <= 'F') 139 | digit = c - 'A' + 10; 140 | else if('a' <= c && c<= 'f') 141 | digit = c - 'a' + 10; 142 | else break; 143 | 144 | value = (value << 4) | digit; 145 | } 146 | 147 | return value; 148 | } 149 | 150 | -------------------------------------------------------------------------------- /mqtt/include/driver/uart_register.h: -------------------------------------------------------------------------------- 1 | //Generated at 2012-07-03 18:44:06 2 | /* 3 | * Copyright (c) 2010 - 2011 Espressif System 4 | * 5 | */ 6 | 7 | #ifndef UART_REGISTER_H_INCLUDED 8 | #define UART_REGISTER_H_INCLUDED 9 | #define REG_UART_BASE( i ) (0x60000000+(i)*0xf00) 10 | //version value:32'h062000 11 | 12 | #define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) 13 | #define UART_RXFIFO_RD_BYTE 0x000000FF 14 | #define UART_RXFIFO_RD_BYTE_S 0 15 | 16 | #define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4) 17 | #define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) 18 | #define UART_BRK_DET_INT_RAW (BIT(7)) 19 | #define UART_CTS_CHG_INT_RAW (BIT(6)) 20 | #define UART_DSR_CHG_INT_RAW (BIT(5)) 21 | #define UART_RXFIFO_OVF_INT_RAW (BIT(4)) 22 | #define UART_FRM_ERR_INT_RAW (BIT(3)) 23 | #define UART_PARITY_ERR_INT_RAW (BIT(2)) 24 | #define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) 25 | #define UART_RXFIFO_FULL_INT_RAW (BIT(0)) 26 | 27 | #define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) 28 | #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) 29 | #define UART_BRK_DET_INT_ST (BIT(7)) 30 | #define UART_CTS_CHG_INT_ST (BIT(6)) 31 | #define UART_DSR_CHG_INT_ST (BIT(5)) 32 | #define UART_RXFIFO_OVF_INT_ST (BIT(4)) 33 | #define UART_FRM_ERR_INT_ST (BIT(3)) 34 | #define UART_PARITY_ERR_INT_ST (BIT(2)) 35 | #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) 36 | #define UART_RXFIFO_FULL_INT_ST (BIT(0)) 37 | 38 | #define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) 39 | #define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) 40 | #define UART_BRK_DET_INT_ENA (BIT(7)) 41 | #define UART_CTS_CHG_INT_ENA (BIT(6)) 42 | #define UART_DSR_CHG_INT_ENA (BIT(5)) 43 | #define UART_RXFIFO_OVF_INT_ENA (BIT(4)) 44 | #define UART_FRM_ERR_INT_ENA (BIT(3)) 45 | #define UART_PARITY_ERR_INT_ENA (BIT(2)) 46 | #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) 47 | #define UART_RXFIFO_FULL_INT_ENA (BIT(0)) 48 | 49 | #define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) 50 | #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) 51 | #define UART_BRK_DET_INT_CLR (BIT(7)) 52 | #define UART_CTS_CHG_INT_CLR (BIT(6)) 53 | #define UART_DSR_CHG_INT_CLR (BIT(5)) 54 | #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) 55 | #define UART_FRM_ERR_INT_CLR (BIT(3)) 56 | #define UART_PARITY_ERR_INT_CLR (BIT(2)) 57 | #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) 58 | #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) 59 | 60 | #define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14) 61 | #define UART_CLKDIV_CNT 0x000FFFFF 62 | #define UART_CLKDIV_S 0 63 | 64 | #define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18) 65 | #define UART_GLITCH_FILT 0x000000FF 66 | #define UART_GLITCH_FILT_S 8 67 | #define UART_AUTOBAUD_EN (BIT(0)) 68 | 69 | #define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C) 70 | #define UART_TXD (BIT(31)) 71 | #define UART_RTSN (BIT(30)) 72 | #define UART_DTRN (BIT(29)) 73 | #define UART_TXFIFO_CNT 0x000000FF 74 | #define UART_TXFIFO_CNT_S 16 75 | #define UART_RXD (BIT(15)) 76 | #define UART_CTSN (BIT(14)) 77 | #define UART_DSRN (BIT(13)) 78 | #define UART_RXFIFO_CNT 0x000000FF 79 | #define UART_RXFIFO_CNT_S 0 80 | 81 | #define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20) 82 | #define UART_TXFIFO_RST (BIT(18)) 83 | #define UART_RXFIFO_RST (BIT(17)) 84 | #define UART_IRDA_EN (BIT(16)) 85 | #define UART_TX_FLOW_EN (BIT(15)) 86 | #define UART_LOOPBACK (BIT(14)) 87 | #define UART_IRDA_RX_INV (BIT(13)) 88 | #define UART_IRDA_TX_INV (BIT(12)) 89 | #define UART_IRDA_WCTL (BIT(11)) 90 | #define UART_IRDA_TX_EN (BIT(10)) 91 | #define UART_IRDA_DPLX (BIT(9)) 92 | #define UART_TXD_BRK (BIT(8)) 93 | #define UART_SW_DTR (BIT(7)) 94 | #define UART_SW_RTS (BIT(6)) 95 | #define UART_STOP_BIT_NUM 0x00000003 96 | #define UART_STOP_BIT_NUM_S 4 97 | #define UART_BIT_NUM 0x00000003 98 | #define UART_BIT_NUM_S 2 99 | #define UART_PARITY_EN (BIT(1)) 100 | #define UART_PARITY (BIT(0)) 101 | 102 | #define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24) 103 | #define UART_RX_TOUT_EN (BIT(31)) 104 | #define UART_RX_TOUT_THRHD 0x0000007F 105 | #define UART_RX_TOUT_THRHD_S 24 106 | #define UART_RX_FLOW_EN (BIT(23)) 107 | #define UART_RX_FLOW_THRHD 0x0000007F 108 | #define UART_RX_FLOW_THRHD_S 16 109 | #define UART_TXFIFO_EMPTY_THRHD 0x0000007F 110 | #define UART_TXFIFO_EMPTY_THRHD_S 8 111 | #define UART_RXFIFO_FULL_THRHD 0x0000007F 112 | #define UART_RXFIFO_FULL_THRHD_S 0 113 | 114 | #define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28) 115 | #define UART_LOWPULSE_MIN_CNT 0x000FFFFF 116 | #define UART_LOWPULSE_MIN_CNT_S 0 117 | 118 | #define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C) 119 | #define UART_HIGHPULSE_MIN_CNT 0x000FFFFF 120 | #define UART_HIGHPULSE_MIN_CNT_S 0 121 | 122 | #define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30) 123 | #define UART_PULSE_NUM_CNT 0x0003FF 124 | #define UART_PULSE_NUM_CNT_S 0 125 | 126 | #define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78) 127 | #define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C) 128 | #endif // UART_REGISTER_H_INCLUDED 129 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/mqtt_msg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: mqtt_msg.h 3 | * Author: Minh Tuan 4 | * 5 | * Created on July 12, 2014, 1:05 PM 6 | */ 7 | 8 | #ifndef MQTT_MSG_H 9 | #define MQTT_MSG_H 10 | #include "mqtt_config.h" 11 | #include "c_types.h" 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /* 17 | * Copyright (c) 2014, Stephen Robinson 18 | * All rights reserved. 19 | * 20 | * Redistribution and use in source and binary forms, with or without 21 | * modification, are permitted provided that the following conditions 22 | * are met: 23 | * 24 | * 1. Redistributions of source code must retain the above copyright 25 | * notice, this list of conditions and the following disclaimer. 26 | * 2. Redistributions in binary form must reproduce the above copyright 27 | * notice, this list of conditions and the following disclaimer in the 28 | * documentation and/or other materials provided with the distribution. 29 | * 3. Neither the name of the copyright holder nor the names of its 30 | * contributors may be used to endorse or promote products derived 31 | * from this software without specific prior written permission. 32 | * 33 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 34 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 37 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 38 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 41 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43 | * POSSIBILITY OF SUCH DAMAGE. 44 | * 45 | */ 46 | /* 7 6 5 4 3 2 1 0*/ 47 | /*| --- Message Type---- | DUP Flag | QoS Level | Retain | 48 | /* Remaining Length */ 49 | 50 | 51 | enum mqtt_message_type 52 | { 53 | MQTT_MSG_TYPE_CONNECT = 1, 54 | MQTT_MSG_TYPE_CONNACK = 2, 55 | MQTT_MSG_TYPE_PUBLISH = 3, 56 | MQTT_MSG_TYPE_PUBACK = 4, 57 | MQTT_MSG_TYPE_PUBREC = 5, 58 | MQTT_MSG_TYPE_PUBREL = 6, 59 | MQTT_MSG_TYPE_PUBCOMP = 7, 60 | MQTT_MSG_TYPE_SUBSCRIBE = 8, 61 | MQTT_MSG_TYPE_SUBACK = 9, 62 | MQTT_MSG_TYPE_UNSUBSCRIBE = 10, 63 | MQTT_MSG_TYPE_UNSUBACK = 11, 64 | MQTT_MSG_TYPE_PINGREQ = 12, 65 | MQTT_MSG_TYPE_PINGRESP = 13, 66 | MQTT_MSG_TYPE_DISCONNECT = 14 67 | }; 68 | 69 | typedef struct mqtt_message 70 | { 71 | uint8_t* data; 72 | uint16_t length; 73 | 74 | } mqtt_message_t; 75 | 76 | typedef struct mqtt_connection 77 | { 78 | mqtt_message_t message; 79 | 80 | uint16_t message_id; 81 | uint8_t* buffer; 82 | uint16_t buffer_length; 83 | 84 | } mqtt_connection_t; 85 | 86 | typedef struct mqtt_connect_info 87 | { 88 | char* client_id; 89 | char* username; 90 | char* password; 91 | char* will_topic; 92 | char* will_message; 93 | int keepalive; 94 | int will_qos; 95 | int will_retain; 96 | int clean_session; 97 | 98 | } mqtt_connect_info_t; 99 | 100 | 101 | static inline int ICACHE_FLASH_ATTR mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; } 102 | static inline int ICACHE_FLASH_ATTR mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; } 103 | static inline int ICACHE_FLASH_ATTR mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; } 104 | static inline int ICACHE_FLASH_ATTR mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); } 105 | 106 | void ICACHE_FLASH_ATTR mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length); 107 | int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length); 108 | const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length); 109 | const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* length); 110 | uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length); 111 | 112 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info); 113 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id); 114 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id); 115 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id); 116 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id); 117 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id); 118 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id); 119 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id); 120 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingreq(mqtt_connection_t* connection); 121 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingresp(mqtt_connection_t* connection); 122 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connection); 123 | 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif 128 | 129 | #endif /* MQTT_MSG_H */ 130 | 131 | -------------------------------------------------------------------------------- /mqtt/mqtt/include/mqtt.h: -------------------------------------------------------------------------------- 1 | /* mqtt.h 2 | * 3 | * Copyright (c) 2014-2015, Tuan PM 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef USER_AT_MQTT_H_ 31 | #define USER_AT_MQTT_H_ 32 | #include "mqtt_config.h" 33 | #include "mqtt_msg.h" 34 | #include "user_interface.h" 35 | 36 | #include "queue.h" 37 | typedef struct mqtt_event_data_t 38 | { 39 | uint8_t type; 40 | const char* topic; 41 | const char* data; 42 | uint16_t topic_length; 43 | uint16_t data_length; 44 | uint16_t data_offset; 45 | } mqtt_event_data_t; 46 | 47 | typedef struct mqtt_state_t 48 | { 49 | uint16_t port; 50 | int auto_reconnect; 51 | mqtt_connect_info_t* connect_info; 52 | uint8_t* in_buffer; 53 | uint8_t* out_buffer; 54 | int in_buffer_length; 55 | int out_buffer_length; 56 | uint16_t message_length; 57 | uint16_t message_length_read; 58 | mqtt_message_t* outbound_message; 59 | mqtt_connection_t mqtt_connection; 60 | uint16_t pending_msg_id; 61 | int pending_msg_type; 62 | int pending_publish_qos; 63 | } mqtt_state_t; 64 | 65 | typedef enum { 66 | WIFI_INIT, 67 | WIFI_CONNECTING, 68 | WIFI_CONNECTING_ERROR, 69 | WIFI_CONNECTED, 70 | DNS_RESOLVE, 71 | TCP_DISCONNECTING, 72 | TCP_DISCONNECTED, 73 | TCP_RECONNECT_DISCONNECTING, 74 | TCP_RECONNECT_REQ, 75 | TCP_RECONNECT, 76 | TCP_CONNECTING, 77 | TCP_CONNECTING_ERROR, 78 | TCP_CONNECTED, 79 | MQTT_CONNECT_SEND, 80 | MQTT_CONNECT_SENDING, 81 | MQTT_SUBSCIBE_SEND, 82 | MQTT_SUBSCIBE_SENDING, 83 | MQTT_DATA, 84 | MQTT_KEEPALIVE_SEND, 85 | MQTT_PUBLISH_RECV, 86 | MQTT_PUBLISHING, 87 | MQTT_DELETING, 88 | MQTT_DELETED, 89 | } tConnState; 90 | 91 | typedef void (*MqttCallback)(uint32_t *args); 92 | typedef void (*MqttDataCallback)(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh); 93 | 94 | typedef struct { 95 | struct espconn *pCon; 96 | uint8_t security; 97 | uint8_t* host; 98 | uint32_t port; 99 | ip_addr_t ip; 100 | mqtt_state_t mqtt_state; 101 | mqtt_connect_info_t connect_info; 102 | MqttCallback connectedCb; 103 | MqttCallback disconnectedCb; 104 | MqttCallback publishedCb; 105 | MqttCallback timeoutCb; 106 | MqttDataCallback dataCb; 107 | ETSTimer mqttTimer; 108 | uint32_t keepAliveTick; 109 | uint32_t reconnectTick; 110 | uint32_t sendTimeout; 111 | tConnState connState; 112 | QUEUE msgQueue; 113 | void* user_data; 114 | } MQTT_Client; 115 | 116 | #define SEC_NONSSL 0 117 | #define SEC_SSL 1 118 | 119 | #define MQTT_FLAG_CONNECTED 1 120 | #define MQTT_FLAG_READY 2 121 | #define MQTT_FLAG_EXIT 4 122 | 123 | #define MQTT_EVENT_TYPE_NONE 0 124 | #define MQTT_EVENT_TYPE_CONNECTED 1 125 | #define MQTT_EVENT_TYPE_DISCONNECTED 2 126 | #define MQTT_EVENT_TYPE_SUBSCRIBED 3 127 | #define MQTT_EVENT_TYPE_UNSUBSCRIBED 4 128 | #define MQTT_EVENT_TYPE_PUBLISH 5 129 | #define MQTT_EVENT_TYPE_PUBLISHED 6 130 | #define MQTT_EVENT_TYPE_EXITED 7 131 | #define MQTT_EVENT_TYPE_PUBLISH_CONTINUATION 8 132 | 133 | void ICACHE_FLASH_ATTR MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32_t port, uint8_t security); 134 | void ICACHE_FLASH_ATTR MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime, uint8_t cleanSession); 135 | void ICACHE_FLASH_ATTR MQTT_DeleteClient(MQTT_Client *mqttClient); 136 | void ICACHE_FLASH_ATTR MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain); 137 | void ICACHE_FLASH_ATTR MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb); 138 | void ICACHE_FLASH_ATTR MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb); 139 | void ICACHE_FLASH_ATTR MQTT_OnPublished(MQTT_Client *mqttClient, MqttCallback publishedCb); 140 | void ICACHE_FLASH_ATTR MQTT_OnTimeout(MQTT_Client *mqttClient, MqttCallback timeoutCb); 141 | void ICACHE_FLASH_ATTR MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb); 142 | BOOL ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos); 143 | void ICACHE_FLASH_ATTR MQTT_Connect(MQTT_Client *mqttClient); 144 | void ICACHE_FLASH_ATTR MQTT_Disconnect(MQTT_Client *mqttClient); 145 | BOOL ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain); 146 | 147 | #endif /* USER_AT_MQTT_H_ */ 148 | -------------------------------------------------------------------------------- /mqtt/Makefile: -------------------------------------------------------------------------------- 1 | # Changelog 2 | # Changed the variables to include the header file directory 3 | # Added global var for the XTENSA tool root 4 | # 5 | # This make file still needs some work. 6 | # 7 | # 8 | # Output directors to store intermediate compiled files 9 | # relative to the project directory 10 | BUILD_BASE = build 11 | FW_BASE = firmware 12 | ESPTOOL = tools/esptool/esptool.py 13 | 14 | 15 | # name for the target project 16 | TARGET = app 17 | 18 | # linker script used for the above linkier step 19 | LD_SCRIPT = eagle.app.v6.ld 20 | 21 | # we create two different files for uploading into the flash 22 | # these are the names and options to generate them 23 | FW_1 = 0x00000 24 | FW_2 = 0x40000 25 | 26 | FLAVOR ?= release 27 | 28 | 29 | ############################################################# 30 | # Select compile 31 | # 32 | ifeq ($(OS),Windows_NT) 33 | # WIN32 34 | # We are under windows. 35 | ifeq ($(XTENSA_CORE),lx106) 36 | # It is xcc 37 | AR = xt-ar 38 | CC = xt-xcc 39 | LD = xt-xcc 40 | NM = xt-nm 41 | CPP = xt-cpp 42 | OBJCOPY = xt-objcopy 43 | #MAKE = xt-make 44 | CCFLAGS += -Os --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal 45 | else 46 | # It is gcc, may be cygwin 47 | # Can we use -fdata-sections? 48 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 49 | AR = xtensa-lx106-elf-ar 50 | CC = xtensa-lx106-elf-gcc 51 | LD = xtensa-lx106-elf-gcc 52 | NM = xtensa-lx106-elf-nm 53 | CPP = xtensa-lx106-elf-cpp 54 | OBJCOPY = xtensa-lx106-elf-objcopy 55 | endif 56 | ESPPORT ?= com1 57 | SDK_BASE ?= C:\Espressif\esp_iot_sdk_v1.3.0 58 | ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) 59 | # ->AMD64 60 | endif 61 | ifeq ($(PROCESSOR_ARCHITECTURE),x86) 62 | # ->IA32 63 | endif 64 | else 65 | # We are under other system, may be Linux. Assume using gcc. 66 | # Can we use -fdata-sections? 67 | ESPPORT ?= /dev/ttyUSB0 68 | SDK_BASE ?= /esptools/esp_iot_sdk_v1.3.0 69 | 70 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 71 | AR = xtensa-lx106-elf-ar 72 | CC = xtensa-lx106-elf-gcc 73 | LD = xtensa-lx106-elf-gcc 74 | NM = xtensa-lx106-elf-nm 75 | CPP = xtensa-lx106-elf-cpp 76 | OBJCOPY = xtensa-lx106-elf-objcopy 77 | UNAME_S := $(shell uname -s) 78 | 79 | ifeq ($(UNAME_S),Linux) 80 | # LINUX 81 | endif 82 | ifeq ($(UNAME_S),Darwin) 83 | # OSX 84 | endif 85 | UNAME_P := $(shell uname -p) 86 | ifeq ($(UNAME_P),x86_64) 87 | # ->AMD64 88 | endif 89 | ifneq ($(filter %86,$(UNAME_P)),) 90 | # ->IA32 91 | endif 92 | ifneq ($(filter arm%,$(UNAME_P)),) 93 | # ->ARM 94 | endif 95 | endif 96 | ############################################################# 97 | 98 | 99 | # which modules (subdirectories) of the project to include in compiling 100 | MODULES = driver mqtt user modules 101 | EXTRA_INCDIR = include $(SDK_BASE)/../include 102 | 103 | # libraries used in this project, mainly provided by the SDK 104 | LIBS = c gcc hal phy pp net80211 lwip wpa main ssl crypto 105 | 106 | # compiler flags using during compilation of source files 107 | CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH 108 | 109 | # linker flags used to generate the main object file 110 | LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static 111 | 112 | ifeq ($(FLAVOR),debug) 113 | CFLAGS += -g -O0 114 | LDFLAGS += -g -O0 115 | endif 116 | 117 | ifeq ($(FLAVOR),release) 118 | CFLAGS += -g -O2 119 | LDFLAGS += -g -O2 120 | endif 121 | 122 | 123 | 124 | # various paths from the SDK used in this project 125 | SDK_LIBDIR = lib 126 | SDK_LDDIR = ld 127 | SDK_INCDIR = include include/json 128 | 129 | #### 130 | #### no user configurable options below here 131 | #### 132 | FW_TOOL ?= $(ESPTOOL) 133 | SRC_DIR := $(MODULES) 134 | BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES)) 135 | 136 | SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) 137 | SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) 138 | 139 | SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) 140 | OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) 141 | LIBS := $(addprefix -l,$(LIBS)) 142 | APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) 143 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 144 | 145 | LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) 146 | 147 | INCDIR := $(addprefix -I,$(SRC_DIR)) 148 | EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) 149 | MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) 150 | 151 | FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_1).bin) 152 | FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_2).bin) 153 | 154 | V ?= $(VERBOSE) 155 | ifeq ("$(V)","1") 156 | Q := 157 | vecho := @true 158 | else 159 | Q := @ 160 | vecho := @echo 161 | endif 162 | 163 | vpath %.c $(SRC_DIR) 164 | 165 | define compile-objects 166 | $1/%.o: %.c 167 | $(vecho) "CC $$<" 168 | $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ 169 | endef 170 | 171 | .PHONY: all checkdirs clean 172 | 173 | all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2) 174 | 175 | $(FW_FILE_1): $(TARGET_OUT) 176 | $(vecho) "FW $@" 177 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 178 | 179 | $(FW_FILE_2): $(TARGET_OUT) 180 | $(vecho) "FW $@" 181 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 182 | 183 | $(TARGET_OUT): $(APP_AR) 184 | $(vecho) "LD $@" 185 | $(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 186 | 187 | $(APP_AR): $(OBJ) 188 | $(vecho) "AR $@" 189 | $(Q) $(AR) cru $@ $^ 190 | 191 | checkdirs: $(BUILD_DIR) $(FW_BASE) 192 | 193 | $(BUILD_DIR): 194 | $(Q) mkdir -p $@ 195 | 196 | firmware: 197 | $(Q) mkdir -p $@ 198 | 199 | flash: $(FW_FILE_1) $(FW_FILE_2) 200 | $(ESPTOOL) -p $(ESPPORT) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2) 201 | 202 | test: flash 203 | screen $(ESPPORT) 115200 204 | 205 | rebuild: clean all 206 | 207 | clean: 208 | $(Q) rm -f $(APP_AR) 209 | $(Q) rm -f $(TARGET_OUT) 210 | $(Q) rm -rf $(BUILD_DIR) 211 | $(Q) rm -rf $(BUILD_BASE) 212 | $(Q) rm -f $(FW_FILE_1) 213 | $(Q) rm -f $(FW_FILE_2) 214 | $(Q) rm -rf $(FW_BASE) 215 | 216 | $(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) 217 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Changelog 2 | # Changed the variables to include the header file directory 3 | # Added global var for the XTENSA tool root 4 | # 5 | # This make file still needs some work. 6 | # 7 | # 8 | # Output directors to store intermediate compiled files 9 | # relative to the project directory 10 | BUILD_BASE = build 11 | FW_BASE = firmware 12 | ESPTOOL = esptool.py 13 | 14 | 15 | # name for the target project 16 | TARGET = app 17 | 18 | # linker script used for the above linkier step 19 | LD_SCRIPT = eagle.app.v6.ld 20 | 21 | # we create two different files for uploading into the flash 22 | # these are the names and options to generate them 23 | FW_1 = 0x00000 24 | FW_2 = 0x40000 25 | 26 | FLAVOR ?= release 27 | 28 | 29 | ############################################################# 30 | # Select compile 31 | # 32 | ifeq ($(OS),Windows_NT) 33 | # WIN32 34 | # We are under windows. 35 | ifeq ($(XTENSA_CORE),lx106) 36 | # It is xcc 37 | AR = xt-ar 38 | CC = xt-xcc 39 | LD = xt-xcc 40 | NM = xt-nm 41 | CPP = xt-cpp 42 | OBJCOPY = xt-objcopy 43 | #MAKE = xt-make 44 | CCFLAGS += -Os --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal 45 | else 46 | # It is gcc, may be cygwin 47 | # Can we use -fdata-sections? 48 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 49 | AR = xtensa-lx106-elf-ar 50 | CC = xtensa-lx106-elf-gcc 51 | LD = xtensa-lx106-elf-gcc 52 | NM = xtensa-lx106-elf-nm 53 | CPP = xtensa-lx106-elf-cpp 54 | OBJCOPY = xtensa-lx106-elf-objcopy 55 | endif 56 | ESPPORT ?= com1 57 | SDK_BASE ?= c:/Espressif/ESP8266_SDK 58 | ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) 59 | # ->AMD64 60 | endif 61 | ifeq ($(PROCESSOR_ARCHITECTURE),x86) 62 | # ->IA32 63 | endif 64 | else 65 | # We are under other system, may be Linux. Assume using gcc. 66 | # Can we use -fdata-sections? 67 | ESPPORT ?= /dev/ttyUSB0 68 | SDK_BASE ?= /opt/local/esp-open-sdk/sdk 69 | 70 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 71 | AR = xtensa-lx106-elf-ar 72 | CC = xtensa-lx106-elf-gcc 73 | LD = xtensa-lx106-elf-gcc 74 | NM = xtensa-lx106-elf-nm 75 | CPP = xtensa-lx106-elf-cpp 76 | OBJCOPY = xtensa-lx106-elf-objcopy 77 | UNAME_S := $(shell uname -s) 78 | 79 | ifeq ($(UNAME_S),Linux) 80 | # LINUX 81 | endif 82 | ifeq ($(UNAME_S),Darwin) 83 | # OSX 84 | endif 85 | UNAME_P := $(shell uname -p) 86 | ifeq ($(UNAME_P),x86_64) 87 | # ->AMD64 88 | endif 89 | ifneq ($(filter %86,$(UNAME_P)),) 90 | # ->IA32 91 | endif 92 | ifneq ($(filter arm%,$(UNAME_P)),) 93 | # ->ARM 94 | endif 95 | endif 96 | ############################################################# 97 | 98 | 99 | # which modules (subdirectories) of the project to include in compiling 100 | MODULES = localinclude include driver/stdout driver/pcd8544 driver/easygpio mqtt mqtt/mqtt mqtt/modules user 101 | EXTRA_INCDIR = $(SDK_BASE)/../include 102 | 103 | # libraries used in this project, mainly provided by the SDK 104 | LIBS = c gcc hal phy pp net80211 lwip wpa main ssl 105 | 106 | # compiler flags using during compilation of source files 107 | CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH 108 | 109 | # linker flags used to generate the main object file 110 | LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static 111 | 112 | ifeq ($(FLAVOR),debug) 113 | CFLAGS += -O0 114 | LDFLAGS += -O0 115 | endif 116 | 117 | ifeq ($(FLAVOR),release) 118 | CFLAGS += -O2 119 | LDFLAGS += -O2 120 | endif 121 | 122 | 123 | 124 | # various paths from the SDK used in this project 125 | SDK_LIBDIR = lib 126 | SDK_LDDIR = ld 127 | SDK_INCDIR = include include/json 128 | 129 | #### 130 | #### no user configurable options below here 131 | #### 132 | FW_TOOL ?= $(ESPTOOL) 133 | SRC_DIR := $(MODULES) 134 | BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES)) 135 | 136 | SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) 137 | SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) 138 | 139 | SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) 140 | OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) 141 | LIBS := $(addprefix -l,$(LIBS)) 142 | APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) 143 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 144 | 145 | LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) 146 | 147 | INCDIR := $(addprefix -I,$(SRC_DIR)) 148 | EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) 149 | MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) 150 | 151 | FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_1).bin) 152 | FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_2).bin) 153 | 154 | V ?= $(VERBOSE) 155 | ifeq ("$(V)","1") 156 | Q := 157 | vecho := @true 158 | else 159 | Q := @ 160 | vecho := @echo 161 | endif 162 | 163 | vpath %.c $(SRC_DIR) 164 | 165 | define compile-objects 166 | $1/%.o: %.c 167 | $(vecho) "CC $$<" 168 | $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ 169 | endef 170 | 171 | .PHONY: all checkdirs clean 172 | 173 | all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2) 174 | 175 | $(FW_FILE_1): $(TARGET_OUT) 176 | $(vecho) "FW $@" 177 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 178 | 179 | $(FW_FILE_2): $(TARGET_OUT) 180 | $(vecho) "FW $@" 181 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 182 | 183 | $(TARGET_OUT): $(APP_AR) 184 | $(vecho) "LD $@" 185 | $(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 186 | 187 | $(APP_AR): $(OBJ) 188 | $(vecho) "AR $@" 189 | $(Q) $(AR) cru $@ $^ 190 | 191 | checkdirs: $(BUILD_DIR) $(FW_BASE) 192 | 193 | $(BUILD_DIR): 194 | $(Q) mkdir -p $@ 195 | 196 | firmware: 197 | $(Q) mkdir -p $@ 198 | 199 | flash: $(FW_FILE_1) $(FW_FILE_2) 200 | $(ESPTOOL) -p $(ESPPORT) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2) 201 | 202 | test: flash 203 | screen $(ESPPORT) 115200 204 | 205 | rebuild: clean all 206 | 207 | clean: 208 | $(Q) rm -f $(APP_AR) 209 | $(Q) rm -f $(TARGET_OUT) 210 | $(Q) rm -rf $(BUILD_DIR) 211 | $(Q) rm -rf $(BUILD_BASE) 212 | $(Q) rm -f $(FW_FILE_1) 213 | $(Q) rm -f $(FW_FILE_2) 214 | $(Q) rm -rf $(FW_BASE) 215 | 216 | $(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) 217 | -------------------------------------------------------------------------------- /driver/easygpio/examples/readgpio/Makefile: -------------------------------------------------------------------------------- 1 | # Changelog 2 | # Changed the variables to include the header file directory 3 | # Added global var for the XTENSA tool root 4 | # 5 | # This make file still needs some work. 6 | # 7 | # 8 | # Output directors to store intermediate compiled files 9 | # relative to the project directory 10 | BUILD_BASE = build 11 | FW_BASE = firmware 12 | ESPTOOL = esptool.py 13 | 14 | 15 | # name for the target project 16 | TARGET = app 17 | 18 | # linker script used for the above linkier step 19 | LD_SCRIPT = eagle.app.v6.ld 20 | 21 | # we create two different files for uploading into the flash 22 | # these are the names and options to generate them 23 | FW_1 = 0x00000 24 | FW_2 = 0x40000 25 | 26 | FLAVOR ?= release 27 | 28 | 29 | ############################################################# 30 | # Select compile 31 | # 32 | ifeq ($(OS),Windows_NT) 33 | # WIN32 34 | # We are under windows. 35 | ifeq ($(XTENSA_CORE),lx106) 36 | # It is xcc 37 | AR = xt-ar 38 | CC = xt-xcc 39 | LD = xt-xcc 40 | NM = xt-nm 41 | CPP = xt-cpp 42 | OBJCOPY = xt-objcopy 43 | #MAKE = xt-make 44 | CCFLAGS += -Os --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal 45 | else 46 | # It is gcc, may be cygwin 47 | # Can we use -fdata-sections? 48 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 49 | AR = xtensa-lx106-elf-ar 50 | CC = xtensa-lx106-elf-gcc 51 | LD = xtensa-lx106-elf-gcc 52 | NM = xtensa-lx106-elf-nm 53 | CPP = xtensa-lx106-elf-cpp 54 | OBJCOPY = xtensa-lx106-elf-objcopy 55 | endif 56 | ESPPORT ?= com1 57 | SDK_BASE ?= c:/Espressif/ESP8266_SDK 58 | ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) 59 | # ->AMD64 60 | endif 61 | ifeq ($(PROCESSOR_ARCHITECTURE),x86) 62 | # ->IA32 63 | endif 64 | else 65 | # We are under other system, may be Linux. Assume using gcc. 66 | # Can we use -fdata-sections? 67 | ESPPORT ?= /dev/ttyUSB0 68 | SDK_BASE ?= /opt/local/esp-open-sdk/sdk 69 | 70 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 71 | AR = xtensa-lx106-elf-ar 72 | CC = xtensa-lx106-elf-gcc 73 | LD = xtensa-lx106-elf-gcc 74 | NM = xtensa-lx106-elf-nm 75 | CPP = xtensa-lx106-elf-cpp 76 | OBJCOPY = xtensa-lx106-elf-objcopy 77 | UNAME_S := $(shell uname -s) 78 | 79 | ifeq ($(UNAME_S),Linux) 80 | # LINUX 81 | endif 82 | ifeq ($(UNAME_S),Darwin) 83 | # OSX 84 | endif 85 | UNAME_P := $(shell uname -p) 86 | ifeq ($(UNAME_P),x86_64) 87 | # ->AMD64 88 | endif 89 | ifneq ($(filter %86,$(UNAME_P)),) 90 | # ->IA32 91 | endif 92 | ifneq ($(filter arm%,$(UNAME_P)),) 93 | # ->ARM 94 | endif 95 | endif 96 | ############################################################# 97 | 98 | EGP_BASE ?= ../dependencies/easygpio/../../../ 99 | DEP_BASE ?= ../dependencies 100 | 101 | # which modules (subdirectories) of the project to include in compiling 102 | MODULES = localinclude $(EGP_BASE) $(DEP_BASE)/stdout user 103 | EXTRA_INCDIR = include $(SDK_BASE)/../include 104 | 105 | # libraries used in this project, mainly provided by the SDK 106 | LIBS = c gcc hal phy pp net80211 lwip wpa main 107 | 108 | # compiler flags using during compilation of source files 109 | CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH 110 | 111 | # linker flags used to generate the main object file 112 | LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static 113 | 114 | ifeq ($(FLAVOR),debug) 115 | CFLAGS += -O0 116 | LDFLAGS += -O0 117 | endif 118 | 119 | ifeq ($(FLAVOR),release) 120 | CFLAGS += -O2 121 | LDFLAGS += -O2 122 | endif 123 | 124 | 125 | 126 | # various paths from the SDK used in this project 127 | SDK_LIBDIR = lib 128 | SDK_LDDIR = ld 129 | SDK_INCDIR = include include/json 130 | 131 | #### 132 | #### no user configurable options below here 133 | #### 134 | FW_TOOL ?= $(ESPTOOL) 135 | SRC_DIR := $(MODULES) 136 | BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(subst ../,, $(MODULES))) 137 | 138 | SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) 139 | SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) 140 | 141 | SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) 142 | OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(subst ../,, $(SRC))) 143 | LIBS := $(addprefix -l,$(LIBS)) 144 | APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) 145 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 146 | 147 | LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) 148 | 149 | INCDIR := $(addprefix -I,$(SRC_DIR)) 150 | EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) 151 | MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) 152 | 153 | FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_1).bin) 154 | FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_2).bin) 155 | 156 | V ?= $(VERBOSE) 157 | ifeq ("$(V)","1") 158 | Q := 159 | vecho := @true 160 | else 161 | Q := @ 162 | vecho := @echo 163 | endif 164 | 165 | vpath %.c $(SRC_DIR) 166 | 167 | define compile-objects 168 | $1/%.o: %.c 169 | $(vecho) "CC $$<" 170 | $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ 171 | endef 172 | 173 | .PHONY: all checkdirs clean 174 | 175 | all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2) 176 | 177 | $(FW_FILE_1): $(TARGET_OUT) 178 | $(vecho) "FW $@" 179 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 180 | 181 | $(FW_FILE_2): $(TARGET_OUT) 182 | $(vecho) "FW $@" 183 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 184 | 185 | $(TARGET_OUT): $(APP_AR) 186 | $(vecho) "LD $@" 187 | $(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 188 | 189 | $(APP_AR): $(OBJ) 190 | $(vecho) "AR $@" 191 | $(Q) $(AR) cru $@ $^ 192 | 193 | checkdirs: $(BUILD_DIR) $(FW_BASE) 194 | 195 | $(BUILD_DIR): 196 | $(Q) mkdir -p $@ 197 | 198 | firmware: 199 | $(Q) mkdir -p $@ 200 | 201 | flash: $(FW_FILE_1) $(FW_FILE_2) 202 | $(ESPTOOL) -p $(ESPPORT) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2) 203 | 204 | test: flash 205 | screen $(ESPPORT) 115200 206 | 207 | rebuild: clean all 208 | 209 | clean: 210 | $(Q) rm -f $(APP_AR) 211 | $(Q) rm -f $(TARGET_OUT) 212 | $(Q) rm -rf $(BUILD_DIR) 213 | $(Q) rm -rf $(BUILD_BASE) 214 | $(Q) rm -f $(FW_FILE_1) 215 | $(Q) rm -f $(FW_FILE_2) 216 | $(Q) rm -rf $(FW_BASE) 217 | 218 | $(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) 219 | -------------------------------------------------------------------------------- /driver/easygpio/examples/writegpio/Makefile: -------------------------------------------------------------------------------- 1 | # Changelog 2 | # Changed the variables to include the header file directory 3 | # Added global var for the XTENSA tool root 4 | # 5 | # This make file still needs some work. 6 | # 7 | # 8 | # Output directors to store intermediate compiled files 9 | # relative to the project directory 10 | BUILD_BASE = build 11 | FW_BASE = firmware 12 | ESPTOOL = esptool.py 13 | 14 | 15 | # name for the target project 16 | TARGET = app 17 | 18 | # linker script used for the above linkier step 19 | LD_SCRIPT = eagle.app.v6.ld 20 | 21 | # we create two different files for uploading into the flash 22 | # these are the names and options to generate them 23 | FW_1 = 0x00000 24 | FW_2 = 0x40000 25 | 26 | FLAVOR ?= release 27 | 28 | 29 | ############################################################# 30 | # Select compile 31 | # 32 | ifeq ($(OS),Windows_NT) 33 | # WIN32 34 | # We are under windows. 35 | ifeq ($(XTENSA_CORE),lx106) 36 | # It is xcc 37 | AR = xt-ar 38 | CC = xt-xcc 39 | LD = xt-xcc 40 | NM = xt-nm 41 | CPP = xt-cpp 42 | OBJCOPY = xt-objcopy 43 | #MAKE = xt-make 44 | CCFLAGS += -Os --rename-section .text=.irom0.text --rename-section .literal=.irom0.literal 45 | else 46 | # It is gcc, may be cygwin 47 | # Can we use -fdata-sections? 48 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 49 | AR = xtensa-lx106-elf-ar 50 | CC = xtensa-lx106-elf-gcc 51 | LD = xtensa-lx106-elf-gcc 52 | NM = xtensa-lx106-elf-nm 53 | CPP = xtensa-lx106-elf-cpp 54 | OBJCOPY = xtensa-lx106-elf-objcopy 55 | endif 56 | ESPPORT ?= com1 57 | SDK_BASE ?= c:/Espressif/ESP8266_SDK 58 | ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) 59 | # ->AMD64 60 | endif 61 | ifeq ($(PROCESSOR_ARCHITECTURE),x86) 62 | # ->IA32 63 | endif 64 | else 65 | # We are under other system, may be Linux. Assume using gcc. 66 | # Can we use -fdata-sections? 67 | ESPPORT ?= /dev/ttyUSB0 68 | SDK_BASE ?= /opt/local/esp-open-sdk/sdk 69 | 70 | CCFLAGS += -Os -ffunction-sections -fno-jump-tables 71 | AR = xtensa-lx106-elf-ar 72 | CC = xtensa-lx106-elf-gcc 73 | LD = xtensa-lx106-elf-gcc 74 | NM = xtensa-lx106-elf-nm 75 | CPP = xtensa-lx106-elf-cpp 76 | OBJCOPY = xtensa-lx106-elf-objcopy 77 | UNAME_S := $(shell uname -s) 78 | 79 | ifeq ($(UNAME_S),Linux) 80 | # LINUX 81 | endif 82 | ifeq ($(UNAME_S),Darwin) 83 | # OSX 84 | endif 85 | UNAME_P := $(shell uname -p) 86 | ifeq ($(UNAME_P),x86_64) 87 | # ->AMD64 88 | endif 89 | ifneq ($(filter %86,$(UNAME_P)),) 90 | # ->IA32 91 | endif 92 | ifneq ($(filter arm%,$(UNAME_P)),) 93 | # ->ARM 94 | endif 95 | endif 96 | ############################################################# 97 | 98 | EGP_BASE ?= ../dependencies/easygpio/../../../ 99 | DEP_BASE ?= ../dependencies 100 | 101 | # which modules (subdirectories) of the project to include in compiling 102 | MODULES = localinclude $(EGP_BASE) $(DEP_BASE)/stdout user 103 | EXTRA_INCDIR = include $(SDK_BASE)/../include 104 | 105 | # libraries used in this project, mainly provided by the SDK 106 | LIBS = c gcc hal phy pp net80211 lwip wpa main 107 | 108 | # compiler flags using during compilation of source files 109 | CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH 110 | 111 | # linker flags used to generate the main object file 112 | LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static 113 | 114 | ifeq ($(FLAVOR),debug) 115 | CFLAGS += -O0 116 | LDFLAGS += -O0 117 | endif 118 | 119 | ifeq ($(FLAVOR),release) 120 | CFLAGS += -O2 121 | LDFLAGS += -O2 122 | endif 123 | 124 | 125 | 126 | # various paths from the SDK used in this project 127 | SDK_LIBDIR = lib 128 | SDK_LDDIR = ld 129 | SDK_INCDIR = include include/json 130 | 131 | #### 132 | #### no user configurable options below here 133 | #### 134 | FW_TOOL ?= $(ESPTOOL) 135 | SRC_DIR := $(MODULES) 136 | BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(subst ../,, $(MODULES))) 137 | 138 | SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) 139 | SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) 140 | 141 | SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) 142 | OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(subst ../,, $(SRC))) 143 | LIBS := $(addprefix -l,$(LIBS)) 144 | APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) 145 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 146 | 147 | LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) 148 | 149 | INCDIR := $(addprefix -I,$(SRC_DIR)) 150 | EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) 151 | MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) 152 | 153 | FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_1).bin) 154 | FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_2).bin) 155 | 156 | V ?= $(VERBOSE) 157 | ifeq ("$(V)","1") 158 | Q := 159 | vecho := @true 160 | else 161 | Q := @ 162 | vecho := @echo 163 | endif 164 | 165 | vpath %.c $(SRC_DIR) 166 | 167 | define compile-objects 168 | $1/%.o: %.c 169 | $(vecho) "CC $$<" 170 | $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ 171 | endef 172 | 173 | .PHONY: all checkdirs clean 174 | 175 | all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2) 176 | 177 | $(FW_FILE_1): $(TARGET_OUT) 178 | $(vecho) "FW $@" 179 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 180 | 181 | $(FW_FILE_2): $(TARGET_OUT) 182 | $(vecho) "FW $@" 183 | $(ESPTOOL) elf2image $< -o $(FW_BASE)/ 184 | 185 | $(TARGET_OUT): $(APP_AR) 186 | $(vecho) "LD $@" 187 | $(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 188 | 189 | $(APP_AR): $(OBJ) 190 | $(vecho) "AR $@" 191 | $(Q) $(AR) cru $@ $^ 192 | 193 | checkdirs: $(BUILD_DIR) $(FW_BASE) 194 | 195 | $(BUILD_DIR): 196 | $(Q) mkdir -p $@ 197 | 198 | firmware: 199 | $(Q) mkdir -p $@ 200 | 201 | flash: $(FW_FILE_1) $(FW_FILE_2) 202 | $(ESPTOOL) -p $(ESPPORT) write_flash $(FW_1) $(FW_FILE_1) $(FW_2) $(FW_FILE_2) 203 | 204 | test: flash 205 | screen $(ESPPORT) 115200 206 | 207 | rebuild: clean all 208 | 209 | clean: 210 | $(Q) rm -f $(APP_AR) 211 | $(Q) rm -f $(TARGET_OUT) 212 | $(Q) rm -rf $(BUILD_DIR) 213 | $(Q) rm -rf $(BUILD_BASE) 214 | $(Q) rm -f $(FW_FILE_1) 215 | $(Q) rm -f $(FW_FILE_2) 216 | $(Q) rm -rf $(FW_BASE) 217 | 218 | $(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) 219 | -------------------------------------------------------------------------------- /driver/stdout/include/stdout/uart_hw.h: -------------------------------------------------------------------------------- 1 | //Generated at 2012-07-03 18:44:06 2 | /* 3 | * Copyright (c) 2010 - 2011 Espressif System 4 | * 5 | */ 6 | 7 | #ifndef UART_REGISTER_H_INCLUDED 8 | #define UART_REGISTER_H_INCLUDED 9 | #define REG_UART_BASE( i ) (0x60000000+(i)*0xf00) 10 | //version value:32'h062000 11 | 12 | #define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) 13 | #define UART_RXFIFO_RD_BYTE 0x000000FF 14 | #define UART_RXFIFO_RD_BYTE_S 0 15 | 16 | #define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4) 17 | #define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) 18 | #define UART_BRK_DET_INT_RAW (BIT(7)) 19 | #define UART_CTS_CHG_INT_RAW (BIT(6)) 20 | #define UART_DSR_CHG_INT_RAW (BIT(5)) 21 | #define UART_RXFIFO_OVF_INT_RAW (BIT(4)) 22 | #define UART_FRM_ERR_INT_RAW (BIT(3)) 23 | #define UART_PARITY_ERR_INT_RAW (BIT(2)) 24 | #define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) 25 | #define UART_RXFIFO_FULL_INT_RAW (BIT(0)) 26 | 27 | #define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) 28 | #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) 29 | #define UART_BRK_DET_INT_ST (BIT(7)) 30 | #define UART_CTS_CHG_INT_ST (BIT(6)) 31 | #define UART_DSR_CHG_INT_ST (BIT(5)) 32 | #define UART_RXFIFO_OVF_INT_ST (BIT(4)) 33 | #define UART_FRM_ERR_INT_ST (BIT(3)) 34 | #define UART_PARITY_ERR_INT_ST (BIT(2)) 35 | #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) 36 | #define UART_RXFIFO_FULL_INT_ST (BIT(0)) 37 | 38 | #define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) 39 | #define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) 40 | #define UART_BRK_DET_INT_ENA (BIT(7)) 41 | #define UART_CTS_CHG_INT_ENA (BIT(6)) 42 | #define UART_DSR_CHG_INT_ENA (BIT(5)) 43 | #define UART_RXFIFO_OVF_INT_ENA (BIT(4)) 44 | #define UART_FRM_ERR_INT_ENA (BIT(3)) 45 | #define UART_PARITY_ERR_INT_ENA (BIT(2)) 46 | #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) 47 | #define UART_RXFIFO_FULL_INT_ENA (BIT(0)) 48 | 49 | #define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) 50 | #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) 51 | #define UART_BRK_DET_INT_CLR (BIT(7)) 52 | #define UART_CTS_CHG_INT_CLR (BIT(6)) 53 | #define UART_DSR_CHG_INT_CLR (BIT(5)) 54 | #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) 55 | #define UART_FRM_ERR_INT_CLR (BIT(3)) 56 | #define UART_PARITY_ERR_INT_CLR (BIT(2)) 57 | #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) 58 | #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) 59 | 60 | #define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14) 61 | #define UART_CLKDIV_CNT 0x000FFFFF 62 | #define UART_CLKDIV_S 0 63 | 64 | #define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18) 65 | #define UART_GLITCH_FILT 0x000000FF 66 | #define UART_GLITCH_FILT_S 8 67 | #define UART_AUTOBAUD_EN (BIT(0)) 68 | 69 | #define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C) 70 | #define UART_TXD (BIT(31)) 71 | #define UART_RTSN (BIT(30)) 72 | #define UART_DTRN (BIT(29)) 73 | #define UART_TXFIFO_CNT 0x000000FF 74 | #define UART_TXFIFO_CNT_S 16 75 | #define UART_RXD (BIT(15)) 76 | #define UART_CTSN (BIT(14)) 77 | #define UART_DSRN (BIT(13)) 78 | #define UART_RXFIFO_CNT 0x000000FF 79 | #define UART_RXFIFO_CNT_S 0 80 | 81 | #define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20) 82 | #define UART_TXFIFO_RST (BIT(18)) 83 | #define UART_RXFIFO_RST (BIT(17)) 84 | #define UART_IRDA_EN (BIT(16)) 85 | #define UART_TX_FLOW_EN (BIT(15)) 86 | #define UART_LOOPBACK (BIT(14)) 87 | #define UART_IRDA_RX_INV (BIT(13)) 88 | #define UART_IRDA_TX_INV (BIT(12)) 89 | #define UART_IRDA_WCTL (BIT(11)) 90 | #define UART_IRDA_TX_EN (BIT(10)) 91 | #define UART_IRDA_DPLX (BIT(9)) 92 | #define UART_TXD_BRK (BIT(8)) 93 | #define UART_SW_DTR (BIT(7)) 94 | #define UART_SW_RTS (BIT(6)) 95 | #define UART_STOP_BIT_NUM 0x00000003 96 | #define UART_STOP_BIT_NUM_S 4 97 | #define UART_BIT_NUM 0x00000003 98 | #define UART_BIT_NUM_S 2 99 | #define UART_PARITY_EN (BIT(1)) 100 | #define UART_PARITY (BIT(0)) 101 | 102 | #define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24) 103 | #define UART_RX_TOUT_EN (BIT(31)) 104 | #define UART_RX_TOUT_THRHD 0x0000007F 105 | #define UART_RX_TOUT_THRHD_S 24 106 | #define UART_RX_FLOW_EN (BIT(23)) 107 | #define UART_RX_FLOW_THRHD 0x0000007F 108 | #define UART_RX_FLOW_THRHD_S 16 109 | #define UART_TXFIFO_EMPTY_THRHD 0x0000007F 110 | #define UART_TXFIFO_EMPTY_THRHD_S 8 111 | #define UART_RXFIFO_FULL_THRHD 0x0000007F 112 | #define UART_RXFIFO_FULL_THRHD_S 0 113 | 114 | #define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28) 115 | #define UART_LOWPULSE_MIN_CNT 0x000FFFFF 116 | #define UART_LOWPULSE_MIN_CNT_S 0 117 | 118 | #define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C) 119 | #define UART_HIGHPULSE_MIN_CNT 0x000FFFFF 120 | #define UART_HIGHPULSE_MIN_CNT_S 0 121 | 122 | #define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30) 123 | #define UART_PULSE_NUM_CNT 0x0003FF 124 | #define UART_PULSE_NUM_CNT_S 0 125 | 126 | #define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78) 127 | #define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C) 128 | #endif // UART_REGISTER_H_INCLUDED 129 | 130 | #define RX_BUFF_SIZE 256 131 | #define TX_BUFF_SIZE 100 132 | #define UART0 0 133 | #define UART1 1 134 | 135 | typedef enum { 136 | FIVE_BITS = 0x0, 137 | SIX_BITS = 0x1, 138 | SEVEN_BITS = 0x2, 139 | EIGHT_BITS = 0x3 140 | } UartBitsNum4Char; 141 | 142 | typedef enum { 143 | ONE_STOP_BIT = 0, 144 | ONE_HALF_STOP_BIT = BIT2, 145 | TWO_STOP_BIT = BIT2 146 | } UartStopBitsNum; 147 | 148 | typedef enum { 149 | NONE_BITS = 0, 150 | ODD_BITS = 0, 151 | EVEN_BITS = BIT4 152 | } UartParityMode; 153 | 154 | typedef enum { 155 | STICK_PARITY_DIS = 0, 156 | STICK_PARITY_EN = BIT3 | BIT5 157 | } UartExistParity; 158 | 159 | typedef enum { 160 | BIT_RATE_9600 = 9600, 161 | BIT_RATE_19200 = 19200, 162 | BIT_RATE_38400 = 38400, 163 | BIT_RATE_57600 = 57600, 164 | BIT_RATE_74880 = 74880, 165 | BIT_RATE_115200 = 115200, 166 | BIT_RATE_230400 = 230400, 167 | BIT_RATE_460800 = 460800, 168 | BIT_RATE_921600 = 921600 169 | } UartBautRate; 170 | 171 | typedef enum { 172 | NONE_CTRL, 173 | HARDWARE_CTRL, 174 | XON_XOFF_CTRL 175 | } UartFlowCtrl; 176 | 177 | typedef enum { 178 | EMPTY, 179 | UNDER_WRITE, 180 | WRITE_OVER 181 | } RcvMsgBuffState; 182 | 183 | typedef struct { 184 | uint32 TrxBuffSize; 185 | uint8 *pTrxBuff; 186 | } TrxMsgBuff; 187 | 188 | typedef enum { 189 | BAUD_RATE_DET, 190 | WAIT_SYNC_FRM, 191 | SRCH_MSG_HEAD, 192 | RCV_MSG_BODY, 193 | RCV_ESC_CHAR, 194 | } RcvMsgState; 195 | 196 | -------------------------------------------------------------------------------- /driver/easygpio/examples/dependencies/stdout/include/stdout/uart_hw.h: -------------------------------------------------------------------------------- 1 | //Generated at 2012-07-03 18:44:06 2 | /* 3 | * Copyright (c) 2010 - 2011 Espressif System 4 | * 5 | */ 6 | 7 | #ifndef UART_REGISTER_H_INCLUDED 8 | #define UART_REGISTER_H_INCLUDED 9 | #define REG_UART_BASE( i ) (0x60000000+(i)*0xf00) 10 | //version value:32'h062000 11 | 12 | #define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) 13 | #define UART_RXFIFO_RD_BYTE 0x000000FF 14 | #define UART_RXFIFO_RD_BYTE_S 0 15 | 16 | #define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4) 17 | #define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) 18 | #define UART_BRK_DET_INT_RAW (BIT(7)) 19 | #define UART_CTS_CHG_INT_RAW (BIT(6)) 20 | #define UART_DSR_CHG_INT_RAW (BIT(5)) 21 | #define UART_RXFIFO_OVF_INT_RAW (BIT(4)) 22 | #define UART_FRM_ERR_INT_RAW (BIT(3)) 23 | #define UART_PARITY_ERR_INT_RAW (BIT(2)) 24 | #define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) 25 | #define UART_RXFIFO_FULL_INT_RAW (BIT(0)) 26 | 27 | #define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) 28 | #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) 29 | #define UART_BRK_DET_INT_ST (BIT(7)) 30 | #define UART_CTS_CHG_INT_ST (BIT(6)) 31 | #define UART_DSR_CHG_INT_ST (BIT(5)) 32 | #define UART_RXFIFO_OVF_INT_ST (BIT(4)) 33 | #define UART_FRM_ERR_INT_ST (BIT(3)) 34 | #define UART_PARITY_ERR_INT_ST (BIT(2)) 35 | #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) 36 | #define UART_RXFIFO_FULL_INT_ST (BIT(0)) 37 | 38 | #define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) 39 | #define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) 40 | #define UART_BRK_DET_INT_ENA (BIT(7)) 41 | #define UART_CTS_CHG_INT_ENA (BIT(6)) 42 | #define UART_DSR_CHG_INT_ENA (BIT(5)) 43 | #define UART_RXFIFO_OVF_INT_ENA (BIT(4)) 44 | #define UART_FRM_ERR_INT_ENA (BIT(3)) 45 | #define UART_PARITY_ERR_INT_ENA (BIT(2)) 46 | #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) 47 | #define UART_RXFIFO_FULL_INT_ENA (BIT(0)) 48 | 49 | #define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) 50 | #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) 51 | #define UART_BRK_DET_INT_CLR (BIT(7)) 52 | #define UART_CTS_CHG_INT_CLR (BIT(6)) 53 | #define UART_DSR_CHG_INT_CLR (BIT(5)) 54 | #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) 55 | #define UART_FRM_ERR_INT_CLR (BIT(3)) 56 | #define UART_PARITY_ERR_INT_CLR (BIT(2)) 57 | #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) 58 | #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) 59 | 60 | #define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14) 61 | #define UART_CLKDIV_CNT 0x000FFFFF 62 | #define UART_CLKDIV_S 0 63 | 64 | #define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18) 65 | #define UART_GLITCH_FILT 0x000000FF 66 | #define UART_GLITCH_FILT_S 8 67 | #define UART_AUTOBAUD_EN (BIT(0)) 68 | 69 | #define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C) 70 | #define UART_TXD (BIT(31)) 71 | #define UART_RTSN (BIT(30)) 72 | #define UART_DTRN (BIT(29)) 73 | #define UART_TXFIFO_CNT 0x000000FF 74 | #define UART_TXFIFO_CNT_S 16 75 | #define UART_RXD (BIT(15)) 76 | #define UART_CTSN (BIT(14)) 77 | #define UART_DSRN (BIT(13)) 78 | #define UART_RXFIFO_CNT 0x000000FF 79 | #define UART_RXFIFO_CNT_S 0 80 | 81 | #define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20) 82 | #define UART_TXFIFO_RST (BIT(18)) 83 | #define UART_RXFIFO_RST (BIT(17)) 84 | #define UART_IRDA_EN (BIT(16)) 85 | #define UART_TX_FLOW_EN (BIT(15)) 86 | #define UART_LOOPBACK (BIT(14)) 87 | #define UART_IRDA_RX_INV (BIT(13)) 88 | #define UART_IRDA_TX_INV (BIT(12)) 89 | #define UART_IRDA_WCTL (BIT(11)) 90 | #define UART_IRDA_TX_EN (BIT(10)) 91 | #define UART_IRDA_DPLX (BIT(9)) 92 | #define UART_TXD_BRK (BIT(8)) 93 | #define UART_SW_DTR (BIT(7)) 94 | #define UART_SW_RTS (BIT(6)) 95 | #define UART_STOP_BIT_NUM 0x00000003 96 | #define UART_STOP_BIT_NUM_S 4 97 | #define UART_BIT_NUM 0x00000003 98 | #define UART_BIT_NUM_S 2 99 | #define UART_PARITY_EN (BIT(1)) 100 | #define UART_PARITY (BIT(0)) 101 | 102 | #define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24) 103 | #define UART_RX_TOUT_EN (BIT(31)) 104 | #define UART_RX_TOUT_THRHD 0x0000007F 105 | #define UART_RX_TOUT_THRHD_S 24 106 | #define UART_RX_FLOW_EN (BIT(23)) 107 | #define UART_RX_FLOW_THRHD 0x0000007F 108 | #define UART_RX_FLOW_THRHD_S 16 109 | #define UART_TXFIFO_EMPTY_THRHD 0x0000007F 110 | #define UART_TXFIFO_EMPTY_THRHD_S 8 111 | #define UART_RXFIFO_FULL_THRHD 0x0000007F 112 | #define UART_RXFIFO_FULL_THRHD_S 0 113 | 114 | #define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28) 115 | #define UART_LOWPULSE_MIN_CNT 0x000FFFFF 116 | #define UART_LOWPULSE_MIN_CNT_S 0 117 | 118 | #define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C) 119 | #define UART_HIGHPULSE_MIN_CNT 0x000FFFFF 120 | #define UART_HIGHPULSE_MIN_CNT_S 0 121 | 122 | #define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30) 123 | #define UART_PULSE_NUM_CNT 0x0003FF 124 | #define UART_PULSE_NUM_CNT_S 0 125 | 126 | #define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78) 127 | #define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C) 128 | #endif // UART_REGISTER_H_INCLUDED 129 | 130 | #define RX_BUFF_SIZE 256 131 | #define TX_BUFF_SIZE 100 132 | #define UART0 0 133 | #define UART1 1 134 | 135 | typedef enum { 136 | FIVE_BITS = 0x0, 137 | SIX_BITS = 0x1, 138 | SEVEN_BITS = 0x2, 139 | EIGHT_BITS = 0x3 140 | } UartBitsNum4Char; 141 | 142 | typedef enum { 143 | ONE_STOP_BIT = 0, 144 | ONE_HALF_STOP_BIT = BIT2, 145 | TWO_STOP_BIT = BIT2 146 | } UartStopBitsNum; 147 | 148 | typedef enum { 149 | NONE_BITS = 0, 150 | ODD_BITS = 0, 151 | EVEN_BITS = BIT4 152 | } UartParityMode; 153 | 154 | typedef enum { 155 | STICK_PARITY_DIS = 0, 156 | STICK_PARITY_EN = BIT3 | BIT5 157 | } UartExistParity; 158 | 159 | typedef enum { 160 | BIT_RATE_9600 = 9600, 161 | BIT_RATE_19200 = 19200, 162 | BIT_RATE_38400 = 38400, 163 | BIT_RATE_57600 = 57600, 164 | BIT_RATE_74880 = 74880, 165 | BIT_RATE_115200 = 115200, 166 | BIT_RATE_230400 = 230400, 167 | BIT_RATE_460800 = 460800, 168 | BIT_RATE_921600 = 921600 169 | } UartBautRate; 170 | 171 | typedef enum { 172 | NONE_CTRL, 173 | HARDWARE_CTRL, 174 | XON_XOFF_CTRL 175 | } UartFlowCtrl; 176 | 177 | typedef enum { 178 | EMPTY, 179 | UNDER_WRITE, 180 | WRITE_OVER 181 | } RcvMsgBuffState; 182 | 183 | typedef struct { 184 | uint32 TrxBuffSize; 185 | uint8 *pTrxBuff; 186 | } TrxMsgBuff; 187 | 188 | typedef enum { 189 | BAUD_RATE_DET, 190 | WAIT_SYNC_FRM, 191 | SRCH_MSG_HEAD, 192 | RCV_MSG_BODY, 193 | RCV_ESC_CHAR, 194 | } RcvMsgState; 195 | 196 | -------------------------------------------------------------------------------- /mqtt/README.md: -------------------------------------------------------------------------------- 1 | **esp_mqtt** 2 | ========== 3 | ![](https://travis-ci.org/tuanpmt/esp_mqtt.svg?branch=master) 4 | 5 | This is MQTT client library for ESP8266, port from: [MQTT client library for Contiki](https://github.com/esar/contiki-mqtt) (thanks) 6 | 7 | 8 | 9 | **Features:** 10 | 11 | * Support subscribing, publishing, authentication, will messages, keep alive pings and all 3 QoS levels (it should be a fully functional client). 12 | * Support multiple connection (to multiple hosts). 13 | * Support SSL connection (sdk 1.3 with path) 14 | * Easy to setup and use 15 | * Update support SDK 1.3 16 | 17 | **Compile:** 18 | 19 | Make sure to add PYTHON PATH and compile PATH to Eclipse environment variable if using Eclipse 20 | 21 | for Windows: 22 | 23 | ```bash 24 | git clone --recursive https://github.com/tuanpmt/esp_mqtt 25 | cd esp_mqtt 26 | #clean 27 | mingw32-make clean 28 | #make 29 | mingw32-make SDK_BASE="c:/Espressif/ESP8266_SDK" FLAVOR="release" all 30 | #flash 31 | mingw32-make ESPPORT="COM1" flash 32 | ``` 33 | 34 | for Mac or Linux: 35 | 36 | ```bash 37 | git clone --recursive https://github.com/tuanpmt/esp_mqtt 38 | cd esp_mqtt 39 | #clean 40 | make clean 41 | #make 42 | make SDK_BASE="/opt/Espressif/ESP8266_SDK" FLAVOR="release" all 43 | #flash 44 | make ESPPORT="/dev/ttyUSB0" flash 45 | ``` 46 | 47 | **Usage** 48 | ```c 49 | #include "ets_sys.h" 50 | #include "driver/uart.h" 51 | #include "osapi.h" 52 | #include "mqtt.h" 53 | #include "wifi.h" 54 | #include "config.h" 55 | #include "debug.h" 56 | #include "gpio.h" 57 | #include "user_interface.h" 58 | #include "mem.h" 59 | 60 | MQTT_Client mqttClient; 61 | 62 | void wifiConnectCb(uint8_t status) 63 | { 64 | if(status == STATION_GOT_IP){ 65 | MQTT_Connect(&mqttClient); 66 | } else { 67 | MQTT_Disconnect(&mqttClient); 68 | } 69 | } 70 | void mqttConnectedCb(uint32_t *args) 71 | { 72 | MQTT_Client* client = (MQTT_Client*)args; 73 | INFO("MQTT: Connected\r\n"); 74 | MQTT_Subscribe(client, "/mqtt/topic/0", 0); 75 | MQTT_Subscribe(client, "/mqtt/topic/1", 1); 76 | MQTT_Subscribe(client, "/mqtt/topic/2", 2); 77 | 78 | MQTT_Publish(client, "/mqtt/topic/0", "hello0", 6, 0, 0); 79 | MQTT_Publish(client, "/mqtt/topic/1", "hello1", 6, 1, 0); 80 | MQTT_Publish(client, "/mqtt/topic/2", "hello2", 6, 2, 0); 81 | 82 | } 83 | 84 | void mqttDisconnectedCb(uint32_t *args) 85 | { 86 | MQTT_Client* client = (MQTT_Client*)args; 87 | INFO("MQTT: Disconnected\r\n"); 88 | } 89 | 90 | void mqttPublishedCb(uint32_t *args) 91 | { 92 | MQTT_Client* client = (MQTT_Client*)args; 93 | INFO("MQTT: Published\r\n"); 94 | } 95 | 96 | void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) 97 | { 98 | char *topicBuf = (char*)os_zalloc(topic_len+1), 99 | *dataBuf = (char*)os_zalloc(data_len+1); 100 | 101 | MQTT_Client* client = (MQTT_Client*)args; 102 | 103 | os_memcpy(topicBuf, topic, topic_len); 104 | topicBuf[topic_len] = 0; 105 | 106 | os_memcpy(dataBuf, data, data_len); 107 | dataBuf[data_len] = 0; 108 | 109 | INFO("Receive topic: %s, data: %s \r\n", topicBuf, dataBuf); 110 | os_free(topicBuf); 111 | os_free(dataBuf); 112 | } 113 | 114 | 115 | void user_init(void) 116 | { 117 | uart_init(BIT_RATE_115200, BIT_RATE_115200); 118 | os_delay_us(1000000); 119 | 120 | CFG_Load(); 121 | 122 | MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.security); 123 | //MQTT_InitConnection(&mqttClient, "192.168.11.122", 1880, 0); 124 | 125 | MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive, 1); 126 | //MQTT_InitClient(&mqttClient, "client_id", "user", "pass", 120, 1); 127 | 128 | MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); 129 | MQTT_OnConnected(&mqttClient, mqttConnectedCb); 130 | MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb); 131 | MQTT_OnPublished(&mqttClient, mqttPublishedCb); 132 | MQTT_OnData(&mqttClient, mqttDataCb); 133 | 134 | WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb); 135 | 136 | INFO("\r\nSystem started ...\r\n"); 137 | } 138 | 139 | ``` 140 | 141 | **Publish message and Subscribe** 142 | 143 | ```c 144 | /* TRUE if success */ 145 | BOOL MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos); 146 | 147 | BOOL MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain); 148 | 149 | ``` 150 | 151 | **Already support LWT: (Last Will and Testament)** 152 | 153 | ```c 154 | 155 | /* Broker will publish a message with qos = 0, retain = 0, data = "offline" to topic "/lwt" if client don't send keepalive packet */ 156 | MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); 157 | 158 | ``` 159 | 160 | #Default configuration 161 | 162 | See: **include/user_config.h** 163 | 164 | If you want to load new default configurations, just change the value of CFG_HOLDER in **include/user_config.h** 165 | 166 | **Define protocol name in include/user_config.h** 167 | 168 | ```c 169 | #define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*/ 170 | //PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/ 171 | ``` 172 | 173 | In the Makefile, it will erase section hold the user configuration at 0x3C000 174 | 175 | ```bash 176 | flash: firmware/0x00000.bin firmware/0x40000.bin 177 | $(PYTHON) $(ESPTOOL) -p $(ESPPORT) write_flash 0x00000 firmware/0x00000.bin 0x3C000 $(BLANKER) 0x40000 firmware/0x40000.bin 178 | ``` 179 | The BLANKER is the blank.bin file you find in your SDKs bin folder. 180 | 181 | **Create SSL Self sign** 182 | 183 | ``` 184 | openssl req -x509 -newkey rsa:1024 -keyout key.pem -out cert.pem -days XXX 185 | ``` 186 | 187 | **SSL Mqtt broker for test** 188 | 189 | ```javascript 190 | var mosca = require('mosca') 191 | var SECURE_KEY = __dirname + '/key.pem'; 192 | var SECURE_CERT = __dirname + '/cert.pem'; 193 | var ascoltatore = { 194 | //using ascoltatore 195 | type: 'mongo', 196 | url: 'mongodb://localhost:27017/mqtt', 197 | pubsubCollection: 'ascoltatori', 198 | mongo: {} 199 | }; 200 | 201 | var moscaSettings = { 202 | port: 1880, 203 | stats: false, 204 | backend: ascoltatore, 205 | persistence: { 206 | factory: mosca.persistence.Mongo, 207 | url: 'mongodb://localhost:27017/mqtt' 208 | }, 209 | secure : { 210 | keyPath: SECURE_KEY, 211 | certPath: SECURE_CERT, 212 | port: 1883 213 | } 214 | }; 215 | 216 | var server = new mosca.Server(moscaSettings); 217 | server.on('ready', setup); 218 | 219 | server.on('clientConnected', function(client) { 220 | console.log('client connected', client.id); 221 | }); 222 | 223 | // fired when a message is received 224 | server.on('published', function(packet, client) { 225 | console.log('Published', packet.payload); 226 | }); 227 | 228 | // fired when the mqtt server is ready 229 | function setup() { 230 | console.log('Mosca server is up and running') 231 | } 232 | ``` 233 | 234 | **Example projects using esp_mqtt:**
235 | - [https://github.com/eadf/esp_mqtt_lcd](https://github.com/eadf/esp_mqtt_lcd) 236 | 237 | **Limited:**
238 | - Not fully supported retransmit for QoS1 and QoS2 239 | 240 | **Status:** *Pre release.* 241 | 242 | [https://github.com/tuanpmt/esp_mqtt/releases](https://github.com/tuanpmt/esp_mqtt/releases) 243 | 244 | [MQTT Broker for test](https://github.com/mcollina/mosca) 245 | 246 | [MQTT Client for test](https://chrome.google.com/webstore/detail/mqttlens/hemojaaeigabkbcookmlgmdigohjobjm?hl=en) 247 | 248 | **Contributing:** 249 | 250 | ***Feel free to contribute to the project in any way you like!*** 251 | 252 | **Requried:** 253 | 254 | SDK esp_iot_sdk_v0.9.4_14_12_19 or higher 255 | 256 | **Authors:** 257 | [Tuan PM](https://twitter.com/TuanPMT) 258 | 259 | 260 | 261 | **LICENSE - "MIT License"** 262 | 263 | Copyright (c) 2014-2015 Tuan PM, https://twitter.com/TuanPMT 264 | 265 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 266 | 267 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 268 | 269 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 270 | -------------------------------------------------------------------------------- /mqtt/driver/uart.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Copyright 2013-2014 Espressif Systems (Wuxi) 3 | * 4 | * FileName: uart.c 5 | * 6 | * Description: Two UART mode configration and interrupt handler. 7 | * Check your hardware connection while use this mode. 8 | * 9 | * Modification history: 10 | * 2014/3/12, v1.0 create this file. 11 | *******************************************************************************/ 12 | #include "ets_sys.h" 13 | #include "osapi.h" 14 | #include "driver/uart.h" 15 | #include "osapi.h" 16 | #include "driver/uart_register.h" 17 | //#include "ssc.h" 18 | 19 | 20 | // UartDev is defined and initialized in rom code. 21 | extern UartDevice UartDev; 22 | //extern os_event_t at_recvTaskQueue[at_recvTaskQueueLen]; 23 | 24 | LOCAL void uart0_rx_intr_handler(void *para); 25 | 26 | /****************************************************************************** 27 | * FunctionName : uart_config 28 | * Description : Internal used function 29 | * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled 30 | * UART1 just used for debug output 31 | * Parameters : uart_no, use UART0 or UART1 defined ahead 32 | * Returns : NONE 33 | *******************************************************************************/ 34 | LOCAL void ICACHE_FLASH_ATTR 35 | uart_config(uint8 uart_no) 36 | { 37 | if (uart_no == UART1) 38 | { 39 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); 40 | } 41 | else 42 | { 43 | /* rcv_buff size if 0x100 */ 44 | ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); 45 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); 46 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); 47 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); 48 | } 49 | 50 | uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate)); 51 | 52 | WRITE_PERI_REG(UART_CONF0(uart_no), UartDev.exist_parity 53 | | UartDev.parity 54 | | (UartDev.stop_bits << UART_STOP_BIT_NUM_S) 55 | | (UartDev.data_bits << UART_BIT_NUM_S)); 56 | 57 | //clear rx and tx fifo,not ready 58 | SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); 59 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); 60 | 61 | //set rx fifo trigger 62 | // WRITE_PERI_REG(UART_CONF1(uart_no), 63 | // ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | 64 | // ((96 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) | 65 | // UART_RX_FLOW_EN); 66 | if (uart_no == UART0) 67 | { 68 | //set rx fifo trigger 69 | WRITE_PERI_REG(UART_CONF1(uart_no), 70 | ((0x10 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | 71 | ((0x10 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | 72 | UART_RX_FLOW_EN | 73 | (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | 74 | UART_RX_TOUT_EN); 75 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA | 76 | UART_FRM_ERR_INT_ENA); 77 | } 78 | else 79 | { 80 | WRITE_PERI_REG(UART_CONF1(uart_no), 81 | ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); 82 | } 83 | 84 | //clear all interrupt 85 | WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); 86 | //enable rx_interrupt 87 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); 88 | } 89 | 90 | /****************************************************************************** 91 | * FunctionName : uart1_tx_one_char 92 | * Description : Internal used function 93 | * Use uart1 interface to transfer one char 94 | * Parameters : uint8 TxChar - character to tx 95 | * Returns : OK 96 | *******************************************************************************/ 97 | LOCAL STATUS 98 | uart_tx_one_char(uint8 uart, uint8 TxChar) 99 | { 100 | while (true) 101 | { 102 | uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { 104 | break; 105 | } 106 | } 107 | 108 | WRITE_PERI_REG(UART_FIFO(uart) , TxChar); 109 | return OK; 110 | } 111 | 112 | /****************************************************************************** 113 | * FunctionName : uart1_write_char 114 | * Description : Internal used function 115 | * Do some special deal while tx char is '\r' or '\n' 116 | * Parameters : char c - character to tx 117 | * Returns : NONE 118 | *******************************************************************************/ 119 | void ICACHE_FLASH_ATTR 120 | uart1_write_char(char c) 121 | { 122 | if (c == '\n') 123 | { 124 | uart_tx_one_char(UART1, '\r'); 125 | uart_tx_one_char(UART1, '\n'); 126 | } 127 | else if (c == '\r') 128 | { 129 | } 130 | else 131 | { 132 | uart_tx_one_char(UART1, c); 133 | } 134 | } 135 | 136 | void ICACHE_FLASH_ATTR 137 | uart0_write_char(char c) 138 | { 139 | if (c == '\n') 140 | { 141 | uart_tx_one_char(UART0, '\r'); 142 | uart_tx_one_char(UART0, '\n'); 143 | } 144 | else if (c == '\r') 145 | { 146 | } 147 | else 148 | { 149 | uart_tx_one_char(UART0, c); 150 | } 151 | } 152 | /****************************************************************************** 153 | * FunctionName : uart0_tx_buffer 154 | * Description : use uart0 to transfer buffer 155 | * Parameters : uint8 *buf - point to send buffer 156 | * uint16 len - buffer len 157 | * Returns : 158 | *******************************************************************************/ 159 | void ICACHE_FLASH_ATTR 160 | uart0_tx_buffer(uint8 *buf, uint16 len) 161 | { 162 | uint16 i; 163 | 164 | for (i = 0; i < len; i++) 165 | { 166 | uart_tx_one_char(UART0, buf[i]); 167 | } 168 | } 169 | 170 | /****************************************************************************** 171 | * FunctionName : uart0_sendStr 172 | * Description : use uart0 to transfer buffer 173 | * Parameters : uint8 *buf - point to send buffer 174 | * uint16 len - buffer len 175 | * Returns : 176 | *******************************************************************************/ 177 | void ICACHE_FLASH_ATTR 178 | uart0_sendStr(const char *str) 179 | { 180 | while(*str) 181 | { 182 | uart_tx_one_char(UART0, *str++); 183 | } 184 | } 185 | 186 | /****************************************************************************** 187 | * FunctionName : uart0_rx_intr_handler 188 | * Description : Internal used function 189 | * UART0 interrupt handler, add self handle code inside 190 | * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg 191 | * Returns : NONE 192 | *******************************************************************************/ 193 | //extern void at_recvTask(void); 194 | 195 | LOCAL void 196 | uart0_rx_intr_handler(void *para) 197 | { 198 | /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents 199 | * uart1 and uart0 respectively 200 | */ 201 | // RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para; 202 | uint8 RcvChar; 203 | uint8 uart_no = UART0;//UartDev.buff_uart_no; 204 | 205 | // if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) 206 | // { 207 | // return; 208 | // } 209 | // if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) 210 | // { 211 | //// at_recvTask(); 212 | // RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; 213 | // system_os_post(at_recvTaskPrio, NULL, RcvChar); 214 | // WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); 215 | // } 216 | if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) 217 | { 218 | os_printf("FRM_ERR\r\n"); 219 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); 220 | } 221 | 222 | if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) 223 | { 224 | // os_printf("fifo full\r\n"); 225 | ETS_UART_INTR_DISABLE();///////// 226 | 227 | //system_os_post(at_recvTaskPrio, 0, 0); 228 | 229 | // WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); 230 | // while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) 231 | // { 232 | //// at_recvTask(); 233 | // RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; 234 | // system_os_post(at_recvTaskPrio, NULL, RcvChar); 235 | // } 236 | } 237 | else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) 238 | { 239 | ETS_UART_INTR_DISABLE();///////// 240 | 241 | //system_os_post(at_recvTaskPrio, 0, 0); 242 | 243 | // WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_TOUT_INT_CLR); 244 | //// os_printf("rx time over\r\n"); 245 | // while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) 246 | // { 247 | //// os_printf("process recv\r\n"); 248 | //// at_recvTask(); 249 | // RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; 250 | // system_os_post(at_recvTaskPrio, NULL, RcvChar); 251 | // } 252 | } 253 | 254 | // WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); 255 | 256 | // if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) 257 | // { 258 | // RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; 259 | // at_recvTask(); 260 | // *(pRxBuff->pWritePos) = RcvChar; 261 | 262 | // system_os_post(at_recvTaskPrio, NULL, RcvChar); 263 | 264 | // //insert here for get one command line from uart 265 | // if (RcvChar == '\r') 266 | // { 267 | // pRxBuff->BuffState = WRITE_OVER; 268 | // } 269 | // 270 | // pRxBuff->pWritePos++; 271 | // 272 | // if (pRxBuff->pWritePos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE)) 273 | // { 274 | // // overflow ...we may need more error handle here. 275 | // pRxBuff->pWritePos = pRxBuff->pRcvMsgBuff ; 276 | // } 277 | // } 278 | } 279 | 280 | /****************************************************************************** 281 | * FunctionName : uart_init 282 | * Description : user interface for init uart 283 | * Parameters : UartBautRate uart0_br - uart0 bautrate 284 | * UartBautRate uart1_br - uart1 bautrate 285 | * Returns : NONE 286 | *******************************************************************************/ 287 | void ICACHE_FLASH_ATTR 288 | uart_init(UartBautRate uart0_br, UartBautRate uart1_br) 289 | { 290 | // rom use 74880 baut_rate, here reinitialize 291 | UartDev.baut_rate = uart0_br; 292 | uart_config(UART0); 293 | UartDev.baut_rate = uart1_br; 294 | uart_config(UART1); 295 | ETS_UART_INTR_ENABLE(); 296 | 297 | // install uart1 putc callback 298 | os_install_putc1((void *)uart0_write_char); 299 | } 300 | 301 | void ICACHE_FLASH_ATTR 302 | uart_reattach() 303 | { 304 | uart_init(BIT_RATE_74880, BIT_RATE_74880); 305 | // ETS_UART_INTR_ATTACH(uart_rx_intr_handler_ssc, &(UartDev.rcv_buff)); 306 | // ETS_UART_INTR_ENABLE(); 307 | } 308 | -------------------------------------------------------------------------------- /user/user_main.c: -------------------------------------------------------------------------------- 1 | /* main.c -- MQTT client example 2 | * 3 | * Copyright (c) 2014-2015, Tuan PM 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "ets_sys.h" 31 | #include "osapi.h" 32 | #include "mqtt.h" 33 | #include "wifi.h" 34 | #include "config.h" 35 | #include "debug.h" 36 | #include "gpio.h" 37 | #include "user_interface.h" 38 | #include "stdout/stdout.h" 39 | #include "mem.h" 40 | #include "pcd8544/pcd8544.h" 41 | #include "user_config.h" 42 | 43 | static uint8_t openhardware_logo[] = { 44 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xe0,0xe0,0xe0,0xc0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0xe0,0xe0,0xe0,0xe0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 45 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x1f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x1e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 46 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xc0,0xe0,0xe0,0xe0,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x1f,0x1f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x1f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xf0,0xe0,0xe0,0xe0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 47 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7f,0x7f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe1,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xe1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x7f,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 48 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x1e,0x00,0x00,0x00,0x00,0x00,0x06,0x1e,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcf,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 49 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x1f,0x3f,0x7f,0xff,0xff,0xff,0x7f,0x7f,0x3f,0x3f,0x1f,0x3f,0x3f,0x3f,0x0f,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0f,0x3f,0x3f,0x3f,0x1f,0x3f,0x3f,0x7f,0xff,0xff,0xff,0xff,0x3f,0x3f,0x1e,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 50 | }; 51 | 52 | static PCD8544_Settings pcd8544_settings; 53 | 54 | #define user_procTaskPeriod 1000 55 | static volatile os_timer_t lcd_timer; 56 | 57 | MQTT_Client mqttClient; 58 | static char clientid[66]; 59 | 60 | void ICACHE_FLASH_ATTR 61 | wifiConnectCb(uint8_t status) { 62 | 63 | // Use the hex encoded system_get_chip_id() value as 64 | // an unique topic (that still fits on the screen) 65 | os_sprintf(clientid, "/%0x", system_get_chip_id()); 66 | 67 | if(status == STATION_GOT_IP){ 68 | os_printf("Connecting to MQTT server %s:%d\n", MQTT_HOST, MQTT_PORT); 69 | MQTT_Connect(&mqttClient); 70 | } else { 71 | MQTT_Disconnect(&mqttClient); 72 | } 73 | } 74 | 75 | void ICACHE_FLASH_ATTR 76 | mqttConnectedCb(uint32_t *args) { 77 | MQTT_Client* client = (MQTT_Client*) args; 78 | INFO("MQTT: Connected! will use %s as MQTT topic \n", clientid); 79 | char *buf = " "; 80 | int i = 0; 81 | 82 | for (i=0; i<6; i++){ 83 | os_sprintf(buf, "/lcd%1d", i); 84 | MQTT_Subscribe(client, buf, 0); 85 | os_sprintf(buf, "%s/lcd%1d", clientid, i); 86 | MQTT_Subscribe(client, buf, 0); 87 | } 88 | 89 | MQTT_Subscribe(client, "/lcd/clearscreen", 0); 90 | os_sprintf(buf, "%s/clearscreen", clientid); 91 | MQTT_Subscribe(client, buf, 0); 92 | MQTT_Subscribe(client, "/lcd/contrast", 0); 93 | os_sprintf(buf, "%s/contrast", clientid); 94 | MQTT_Subscribe(client, buf, 0); 95 | } 96 | 97 | void mqttDisconnectedCb(uint32_t *args) { 98 | MQTT_Client* client = (MQTT_Client*)args; 99 | INFO("MQTT: Disconnected\r\n"); 100 | } 101 | 102 | void ICACHE_FLASH_ATTR 103 | mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len) { 104 | 105 | char *topicBuf = (char*) os_zalloc(topic_len + 1), *dataBuf = (char*) os_zalloc(data_len + 1); 106 | 107 | MQTT_Client* client = (MQTT_Client*) args; 108 | os_memcpy(topicBuf, topic, topic_len); 109 | topicBuf[topic_len] = 0; 110 | char *sp = topicBuf; // string pointer accessing internals of topicBuf 111 | 112 | os_memcpy(dataBuf, data, data_len); 113 | dataBuf[data_len] = 0; 114 | 115 | INFO("Received topic: %s, data: %s [%d]\n", topicBuf, dataBuf, data_len); 116 | if (strncmp(sp, clientid, strlen(clientid)) == 0) { 117 | sp += strlen(clientid); 118 | } 119 | 120 | if (strcmp(sp, "/lcd0") == 0) { 121 | PCD8544_gotoXY(0,0); 122 | PCD8544_lcdPrint(dataBuf); 123 | PCD8544_lcdPad(PCD8544_LCD_CHARS_PER_LINE-data_len); 124 | } else if (strcmp(sp, "/lcd1") == 0) { 125 | PCD8544_gotoXY(0,1); 126 | PCD8544_lcdPrint(dataBuf); 127 | PCD8544_lcdPad(PCD8544_LCD_CHARS_PER_LINE-data_len); 128 | } else if (strcmp(sp, "/lcd2") == 0) { 129 | PCD8544_gotoXY(0,2); 130 | PCD8544_lcdPrint(dataBuf); 131 | PCD8544_lcdPad(PCD8544_LCD_CHARS_PER_LINE-data_len); 132 | } else if (strcmp(sp, "/lcd3") == 0) { 133 | PCD8544_gotoXY(0,3); 134 | PCD8544_lcdPrint(dataBuf); 135 | PCD8544_lcdPad(PCD8544_LCD_CHARS_PER_LINE-data_len); 136 | } else if (strcmp(sp, "/lcd4") == 0) { 137 | PCD8544_gotoXY(0,4); 138 | PCD8544_lcdPrint(dataBuf); 139 | PCD8544_lcdPad(PCD8544_LCD_CHARS_PER_LINE-data_len); 140 | } else if (strcmp(sp, "/lcd5") == 0) { 141 | PCD8544_gotoXY(0,5); 142 | PCD8544_lcdPrint(dataBuf); 143 | PCD8544_lcdPad(PCD8544_LCD_CHARS_PER_LINE-data_len); 144 | } else if ( (strcmp(topicBuf, "/lcd/contrast") == 0) || (strcmp(sp, "/contrast") == 0)) { 145 | uint8_t contrast = atoi(dataBuf); 146 | if (contrast>0){ 147 | // atoi("random non-numeric string") will return 0 148 | INFO("Setting contrast to %d\n", contrast); 149 | PCD8544_setContrast(contrast); 150 | } 151 | } else if ((strcmp(topicBuf, "/lcd/clearscreen") == 0) || (strcmp(sp, "/clearscreen") == 0)) { 152 | PCD8544_lcdClear(); 153 | } 154 | 155 | os_free(topicBuf); 156 | os_free(dataBuf); 157 | } 158 | 159 | /** 160 | * Show open hardware logo at startup 161 | */ 162 | static void ICACHE_FLASH_ATTR 163 | lcdInitTask(os_event_t *events) { 164 | static uint32_t loopIterations = 0; 165 | loopIterations+=1; 166 | if (loopIterations < 2) { 167 | // I wonder why the calls to initLCD in user_init doesn't 'take' 168 | PCD8544_initLCD(&pcd8544_settings); 169 | os_delay_us(50000); 170 | PCD8544_lcdImage(openhardware_logo); 171 | os_printf("Initiating display: %d\n", loopIterations); 172 | os_timer_disarm(&lcd_timer); 173 | os_timer_arm(&lcd_timer, user_procTaskPeriod, 0); 174 | } else if (loopIterations == 2){ 175 | PCD8544_lcdClear(); 176 | PCD8544_gotoXY(0,0); 177 | PCD8544_lcdPrint("mqtt topic:"); 178 | PCD8544_gotoXY(0,1); 179 | PCD8544_lcdPrint(clientid); 180 | } 181 | } 182 | 183 | void ICACHE_FLASH_ATTR 184 | user_init(void) { 185 | pcd8544_settings.lcdVop = PCD8544_CONTRAST; 186 | pcd8544_settings.tempCoeff = 0x04; 187 | pcd8544_settings.biasMode = 0x14; 188 | pcd8544_settings.inverse = false; 189 | 190 | // you can change these values to any pin you like and have access to 191 | pcd8544_settings.resetPin = PCD8544_RESET_PIN; //-1; This pin is now optional. 192 | // Set it to negative value to disable. 193 | // If you do disable it, you must tie LCD reset pin to esp reset via resistor. 194 | pcd8544_settings.scePin = PCD8544_SCE_PIN; //-1; This pin is now optional. 195 | // Set it to negative value to disable. 196 | // If you do disable it, you must tie LCD CE pin to GND via resistor. 197 | // dcPin, sdinPin and sclkPin can be used for other SPI devices if scePin is *NOT* disabled. 198 | pcd8544_settings.dcPin = PCD8544_DC_PIN; 199 | pcd8544_settings.sdinPin = PCD8544_SDIN_PIN; 200 | pcd8544_settings.sclkPin = PCD8544_SCLK_PIN; 201 | 202 | // Make uart0 work with just the TX pin. Baud:115200,n,8,1 203 | // The RX pin is now free for GPIO use. 204 | stdout_init(); 205 | 206 | os_delay_us(1000000); // wait a second 207 | PCD8544_init(&pcd8544_settings); 208 | PCD8544_initLCD(&pcd8544_settings); 209 | 210 | CFG_Load(); 211 | 212 | MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.security); 213 | 214 | MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive, 1); 215 | 216 | MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0); 217 | MQTT_OnConnected(&mqttClient, mqttConnectedCb); 218 | MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb); 219 | MQTT_OnData(&mqttClient, mqttDataCb); 220 | 221 | WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb); 222 | 223 | os_timer_setfn(&lcd_timer, (os_timer_func_t*) lcdInitTask, NULL); 224 | os_timer_arm(&lcd_timer, user_procTaskPeriod, 0); 225 | 226 | INFO("\nSystem started ...\n"); 227 | } 228 | -------------------------------------------------------------------------------- /driver/easygpio/easygpio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * easygpio.c 3 | * 4 | * Copyright (c) 2015, eadf (https://github.com/eadf) 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #include "easygpio/easygpio.h" 33 | #include "gpio.h" 34 | #include "osapi.h" 35 | #include "ets_sys.h" 36 | 37 | #define EASYGPIO_USE_GPIO_INPUT_GET 38 | 39 | static void ICACHE_FLASH_ATTR 40 | gpio16_output_conf(void) { 41 | WRITE_PERI_REG(PAD_XPD_DCDC_CONF, 42 | (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbcUL) | 0x1UL); // mux configuration for XPD_DCDC to output rtc_gpio0 43 | 44 | WRITE_PERI_REG(RTC_GPIO_CONF, 45 | (READ_PERI_REG(RTC_GPIO_CONF) & 0xfffffffeUL) | 0x0UL); //mux configuration for out enable 46 | 47 | WRITE_PERI_REG(RTC_GPIO_ENABLE, 48 | (READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL) | 0x1UL); //out enable 49 | } 50 | 51 | static void ICACHE_FLASH_ATTR 52 | gpio16_input_conf(void) { 53 | WRITE_PERI_REG(PAD_XPD_DCDC_CONF, 54 | (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbcUL) | 0x1UL); // mux configuration for XPD_DCDC and rtc_gpio0 connection 55 | 56 | WRITE_PERI_REG(RTC_GPIO_CONF, 57 | (READ_PERI_REG(RTC_GPIO_CONF) & 0xfffffffeUL) | 0x0UL); //mux configuration for out enable 58 | 59 | WRITE_PERI_REG(RTC_GPIO_ENABLE, 60 | READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL); //out disable 61 | } 62 | 63 | /** 64 | * Returns the number of active pins in the gpioMask. 65 | */ 66 | uint8_t ICACHE_FLASH_ATTR 67 | easygpio_countBits(uint32_t gpioMask) { 68 | 69 | uint8_t i=0; 70 | uint8_t numberOfPins=0; 71 | for (i=0; i<32; i++){ 72 | numberOfPins += (gpioMask & BIT(i))?1:0; 73 | } 74 | return numberOfPins; 75 | } 76 | 77 | /** 78 | * Returns the gpio name and func for a specific pin. 79 | */ 80 | bool ICACHE_FLASH_ATTR 81 | easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func) { 82 | 83 | if (gpio_pin == 6 || gpio_pin == 7 || gpio_pin == 8 || gpio_pin == 11 || gpio_pin >= 17) { 84 | os_printf("easygpio_getGPIONameFunc Error: There is no GPIO%d, check your code\n", gpio_pin); 85 | return false; 86 | } 87 | if (gpio_pin == 16) { 88 | os_printf("easygpio_getGPIONameFunc Error: GPIO16 does not have gpio_name and gpio_func\n"); 89 | return false; 90 | } 91 | switch ( gpio_pin ) { 92 | case 0: 93 | *gpio_func = FUNC_GPIO0; 94 | *gpio_name = PERIPHS_IO_MUX_GPIO0_U; 95 | return true; 96 | case 1: 97 | *gpio_func = FUNC_GPIO1; 98 | *gpio_name = PERIPHS_IO_MUX_U0TXD_U; 99 | return true; 100 | case 2: 101 | *gpio_func = FUNC_GPIO2; 102 | *gpio_name = PERIPHS_IO_MUX_GPIO2_U; 103 | return true; 104 | case 3: 105 | *gpio_func = FUNC_GPIO3; 106 | *gpio_name = PERIPHS_IO_MUX_U0RXD_U; 107 | return true; 108 | case 4: 109 | *gpio_func = FUNC_GPIO4; 110 | *gpio_name = PERIPHS_IO_MUX_GPIO4_U; 111 | return true; 112 | case 5: 113 | *gpio_func = FUNC_GPIO5; 114 | *gpio_name = PERIPHS_IO_MUX_GPIO5_U; 115 | return true; 116 | case 9: 117 | *gpio_func = FUNC_GPIO9; 118 | *gpio_name = PERIPHS_IO_MUX_SD_DATA2_U; 119 | return true; 120 | case 10: 121 | *gpio_func = FUNC_GPIO10; 122 | *gpio_name = PERIPHS_IO_MUX_SD_DATA3_U; 123 | return true; 124 | case 12: 125 | *gpio_func = FUNC_GPIO12; 126 | *gpio_name = PERIPHS_IO_MUX_MTDI_U; 127 | return true; 128 | case 13: 129 | *gpio_func = FUNC_GPIO13; 130 | *gpio_name = PERIPHS_IO_MUX_MTCK_U; 131 | return true; 132 | case 14: 133 | *gpio_func = FUNC_GPIO14; 134 | *gpio_name = PERIPHS_IO_MUX_MTMS_U; 135 | return true; 136 | case 15: 137 | *gpio_func = FUNC_GPIO15; 138 | *gpio_name = PERIPHS_IO_MUX_MTDO_U; 139 | return true; 140 | default: 141 | return false; 142 | } 143 | return true; 144 | } 145 | 146 | /** 147 | * Sets the pull up registers for a pin. 148 | */ 149 | static void ICACHE_FLASH_ATTR 150 | easygpio_setupPullsByName(uint32_t gpio_name, EasyGPIO_PullStatus pullStatus) { 151 | 152 | if (EASYGPIO_PULLUP == pullStatus) { 153 | PIN_PULLUP_EN(gpio_name); 154 | } else { 155 | PIN_PULLUP_DIS(gpio_name); 156 | } 157 | } 158 | 159 | /** 160 | * Sets the pull registers for a pin. 161 | */ 162 | bool ICACHE_FLASH_ATTR 163 | easygpio_pullMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus) { 164 | uint32_t gpio_name; 165 | uint8_t gpio_func; 166 | 167 | if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) { 168 | return false; 169 | } 170 | 171 | easygpio_setupPullsByName(gpio_name, pullStatus); 172 | return true; 173 | } 174 | 175 | /** 176 | * Sets the 'gpio_pin' pin as a GPIO and sets the pull register for that pin. 177 | * 'pullStatus' has no effect on output pins or GPIO16 178 | */ 179 | bool ICACHE_FLASH_ATTR 180 | easygpio_pinMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, EasyGPIO_PinMode pinMode) { 181 | uint32_t gpio_name; 182 | uint8_t gpio_func; 183 | 184 | if (16==gpio_pin) { 185 | // ignoring pull status on GPIO16 for now 186 | if (EASYGPIO_OUTPUT == pinMode) { 187 | gpio16_output_conf(); 188 | } else { 189 | gpio16_input_conf(); 190 | } 191 | return true; 192 | } else if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) { 193 | return false; 194 | } 195 | 196 | PIN_FUNC_SELECT(gpio_name, gpio_func); 197 | easygpio_setupPullsByName(gpio_name, pullStatus); 198 | 199 | if (EASYGPIO_OUTPUT != pinMode) { 200 | GPIO_DIS_OUTPUT(GPIO_ID_PIN(gpio_pin)); 201 | } else { 202 | // must enable the pin or else the WRITE_PERI_REG won't work 203 | gpio_output_set(0, 0, BIT(GPIO_ID_PIN(gpio_pin)),0); 204 | } 205 | return true; 206 | } 207 | 208 | /** 209 | * Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin. 210 | * The 'interruptArg' is the function argument that will be sent to your interruptHandler 211 | */ 212 | bool ICACHE_FLASH_ATTR 213 | easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void *arg), void *interruptArg) { 214 | uint32_t gpio_name; 215 | uint8_t gpio_func; 216 | 217 | if (gpio_pin == 16) { 218 | os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n"); 219 | return false; 220 | } 221 | if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) { 222 | return false; 223 | } 224 | 225 | ETS_GPIO_INTR_ATTACH(interruptHandler, interruptArg); 226 | ETS_GPIO_INTR_DISABLE(); 227 | 228 | PIN_FUNC_SELECT(gpio_name, gpio_func); 229 | 230 | easygpio_setupPullsByName(gpio_name, pullStatus); 231 | 232 | // disable output 233 | GPIO_DIS_OUTPUT(gpio_pin); 234 | 235 | gpio_register_set(GPIO_PIN_ADDR(gpio_pin), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) 236 | | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) 237 | | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE)); 238 | 239 | //clear gpio14 status 240 | GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(gpio_pin)); 241 | ETS_GPIO_INTR_ENABLE(); 242 | 243 | return true; 244 | } 245 | 246 | /** 247 | * Detach the interrupt handler from the 'gpio_pin' pin. 248 | */ 249 | bool ICACHE_FLASH_ATTR 250 | easygpio_detachInterrupt(uint8_t gpio_pin) { 251 | 252 | if (gpio_pin == 16) { 253 | os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n"); 254 | return false; 255 | } 256 | 257 | // Don't know how to detach interrupt, yet. 258 | // Quick and dirty fix - just disable the interrupt 259 | gpio_pin_intr_state_set(GPIO_ID_PIN(gpio_pin), GPIO_PIN_INTR_DISABLE); 260 | return true; 261 | } 262 | 263 | /** 264 | * Uniform way of setting GPIO output value. Handles GPIO 0-16. 265 | * 266 | * You can not rely on that this function will switch the gpio to an output like GPIO_OUTPUT_SET does. 267 | * Use easygpio_outputEnable() to change an input gpio to output mode. 268 | */ 269 | void 270 | easygpio_outputSet(uint8_t gpio_pin, uint8_t value) { 271 | if (16==gpio_pin) { 272 | WRITE_PERI_REG(RTC_GPIO_OUT, 273 | (READ_PERI_REG(RTC_GPIO_OUT) & 0xfffffffeUL) | (0x1UL & value)); 274 | } else { 275 | #ifdef EASYGPIO_USE_GPIO_OUTPUT_SET 276 | GPIO_OUTPUT_SET(GPIO_ID_PIN(gpio_pin), value); 277 | #else 278 | if (value&1){ 279 | WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR, READ_PERI_REG(PERIPHS_GPIO_BASEADDR) | BIT(gpio_pin)); 280 | } else { 281 | WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR, READ_PERI_REG(PERIPHS_GPIO_BASEADDR) & ~BIT(gpio_pin)); 282 | } 283 | #endif 284 | } 285 | } 286 | 287 | /** 288 | * Uniform way of getting GPIO input value. Handles GPIO 0-16. 289 | * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. 290 | * If you know that you won't be using GPIO16 then you'd better off by just using GPIO_INPUT_GET(). 291 | */ 292 | uint8_t 293 | easygpio_inputGet(uint8_t gpio_pin) { 294 | if (16==gpio_pin) { 295 | return (READ_PERI_REG(RTC_GPIO_IN_DATA) & 1UL); 296 | } else { 297 | #ifdef EASYGPIO_USE_GPIO_INPUT_GET 298 | return GPIO_INPUT_GET(GPIO_ID_PIN(gpio_pin)); 299 | #else 300 | // this does *not* work, maybe GPIO_IN_ADDRESS is the wrong address 301 | return ((GPIO_REG_READ(GPIO_IN_ADDRESS) > gpio_pin) & 1UL); 302 | #endif 303 | } 304 | } 305 | 306 | /** 307 | * Uniform way of turning an output GPIO pin into input mode. Handles GPIO 0-16. 308 | * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. 309 | * This function does the same thing as GPIO_DIS_OUTPUT, but works on GPIO16 too. 310 | */ 311 | void easygpio_outputDisable(uint8_t gpio_pin) { 312 | if (16==gpio_pin) { 313 | WRITE_PERI_REG(RTC_GPIO_ENABLE, 314 | READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL); //out disable 315 | } else { 316 | GPIO_DIS_OUTPUT(GPIO_ID_PIN(gpio_pin)); 317 | } 318 | } 319 | 320 | /** 321 | * Uniform way of turning an input GPIO pin into output mode. Handles GPIO 0-16. 322 | * The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place. 323 | * 324 | * This function: 325 | * - should only be used to convert a input pin into an output pin. 326 | * - is a little bit slower than easygpio_outputSet() so you should use that 327 | * function to just change output value. 328 | * - does the same thing as GPIO_OUTPUT_SET, but works on GPIO16 too. 329 | */ 330 | void easygpio_outputEnable(uint8_t gpio_pin, uint8_t value) { 331 | if (16==gpio_pin) { 332 | // write the value before flipping to output 333 | // - so we don't flash previous value for a few ns. 334 | WRITE_PERI_REG(RTC_GPIO_OUT, 335 | (READ_PERI_REG(RTC_GPIO_OUT) & 0xfffffffeUL) | (0x1UL & value)); 336 | 337 | WRITE_PERI_REG(RTC_GPIO_ENABLE, 338 | (READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL) | 0x1UL); //out enable 339 | 340 | } else { 341 | GPIO_OUTPUT_SET(GPIO_ID_PIN(gpio_pin), value); 342 | } 343 | } 344 | -------------------------------------------------------------------------------- /driver/pcd8544/pcd8544.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pcd8544.c 3 | * 4 | * PCD8544 bit-banging driver ported from http://playground.arduino.cc/Code/PCD8544 5 | * 6 | * Created on: Jan 7, 2015 7 | * Author: Eadf 8 | */ 9 | 10 | #include "pcd8544/pcd8544.h" 11 | #include "easygpio/easygpio.h" 12 | #include "osapi.h" 13 | #include "ets_sys.h" 14 | #include "os_type.h" 15 | #include "gpio.h" 16 | #include "gpio.h" 17 | 18 | // These default pin definitions can be changed to any valid GPIO pin. 19 | // The code in PCD8544_init() should automagically adapt 20 | 21 | static int8_t pinReset= 4; // LCD RST .... Pin 1 22 | static int8_t pinSce = 5; // LCD CE .... Pin 2 23 | static int8_t pinDc = 12; // LCD DC .... Pin 3 24 | static int8_t pinSdin = 13; // LCD Din .... Pin 4 25 | static int8_t pinSclk = 14; // LCD Clk .... Pin 5 26 | // LCD Vcc .... Pin 6 27 | // LCD BL .... Pin 7 28 | // LCD Gnd .... Pin 8 29 | 30 | static bool PCD8544_isInitiated = false; 31 | 32 | #define PCD8544_FUNCTIONSET 0x20 33 | #define PCD8544_SETVOP 0x80 34 | #define PCD8544_EXTENDEDINSTRUCTION 0x01 35 | 36 | #define LOW 0 37 | #define HIGH 1 38 | #define LCD_CMD LOW 39 | #define LCD_DATA HIGH 40 | 41 | #define LCD_X 84 42 | #define LCD_Y 48 43 | 44 | #define CLOCK_HIGH_TIME 14 // 14 us 45 | 46 | static void PCD8544_lcdWrite8(bool dc, uint8_t data); 47 | static void PCD8544_shiftOut8(bool msbFirst, uint8_t data); 48 | 49 | static const uint8_t ASCII[][5] = 50 | { 51 | {0x00, 0x00, 0x00, 0x00, 0x00} // 20 52 | ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 ! 53 | ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 " 54 | ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 # 55 | ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $ 56 | ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 % 57 | ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 & 58 | ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ' 59 | ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 ( 60 | ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 ) 61 | ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a * 62 | ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b + 63 | ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c , 64 | ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d - 65 | ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e . 66 | ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f / 67 | ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0 68 | ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1 69 | ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2 70 | ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3 71 | ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4 72 | ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5 73 | ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6 74 | ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7 75 | ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8 76 | ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9 77 | ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a : 78 | ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ; 79 | ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c < 80 | ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d = 81 | ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e > 82 | ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ? 83 | ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @ 84 | ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A 85 | ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B 86 | ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C 87 | ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D 88 | ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E 89 | ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F 90 | ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G 91 | ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H 92 | ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I 93 | ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J 94 | ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K 95 | ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L 96 | ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M 97 | ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N 98 | ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O 99 | ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P 100 | ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q 101 | ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R 102 | ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S 103 | ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T 104 | ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U 105 | ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V 106 | ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W 107 | ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X 108 | ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y 109 | ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z 110 | ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [ 111 | ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥ 112 | ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ] 113 | ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^ 114 | ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _ 115 | ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 ` 116 | ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a 117 | ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b 118 | ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c 119 | ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d 120 | ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e 121 | ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f 122 | ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g 123 | ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h 124 | ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i 125 | ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j 126 | ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k 127 | ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l 128 | ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m 129 | ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n 130 | ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o 131 | ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p 132 | ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q 133 | ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r 134 | ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s 135 | ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t 136 | ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u 137 | ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v 138 | ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w 139 | ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x 140 | ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y 141 | ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z 142 | ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b { 143 | ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c | 144 | ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d } 145 | ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ← 146 | ,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f → 147 | }; 148 | 149 | void ICACHE_FLASH_ATTR 150 | PCD8544_printBinary(uint32_t data){ 151 | int i = 0; 152 | for (i=8*sizeof(uint32_t)-1; i>=0; i--){ 153 | if (i > 1 && (i+1)%4==0) os_printf(" "); 154 | if (data & 1<0x7f) { 180 | character = '?'; 181 | } 182 | int index = 0; 183 | for (; index < 5; index++) { 184 | PCD8544_lcdWrite8(LCD_DATA, ASCII[character - 0x20][index]); 185 | } 186 | PCD8544_lcdWrite8(LCD_DATA, 0x00); 187 | } 188 | 189 | void ICACHE_FLASH_ATTR 190 | PCD8544_lcdPrint(char *characters) { 191 | while (*characters) { 192 | PCD8544_lcdCharacter(*characters++); 193 | } 194 | } 195 | 196 | /** 197 | * print ' ' a number of times 198 | */ 199 | void ICACHE_FLASH_ATTR 200 | PCD8544_lcdPad(int16_t spaces) { 201 | uint8_t i=0; 202 | //os_printf("PCD8544_lcdPad: padding %d spaces\n", spaces); 203 | for (i=0; i=0; bit--) { 232 | dataBit = (data>>bit)&1; 233 | os_delay_us(CLOCK_HIGH_TIME); 234 | GPIO_OUTPUT_SET(pinSclk, 0); 235 | GPIO_OUTPUT_SET(pinSdin, dataBit); 236 | os_delay_us(CLOCK_HIGH_TIME); 237 | GPIO_OUTPUT_SET(pinSclk, 1); 238 | os_delay_us(CLOCK_HIGH_TIME); 239 | GPIO_OUTPUT_SET(pinSclk, 0); 240 | } 241 | } else { 242 | for (bit = 0; bit<=7; bit++) { 243 | dataBit = (data>>bit)&1; 244 | os_delay_us(CLOCK_HIGH_TIME); 245 | GPIO_OUTPUT_SET(pinSclk, 0); 246 | GPIO_OUTPUT_SET(pinSdin, dataBit); 247 | os_delay_us(CLOCK_HIGH_TIME); 248 | GPIO_OUTPUT_SET(pinSclk, 1); 249 | os_delay_us(CLOCK_HIGH_TIME); 250 | GPIO_OUTPUT_SET(pinSclk, 0); 251 | } 252 | } 253 | os_delay_us(2*CLOCK_HIGH_TIME); 254 | } 255 | 256 | static void ICACHE_FLASH_ATTR 257 | PCD8544_lcdWrite8(bool dc, uint8_t data) { 258 | GPIO_OUTPUT_SET(pinDc, dc); 259 | if (pinSce>=0) { 260 | GPIO_OUTPUT_SET(pinSce, LOW); 261 | } 262 | PCD8544_shiftOut8(true, data); 263 | if (pinSce>=0) { 264 | GPIO_OUTPUT_SET(pinSce, HIGH); 265 | } 266 | os_delay_us(CLOCK_HIGH_TIME); 267 | } 268 | 269 | /** 270 | * draws a box 271 | */ 272 | void ICACHE_FLASH_ATTR 273 | PCD8544_drawLine(void) { 274 | uint8_t j; 275 | for(j=0; j<84; j++) { // top 276 | PCD8544_gotoXY(j,0); 277 | PCD8544_lcdWrite8(LCD_DATA,0x01); 278 | } 279 | for(j=0; j<84; j++) { //Bottom 280 | 281 | PCD8544_gotoXY(j,5); 282 | PCD8544_lcdWrite8(LCD_DATA,0x80); 283 | } 284 | for(j=0; j<6; j++) {// Right 285 | 286 | PCD8544_gotoXY(83,j); 287 | PCD8544_lcdWrite8(LCD_DATA,0xff); 288 | } 289 | for(j=0; j<6; j++) {// Left 290 | 291 | PCD8544_gotoXY(0,j); 292 | PCD8544_lcdWrite8(LCD_DATA,0xff); 293 | } 294 | } 295 | 296 | /** 297 | * Sets the contrast [0x00 - 0x7f]. 298 | * Useful, visible range is about 40-60. 299 | */ 300 | void ICACHE_FLASH_ATTR 301 | PCD8544_setContrast(uint8_t contrast) { 302 | if (contrast != 0) { 303 | contrast = 0x80|(contrast&0x7f); 304 | } 305 | PCD8544_lcdWrite8( LCD_CMD, PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION ); 306 | PCD8544_lcdWrite8( LCD_CMD, PCD8544_SETVOP | contrast); 307 | PCD8544_lcdWrite8( LCD_CMD, PCD8544_FUNCTIONSET); 308 | } 309 | 310 | /** 311 | * Set up the GPIO pins and the rest of the environment 312 | */ 313 | void ICACHE_FLASH_ATTR 314 | PCD8544_init(PCD8544_Settings *settings) { 315 | 316 | if (settings!=NULL){ 317 | pinReset = settings->resetPin; 318 | pinSce = settings->scePin; 319 | pinDc = settings->dcPin; 320 | pinSdin = settings->sdinPin; 321 | pinSclk = settings->sclkPin; 322 | } 323 | uint8_t uniquePins = 3; 324 | uint32_t bits = BIT(pinDc)|BIT(pinSdin)|BIT(pinSclk); 325 | if (pinReset>=0) { 326 | uniquePins += 1; 327 | bits |= BIT(pinReset); 328 | } 329 | if (pinSce>=0) { 330 | uniquePins += 1; 331 | bits |= BIT(pinSce); 332 | } 333 | 334 | if (easygpio_countBits(bits)!=uniquePins) { 335 | os_printf("PCD8544_init Error: you must specify exactly %d unique pin numbers\n", uniquePins); 336 | return; 337 | } 338 | 339 | // Define each used pin as a GPIO output 340 | if(pinReset>=0) { 341 | if (!easygpio_pinMode(pinReset, EASYGPIO_NOPULL, EASYGPIO_OUTPUT)) { 342 | return; 343 | } 344 | } 345 | if(pinSce>=0) { 346 | if (!easygpio_pinMode(pinSce, EASYGPIO_NOPULL, EASYGPIO_OUTPUT)) { 347 | return; 348 | } 349 | } 350 | if (!(easygpio_pinMode(pinDc, EASYGPIO_NOPULL, EASYGPIO_OUTPUT) && 351 | easygpio_pinMode(pinSdin, EASYGPIO_NOPULL, EASYGPIO_OUTPUT) && 352 | easygpio_pinMode(pinSclk, EASYGPIO_NOPULL, EASYGPIO_OUTPUT))) { 353 | return; 354 | } 355 | 356 | // Set default pin output values 357 | if (pinReset>=0) 358 | GPIO_OUTPUT_SET(pinReset, HIGH); 359 | if (pinSce>=0) 360 | GPIO_OUTPUT_SET(pinSce, HIGH); 361 | GPIO_OUTPUT_SET(pinDc, HIGH); 362 | GPIO_OUTPUT_SET(pinSdin, LOW); 363 | GPIO_OUTPUT_SET(pinSclk, LOW); 364 | 365 | PCD8544_isInitiated = true; 366 | PCD8544_initLCD(settings); 367 | } 368 | 369 | /** 370 | * initiate the LCD itself 371 | */ 372 | void ICACHE_FLASH_ATTR 373 | PCD8544_initLCD(PCD8544_Settings *settings) { 374 | if (!PCD8544_isInitiated) { 375 | os_printf("PCD8544 module is not completely configured. Check your pin definitions.\r\n"); 376 | return; 377 | } 378 | 379 | if (pinReset>=0){ 380 | os_delay_us(10000); 381 | GPIO_OUTPUT_SET(pinReset, LOW); 382 | os_delay_us(CLOCK_HIGH_TIME*3); 383 | GPIO_OUTPUT_SET(pinReset, HIGH); 384 | os_delay_us(10000); 385 | } 386 | 387 | PCD8544_lcdWrite8( LCD_CMD, 0x21 ); // LCD Extended Commands. 388 | if (settings!=NULL) { 389 | PCD8544_lcdWrite8( LCD_CMD, 0x80|(settings->lcdVop&0x7F) ); // Set LCD Vop (Contrast). //B1 390 | PCD8544_lcdWrite8( LCD_CMD, settings->tempCoeff ); // Set Temp coefficent. //0x04 391 | PCD8544_lcdWrite8( LCD_CMD, settings->biasMode ); // LCD bias mode 1:48. //0x13 392 | PCD8544_lcdWrite8( LCD_CMD, settings->inverse?0x0d:0x0C ); // LCD 0x0C in normal mode. 0x0d for inverse 393 | } else { 394 | PCD8544_lcdWrite8( LCD_CMD, 0xB1 ); // Set LCD Vop (Contrast). //B1 395 | PCD8544_lcdWrite8( LCD_CMD, 0x04 ); // Set Temp coefficent. //0x04 396 | PCD8544_lcdWrite8( LCD_CMD, 0x14 ); // LCD bias mode 1:48. //0x13 397 | PCD8544_lcdWrite8( LCD_CMD, 0x0C ); // LCD in normal mode. 0x0d for inverse 398 | } 399 | 400 | PCD8544_lcdWrite8( LCD_CMD, 0x20); 401 | PCD8544_lcdWrite8( LCD_CMD, 0x0C); 402 | os_delay_us(100000); 403 | PCD8544_lcdClear(); 404 | os_delay_us(10000); 405 | os_printf("--------------------------------------\n"); 406 | os_printf("-Initiated LCD display with these pins:\n"); 407 | os_printf("--------------------------------------\n"); 408 | if (pinReset>=0) 409 | os_printf(" LCD RST Pin 1 <=> GPIO%d\n", pinReset); 410 | else 411 | os_printf(" LCD RST Pin 1 <=> NC (esp reset)\n"); 412 | if (pinSce>=0) 413 | os_printf(" LCD CE Pin 2 <=> GPIO%d\n", pinSce); 414 | else 415 | os_printf(" LCD CE Pin 2 <=> NC (pull low)\n"); 416 | os_printf(" LCD DC Pin 3 <=> GPIO%d\n", pinDc); 417 | os_printf(" LCD Din Pin 4 <=> GPIO%d\n", pinSdin); 418 | os_printf(" LCD Clk Pin 5 <=> GPIO%d\n", pinSclk); 419 | os_printf(" Some ESP-12 boards have GPIO4 & GPIO5 reversed\n\n", pinSclk); 420 | 421 | } 422 | 423 | -------------------------------------------------------------------------------- /mqtt/mqtt/mqtt_msg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Stephen Robinson 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the copyright holder nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include 33 | #include "mqtt_msg.h" 34 | #include "user_config.h" 35 | #define MQTT_MAX_FIXED_HEADER_SIZE 3 36 | 37 | enum mqtt_connect_flag 38 | { 39 | MQTT_CONNECT_FLAG_USERNAME = 1 << 7, 40 | MQTT_CONNECT_FLAG_PASSWORD = 1 << 6, 41 | MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5, 42 | MQTT_CONNECT_FLAG_WILL = 1 << 2, 43 | MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1 44 | }; 45 | 46 | struct __attribute((__packed__)) mqtt_connect_variable_header 47 | { 48 | uint8_t lengthMsb; 49 | uint8_t lengthLsb; 50 | #if defined(PROTOCOL_NAMEv31) 51 | uint8_t magic[6]; 52 | #elif defined(PROTOCOL_NAMEv311) 53 | uint8_t magic[4]; 54 | #else 55 | #error "Please define protocol name" 56 | #endif 57 | uint8_t version; 58 | uint8_t flags; 59 | uint8_t keepaliveMsb; 60 | uint8_t keepaliveLsb; 61 | }; 62 | 63 | static int ICACHE_FLASH_ATTR append_string(mqtt_connection_t* connection, const char* string, int len) 64 | { 65 | if(connection->message.length + len + 2 > connection->buffer_length) 66 | return -1; 67 | 68 | connection->buffer[connection->message.length++] = len >> 8; 69 | connection->buffer[connection->message.length++] = len & 0xff; 70 | memcpy(connection->buffer + connection->message.length, string, len); 71 | connection->message.length += len; 72 | 73 | return len + 2; 74 | } 75 | 76 | static uint16_t ICACHE_FLASH_ATTR append_message_id(mqtt_connection_t* connection, uint16_t message_id) 77 | { 78 | // If message_id is zero then we should assign one, otherwise 79 | // we'll use the one supplied by the caller 80 | while(message_id == 0) 81 | message_id = ++connection->message_id; 82 | 83 | if(connection->message.length + 2 > connection->buffer_length) 84 | return 0; 85 | 86 | connection->buffer[connection->message.length++] = message_id >> 8; 87 | connection->buffer[connection->message.length++] = message_id & 0xff; 88 | 89 | return message_id; 90 | } 91 | 92 | static int ICACHE_FLASH_ATTR init_message(mqtt_connection_t* connection) 93 | { 94 | connection->message.length = MQTT_MAX_FIXED_HEADER_SIZE; 95 | return MQTT_MAX_FIXED_HEADER_SIZE; 96 | } 97 | 98 | static mqtt_message_t* ICACHE_FLASH_ATTR fail_message(mqtt_connection_t* connection) 99 | { 100 | connection->message.data = connection->buffer; 101 | connection->message.length = 0; 102 | return &connection->message; 103 | } 104 | 105 | static mqtt_message_t* ICACHE_FLASH_ATTR fini_message(mqtt_connection_t* connection, int type, int dup, int qos, int retain) 106 | { 107 | int remaining_length = connection->message.length - MQTT_MAX_FIXED_HEADER_SIZE; 108 | 109 | if(remaining_length > 127) 110 | { 111 | connection->buffer[0] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1); 112 | connection->buffer[1] = 0x80 | (remaining_length % 128); 113 | connection->buffer[2] = remaining_length / 128; 114 | connection->message.length = remaining_length + 3; 115 | connection->message.data = connection->buffer; 116 | } 117 | else 118 | { 119 | connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1); 120 | connection->buffer[2] = remaining_length; 121 | connection->message.length = remaining_length + 2; 122 | connection->message.data = connection->buffer + 1; 123 | } 124 | 125 | return &connection->message; 126 | } 127 | 128 | void ICACHE_FLASH_ATTR mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length) 129 | { 130 | memset(connection, 0, sizeof(mqtt_connection_t)); 131 | connection->buffer = buffer; 132 | connection->buffer_length = buffer_length; 133 | } 134 | 135 | int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length) 136 | { 137 | int i; 138 | int totlen = 0; 139 | 140 | for(i = 1; i < length; ++i) 141 | { 142 | totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); 143 | if((buffer[i] & 0x80) == 0) 144 | { 145 | ++i; 146 | break; 147 | } 148 | } 149 | totlen += i; 150 | 151 | return totlen; 152 | } 153 | 154 | const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length) 155 | { 156 | int i; 157 | int totlen = 0; 158 | int topiclen; 159 | 160 | for(i = 1; i < *length; ++i) 161 | { 162 | totlen += (buffer[i] & 0x7f) << (7 * (i -1)); 163 | if((buffer[i] & 0x80) == 0) 164 | { 165 | ++i; 166 | break; 167 | } 168 | } 169 | totlen += i; 170 | 171 | if(i + 2 >= *length) 172 | return NULL; 173 | topiclen = buffer[i++] << 8; 174 | topiclen |= buffer[i++]; 175 | 176 | if(i + topiclen > *length) 177 | return NULL; 178 | 179 | *length = topiclen; 180 | return (const char*)(buffer + i); 181 | } 182 | 183 | const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* length) 184 | { 185 | int i; 186 | int totlen = 0; 187 | int topiclen; 188 | 189 | for(i = 1; i < *length; ++i) 190 | { 191 | totlen += (buffer[i] & 0x7f) << (7 * (i - 1)); 192 | if((buffer[i] & 0x80) == 0) 193 | { 194 | ++i; 195 | break; 196 | } 197 | } 198 | totlen += i; 199 | 200 | if(i + 2 >= *length) 201 | return NULL; 202 | topiclen = buffer[i++] << 8; 203 | topiclen |= buffer[i++]; 204 | 205 | if(i + topiclen >= *length){ 206 | *length = 0; 207 | return NULL; 208 | } 209 | i += topiclen; 210 | 211 | if(mqtt_get_qos(buffer) > 0) 212 | { 213 | if(i + 2 >= *length) 214 | return NULL; 215 | i += 2; 216 | } 217 | 218 | if(totlen < i) 219 | return NULL; 220 | 221 | if(totlen <= *length) 222 | *length = totlen - i; 223 | else 224 | *length = *length - i; 225 | return (const char*)(buffer + i); 226 | } 227 | 228 | uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length) 229 | { 230 | if(length < 1) 231 | return 0; 232 | 233 | switch(mqtt_get_type(buffer)) 234 | { 235 | case MQTT_MSG_TYPE_PUBLISH: 236 | { 237 | int i; 238 | int topiclen; 239 | 240 | for(i = 1; i < length; ++i) 241 | { 242 | if((buffer[i] & 0x80) == 0) 243 | { 244 | ++i; 245 | break; 246 | } 247 | } 248 | 249 | if(i + 2 >= length) 250 | return 0; 251 | topiclen = buffer[i++] << 8; 252 | topiclen |= buffer[i++]; 253 | 254 | if(i + topiclen >= length) 255 | return 0; 256 | i += topiclen; 257 | 258 | if(mqtt_get_qos(buffer) > 0) 259 | { 260 | if(i + 2 >= length) 261 | return 0; 262 | //i += 2; 263 | } else { 264 | return 0; 265 | } 266 | 267 | return (buffer[i] << 8) | buffer[i + 1]; 268 | } 269 | case MQTT_MSG_TYPE_PUBACK: 270 | case MQTT_MSG_TYPE_PUBREC: 271 | case MQTT_MSG_TYPE_PUBREL: 272 | case MQTT_MSG_TYPE_PUBCOMP: 273 | case MQTT_MSG_TYPE_SUBACK: 274 | case MQTT_MSG_TYPE_UNSUBACK: 275 | case MQTT_MSG_TYPE_SUBSCRIBE: 276 | { 277 | // This requires the remaining length to be encoded in 1 byte, 278 | // which it should be. 279 | if(length >= 4 && (buffer[1] & 0x80) == 0) 280 | return (buffer[2] << 8) | buffer[3]; 281 | else 282 | return 0; 283 | } 284 | 285 | default: 286 | return 0; 287 | } 288 | } 289 | 290 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info) 291 | { 292 | struct mqtt_connect_variable_header* variable_header; 293 | 294 | init_message(connection); 295 | 296 | if(connection->message.length + sizeof(*variable_header) > connection->buffer_length) 297 | return fail_message(connection); 298 | variable_header = (void*)(connection->buffer + connection->message.length); 299 | connection->message.length += sizeof(*variable_header); 300 | 301 | variable_header->lengthMsb = 0; 302 | #if defined(PROTOCOL_NAMEv31) 303 | variable_header->lengthLsb = 6; 304 | memcpy(variable_header->magic, "MQIsdp", 6); 305 | variable_header->version = 3; 306 | #elif defined(PROTOCOL_NAMEv311) 307 | variable_header->lengthLsb = 4; 308 | memcpy(variable_header->magic, "MQTT", 4); 309 | variable_header->version = 4; 310 | #else 311 | #error "Please define protocol name" 312 | #endif 313 | 314 | variable_header->flags = 0; 315 | variable_header->keepaliveMsb = info->keepalive >> 8; 316 | variable_header->keepaliveLsb = info->keepalive & 0xff; 317 | 318 | if(info->clean_session) 319 | variable_header->flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION; 320 | 321 | if(info->client_id != NULL && info->client_id[0] != '\0') 322 | { 323 | if(append_string(connection, info->client_id, strlen(info->client_id)) < 0) 324 | return fail_message(connection); 325 | } 326 | else 327 | return fail_message(connection); 328 | 329 | if(info->will_topic != NULL && info->will_topic[0] != '\0') 330 | { 331 | if(append_string(connection, info->will_topic, strlen(info->will_topic)) < 0) 332 | return fail_message(connection); 333 | 334 | if(append_string(connection, info->will_message, strlen(info->will_message)) < 0) 335 | return fail_message(connection); 336 | 337 | variable_header->flags |= MQTT_CONNECT_FLAG_WILL; 338 | if(info->will_retain) 339 | variable_header->flags |= MQTT_CONNECT_FLAG_WILL_RETAIN; 340 | variable_header->flags |= (info->will_qos & 3) << 3; 341 | } 342 | 343 | if(info->username != NULL && info->username[0] != '\0') 344 | { 345 | if(append_string(connection, info->username, strlen(info->username)) < 0) 346 | return fail_message(connection); 347 | 348 | variable_header->flags |= MQTT_CONNECT_FLAG_USERNAME; 349 | } 350 | 351 | if(info->password != NULL && info->password[0] != '\0') 352 | { 353 | if(append_string(connection, info->password, strlen(info->password)) < 0) 354 | return fail_message(connection); 355 | 356 | variable_header->flags |= MQTT_CONNECT_FLAG_PASSWORD; 357 | } 358 | 359 | return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0); 360 | } 361 | 362 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id) 363 | { 364 | init_message(connection); 365 | 366 | if(topic == NULL || topic[0] == '\0') 367 | return fail_message(connection); 368 | 369 | if(append_string(connection, topic, strlen(topic)) < 0) 370 | return fail_message(connection); 371 | 372 | if(qos > 0) 373 | { 374 | if((*message_id = append_message_id(connection, 0)) == 0) 375 | return fail_message(connection); 376 | } 377 | else 378 | *message_id = 0; 379 | 380 | if(connection->message.length + data_length > connection->buffer_length) 381 | return fail_message(connection); 382 | memcpy(connection->buffer + connection->message.length, data, data_length); 383 | connection->message.length += data_length; 384 | 385 | return fini_message(connection, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain); 386 | } 387 | 388 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id) 389 | { 390 | init_message(connection); 391 | if(append_message_id(connection, message_id) == 0) 392 | return fail_message(connection); 393 | return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0); 394 | } 395 | 396 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id) 397 | { 398 | init_message(connection); 399 | if(append_message_id(connection, message_id) == 0) 400 | return fail_message(connection); 401 | return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0); 402 | } 403 | 404 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id) 405 | { 406 | init_message(connection); 407 | if(append_message_id(connection, message_id) == 0) 408 | return fail_message(connection); 409 | return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0); 410 | } 411 | 412 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id) 413 | { 414 | init_message(connection); 415 | if(append_message_id(connection, message_id) == 0) 416 | return fail_message(connection); 417 | return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0); 418 | } 419 | 420 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id) 421 | { 422 | init_message(connection); 423 | 424 | if(topic == NULL || topic[0] == '\0') 425 | return fail_message(connection); 426 | 427 | if((*message_id = append_message_id(connection, 0)) == 0) 428 | return fail_message(connection); 429 | 430 | if(append_string(connection, topic, strlen(topic)) < 0) 431 | return fail_message(connection); 432 | 433 | if(connection->message.length + 1 > connection->buffer_length) 434 | return fail_message(connection); 435 | connection->buffer[connection->message.length++] = qos; 436 | 437 | return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0); 438 | } 439 | 440 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id) 441 | { 442 | init_message(connection); 443 | 444 | if(topic == NULL || topic[0] == '\0') 445 | return fail_message(connection); 446 | 447 | if((*message_id = append_message_id(connection, 0)) == 0) 448 | return fail_message(connection); 449 | 450 | if(append_string(connection, topic, strlen(topic)) < 0) 451 | return fail_message(connection); 452 | 453 | return fini_message(connection, MQTT_MSG_TYPE_UNSUBSCRIBE, 0, 1, 0); 454 | } 455 | 456 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingreq(mqtt_connection_t* connection) 457 | { 458 | init_message(connection); 459 | return fini_message(connection, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0); 460 | } 461 | 462 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingresp(mqtt_connection_t* connection) 463 | { 464 | init_message(connection); 465 | return fini_message(connection, MQTT_MSG_TYPE_PINGRESP, 0, 0, 0); 466 | } 467 | 468 | mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connection) 469 | { 470 | init_message(connection); 471 | return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0); 472 | } 473 | --------------------------------------------------------------------------------