From 737f0d4822a2649a99f114d637301718b75b867d Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Mon, 20 Feb 2017 12:56:02 +0300 Subject: [PATCH 01/83] fix copypasta --- DeviceHiveESP8266.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/DeviceHiveESP8266.md b/DeviceHiveESP8266.md index 05d0601..d93610d 100644 --- a/DeviceHiveESP8266.md +++ b/DeviceHiveESP8266.md @@ -1187,16 +1187,14 @@ Reads tag's uid and type. MFRC522 is a RFID tag reader. It should be connected v *Example*: ```json { - "uid":"0xA435AA7D", - "type":"MIFARE 1KB" + "CS":15 } ``` Return "OK" in status and json like below in result on success. Or "Error" and description in result on error. ```json { - "voltage":3.2040, - "current":0.0466, - "power":0.1520 + "uid":"0xA435AA7D", + "type":"MIFARE 1KB" } ``` From 9b05af27c869029f8b3b7c513f6683dca9806da1 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Mon, 13 Mar 2017 16:48:10 +0300 Subject: [PATCH 02/83] [wip] websocket connection establishment --- firmware-src/sources/dhconnector.c | 229 ++++++++------------- firmware-src/sources/dhconnector.h | 10 +- firmware-src/sources/dhrequest.c | 175 +++++++--------- firmware-src/sources/dhrequest.h | 88 +++----- firmware-src/sources/dhsender_queue.c | 4 +- firmware-src/sources/dhsettings.h | 2 +- firmware-src/sources/dhterminal_commands.c | 8 +- firmware-src/sources/rest.c | 6 +- firmware-src/sources/uploadable_api.c | 6 +- 9 files changed, 197 insertions(+), 331 deletions(-) diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index 2ba16e9..f24b267 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -18,7 +18,6 @@ #include #include "dhrequest.h" #include "dhconnector.h" -#include "dhsender.h" #include "dhdebug.h" #include "dhmem.h" #include "dhutils.h" @@ -30,11 +29,9 @@ LOCAL CONNECTION_STATE mConnectionState; LOCAL struct espconn mDHConnector; LOCAL dhconnector_command_json_cb mCommandCallback; -LOCAL HTTP_REQUEST mRegisterRequest; -LOCAL HTTP_REQUEST mPollRequest; -LOCAL HTTP_REQUEST mInfoRequest; LOCAL os_timer_t mRetryTimer; LOCAL unsigned char mNeedRecover = 0; +LOCAL char mWSUrl[DHSETTINGS_SERVER_MAX_LENGTH]; LOCAL void set_state(CONNECTION_STATE state); @@ -57,93 +54,56 @@ LOCAL void ICACHE_FLASH_ATTR network_error_cb(void *arg, sint8 err) { LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { int type; - unsigned int id; - char command[128] = ""; - const char *params; - int paramslen = 0; - char timestamp[128] = ""; while (jparser->pos < jparser->len) { type = jsonparse_next(jparser); if(type == JSON_TYPE_PAIR_NAME) { - if (jsonparse_strcmp_value(jparser, "serverTimestamp") == 0) { + if (jsonparse_strcmp_value(jparser, "webSocketServerUrl") == 0) { jsonparse_next(jparser); if (jsonparse_next(jparser) != JSON_TYPE_ERROR) { - jsonparse_copy_value(jparser, timestamp, sizeof(timestamp)); - dhdebug("Timestamp received %s", timestamp); - dhrequest_update_poll(&mPollRequest, timestamp); + jsonparse_copy_value(jparser, mWSUrl, sizeof(mWSUrl)); + dhdebug("WebSocker URL received %s", mWSUrl); } break; - } else if (jsonparse_strcmp_value(jparser, "command") == 0) { - jsonparse_next(jparser); - if(jsonparse_next(jparser) != JSON_TYPE_ERROR) - jsonparse_copy_value(jparser, command, sizeof(command)); - } else if (jsonparse_strcmp_value(jparser, "id") == 0) { - jsonparse_next(jparser); - if(jsonparse_next(jparser) != JSON_TYPE_ERROR) - id = jsonparse_get_value_as_ulong(jparser); - } else if (jsonparse_strcmp_value(jparser, "parameters") == 0) { - jsonparse_next(jparser); - if(jsonparse_next(jparser) != JSON_TYPE_ERROR) { - // there is an issue with extracting subjson with jparser->vstart or jparser_copy_value - params = &jparser->json[jparser->pos - 1]; - if(*params == '{') { - int end = jparser->pos; - while(end < jparser->len && jparser->json[end] != '}') { - end++; - } - paramslen = end - jparser->pos + 2; - } - } - } else if (jsonparse_strcmp_value(jparser, "timestamp") == 0) { - jsonparse_next(jparser); - if(jsonparse_next(jparser) != JSON_TYPE_ERROR) - jsonparse_copy_value(jparser, timestamp, sizeof(timestamp)); } } else if(type == JSON_TYPE_ERROR) { break; } } - if (mConnectionState == CS_POLL) { - if(timestamp[0]) { - dhdebug("Timestamp received %s", timestamp); - dhrequest_update_poll(&mPollRequest, timestamp); - } - COMMAND_RESULT cb; - cb.callback = dhsender_response; - cb.data.id = id; - mCommandCallback(&cb, command, params, paramslen); - } } LOCAL void network_recv_cb(void *arg, char *data, unsigned short len) { dhstatistic_add_bytes_received(len); + if (mConnectionState == CS_OPERATE) { + // TODO TODO TODO + return; + } const char *rc = find_http_responce_code(data, len); if (rc) { // HTTP - if (*rc == '2') { // HTTP responce code 2xx - Success - if (mConnectionState == CS_REGISTER) { - dhdebug("Successfully register"); - } else { - char *content = (char *) os_strstr(data, (char *) "\r\n\r\n"); - if (content && mConnectionState != CS_CUSTOM) { - int deep = 0; - unsigned int pos = 0; - unsigned int jsonstart = 0; - while (pos < len) { - if (data[pos] == '{') { - if (deep == 0) - jsonstart = pos; - deep++; - } else if (data[pos] == '}') { - deep--; - if (deep == 0) { - struct jsonparse_state jparser; - jsonparse_setup(&jparser, &data[jsonstart], - pos - jsonstart + 1); - parse_json(&jparser); - } + if (rc[0] == '1' && rc[1] == '0' && rc[2] == '1' && mConnectionState == CS_WEBSOCKET) { // HTTP responce code 101 - Switching Protocols + set_state(CS_OPERATE); + dhdebug("WebSocket connection is established"); + // do not disconnect + return; + } else if (*rc == '2' && mConnectionState == CS_GETINFO) { // HTTP responce code 2xx - Success + if (os_strstr(data, (char *) "\r\n\r\n")) { + int deep = 0; + unsigned int pos = 0; + unsigned int jsonstart = 0; + while (pos < len) { + if (data[pos] == '{') { + if (deep == 0) + jsonstart = pos; + deep++; + } else if (data[pos] == '}') { + deep--; + if (deep == 0) { + struct jsonparse_state jparser; + jsonparse_setup(&jparser, &data[jsonstart], + pos - jsonstart + 1); + parse_json(&jparser); } - pos++; } + pos++; } } } else { @@ -172,16 +132,17 @@ LOCAL void network_connect_cb(void *arg) { espconn_set_keepalive(&mDHConnector, ESPCONN_KEEPINTVL, &keepalive); keepalive = 3; espconn_set_keepalive(&mDHConnector, ESPCONN_KEEPCNT, &keepalive); - switch(mConnectionState) { + switch (mConnectionState) { case CS_GETINFO: - request = &mInfoRequest; + request = dhrequest_create_info(dhsettings_get_devicehive_server()); dhdebug("Send info request..."); break; - case CS_REGISTER: - request = &mRegisterRequest; - dhdebug("Send register request..."); + case CS_WEBSOCKET: + request = dhrequest_create_wsrequest(dhsettings_get_devicehive_server(), mWSUrl); + dhdebug("Send web socket upgrade request..."); break; - case CS_POLL: + // TODO TODO TODO + /*case CS_POLL: case CS_CUSTOM: request = custom_firmware_request(); if(request) { @@ -190,12 +151,12 @@ LOCAL void network_connect_cb(void *arg) { request = &mPollRequest; dhdebug("Send poll request..."); } - break; + break;*/ default: dhdebug("ASSERT: networkConnectCb wrong state %d", mConnectionState); } int res; - if( (res = espconn_send(&mDHConnector, request->data, request->len)) != ESPCONN_OK) { + if ( (res = espconn_send(&mDHConnector, request->data, request->len)) != ESPCONN_OK) { mConnectionState = CS_DISCONNECT; dhesperrors_espconn_result("network_connect_cb failed:", res); espconn_disconnect(&mDHConnector); @@ -210,14 +171,14 @@ LOCAL void network_disconnect_cb(void *arg) { arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); break; case CS_GETINFO: - set_state(CS_REGISTER); + set_state(CS_WEBSOCKET); break; - case CS_REGISTER: - mConnectionState = CS_POLL; - /* no break */ - case CS_POLL: - arm_repeat_timer(DHREQUEST_PAUSE_MS); + case CS_WEBSOCKET: + case CS_OPERATE: + mConnectionState = CS_DISCONNECT; + arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); break; +/* TODO TODO TODO case CS_CUSTOM: if (dhterminal_is_in_use()) { dhdebug("Terminal is in use, no deep sleep"); @@ -227,6 +188,7 @@ LOCAL void network_disconnect_cb(void *arg) { // after deep sleep chip will be rebooted } break; +*/ default: dhdebug("ASSERT: networkDisconnectCb wrong state %d", mConnectionState); } @@ -251,56 +213,19 @@ LOCAL void ICACHE_FLASH_ATTR resolve_cb(const char *name, ip_addr_t *ip, void *a unsigned char *bip = (unsigned char *) ip; dhdebug("Host %s ip: %d.%d.%d.%d, using port %d", name, bip[0], bip[1], bip[2], bip[3], mDHConnector.proto.tcp->remote_port); - dhsender_init(ip, mDHConnector.proto.tcp->remote_port); dhconnector_init_connection(ip); - if(mPollRequest.len) - set_state(CS_POLL); - else + if(mConnectionState == CS_DISCONNECT) set_state(CS_GETINFO); + else if(mConnectionState == CS_RESOLVEWEBSOCKET) + set_state(CS_WEBSOCKET); + else + dhdebug("ASSERT: Wrong state on resolve"); } -LOCAL void ICACHE_FLASH_ATTR start_resolve_dh_server() { +LOCAL void ICACHE_FLASH_ATTR start_resolve_dh_server(const char *server) { static ip_addr_t ip; - const char *server = dhrequest_current_server(); - char host[os_strlen(server) + 1]; - const char *fr = server; - while(*fr != ':') { - fr++; - if(*fr == 0) { - fr = 0; - break; - } - } - if(fr) { - fr++; - if(*fr != '/') - fr = 0; - } - if (fr) { - while (*fr == '/') - fr++; - int i = 0; - while (*fr != '/' && *fr != ':' && *fr != 0) - host[i++] = *fr++; - // read port if present - int port = 0; - if(*fr == ':') { - unsigned char d; - fr++; - while ( (d = *fr - 0x30) < 10) { - fr++; - port = port*10 + d; - if(port > 0xFFFF) - break; - } - } - if(port && port < 0xFFFF) - mDHConnector.proto.tcp->remote_port = port; - else if (os_strncmp(dhrequest_current_server(), "https", 5) == 0) - mDHConnector.proto.tcp->remote_port = 443; // HTTPS default port - else - mDHConnector.proto.tcp->remote_port = 80; //HTTP default port - host[i] = 0; + char host[DHREQUEST_HOST_MAX_BUF_LEN]; + if(dhrequest_parse_url(server, host, &mDHConnector.proto.tcp->remote_port)) { dhdebug("Resolving %s", host); err_t r = espconn_gethostbyname(&mDHConnector, host, &ip, resolve_cb); if(r == ESPCONN_OK) { @@ -331,12 +256,25 @@ LOCAL void ICACHE_FLASH_ATTR set_state(CONNECTION_STATE state) { } switch(state) { case CS_DISCONNECT: - start_resolve_dh_server(); + if(os_strncmp(dhsettings_get_devicehive_server(), "ws://", 5) == 0 || + os_strncmp(dhsettings_get_devicehive_server(), "wss://", 6) == 0 ) { + snprintf(mWSUrl, sizeof(mWSUrl), "%s", dhsettings_get_devicehive_server()); + mConnectionState = CS_RESOLVEWEBSOCKET; + start_resolve_dh_server(mWSUrl); + } else { + mWSUrl[0] = 0; + start_resolve_dh_server(dhsettings_get_devicehive_server()); + } + break; + case CS_RESOLVEWEBSOCKET: + if(mWSUrl[0] == 0) { + dhdebug("Failed to get WebSocket URL"); + set_state(CS_DISCONNECT); + } + start_resolve_dh_server(mWSUrl); break; case CS_GETINFO: - case CS_REGISTER: - case CS_POLL: - case CS_CUSTOM: + case CS_WEBSOCKET: { const sint8 cr = espconn_connect(&mDHConnector); if(cr == ESPCONN_ISCONN) @@ -347,6 +285,8 @@ LOCAL void ICACHE_FLASH_ATTR set_state(CONNECTION_STATE state) { } break; } + case CS_OPERATE: + break; default: dhdebug("ASSERT: set_state wrong state %d", mConnectionState); } @@ -360,8 +300,8 @@ LOCAL void ICACHE_FLASH_ATTR wifi_state_cb(System_Event_t *event) { mConnectionState = CS_DISCONNECT; arm_repeat_timer(DHREQUEST_PAUSE_MS); - if(dhrequest_current_deviceid()[0]) { - mdnsd_start(dhrequest_current_deviceid(), event->event_info.got_ip.ip.addr); + if(dhsettings_get_devicehive_deviceid()[0]) { + mdnsd_start(dhsettings_get_devicehive_deviceid(), event->event_info.got_ip.ip.addr); } } else { dhdebug("ERROR: WiFi reports STAMODE_GOT_IP, but no actual ip found"); @@ -378,30 +318,25 @@ LOCAL void ICACHE_FLASH_ATTR wifi_state_cb(System_Event_t *event) { } void ICACHE_FLASH_ATTR dhconnector_init(dhconnector_command_json_cb cb) { - dhrequest_load_settings(); mCommandCallback = cb; mConnectionState = CS_DISCONNECT; - dhrequest_create_info(&mInfoRequest); - dhrequest_create_register(&mRegisterRequest); - mPollRequest.len = mPollRequest.data[0] = 0; - wifi_set_opmode(STATION_MODE); wifi_station_set_auto_connect(1); wifi_station_set_reconnect_policy(true); struct station_config stationConfig; wifi_station_get_config(&stationConfig); wifi_set_phy_mode(PHY_MODE_11N); - if(dhrequest_current_deviceid()[0]) { - char hostname[33]; - // limit length to 32 chars due to the sdk limit - snprintf(hostname, sizeof(hostname), "%s", dhrequest_current_deviceid()); - wifi_station_set_hostname(hostname); - } os_memset(stationConfig.ssid, 0, sizeof(stationConfig.ssid)); os_memset(stationConfig.password, 0, sizeof(stationConfig.password)); snprintf(stationConfig.ssid, sizeof(stationConfig.ssid), "%s", dhsettings_get_wifi_ssid()); snprintf(stationConfig.password, sizeof(stationConfig.password), "%s", dhsettings_get_wifi_password()); + if(dhsettings_get_devicehive_deviceid()[0]) { + char hostname[33]; + // limit length to 32 chars due to the sdk limit + snprintf(hostname, sizeof(hostname), "%s", dhsettings_get_devicehive_deviceid()); + wifi_station_set_hostname(hostname); + } wifi_station_set_config(&stationConfig); static esp_tcp tcp; diff --git a/firmware-src/sources/dhconnector.h b/firmware-src/sources/dhconnector.h index 9fef1b7..70ab587 100644 --- a/firmware-src/sources/dhconnector.h +++ b/firmware-src/sources/dhconnector.h @@ -18,11 +18,11 @@ typedef void (*dhconnector_command_json_cb)(COMMAND_RESULT *cb, /** Current connection state. */ typedef enum { - CS_DISCONNECT, ///< Disconnected from DeviceHive server. - CS_GETINFO, ///< Getting info from DeviceHive server. - CS_REGISTER, ///< Registering on DeviceHive server. - CS_POLL, ///< Polling command from DeviceHive server. - CS_CUSTOM ///< Custom firmware mode. + CS_DISCONNECT, ///< Disconnected from DeviceHive server. + CS_GETINFO, ///< Getting info from DeviceHive server with WebSocket url. + CS_RESOLVEWEBSOCKET,///< Resolve WebSocket url. + CS_WEBSOCKET, ///< Request to switch protocol to WebSocket. + CS_OPERATE ///< Normal operational state. } CONNECTION_STATE; /** diff --git a/firmware-src/sources/dhrequest.c b/firmware-src/sources/dhrequest.c index b2181ba..855169b 100644 --- a/firmware-src/sources/dhrequest.c +++ b/firmware-src/sources/dhrequest.c @@ -13,120 +13,93 @@ #include #include #include +#include #include "dhrequest.h" #include "user_config.h" #include "dhdebug.h" -#include "dhsettings.h" -#include "dhmem.h" #include "snprintf.h" -#include "irom.h" - -RO_DATA char REGISTER_JSON[] = - "{\"name\":\"%s\",\"key\":\"%s\",\"status\":\"Online\",\"deviceClass\":{\"name\":\"ESP Class\",\"version\":\""FIRMWARE_VERSION"\",\"offlineTimeout\":\"900\"}}"; -RO_DATA char UPDATE_JSON[] = - "{\"status\":\"%s\",\"result\":%s%s%s}"; -RO_DATA char NOTIFICATION_JSON[] = - "{\"notification\":\"%s\",\"parameters\":%s%s%s}"; - -RO_DATA char HTTP_REQUEST_PATTERN[] = - "%s %s%s%s%s%s HTTP/1.0\r\nAuthorization: Bearer %s\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: %s\r\n\r\n%s"; - -LOCAL char mServer[DHSETTINGS_SERVER_MAX_LENGTH]; -LOCAL char mDeviceId[DHSETTINGS_DEVICEID_MAX_LENGTH]; -LOCAL char mAccessKey[DHSETTINGS_ACCESSKEY_MAX_LENGTH]; - -LOCAL unsigned short mServerLen; -LOCAL unsigned short mDeviceIdLen; -LOCAL unsigned short mAccessKeyLen; - -void ICACHE_FLASH_ATTR dhrequest_load_settings() { - mServerLen = snprintf(mServer, sizeof(mServer), "%s", dhsettings_get_devicehive_server()); - mDeviceIdLen = snprintf(mDeviceId, sizeof(mDeviceId), "%s", dhsettings_get_devicehive_deviceid()); - mAccessKeyLen = snprintf(mAccessKey, sizeof(mAccessKey), "%s", dhsettings_get_devicehive_accesskey()); -} - -const char * ICACHE_FLASH_ATTR dhrequest_current_server() { - return mServer; -} - -const char * ICACHE_FLASH_ATTR dhrequest_current_deviceid() { - return mDeviceId; -} +#include "dhsettings.h" -const char * ICACHE_FLASH_ATTR dhrequest_current_accesskey() { - return mAccessKey; -} +RO_DATA char HTTP_INFO_REQUEST_PATTERN[] = + "GET %s/info HTTP/1.1\r\n" + "Host: %s\r\n\r\n"; -void ICACHE_FLASH_ATTR dhrequest_create_register(HTTP_REQUEST *buf) { - uint8 mac[6]; - char keybuf[64]; - if(!wifi_get_macaddr(STATION_IF, mac)) - memset(mac,0, sizeof(mac)); - int keybuflen = snprintf(keybuf, sizeof(keybuf) - 1, "%X%X%X%X%X%X%X", system_get_chip_id(), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - char lenbuf[16]; - char jsonbuf[sizeof(REGISTER_JSON) - 4 + DHSETTINGS_DEVICEID_MAX_LENGTH + keybuflen]; - const unsigned int jsonbuflen = snprintf(jsonbuf, sizeof(jsonbuf), REGISTER_JSON, mDeviceId, keybuf); - snprintf(lenbuf, sizeof(lenbuf), "%d", jsonbuflen); - buf->len = snprintf(buf->data, sizeof(buf->data), HTTP_REQUEST_PATTERN, "PUT", mServer, "/device/", mDeviceId, "", "", mAccessKey, lenbuf, jsonbuf); - dhdebug("Register request created, %d/%d", buf->len + 1, sizeof(buf->data)); -} +RO_DATA char HTTP_WS_REQUEST_PATTERN[] = + "GET %s/device HTTP/1.1\r\n" + "Host: %s\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Origin: %s\r\n" + "Sec-WebSocket-Protocol: chat, superchat\r\n" + "Sec-WebSocket-Version: 13\r\n\r\n"; -void ICACHE_FLASH_ATTR dhrequest_create_poll(HTTP_REQUEST *buf, const char *timestamp) { - dhrequest_update_poll(buf, timestamp); -} -void ICACHE_FLASH_ATTR dhrequest_update_poll(HTTP_REQUEST *old, const char *timestamp) { - const unsigned int timestamplength = os_strlen(timestamp); - const unsigned int len = sizeof(HTTP_REQUEST_PATTERN) - 18 + 3 + mServerLen + 8 + mDeviceIdLen + 24 + timestamplength + mAccessKeyLen + 1; - if(old) { - if(old->len + 1 == len) { - char *current_timestamp = &old->data[4 + mServerLen + 8 + mDeviceIdLen + 24]; - int i; - int cp = 0; - for(i = 0; i < timestamplength; i++) { - if(cp || timestamp[i] > current_timestamp[i]) { - cp = 1; - current_timestamp[i] = timestamp[i]; - } else if(timestamp[i] < current_timestamp[i]) { - dhdebug("Timestamp is older then current"); - return; - } - } - dhdebug("Poll request updated"); - return; +const char * ICACHE_FLASH_ATTR dhrequest_parse_url(const char *url, char *host, int *port) { + int i; + const char *fr = url; + while (*fr != ':') { + fr++; + if (*fr == 0) { + return NULL; } } - old->len = snprintf(old->data, sizeof(old->data), HTTP_REQUEST_PATTERN, "GET", mServer, "/device/", mDeviceId, "/command/poll?timestamp=", timestamp, mAccessKey, "0", ""); - dhdebug("Poll request created, %d/%d/%d", old->len + 1, len, sizeof(old->data)); -} + for(i = 0; i < 2; i++) { + fr++; + if (*fr != '/') + return NULL; + } + fr++; + i = 0; + while (*fr != '/' && *fr != ':' && *fr != 0 && i < (DHREQUEST_HOST_MAX_BUF_LEN - 1)) + host[i++] = *fr++; + host[i] = 0; -void ICACHE_FLASH_ATTR dhrequest_create_update(HTTP_REQUEST *buf, unsigned int commandId, const char *status, const char *result) { - char idbuf[16]; - snprintf(idbuf, sizeof(idbuf), "%u", commandId); - char jsonbuf[sizeof(UPDATE_JSON) - 6 + os_strlen(status) + os_strlen(result)]; - char extra[] = "\""; - if(result[0] == '{') - extra[0] = 0; - const unsigned int jsonbuflen = snprintf(jsonbuf, sizeof(jsonbuf), UPDATE_JSON, status, extra, result, extra); - char lenbuf[16]; - snprintf(lenbuf, sizeof(lenbuf), "%d", jsonbuflen); - buf->len = snprintf(buf->data, sizeof(buf->data), HTTP_REQUEST_PATTERN, "PUT", mServer, "/device/", mDeviceId, "/command/", idbuf, mAccessKey, lenbuf, jsonbuf); - dhdebug("Update %d request created, %d/%d", commandId, buf->len + 1, sizeof(buf->data)); + // read port if present + int p = 0; + if (*fr == ':') { + unsigned char d; + fr++; + while ((d = *fr - 0x30) < 10) { + fr++; + p = p * 10 + d; + if (p > 0xFFFF) + break; + } + } + if (p && p < 0xFFFF) + *port = p; + else if (os_strncmp(url, "https", 5) == 0 || os_strncmp(url, "wss", 3) == 0) + *port = 443; // HTTPS default port + else + *port = 80; //HTTP default port + while (*fr != '/' && *fr != 0) + fr++; + return *fr ? fr : "/"; } -void ICACHE_FLASH_ATTR dhrequest_create_info(HTTP_REQUEST *buf) { - buf->len = snprintf(buf->data, sizeof(buf->data), HTTP_REQUEST_PATTERN, "GET", mServer, "/info", "", "", "", mAccessKey, "0", ""); - dhdebug("Info request created, %d/%d", buf->len + 1, sizeof(buf->data)); +HTTP_REQUEST * ICACHE_FLASH_ATTR dhrequest_create_info(const char *api) { + static char sbuf[sizeof(unsigned int) + sizeof(HTTP_INFO_REQUEST_PATTERN) + DHSETTINGS_SERVER_MAX_LENGTH]; + HTTP_REQUEST *buf = (HTTP_REQUEST *)sbuf; + char host[DHREQUEST_HOST_MAX_BUF_LEN]; + int port; + const char *path = dhrequest_parse_url(api, host, &port); + if (path == NULL) + return NULL; + buf->len = snprintf(buf->data, sizeof(sbuf) - sizeof(unsigned int), HTTP_INFO_REQUEST_PATTERN, path, host); + dhdebug("Info request created, %d/%d", buf->len + 1, sizeof(sbuf) - sizeof(unsigned int)); + return buf; } -void ICACHE_FLASH_ATTR dhrequest_create_notification(HTTP_REQUEST *buf, const char *name, const char *parameters) { - char jsonbuf[sizeof(NOTIFICATION_JSON) - 6 + os_strlen(name) + os_strlen(parameters)]; - char extra[] = "\""; - if(parameters[0] == '{') - extra[0] = 0; - const unsigned int jsonbuflen = snprintf(jsonbuf, sizeof(jsonbuf), NOTIFICATION_JSON, name, extra, parameters, extra); - char lenbuf[16]; - snprintf(lenbuf, sizeof(lenbuf), "%d", jsonbuflen); - buf->len = snprintf(buf->data, sizeof(buf->data), HTTP_REQUEST_PATTERN, "POST", mServer, "/device/", mDeviceId, "/notification", "", mAccessKey, lenbuf, jsonbuf); - dhdebug("Notification created, %d/%d", buf->len + 1, sizeof(buf->data)); +HTTP_REQUEST * ICACHE_FLASH_ATTR dhrequest_create_wsrequest(const char *api, const char *url) { + static char sbuf[sizeof(unsigned int) + sizeof(HTTP_WS_REQUEST_PATTERN) + 2 * DHSETTINGS_SERVER_MAX_LENGTH]; + HTTP_REQUEST *buf = (HTTP_REQUEST *)sbuf; + char host[DHREQUEST_HOST_MAX_BUF_LEN]; + int port; + const char *path = dhrequest_parse_url(url, host, &port); + if (path == NULL) + return NULL; + buf->len = snprintf(buf->data, sizeof(sbuf) - sizeof(unsigned int), HTTP_WS_REQUEST_PATTERN, path, host, api); + dhdebug("WS request created, %d/%d", buf->len + 1, sizeof(sbuf) - sizeof(unsigned int)); + return buf; } diff --git a/firmware-src/sources/dhrequest.h b/firmware-src/sources/dhrequest.h index 3b4b01d..91bc906 100644 --- a/firmware-src/sources/dhrequest.h +++ b/firmware-src/sources/dhrequest.h @@ -1,10 +1,9 @@ /** * \file dhrequest.h - * \brief Generating HTTP request for DeviceHive server. + * \brief Generating HTTP requests for DeviceHive server. * \author Nikolay Khabarov - * \date 2015 + * \date 2017 * \copyright DeviceHive MIT - * \details All generated request will stored in dynamic memory. When request no longer need in have to be free with dhrequest_free(). */ #ifndef _DHREQUEST_H_ @@ -13,80 +12,39 @@ #include "dhsettings.h" #include "user_config.h" -/** HTTP requests theoretical max size */ -#define HTTP_REQUEST_MIN_ALLOWED_PAYLOAD 2*INTERFACES_BUF_SIZE + 943 // 943 for json formatting and some extra text fields, we use exactly this value to pad to KB. -#define HTTP_REQUEST_MAX_SIZE (DHSETTINGS_SERVER_MAX_LENGTH + DHSETTINGS_ACCESSKEY_MAX_LENGTH + HTTP_REQUEST_MIN_ALLOWED_PAYLOAD) +/** Maximum length of host in urls */ +#define DHREQUEST_HOST_MAX_BUF_LEN 256 + +/** Structure for HTTP request */ typedef struct { unsigned int len; - char data[HTTP_REQUEST_MAX_SIZE]; + char data[]; } HTTP_REQUEST; /** - * \brief Load DeviceHive server credentials from storage. - */ -void dhrequest_load_settings(); - -/** - * \brief Get current DeviceHive server URL. - * \return Pointer to null terminated buffer with DeviceHive server URL. - */ -const char *dhrequest_current_server(); - -/** - * \brief Get current DeviceHive DeviceId. - * \return Pointer to null terminated buffer with DeviceHive DeviceId. - */ -const char *dhrequest_current_deviceid(); - -/** - * \brief Get current DeviceHive AccessKey. - * \return Pointer to null terminated buffer with AccessKey. - */ -const char *dhrequest_current_accesskey(); - -/** - * \brief Create register request. - * \param[out] buf Buffer where request should be created. - */ -void dhrequest_create_register(HTTP_REQUEST *buf); - -/** - * \brief Create poll request. - * \param[out] buf Buffer where request should be created. - * \param[in] timestamp Pointer to null terminated string with timestamp that will be used in poll request. + * \brief Extract host, port, path from URL + * \param[in] url URL to parse. + * \param[out] host Pointer with bugger where to store host. Should be at least DHREQUEST_HOST_MAX_BUF_LEN bytes. Cannot extract more then DHREQUEST_HOST_MAX_BUF_LEN - 1 chars. + * \param[out] port Pointer to int value to store port. + * \return Pointer to url's path or NULL on error. */ -void dhrequest_create_poll(HTTP_REQUEST *buf, const char *timestamp); - -/** - * \brief Create update request. - * \param[out] buf Buffer where request should be created. - * \param[in] commandId Id of command for update. - * \param[in] status Null terminated string with command status. - * \param[in] result Null terminated string with command result. - * \return Pointer created request or NULL if no memory. - */ -void dhrequest_create_update(HTTP_REQUEST *buf, unsigned int commandId, const char *status, const char *result); +const char *dhrequest_parse_url(const char *url, char *host, int *port); /** * \brief Create info request. - * \param[out] buf Buffer where request should be created. - */ -void dhrequest_create_info(HTTP_REQUEST *buf); - -/** - * \brief Create notification request. - * \param[out] buf Buffer where request should be created. - * \param[in] name Notification name. - * \param[in] parameters Notification parameters. + * \details Return valuse is single instance. Each call return pointer to the same buffer. + * \param[in] api DeviceHive API url. + * \return Pointer to HTTP_REQUEST struct. */ -void dhrequest_create_notification(HTTP_REQUEST *buf, const char *name, const char *parameters); +HTTP_REQUEST *dhrequest_create_info(const char *api); /** - * \brief Update poll request. - * \details This function updates timestamp in poll request. If timestamp string length is different, request will be recreated, otherwise original will be reused. - * \param[in] old Pointer for request that should be updated. - * \param[in] timestamp Null terminated string with new timestamp. + * \brief Create WebSocket upgrade request. + * \details Return value is single instance. Each call return pointer to the same buffer. + * \param[in] api DeviceHive API url. + * \param[in] url WebSocket API url. + * \return Pointer to HTTP_REQUEST struct. */ -void dhrequest_update_poll(HTTP_REQUEST *old, const char *timestamp); +HTTP_REQUEST *dhrequest_create_wsrequest(const char *api, const char *url); #endif /* _DHREQUEST_H_ */ diff --git a/firmware-src/sources/dhsender_queue.c b/firmware-src/sources/dhsender_queue.c index b3e2c83..4d8d078 100644 --- a/firmware-src/sources/dhsender_queue.c +++ b/firmware-src/sources/dhsender_queue.c @@ -89,7 +89,7 @@ int ICACHE_FLASH_ATTR dhsender_queue_take(HTTP_REQUEST *out, unsigned int *is_no if(mQueueSize < MEM_RECOVER_THRESHOLD && dhmem_isblock()) dhmem_unblock(); - char buf[HTTP_REQUEST_MIN_ALLOWED_PAYLOAD]; + /*char buf[HTTP_REQUEST_MIN_ALLOWED_PAYLOAD]; if(dhsender_data_to_json(buf, sizeof(buf), item.notification_type == RNT_NOTIFICATION_GPIO, item.data_type, &item.data, item.data_len, item.pin) < 0) { @@ -126,7 +126,7 @@ int ICACHE_FLASH_ATTR dhsender_queue_take(HTTP_REQUEST *out, unsigned int *is_no default: dhdebug("ERROR: Unknown type of request %d", item.type); return 0; - } + }*/ return 1; } diff --git a/firmware-src/sources/dhsettings.h b/firmware-src/sources/dhsettings.h index c012c9e..803165c 100644 --- a/firmware-src/sources/dhsettings.h +++ b/firmware-src/sources/dhsettings.h @@ -81,7 +81,7 @@ const char *dhsettings_get_devicehive_deviceid(); * \brief Get DeviceHive AccessKey. * \return Pointer to buffer with null terminated string. */ -const char *dhsettings_get_devicehive_acceykey(); +const char *dhsettings_get_devicehive_accesskey(); /** * \brief Set Wi-Fi mode. diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index 7d5b7ff..3cfd5b8 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -178,11 +178,11 @@ void ICACHE_FLASH_ATTR dhterminal_commands_status(const char *args) { case CS_GETINFO: dhuart_send_str("getting info from server"); break; - case CS_REGISTER: - dhuart_send_str("registering device"); + case CS_RESOLVEWEBSOCKET: + case CS_WEBSOCKET: + dhuart_send_str("connecting to web socket"); break; - case CS_POLL: - case CS_CUSTOM: + case CS_OPERATE: dhuart_send_str("successfully connected to server"); break; default: diff --git a/firmware-src/sources/rest.c b/firmware-src/sources/rest.c index 0d12d61..b3c5385 100644 --- a/firmware-src/sources/rest.c +++ b/firmware-src/sources/rest.c @@ -12,7 +12,7 @@ #include #include #include "rest.h" -#include "dhrequest.h" +#include "dhsettings.h" #include "dhcommands.h" #include "dhsender_data.h" #include "user_config.h" @@ -75,11 +75,11 @@ HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR rest_handle(const char *path, const char answer->content.len = sizeof(desription) - 1; return HRCS_ANSWERED_HTML; } - if(dhrequest_current_accesskey()[0]) { + if(dhsettings_get_devicehive_accesskey()[0]) { if(key == 0) { return HRCS_UNAUTHORIZED; } - if(os_strcmp(key, dhrequest_current_accesskey())) { + if(os_strcmp(key, dhsettings_get_devicehive_accesskey())) { return HRCS_UNAUTHORIZED; } } diff --git a/firmware-src/sources/uploadable_api.c b/firmware-src/sources/uploadable_api.c index 852b312..06ebccf 100644 --- a/firmware-src/sources/uploadable_api.c +++ b/firmware-src/sources/uploadable_api.c @@ -11,7 +11,7 @@ #include #include -#include "dhrequest.h" +#include "dhsettings.h" #include "uploadable_page.h" HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR uploadable_api_handle(const char *path, const char *key, @@ -19,11 +19,11 @@ HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR uploadable_api_handle(const char *path, c static const char flash[] = "/flash/page/"; answer->content.len = 0; if(os_strncmp(path, flash, sizeof(flash) - 1) == 0) { - if(dhrequest_current_accesskey()[0]) { + if(dhsettings_get_devicehive_accesskey()[0]) { if(key == 0) { return HRCS_UNAUTHORIZED; } - if(os_strcmp(key, dhrequest_current_accesskey())) { + if(os_strcmp(key, dhsettings_get_devicehive_accesskey())) { return HRCS_UNAUTHORIZED; } } From a59caabdc221d931f511cc617014bd90e50b0e96 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Tue, 14 Mar 2017 14:38:25 +0300 Subject: [PATCH 03/83] [wip] websocket communication --- firmware-src/sources/dhconnector.c | 13 +- firmware-src/sources/dhconnector_websocket.c | 119 +++++++++++++++++++ firmware-src/sources/dhconnector_websocket.h | 18 +++ firmware-src/sources/dhrequest.c | 2 +- 4 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 firmware-src/sources/dhconnector_websocket.c create mode 100644 firmware-src/sources/dhconnector_websocket.h diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index f24b267..e65b15f 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -25,6 +25,7 @@ #include "snprintf.h" #include "dhstatistic.h" #include "mdnsd.h" +#include "dhconnector_websocket.h" LOCAL CONNECTION_STATE mConnectionState; LOCAL struct espconn mDHConnector; @@ -71,10 +72,19 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { } } +LOCAL void ws_send(const char *data, unsigned int len) { + if (mConnectionState != CS_OPERATE) + return; + if (espconn_send(&mDHConnector, (uint8 *)data, len) != ESPCONN_OK) { + mConnectionState = CS_DISCONNECT; + arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); + } +} + LOCAL void network_recv_cb(void *arg, char *data, unsigned short len) { dhstatistic_add_bytes_received(len); if (mConnectionState == CS_OPERATE) { - // TODO TODO TODO + dhconnector_websocket_parse(data, len); return; } const char *rc = find_http_responce_code(data, len); @@ -82,6 +92,7 @@ LOCAL void network_recv_cb(void *arg, char *data, unsigned short len) { if (rc[0] == '1' && rc[1] == '0' && rc[2] == '1' && mConnectionState == CS_WEBSOCKET) { // HTTP responce code 101 - Switching Protocols set_state(CS_OPERATE); dhdebug("WebSocket connection is established"); + dhconnector_websocket_start(ws_send); // do not disconnect return; } else if (*rc == '2' && mConnectionState == CS_GETINFO) { // HTTP responce code 2xx - Success diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c new file mode 100644 index 0000000..f7fc94d --- /dev/null +++ b/firmware-src/sources/dhconnector_websocket.c @@ -0,0 +1,119 @@ +/* + * dhconnector_websocket.cpp + * + * Copyright 2017 DeviceHive + * + * Author: Nikolay Khabarov + * + * Description: Module for connecting to remote DeviceHive server via WebSocket + * + */ + +#include "dhconnector_websocket.h" +#include +#include +#include +#include +#include +#include "dhsettings.h" +#include "irom.h" +#include "snprintf.h" +#include "dhdebug.h" +#include "rand.h" + +#define PAYLOAD_BUF_SIZE (DHSETTINGS_DEVICEID_MAX_LENGTH + DHSETTINGS_ACCESSKEY_MAX_LENGTH + 512) +#define WEBSOCKET_HEADER_MAX_SIZE 4 +#define WEBSOCKET_MASK_SIZE 4 + +LOCAL dhconnector_websocket_send_proto mSendFunc; +LOCAL char mBuf[PAYLOAD_BUF_SIZE + WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SIZE]; +LOCAL char *mPayLoadBuf = &mBuf[WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SIZE]; +LOCAL unsigned int mPayLoadBufLen = 0; + +LOCAL void ICACHE_FLASH_ATTR mask() { + uint32_t *mask = (uint32_t *)&mBuf[WEBSOCKET_HEADER_MAX_SIZE]; + *mask = rand(); + int i, j; + for(i = 0, j = 0; i < mPayLoadBufLen; i++, j++) { + if(j >= WEBSOCKET_MASK_SIZE) + j = 0; + mPayLoadBuf[i] ^= mBuf[WEBSOCKET_HEADER_MAX_SIZE + j]; + } +} + +LOCAL void ICACHE_FLASH_ATTR send_payload() { + if (mPayLoadBufLen < 126) { + mBuf[2] = 0x81; // final text frame + mBuf[3] = 0x80 | mPayLoadBufLen; // masked, size +dhdebug_dump(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); + mask(); + mSendFunc(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); + } else { // if (mPayLoadBufLen < 65536) - buf is always smaller then 65536, so there is no implementation for buf more then 65535 bytes. + mBuf[0] = 0x81; // final text frame + mBuf[1] = 0x80 | 126; // masked, size in the next two bytes + mBuf[2] = (mPayLoadBufLen >> 8) & 0xFF; + mBuf[3] = mPayLoadBufLen & 0xFF; +dhdebug_dump(mBuf, mPayLoadBufLen + 4 + WEBSOCKET_MASK_SIZE); + mask(); + mSendFunc(mBuf, mPayLoadBufLen + 4 + WEBSOCKET_MASK_SIZE); + } +} + +LOCAL void ICACHE_FLASH_ATTR start() { + RO_DATA char template[] = "{\"action\": \"authenticate\", \"accessKey\": \"%s\"}"; + mPayLoadBufLen = snprintf(mPayLoadBuf, PAYLOAD_BUF_SIZE, template, dhsettings_get_devicehive_accesskey()); + send_payload(); +} + +void ICACHE_FLASH_ATTR dhconnector_websocket_start(dhconnector_websocket_send_proto send_func) { + mSendFunc = send_func; + start(); +} + +void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned int len) { + // check and response on ping + if (len == 2) { + if (data[0] == 0x89 && data[1] == 0x00) {// PING + static char pong_buf[2] = {0x8A, 0x00}; // PONG + mSendFunc(pong_buf, sizeof(pong_buf)); + return; + } + } + + // check data + if (data[0] != 0x81) { + // always expect final text frame + dhdebug("WebSocket error - wrong header 0x%X", data[0]); + return; + } + if (data[1] & 0x80) { + // always expect unmasked data + dhdebug("WebSocket error - masked data from server"); + return; + } + + // check length + unsigned int wslen = (data[1] & 0x7F); + if (wslen == 127) { + dhdebug("WebSocket error - cannot handle more then 65535 bytes"); + return; + }else if (wslen == 126) { + wslen = data[2]; + wslen <<= 8; + wslen |= data[3]; + data += 4; + len -= 4; + } else if (wslen < 126) { + data += 2; + len -= 2; + } + if (wslen != len) { + // it is final frame, we checked before, received and header lengths should be equal + dhdebug("WebSocket error - length mismatch"); + return; + } + + // here we should have JSON in data and len variables + dhdebug("WS got response"); + dhdebug_dump(data, len); +} diff --git a/firmware-src/sources/dhconnector_websocket.h b/firmware-src/sources/dhconnector_websocket.h new file mode 100644 index 0000000..001694c --- /dev/null +++ b/firmware-src/sources/dhconnector_websocket.h @@ -0,0 +1,18 @@ +/* + * \file dhconnector_websocket.h + * \brief Main connectivity to DeviceHive with WebSocket + * \author Nikolay Khabarov + * \date 2017 + * \copyright DeviceHive MIT + */ + +#ifndef _DHCONNECTOR_WEBSOCKET_H_ +#define _DHCONNECTOR_WEBSOCKET_H_ + +/** Function prototype for sendind data. */ +typedef void (*dhconnector_websocket_send_proto)(const char *data, unsigned int len); + +void dhconnector_websocket_start(dhconnector_websocket_send_proto send_func); +void dhconnector_websocket_parse(const char *data, unsigned int len); + +#endif /* _DHCONNECTOR_WEBSOCKET_H_ */ diff --git a/firmware-src/sources/dhrequest.c b/firmware-src/sources/dhrequest.c index 855169b..dac5124 100644 --- a/firmware-src/sources/dhrequest.c +++ b/firmware-src/sources/dhrequest.c @@ -25,7 +25,7 @@ RO_DATA char HTTP_INFO_REQUEST_PATTERN[] = "Host: %s\r\n\r\n"; RO_DATA char HTTP_WS_REQUEST_PATTERN[] = - "GET %s/device HTTP/1.1\r\n" + "GET %s/client HTTP/1.1\r\n" "Host: %s\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" From 420a19f51c966f7dc034f98e9b6469cbc95de9b2 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Tue, 14 Mar 2017 20:38:59 +0300 Subject: [PATCH 04/83] remove unnessery dumps --- firmware-src/sources/devices/mlx90614.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware-src/sources/devices/mlx90614.c b/firmware-src/sources/devices/mlx90614.c index 294a756..717845e 100644 --- a/firmware-src/sources/devices/mlx90614.c +++ b/firmware-src/sources/devices/mlx90614.c @@ -36,7 +36,6 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, f dhdebug("mlx90614: failed to read Ta"); return status; } - dhdebug_dump(buf, 2); raw_temperature = signedInt16le(buf, 0); *ambient = raw_temperature * 0.02f - 273.15f; @@ -49,7 +48,6 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, f dhdebug("mlx90614: failed to read Tobj1"); return status; } - dhdebug_dump(buf, 2); raw_temperature = signedInt16le(buf, 0); *object = raw_temperature * 0.02f - 273.15f; return DHI2C_OK; From 49536b8fa3878ac494719b4354a968d180677910 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Tue, 14 Mar 2017 20:45:44 +0300 Subject: [PATCH 05/83] split dh protocol and ws impl --- firmware-src/sources/dhconnector.c | 32 ++++-- firmware-src/sources/dhconnector_websocket.c | 40 ++++--- firmware-src/sources/dhconnector_websocket.h | 6 +- .../sources/dhconnector_websocket_api.c | 108 ++++++++++++++++++ .../sources/dhconnector_websocket_api.h | 17 +++ 5 files changed, 175 insertions(+), 28 deletions(-) create mode 100644 firmware-src/sources/dhconnector_websocket_api.c create mode 100644 firmware-src/sources/dhconnector_websocket_api.h diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index e65b15f..1f7f675 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -57,7 +57,7 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { int type; while (jparser->pos < jparser->len) { type = jsonparse_next(jparser); - if(type == JSON_TYPE_PAIR_NAME) { + if (type == JSON_TYPE_PAIR_NAME) { if (jsonparse_strcmp_value(jparser, "webSocketServerUrl") == 0) { jsonparse_next(jparser); if (jsonparse_next(jparser) != JSON_TYPE_ERROR) { @@ -66,22 +66,32 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { } break; } - } else if(type == JSON_TYPE_ERROR) { + } else if (type == JSON_TYPE_ERROR) { + if (jparser->pos > 0 && jparser->len - jparser->pos >= 3) { // fix issue with parsing null value + if (os_strncmp(&jparser->json[jparser->pos - 1], "null", 4) == 0) { + jparser->pos += 3; + jparser->vtype = JSON_TYPE_NULL; + continue; + } + } break; } } } -LOCAL void ws_send(const char *data, unsigned int len) { +LOCAL void ICACHE_FLASH_ATTR ws_error() { + // close connection and restart everything on error + espconn_disconnect(&mDHConnector); +} + +LOCAL void ICACHE_FLASH_ATTR ws_send(const char *data, unsigned int len) { if (mConnectionState != CS_OPERATE) return; - if (espconn_send(&mDHConnector, (uint8 *)data, len) != ESPCONN_OK) { - mConnectionState = CS_DISCONNECT; - arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); - } + if (espconn_send(&mDHConnector, (uint8 *)data, len) != ESPCONN_OK) + ws_error(); } -LOCAL void network_recv_cb(void *arg, char *data, unsigned short len) { +LOCAL void ICACHE_FLASH_ATTR network_recv_cb(void *arg, char *data, unsigned short len) { dhstatistic_add_bytes_received(len); if (mConnectionState == CS_OPERATE) { dhconnector_websocket_parse(data, len); @@ -92,7 +102,7 @@ LOCAL void network_recv_cb(void *arg, char *data, unsigned short len) { if (rc[0] == '1' && rc[1] == '0' && rc[2] == '1' && mConnectionState == CS_WEBSOCKET) { // HTTP responce code 101 - Switching Protocols set_state(CS_OPERATE); dhdebug("WebSocket connection is established"); - dhconnector_websocket_start(ws_send); + dhconnector_websocket_start(ws_send, ws_error); // do not disconnect return; } else if (*rc == '2' && mConnectionState == CS_GETINFO) { // HTTP responce code 2xx - Success @@ -178,12 +188,10 @@ LOCAL void network_connect_cb(void *arg) { LOCAL void network_disconnect_cb(void *arg) { switch(mConnectionState) { - case CS_DISCONNECT: - arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); - break; case CS_GETINFO: set_state(CS_WEBSOCKET); break; + case CS_DISCONNECT: case CS_WEBSOCKET: case CS_OPERATE: mConnectionState = CS_DISCONNECT; diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c index f7fc94d..fc9bc6a 100644 --- a/firmware-src/sources/dhconnector_websocket.c +++ b/firmware-src/sources/dhconnector_websocket.c @@ -16,19 +16,20 @@ #include #include #include "dhsettings.h" -#include "irom.h" -#include "snprintf.h" #include "dhdebug.h" #include "rand.h" +#include "user_config.h" +#include "dhconnector_websocket_api.h" #define PAYLOAD_BUF_SIZE (DHSETTINGS_DEVICEID_MAX_LENGTH + DHSETTINGS_ACCESSKEY_MAX_LENGTH + 512) #define WEBSOCKET_HEADER_MAX_SIZE 4 #define WEBSOCKET_MASK_SIZE 4 LOCAL dhconnector_websocket_send_proto mSendFunc; +LOCAL dhconnector_websocket_error mErrFunc; LOCAL char mBuf[PAYLOAD_BUF_SIZE + WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SIZE]; LOCAL char *mPayLoadBuf = &mBuf[WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SIZE]; -LOCAL unsigned int mPayLoadBufLen = 0; +LOCAL int mPayLoadBufLen = 0; LOCAL void ICACHE_FLASH_ATTR mask() { uint32_t *mask = (uint32_t *)&mBuf[WEBSOCKET_HEADER_MAX_SIZE]; @@ -42,7 +43,9 @@ LOCAL void ICACHE_FLASH_ATTR mask() { } LOCAL void ICACHE_FLASH_ATTR send_payload() { - if (mPayLoadBufLen < 126) { + if (mPayLoadBufLen <= 0) { + return; + } else if (mPayLoadBufLen < 126) { mBuf[2] = 0x81; // final text frame mBuf[3] = 0x80 | mPayLoadBufLen; // masked, size dhdebug_dump(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); @@ -59,15 +62,14 @@ dhdebug_dump(mBuf, mPayLoadBufLen + 4 + WEBSOCKET_MASK_SIZE); } } -LOCAL void ICACHE_FLASH_ATTR start() { - RO_DATA char template[] = "{\"action\": \"authenticate\", \"accessKey\": \"%s\"}"; - mPayLoadBufLen = snprintf(mPayLoadBuf, PAYLOAD_BUF_SIZE, template, dhsettings_get_devicehive_accesskey()); - send_payload(); -} - -void ICACHE_FLASH_ATTR dhconnector_websocket_start(dhconnector_websocket_send_proto send_func) { +void ICACHE_FLASH_ATTR dhconnector_websocket_start(dhconnector_websocket_send_proto send_func, + dhconnector_websocket_error err_func) { mSendFunc = send_func; - start(); + mErrFunc = err_func; + + mPayLoadBufLen = dhconnector_websocket_api_start(mPayLoadBuf, PAYLOAD_BUF_SIZE); + send_payload(); + // TODO check with timeout that we have connected } void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned int len) { @@ -84,11 +86,13 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in if (data[0] != 0x81) { // always expect final text frame dhdebug("WebSocket error - wrong header 0x%X", data[0]); + mErrFunc(); return; } if (data[1] & 0x80) { // always expect unmasked data dhdebug("WebSocket error - masked data from server"); + mErrFunc(); return; } @@ -96,8 +100,9 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in unsigned int wslen = (data[1] & 0x7F); if (wslen == 127) { dhdebug("WebSocket error - cannot handle more then 65535 bytes"); + mErrFunc(); return; - }else if (wslen == 126) { + } else if (wslen == 126) { wslen = data[2]; wslen <<= 8; wslen |= data[3]; @@ -110,10 +115,17 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in if (wslen != len) { // it is final frame, we checked before, received and header lengths should be equal dhdebug("WebSocket error - length mismatch"); + mErrFunc(); return; } // here we should have JSON in data and len variables dhdebug("WS got response"); - dhdebug_dump(data, len); +dhdebug_dump(data, len); + + mPayLoadBufLen = dhconnector_websocket_api_communicate(data, len, mPayLoadBuf, PAYLOAD_BUF_SIZE); + if (mPayLoadBufLen == DHCONNECT_WEBSOCKET_API_ERROR) + mErrFunc(); + else if (mPayLoadBufLen > 0) + send_payload(); } diff --git a/firmware-src/sources/dhconnector_websocket.h b/firmware-src/sources/dhconnector_websocket.h index 001694c..7283278 100644 --- a/firmware-src/sources/dhconnector_websocket.h +++ b/firmware-src/sources/dhconnector_websocket.h @@ -9,10 +9,12 @@ #ifndef _DHCONNECTOR_WEBSOCKET_H_ #define _DHCONNECTOR_WEBSOCKET_H_ -/** Function prototype for sendind data. */ +/** Function prototype for sending data. */ typedef void (*dhconnector_websocket_send_proto)(const char *data, unsigned int len); +/** Function prototype for error callback. */ +typedef void (*dhconnector_websocket_error)(); -void dhconnector_websocket_start(dhconnector_websocket_send_proto send_func); +void dhconnector_websocket_start(dhconnector_websocket_send_proto send_func, dhconnector_websocket_error err_func); void dhconnector_websocket_parse(const char *data, unsigned int len); #endif /* _DHCONNECTOR_WEBSOCKET_H_ */ diff --git a/firmware-src/sources/dhconnector_websocket_api.c b/firmware-src/sources/dhconnector_websocket_api.c new file mode 100644 index 0000000..1053091 --- /dev/null +++ b/firmware-src/sources/dhconnector_websocket_api.c @@ -0,0 +1,108 @@ +/* + * dhconnector_websocket_api.cpp + * + * Copyright 2017 DeviceHive + * + * Author: Nikolay Khabarov + * + * Description: DeviceHive WebSocket protocol implementation + * + */ + +#include "dhconnector_websocket_api.h" +#include +#include +#include +#include +#include +#include +#include "dhsettings.h" +#include "irom.h" +#include "snprintf.h" +#include "dhdebug.h" +#include "rand.h" +#include "user_config.h" + +int ICACHE_FLASH_ATTR dhconnector_websocket_api_start(char *buf, unsigned int maxlen) { + RO_DATA char template[] = + "{" + "\"action\":\"authenticate\"," + "\"accessKey\":\"%s\"" + "}"; + return snprintf(buf, maxlen, template, dhsettings_get_devicehive_accesskey()); +} + +int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsigned int inlen, char *out, unsigned int outmaxlen) { + int type; + int iserror = 1; + char action[32]; + action[0] = 0; + struct jsonparse_state jparser; + jsonparse_setup(&jparser, in, inlen); + while (jparser.pos < jparser.len) { + type = jsonparse_next(&jparser); + if (type == JSON_TYPE_PAIR_NAME) { + if (jsonparse_strcmp_value(&jparser, "status") == 0) { + jsonparse_next(&jparser); + if (jsonparse_next(&jparser) != JSON_TYPE_ERROR) { + iserror = jsonparse_strcmp_value(&jparser, "success"); + } + } else if (jsonparse_strcmp_value(&jparser, "action") == 0) { + jsonparse_next(&jparser); + if (jsonparse_next(&jparser) != JSON_TYPE_ERROR) + jsonparse_copy_value(&jparser, action, sizeof(action)); + } + } else if (type == JSON_TYPE_ERROR) { + if (jparser.pos > 0 && jparser.len - jparser.pos >= 3) { // fix issue with parsing null value + if (os_strncmp(&jparser.json[jparser.pos - 1], "null", 4) == 0) { + jparser.pos += 3; + jparser.vtype = JSON_TYPE_NULL; + continue; + } + } + break; + } + } + + if (iserror) { + dhdebug("Action bad return status: "); + char b[inlen + 1]; + os_memcpy(b, in, inlen); + b[inlen] = 0; + dhdebug("%s", b); + return DHCONNECT_WEBSOCKET_API_ERROR; + } + + if (os_strcmp(action, "authenticate") == 0) { + RO_DATA char template[] = + "{" + "\"action\":\"device/save\"," + "\"deviceId\":\"%s\"," + "\"deviceKey\":\"%s\"," + "\"device\":{" + "\"name\":\"%s\"," + "\"key\":\"%s\"," + "\"status\":\"Online\"," + "\"deviceClass\":{" + "\"name\":\"ESP Class\"," + "\"version\":\""FIRMWARE_VERSION"\"," + "\"offlineTimeout\":\"900\"" + "}" + "}" + "}"; + char dk[9]; + snprintf(dk, sizeof(dk), "%s", dhsettings_get_devicehive_accesskey()); + return snprintf(out, outmaxlen, template, + dhsettings_get_devicehive_deviceid(), dk, + dhsettings_get_devicehive_deviceid(), dk); + } else if (os_strcmp(action, "device/save") == 0) { + RO_DATA char template[] = + "{" + "\"action\":\"command/subscribe\"," + "\"deviceGuids\":[\"%s\"]" + "}"; + return snprintf(out, outmaxlen, template, + dhsettings_get_devicehive_deviceid()); + } + return 0; +} diff --git a/firmware-src/sources/dhconnector_websocket_api.h b/firmware-src/sources/dhconnector_websocket_api.h new file mode 100644 index 0000000..7a920e2 --- /dev/null +++ b/firmware-src/sources/dhconnector_websocket_api.h @@ -0,0 +1,17 @@ +/* + * \file dhconnector_websocket_api.h + * \brief Main connectivity to DeviceHive via WebSocket + * \author Nikolay Khabarov + * \date 2017 + * \copyright DeviceHive MIT + */ + +#ifndef _DHCONNECTOR_WEBSOCKET_API_H_ +#define _DHCONNECTOR_WEBSOCKET_API_H_ + +#define DHCONNECT_WEBSOCKET_API_ERROR -1 + +int dhconnector_websocket_api_start(char *buf, unsigned int maxlen); +int dhconnector_websocket_api_communicate(const char *in, unsigned int inlen, char *out, unsigned int outmaxlen); + +#endif /* _DHCONNECTOR_WEBSOCKET_API_H_ */ From 6f995f060c2a8d2dbbff89b6aea9045c7689c050 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Fri, 17 Mar 2017 19:18:59 +0300 Subject: [PATCH 06/83] [wip] dh ws protocol in progress --- firmware-src/sources/dhconnector.c | 52 ++++---- firmware-src/sources/dhconnector.h | 7 +- firmware-src/sources/dhconnector_websocket.c | 26 ++-- .../sources/dhconnector_websocket_api.c | 84 +++++++++---- firmware-src/sources/dhsender.c | 119 ++---------------- firmware-src/sources/dhsender.h | 22 ++-- firmware-src/sources/dhsender_data.h | 7 ++ firmware-src/sources/dhsender_queue.c | 55 +++++--- firmware-src/sources/dhsender_queue.h | 5 +- firmware-src/sources/dhstatistic.c | 2 +- firmware-src/sources/dhstatistic.h | 2 +- firmware-src/sources/main.c | 3 +- 12 files changed, 176 insertions(+), 208 deletions(-) diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index 1f7f675..9e725a7 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -29,7 +29,6 @@ LOCAL CONNECTION_STATE mConnectionState; LOCAL struct espconn mDHConnector; -LOCAL dhconnector_command_json_cb mCommandCallback; LOCAL os_timer_t mRetryTimer; LOCAL unsigned char mNeedRecover = 0; LOCAL char mWSUrl[DHSETTINGS_SERVER_MAX_LENGTH]; @@ -57,18 +56,18 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { int type; while (jparser->pos < jparser->len) { type = jsonparse_next(jparser); - if (type == JSON_TYPE_PAIR_NAME) { - if (jsonparse_strcmp_value(jparser, "webSocketServerUrl") == 0) { + if(type == JSON_TYPE_PAIR_NAME) { + if(jsonparse_strcmp_value(jparser, "webSocketServerUrl") == 0) { jsonparse_next(jparser); - if (jsonparse_next(jparser) != JSON_TYPE_ERROR) { + if(jsonparse_next(jparser) != JSON_TYPE_ERROR) { jsonparse_copy_value(jparser, mWSUrl, sizeof(mWSUrl)); dhdebug("WebSocker URL received %s", mWSUrl); } break; } - } else if (type == JSON_TYPE_ERROR) { - if (jparser->pos > 0 && jparser->len - jparser->pos >= 3) { // fix issue with parsing null value - if (os_strncmp(&jparser->json[jparser->pos - 1], "null", 4) == 0) { + } else if(type == JSON_TYPE_ERROR) { + if(jparser->pos > 0 && jparser->len - jparser->pos >= 3) { // fix issue with parsing null value + if(os_strncmp(&jparser->json[jparser->pos - 1], "null", 4) == 0) { jparser->pos += 3; jparser->vtype = JSON_TYPE_NULL; continue; @@ -80,44 +79,47 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { } LOCAL void ICACHE_FLASH_ATTR ws_error() { + dhstatistic_inc_server_errors_count(); // close connection and restart everything on error espconn_disconnect(&mDHConnector); } LOCAL void ICACHE_FLASH_ATTR ws_send(const char *data, unsigned int len) { - if (mConnectionState != CS_OPERATE) + if(mConnectionState != CS_OPERATE) return; - if (espconn_send(&mDHConnector, (uint8 *)data, len) != ESPCONN_OK) + if(espconn_send(&mDHConnector, (uint8 *)data, len) != ESPCONN_OK) ws_error(); + else + dhstatistic_add_bytes_sent(len); } LOCAL void ICACHE_FLASH_ATTR network_recv_cb(void *arg, char *data, unsigned short len) { dhstatistic_add_bytes_received(len); - if (mConnectionState == CS_OPERATE) { + if(mConnectionState == CS_OPERATE) { dhconnector_websocket_parse(data, len); return; } const char *rc = find_http_responce_code(data, len); - if (rc) { // HTTP - if (rc[0] == '1' && rc[1] == '0' && rc[2] == '1' && mConnectionState == CS_WEBSOCKET) { // HTTP responce code 101 - Switching Protocols + if(rc) { // HTTP + if(rc[0] == '1' && rc[1] == '0' && rc[2] == '1' && mConnectionState == CS_WEBSOCKET) { // HTTP responce code 101 - Switching Protocols set_state(CS_OPERATE); dhdebug("WebSocket connection is established"); dhconnector_websocket_start(ws_send, ws_error); // do not disconnect return; - } else if (*rc == '2' && mConnectionState == CS_GETINFO) { // HTTP responce code 2xx - Success - if (os_strstr(data, (char *) "\r\n\r\n")) { + } else if(*rc == '2' && mConnectionState == CS_GETINFO) { // HTTP responce code 2xx - Success + if(os_strstr(data, (char *) "\r\n\r\n")) { int deep = 0; unsigned int pos = 0; unsigned int jsonstart = 0; while (pos < len) { - if (data[pos] == '{') { - if (deep == 0) + if(data[pos] == '{') { + if(deep == 0) jsonstart = pos; deep++; - } else if (data[pos] == '}') { + } else if(data[pos] == '}') { deep--; - if (deep == 0) { + if(deep == 0) { struct jsonparse_state jparser; jsonparse_setup(&jparser, &data[jsonstart], pos - jsonstart + 1); @@ -132,12 +134,12 @@ LOCAL void ICACHE_FLASH_ATTR network_recv_cb(void *arg, char *data, unsigned sho dhdebug("Connector HTTP response bad status %c%c%c", rc[0],rc[1],rc[2]); dhdebug_ram(data); dhdebug("--------------------------------------"); - dhstatistic_server_errors_count(); + dhstatistic_inc_server_errors_count(); } } else { mConnectionState = CS_DISCONNECT; dhdebug("Connector HTTP magic number is wrong"); - dhstatistic_server_errors_count(); + dhstatistic_inc_server_errors_count(); } espconn_disconnect(&mDHConnector); } @@ -177,7 +179,7 @@ LOCAL void network_connect_cb(void *arg) { dhdebug("ASSERT: networkConnectCb wrong state %d", mConnectionState); } int res; - if ( (res = espconn_send(&mDHConnector, request->data, request->len)) != ESPCONN_OK) { + if( (res = espconn_send(&mDHConnector, request->data, request->len)) != ESPCONN_OK) { mConnectionState = CS_DISCONNECT; dhesperrors_espconn_result("network_connect_cb failed:", res); espconn_disconnect(&mDHConnector); @@ -199,7 +201,7 @@ LOCAL void network_disconnect_cb(void *arg) { break; /* TODO TODO TODO case CS_CUSTOM: - if (dhterminal_is_in_use()) { + if(dhterminal_is_in_use()) { dhdebug("Terminal is in use, no deep sleep"); arm_repeat_timer(CUSTOM_NOTIFICATION_INTERVAL_MS); } else { @@ -222,7 +224,7 @@ LOCAL void ICACHE_FLASH_ATTR dhconnector_init_connection(ip_addr_t *ip) { } LOCAL void ICACHE_FLASH_ATTR resolve_cb(const char *name, ip_addr_t *ip, void *arg) { - if (ip == NULL) { + if(ip == NULL) { dhdebug("Resolve %s failed. Trying again...", name); mConnectionState = CS_DISCONNECT; arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); @@ -327,7 +329,6 @@ LOCAL void ICACHE_FLASH_ATTR wifi_state_cb(System_Event_t *event) { } } else if(event->event == EVENT_STAMODE_DISCONNECTED) { os_timer_disarm(&mRetryTimer); - dhsender_stop_repeat(); dhesperrors_disconnect_reason("WiFi disconnected", event->event_info.disconnected.reason); dhstatistic_inc_wifi_lost_count(); mdnsd_stop(); @@ -336,8 +337,7 @@ LOCAL void ICACHE_FLASH_ATTR wifi_state_cb(System_Event_t *event) { } } -void ICACHE_FLASH_ATTR dhconnector_init(dhconnector_command_json_cb cb) { - mCommandCallback = cb; +void ICACHE_FLASH_ATTR dhconnector_init() { mConnectionState = CS_DISCONNECT; wifi_set_opmode(STATION_MODE); diff --git a/firmware-src/sources/dhconnector.h b/firmware-src/sources/dhconnector.h index 70ab587..f09e774 100644 --- a/firmware-src/sources/dhconnector.h +++ b/firmware-src/sources/dhconnector.h @@ -12,10 +12,6 @@ #include "dhrequest.h" #include "dhsender_data.h" -/** Function prototype for handling function. */ -typedef void (*dhconnector_command_json_cb)(COMMAND_RESULT *cb, - const char *command, const char *params, unsigned int paramslen); - /** Current connection state. */ typedef enum { CS_DISCONNECT, ///< Disconnected from DeviceHive server. @@ -27,9 +23,8 @@ typedef enum { /** * \brief Initializes connector, parameters are taken from permanent storage. - * \param[in] cb Pointer to command callback. */ -void dhconnector_init(dhconnector_command_json_cb cb); +void dhconnector_init(); /** * \brief Get connector current state. diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c index fc9bc6a..f5043a1 100644 --- a/firmware-src/sources/dhconnector_websocket.c +++ b/firmware-src/sources/dhconnector_websocket.c @@ -43,15 +43,15 @@ LOCAL void ICACHE_FLASH_ATTR mask() { } LOCAL void ICACHE_FLASH_ATTR send_payload() { - if (mPayLoadBufLen <= 0) { + if(mPayLoadBufLen <= 0) { return; - } else if (mPayLoadBufLen < 126) { + } else if(mPayLoadBufLen < 126) { mBuf[2] = 0x81; // final text frame mBuf[3] = 0x80 | mPayLoadBufLen; // masked, size dhdebug_dump(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); mask(); mSendFunc(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); - } else { // if (mPayLoadBufLen < 65536) - buf is always smaller then 65536, so there is no implementation for buf more then 65535 bytes. + } else { // if(mPayLoadBufLen < 65536) - buf is always smaller then 65536, so there is no implementation for buf more then 65535 bytes. mBuf[0] = 0x81; // final text frame mBuf[1] = 0x80 | 126; // masked, size in the next two bytes mBuf[2] = (mPayLoadBufLen >> 8) & 0xFF; @@ -74,8 +74,8 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_start(dhconnector_websocket_send_pr void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned int len) { // check and response on ping - if (len == 2) { - if (data[0] == 0x89 && data[1] == 0x00) {// PING + if(len == 2) { + if(data[0] == 0x89 && data[1] == 0x00) {// PING static char pong_buf[2] = {0x8A, 0x00}; // PONG mSendFunc(pong_buf, sizeof(pong_buf)); return; @@ -83,13 +83,13 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in } // check data - if (data[0] != 0x81) { + if(data[0] != 0x81) { // always expect final text frame dhdebug("WebSocket error - wrong header 0x%X", data[0]); mErrFunc(); return; } - if (data[1] & 0x80) { + if(data[1] & 0x80) { // always expect unmasked data dhdebug("WebSocket error - masked data from server"); mErrFunc(); @@ -98,21 +98,21 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in // check length unsigned int wslen = (data[1] & 0x7F); - if (wslen == 127) { + if(wslen == 127) { dhdebug("WebSocket error - cannot handle more then 65535 bytes"); mErrFunc(); return; - } else if (wslen == 126) { + } else if(wslen == 126) { wslen = data[2]; wslen <<= 8; wslen |= data[3]; data += 4; len -= 4; - } else if (wslen < 126) { + } else if(wslen < 126) { data += 2; len -= 2; } - if (wslen != len) { + if(wslen != len) { // it is final frame, we checked before, received and header lengths should be equal dhdebug("WebSocket error - length mismatch"); mErrFunc(); @@ -124,8 +124,8 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in dhdebug_dump(data, len); mPayLoadBufLen = dhconnector_websocket_api_communicate(data, len, mPayLoadBuf, PAYLOAD_BUF_SIZE); - if (mPayLoadBufLen == DHCONNECT_WEBSOCKET_API_ERROR) + if(mPayLoadBufLen == DHCONNECT_WEBSOCKET_API_ERROR) mErrFunc(); - else if (mPayLoadBufLen > 0) + else if(mPayLoadBufLen > 0) send_payload(); } diff --git a/firmware-src/sources/dhconnector_websocket_api.c b/firmware-src/sources/dhconnector_websocket_api.c index 1053091..7d1e203 100644 --- a/firmware-src/sources/dhconnector_websocket_api.c +++ b/firmware-src/sources/dhconnector_websocket_api.c @@ -22,6 +22,9 @@ #include "dhdebug.h" #include "rand.h" #include "user_config.h" +#include "dhcommands.h" +#include "dhsender.h" +#include "dhsender_queue.h" int ICACHE_FLASH_ATTR dhconnector_websocket_api_start(char *buf, unsigned int maxlen) { RO_DATA char template[] = @@ -32,29 +35,65 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_start(char *buf, unsigned int ma return snprintf(buf, maxlen, template, dhsettings_get_devicehive_accesskey()); } +LOCAL int check_bad_status(int status, const char *in, unsigned int inlen) { + if(status) { + dhdebug("Action bad return status: "); + char b[inlen + 1]; + os_memcpy(b, in, inlen); + b[inlen] = 0; + dhdebug("%s", b); + } + return status; +} + int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsigned int inlen, char *out, unsigned int outmaxlen) { int type; - int iserror = 1; + int status_not_success = 1; char action[32]; + char command[128]; + const char *params; + unsigned int paramslen; + unsigned int id; action[0] = 0; struct jsonparse_state jparser; jsonparse_setup(&jparser, in, inlen); while (jparser.pos < jparser.len) { type = jsonparse_next(&jparser); - if (type == JSON_TYPE_PAIR_NAME) { - if (jsonparse_strcmp_value(&jparser, "status") == 0) { + if(type == JSON_TYPE_PAIR_NAME) { + if(jsonparse_strcmp_value(&jparser, "status") == 0) { jsonparse_next(&jparser); - if (jsonparse_next(&jparser) != JSON_TYPE_ERROR) { - iserror = jsonparse_strcmp_value(&jparser, "success"); + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) { + status_not_success = jsonparse_strcmp_value(&jparser, "success"); } - } else if (jsonparse_strcmp_value(&jparser, "action") == 0) { + } else if(jsonparse_strcmp_value(&jparser, "action") == 0) { jsonparse_next(&jparser); - if (jsonparse_next(&jparser) != JSON_TYPE_ERROR) + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) jsonparse_copy_value(&jparser, action, sizeof(action)); + } else if(jsonparse_strcmp_value(&jparser, "command") == 0) { + jsonparse_next(&jparser); + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) + jsonparse_copy_value(&jparser, command, sizeof(command)); + } + } else if(jsonparse_strcmp_value(&jparser, "id") == 0) { + jsonparse_next(&jparser); + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) + id = jsonparse_get_value_as_ulong(&jparser); + } else if(jsonparse_strcmp_value(&jparser, "parameters") == 0) { + jsonparse_next(&jparser); + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) { + // there is an issue with extracting subjson with jparser->vstart or jparser_copy_value + params = &jparser.json[jparser.pos - 1]; + if(*params == '{') { + int end = jparser.pos; + while(end < jparser.len && jparser.json[end] != '}') { + end++; + } + paramslen = end - jparser.pos + 2; + } } - } else if (type == JSON_TYPE_ERROR) { - if (jparser.pos > 0 && jparser.len - jparser.pos >= 3) { // fix issue with parsing null value - if (os_strncmp(&jparser.json[jparser.pos - 1], "null", 4) == 0) { + } else if(type == JSON_TYPE_ERROR) { + if(jparser.pos > 0 && jparser.len - jparser.pos >= 3) { // fix issue with parsing null value + if(os_strncmp(&jparser.json[jparser.pos - 1], "null", 4) == 0) { jparser.pos += 3; jparser.vtype = JSON_TYPE_NULL; continue; @@ -64,16 +103,13 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsi } } - if (iserror) { - dhdebug("Action bad return status: "); - char b[inlen + 1]; - os_memcpy(b, in, inlen); - b[inlen] = 0; - dhdebug("%s", b); - return DHCONNECT_WEBSOCKET_API_ERROR; - } - - if (os_strcmp(action, "authenticate") == 0) { + if(os_strcmp(action, "command/insert") == 0) { + COMMAND_RESULT cb; + cb.callback = dhsender_response; + cb.data.id = id; + dhcommands_do(&cb, command, params, paramslen); + return 0; + } else if(os_strcmp(action, "authenticate") == 0) { RO_DATA char template[] = "{" "\"action\":\"device/save\"," @@ -91,16 +127,22 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsi "}" "}"; char dk[9]; + if(check_bad_status(status_not_success, in, inlen)) { + return DHCONNECT_WEBSOCKET_API_ERROR; + } snprintf(dk, sizeof(dk), "%s", dhsettings_get_devicehive_accesskey()); return snprintf(out, outmaxlen, template, dhsettings_get_devicehive_deviceid(), dk, dhsettings_get_devicehive_deviceid(), dk); - } else if (os_strcmp(action, "device/save") == 0) { + } else if(os_strcmp(action, "device/save") == 0) { RO_DATA char template[] = "{" "\"action\":\"command/subscribe\"," "\"deviceGuids\":[\"%s\"]" "}"; + if(check_bad_status(status_not_success, in, inlen)) { + return DHCONNECT_WEBSOCKET_API_ERROR; + } return snprintf(out, outmaxlen, template, dhsettings_get_devicehive_deviceid()); } diff --git a/firmware-src/sources/dhsender.c b/firmware-src/sources/dhsender.c index b52c97d..9a83cdb 100644 --- a/firmware-src/sources/dhsender.c +++ b/firmware-src/sources/dhsender.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -26,42 +27,21 @@ #define DHSENDER_RETRY_COUNT 5 -LOCAL struct espconn mDHSender = {0}; -LOCAL os_timer_t mRepeatTimer = {0}; -LOCAL unsigned char mStopped = 0; -LOCAL HTTP_REQUEST mSenderRequest; +LOCAL SENDER_JSON_DATA mDataToSend; LOCAL unsigned int isCurrentNotification; LOCAL int mSenderTook = 0; -LOCAL void dhsender_next(void *arg); - -LOCAL void ICACHE_FLASH_ATTR dhsender_arm_timer(unsigned int ms) { - os_timer_disarm(&mRepeatTimer); - os_timer_setfn(&mRepeatTimer, (os_timer_func_t *)dhsender_next, NULL); - os_timer_arm(&mRepeatTimer, ms, 0); -} - -LOCAL void ICACHE_FLASH_ATTR dhsender_next(void *arg) { - if(mStopped) - return; +SENDER_JSON_DATA * ICACHE_FLASH_ATTR dhsender_next(void *arg) { if(mSenderTook == 0) { - if(dhsender_queue_take(&mSenderRequest, &isCurrentNotification)) - mSenderTook = DHSENDER_RETRY_COUNT; - else - return; - } - sint8 cr = espconn_connect(&mDHSender); - if(cr == ESPCONN_ISCONN) { - return; - } else if (cr != ESPCONN_OK) { - dhesperrors_espconn_result("Sender espconn_connect failed:", cr); - dhsender_arm_timer(RETRY_CONNECTION_INTERVAL_MS); - } else { + if(dhsender_queue_take(&mDataToSend, &isCurrentNotification) == 0) + return NULL; + mSenderTook = DHSENDER_RETRY_COUNT; dhdebug("Sender start"); } + return &mDataToSend; } -LOCAL void ICACHE_FLASH_ATTR decrementSenderTook() { +void ICACHE_FLASH_ATTR dhsender_current_fail() { if(mSenderTook) { if(mSenderTook == 1) { dhdebug("WARNING: Request is not delivered after %u attempts", DHSENDER_RETRY_COUNT); @@ -74,83 +54,8 @@ LOCAL void ICACHE_FLASH_ATTR decrementSenderTook() { } } -LOCAL void ICACHE_FLASH_ATTR senderDisconnectCb(void *arg) { - if(mSenderTook == 0) { - dhsender_arm_timer(DHREQUEST_PAUSE_MS); - } else { - decrementSenderTook(); - dhsender_arm_timer(RETRY_CONNECTION_INTERVAL_MS); - } -} - -LOCAL void ICACHE_FLASH_ATTR senderErrorCb(void *arg, sint8 err) { - dhesperrors_espconn_result("Sender error occurred:", err); - decrementSenderTook(); - dhsender_arm_timer(RETRY_CONNECTION_INTERVAL_MS); - dhstatistic_inc_network_errors_count(); -} - -LOCAL void ICACHE_FLASH_ATTR senderRecvCb(void *arg, char *data, unsigned short len) { - dhstatistic_add_bytes_received(len); - const char *rc = find_http_responce_code(data, len); - if (rc) { // HTTP - if (*rc == '2') { // HTTP responce code 2xx - Success - mSenderTook = 0; - dhdebug("Sender received OK"); - } else { - dhdebug("Sender HTTP response bad status %c%c%c", rc[0],rc[1],rc[2]); - dhdebug_ram(data); - dhdebug("--------------------------------------"); - dhstatistic_server_errors_count(); - } - } else { - dhdebug("Sender received wrong HTTP magic"); - dhstatistic_server_errors_count(); - } - espconn_disconnect(&mDHSender); -} - -LOCAL void ICACHE_FLASH_ATTR senderConnectCb(void *arg) { - int res; - uint32_t keepalive; - espconn_set_opt(&mDHSender, ESPCONN_KEEPALIVE); - //set keepalive: 40s = 30 + 5 * 2 - keepalive = 30; - espconn_set_keepalive(&mDHSender, ESPCONN_KEEPIDLE, &keepalive); - keepalive = 5; - espconn_set_keepalive(&mDHSender, ESPCONN_KEEPINTVL, &keepalive); - keepalive = 2; - espconn_set_keepalive(&mDHSender, ESPCONN_KEEPCNT, &keepalive); - if( (res = espconn_send(&mDHSender, mSenderRequest.data, mSenderRequest.len)) != ESPCONN_OK) { - dhesperrors_espconn_result("sender espconn_send failed:", res); - espconn_disconnect(&mDHSender); - } else { - dhstatistic_add_bytes_sent(mSenderRequest.len); - } -} - -void ICACHE_FLASH_ATTR dhsender_init(ip_addr_t *ip, int port) { - static esp_tcp tcp; - static int local_port = -1; - if(local_port == -1) - local_port = espconn_port(); - mDHSender.type = ESPCONN_TCP; - mDHSender.state = ESPCONN_NONE; - mDHSender.proto.tcp = &tcp; - mDHSender.proto.tcp->local_port = local_port; - mDHSender.proto.tcp->remote_port = port; - os_memcpy(mDHSender.proto.tcp->remote_ip, &ip->addr, sizeof(ip->addr)); - espconn_regist_connectcb(&mDHSender, senderConnectCb); - espconn_regist_recvcb(&mDHSender, senderRecvCb); - espconn_regist_reconcb(&mDHSender, senderErrorCb); - espconn_regist_disconcb(&mDHSender, senderDisconnectCb); - mStopped = 0; - dhsender_arm_timer(DHREQUEST_PAUSE_MS); -} - -void ICACHE_FLASH_ATTR dhsender_stop_repeat() { - mStopped = 1; - os_timer_disarm(&mRepeatTimer); +void ICACHE_FLASH_ATTR dhsender_current_success() { + mSenderTook = 0; } void ICACHE_FLASH_ATTR dhsender_response(CommandResultArgument cid, RESPONCE_STATUS status, REQUEST_DATA_TYPE data_type, ...) { @@ -161,7 +66,7 @@ void ICACHE_FLASH_ATTR dhsender_response(CommandResultArgument cid, RESPONCE_STA dhsender_next(NULL); } else { dhstatistic_inc_responces_dropped_count(); - dhdebug("ERROR: No memory for response."); + dhdebug("ERROR: No memory for response"); } va_end(ap); } @@ -174,7 +79,7 @@ void ICACHE_FLASH_ATTR dhsender_notification(REQUEST_NOTIFICATION_TYPE type, REQ dhsender_next(NULL); } else { dhstatistic_inc_notifications_dropped_count(); - dhdebug("ERROR: No memory for notification."); + dhdebug("ERROR: No memory for notification"); } va_end(ap); } diff --git a/firmware-src/sources/dhsender.h b/firmware-src/sources/dhsender.h index b78f8ab..5531d35 100644 --- a/firmware-src/sources/dhsender.h +++ b/firmware-src/sources/dhsender.h @@ -17,17 +17,20 @@ #include "dhsender_data.h" /** - * \brief Initializes sender for using remote DeviceHive server. - * \param[in] ip Remote server IP. - * \param[in] port Remote server port. + * \brief Notify that current data was failed to send. */ -void dhsender_init(ip_addr_t *ip, int port); +void dhsender_current_fail(); /** - * \brief Start sending data from queue. - * \details It does nothing if data sending is already in progress or there is no data for sending + * \brief Notify that current data was sent. */ -void dhsender_start(); +void dhsender_current_success(); + +/** + * \brief Get next struct SENDER_JSON_DATA which should be sent. + * \return Pointer to SENDER_JSON_DATA or NULL if there is no data to send. + */ +SENDER_JSON_DATA *dhsender_next(); /** * \brief Send command response. @@ -46,9 +49,4 @@ void dhsender_response(CommandResultArgument cid, RESPONCE_STATUS status, REQUES */ void dhsender_notification(REQUEST_NOTIFICATION_TYPE type, REQUEST_DATA_TYPE data_type, ...); -/** - * \brief Stops repeat attempts on error. - */ -void dhsender_stop_repeat(); - #endif /* _DHSENDER_H_ */ diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index 89639ab..aadc427 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -11,6 +11,7 @@ #include #include "user_config.h" +#include "dhsettings.h" /** Data type that should be read from arguments and how it will be formatted in response or notification. */ typedef enum { @@ -76,6 +77,12 @@ typedef union { GPIO_DATA gpio; ///< GPIO data. } SENDERDATA; +/** Struct for passing JSON. */ +typedef union { + char json[((3 * INTERFACES_BUF_SIZE + DHSETTINGS_DEVICEID_MAX_LENGTH) / 1024 + 1) * 1024]; ///< JSON string + unsigned int jsonlen; ///< Length of JSON +} SENDER_JSON_DATA; + /** * \brief Parse va list to SENDERDATA. * \param[in] ap Std va list. diff --git a/firmware-src/sources/dhsender_queue.c b/firmware-src/sources/dhsender_queue.c index 4d8d078..3be4e0d 100644 --- a/firmware-src/sources/dhsender_queue.c +++ b/firmware-src/sources/dhsender_queue.c @@ -49,7 +49,7 @@ int ICACHE_FLASH_ATTR dhsender_queue_add(REQUEST_TYPE type, REQUEST_NOTIFICATION ETS_INTR_LOCK(); if(mQueueAddPos == mQueueTakePos) { ETS_INTR_UNLOCK(); - dhdebug("ERROR: no space for request"); + dhdebug("ERROR: No space in queue"); return 0; } mQueue[mQueueAddPos].id = id; @@ -71,7 +71,7 @@ int ICACHE_FLASH_ATTR dhsender_queue_add(REQUEST_TYPE type, REQUEST_NOTIFICATION return 1; } -int ICACHE_FLASH_ATTR dhsender_queue_take(HTTP_REQUEST *out, unsigned int *is_notification) { +int ICACHE_FLASH_ATTR dhsender_queue_take(SENDER_JSON_DATA *out, unsigned int *is_notification) { if(mQueueTakePos < 0) return 0; ETS_INTR_LOCK(); @@ -89,44 +89,67 @@ int ICACHE_FLASH_ATTR dhsender_queue_take(HTTP_REQUEST *out, unsigned int *is_no if(mQueueSize < MEM_RECOVER_THRESHOLD && dhmem_isblock()) dhmem_unblock(); - /*char buf[HTTP_REQUEST_MIN_ALLOWED_PAYLOAD]; - if(dhsender_data_to_json(buf, sizeof(buf), - item.notification_type == RNT_NOTIFICATION_GPIO, item.data_type, - &item.data, item.data_len, item.pin) < 0) { - snprintf(buf, sizeof(buf), "Failed to convert data to json"); - item.type = RT_RESPONCE_ERROR; - } - *is_notification = 0; + unsigned int pos = 0; switch(item.type) { case RT_RESPONCE_OK: case RT_RESPONCE_ERROR: - dhrequest_create_update(out, item.id, (item.type == RT_RESPONCE_OK) ? STATUS_OK : STATUS_ERROR, buf); + pos = snprintf(out->json, sizeof(out->json), + "{" + "\"action\":\"command/update\"," + "\"deviceGuid\":\"%s\"," + "\"commandId\":%d," + "\"command\":{" + "\"status\":\"%s\"," + "\"result\":" + , dhsettings_get_devicehive_deviceid(), item.id, + (item.type == RT_RESPONCE_OK) ? STATUS_OK : STATUS_ERROR); break; case RT_NOTIFICATION: + { + char *notification_name = NULL; *is_notification = 1; switch(item.notification_type) { case RNT_NOTIFICATION_GPIO: - dhrequest_create_notification(out, "gpio/int", buf); + notification_name = "gpio/int"; break; case RNT_NOTIFICATION_ADC: - dhrequest_create_notification(out, "adc/int", buf); + notification_name = "adc/int"; break; case RNT_NOTIFICATION_UART: - dhrequest_create_notification(out, "uart/int", buf); + notification_name = "uart/int"; break; case RNT_NOTIFICATION_ONEWIRE: - dhrequest_create_notification(out, "onewire/master/int", buf); + notification_name = "onewire/master/int"; break; default: dhdebug("ERROR: Unknown notification type of request %d", item.notification_type); return 0; } + pos = snprintf(out->json, sizeof(out->json), + "{" + "\"action\":\"notification/insert\"," + "\"deviceGuid\":\"%s\"," + "\"notification\": {" + "\"notification\":\"%s\"," + "\"parameters\":" + , dhsettings_get_devicehive_deviceid(), notification_name); break; + } default: dhdebug("ERROR: Unknown type of request %d", item.type); return 0; - }*/ + } + + if(dhsender_data_to_json(&out->json[pos], sizeof(out->json) - pos, + item.notification_type == RNT_NOTIFICATION_GPIO, item.data_type, + &item.data, item.data_len, item.pin) < 0) { + pos += snprintf(&out->json[pos], sizeof(out->json) - pos, "Failed to convert data to json"); + item.type = RT_RESPONCE_ERROR; + } + + pos += snprintf(&out->json[pos], sizeof(out->json) - pos, "}}"); + out->jsonlen = pos; return 1; } diff --git a/firmware-src/sources/dhsender_queue.h b/firmware-src/sources/dhsender_queue.h index b22f931..56acf37 100644 --- a/firmware-src/sources/dhsender_queue.h +++ b/firmware-src/sources/dhsender_queue.h @@ -10,7 +10,6 @@ #define _DHSENDER_QUEUE_H_ #include -#include "dhrequest.h" #include "dhsender_data.h" /** @@ -27,11 +26,11 @@ int dhsender_queue_add(REQUEST_TYPE type, REQUEST_NOTIFICATION_TYPE notification /** * \brief Take one item from queue. * \details Taken item will be deleted from queue. - * \param[out] out Pointer to HTTP_REQUEST that should be created. + * \param[out] out Pointer to SENDER_JSON_DATA that should be created. * \param[out] is_notification Pointer to variable that will receive non zero value if taken request is notification, zero value otherwise. * \return Non zero value on success, zero on error. */ -int dhsender_queue_take(HTTP_REQUEST *out, unsigned int *is_notification); +int dhsender_queue_take(SENDER_JSON_DATA *out, unsigned int *is_notification); /** * \brief Getting current queue size. diff --git a/firmware-src/sources/dhstatistic.c b/firmware-src/sources/dhstatistic.c index baa888f..440d3e9 100644 --- a/firmware-src/sources/dhstatistic.c +++ b/firmware-src/sources/dhstatistic.c @@ -38,7 +38,7 @@ void ICACHE_FLASH_ATTR dhstatistic_inc_wifi_lost_count() { mStatistic.wifiLosts++; } -void ICACHE_FLASH_ATTR dhstatistic_server_errors_count() { +void ICACHE_FLASH_ATTR dhstatistic_inc_server_errors_count() { mStatistic.serverErrors++; } diff --git a/firmware-src/sources/dhstatistic.h b/firmware-src/sources/dhstatistic.h index 32c28cb..9a57e40 100644 --- a/firmware-src/sources/dhstatistic.h +++ b/firmware-src/sources/dhstatistic.h @@ -61,7 +61,7 @@ void dhstatistic_inc_wifi_lost_count(); /** * \brief Increment number of server errors. */ -void dhstatistic_server_errors_count(); +void dhstatistic_inc_server_errors_count(); /** * \brief Increment number of notifications. diff --git a/firmware-src/sources/main.c b/firmware-src/sources/main.c index ddc21be..05dc465 100644 --- a/firmware-src/sources/main.c +++ b/firmware-src/sources/main.c @@ -14,7 +14,6 @@ #include #include #include "gpio.h" -#include "dhcommands.h" #include "dhdebug.h" #include "dhuart.h" #include "dhsender_queue.h" @@ -133,7 +132,7 @@ void user_init(void) { } else { if(dhsettings_get_wifi_mode() == WIFI_MODE_CLIENT) { dhsender_queue_init(); - dhconnector_init(dhcommands_do); + dhconnector_init(); dhgpio_init(); } else if(dhsettings_get_wifi_mode() == WIFI_MODE_AP) { dhap_init(dhsettings_get_wifi_ssid(), dhsettings_get_wifi_password()); From 8dd4ec1312090233b7bac9e7accf476185609a10 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Mon, 20 Mar 2017 18:08:00 +0300 Subject: [PATCH 07/83] ws finally works --- firmware-src/sources/dhconnector_websocket.c | 53 +++++++++++++----- firmware-src/sources/dhconnector_websocket.h | 11 ++++ .../sources/dhconnector_websocket_api.c | 54 ++++++++----------- .../sources/dhconnector_websocket_api.h | 14 +++++ firmware-src/sources/dhsender.c | 14 +++-- firmware-src/sources/dhsender.h | 9 ++++ firmware-src/sources/dhsender_data.c | 4 +- firmware-src/sources/dhsender_data.h | 10 ++-- firmware-src/sources/dhsender_queue.c | 7 ++- firmware-src/sources/dhutils.h | 6 +++ 10 files changed, 127 insertions(+), 55 deletions(-) diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c index f5043a1..62c3c3b 100644 --- a/firmware-src/sources/dhconnector_websocket.c +++ b/firmware-src/sources/dhconnector_websocket.c @@ -20,8 +20,14 @@ #include "rand.h" #include "user_config.h" #include "dhconnector_websocket_api.h" +#include "dhsettings.h" +#include "dhutils.h" +#include "dhsender_data.h" +#include "dhsender.h" -#define PAYLOAD_BUF_SIZE (DHSETTINGS_DEVICEID_MAX_LENGTH + DHSETTINGS_ACCESSKEY_MAX_LENGTH + 512) +#define PAYLOAD_BUF_SIZE (MAX( \ + ROUND_KB(DHSETTINGS_DEVICEID_MAX_LENGTH + DHSETTINGS_ACCESSKEY_MAX_LENGTH + 512), \ + SENDER_JSON_MAX_LENGTH)) #define WEBSOCKET_HEADER_MAX_SIZE 4 #define WEBSOCKET_MASK_SIZE 4 @@ -31,6 +37,15 @@ LOCAL char mBuf[PAYLOAD_BUF_SIZE + WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SI LOCAL char *mPayLoadBuf = &mBuf[WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SIZE]; LOCAL int mPayLoadBufLen = 0; +LOCAL void ICACHE_FLASH_ATTR error(data, len) { + mErrFunc(); + dhsender_current_fail(); + char b[len + 1]; + os_memcpy(b, data, len); + b[len] = 0; + dhdebug("%s", b); +} + LOCAL void ICACHE_FLASH_ATTR mask() { uint32_t *mask = (uint32_t *)&mBuf[WEBSOCKET_HEADER_MAX_SIZE]; *mask = rand(); @@ -48,7 +63,6 @@ LOCAL void ICACHE_FLASH_ATTR send_payload() { } else if(mPayLoadBufLen < 126) { mBuf[2] = 0x81; // final text frame mBuf[3] = 0x80 | mPayLoadBufLen; // masked, size -dhdebug_dump(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); mask(); mSendFunc(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); } else { // if(mPayLoadBufLen < 65536) - buf is always smaller then 65536, so there is no implementation for buf more then 65535 bytes. @@ -56,17 +70,30 @@ dhdebug_dump(&mBuf[2], mPayLoadBufLen + 2 + WEBSOCKET_MASK_SIZE); mBuf[1] = 0x80 | 126; // masked, size in the next two bytes mBuf[2] = (mPayLoadBufLen >> 8) & 0xFF; mBuf[3] = mPayLoadBufLen & 0xFF; -dhdebug_dump(mBuf, mPayLoadBufLen + 4 + WEBSOCKET_MASK_SIZE); mask(); mSendFunc(mBuf, mPayLoadBufLen + 4 + WEBSOCKET_MASK_SIZE); } } +LOCAL void ICACHE_FLASH_ATTR check_queue() { + dhsender_current_success(); + SENDER_JSON_DATA *data = dhsender_next(); + if(data) { + dhdebug("Sender start with %d bytes", data->jsonlen); + // sizeof(data->json) always is equal or lower then PAYLOAD_BUF_SIZE + os_memcpy(mPayLoadBuf, data->json, data->jsonlen); + mPayLoadBufLen = data->jsonlen; + send_payload(); + } +} + void ICACHE_FLASH_ATTR dhconnector_websocket_start(dhconnector_websocket_send_proto send_func, dhconnector_websocket_error err_func) { mSendFunc = send_func; mErrFunc = err_func; + dhsender_set_cb(check_queue); + mPayLoadBufLen = dhconnector_websocket_api_start(mPayLoadBuf, PAYLOAD_BUF_SIZE); send_payload(); // TODO check with timeout that we have connected @@ -86,13 +113,13 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in if(data[0] != 0x81) { // always expect final text frame dhdebug("WebSocket error - wrong header 0x%X", data[0]); - mErrFunc(); + error(data, len); return; } if(data[1] & 0x80) { // always expect unmasked data dhdebug("WebSocket error - masked data from server"); - mErrFunc(); + error(data, len); return; } @@ -100,7 +127,7 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in unsigned int wslen = (data[1] & 0x7F); if(wslen == 127) { dhdebug("WebSocket error - cannot handle more then 65535 bytes"); - mErrFunc(); + error(data, len); return; } else if(wslen == 126) { wslen = data[2]; @@ -115,17 +142,17 @@ void ICACHE_FLASH_ATTR dhconnector_websocket_parse(const char *data, unsigned in if(wslen != len) { // it is final frame, we checked before, received and header lengths should be equal dhdebug("WebSocket error - length mismatch"); - mErrFunc(); + error(data, len); return; } // here we should have JSON in data and len variables - dhdebug("WS got response"); -dhdebug_dump(data, len); - + dhdebug("WS got %d bytes", len); mPayLoadBufLen = dhconnector_websocket_api_communicate(data, len, mPayLoadBuf, PAYLOAD_BUF_SIZE); - if(mPayLoadBufLen == DHCONNECT_WEBSOCKET_API_ERROR) - mErrFunc(); - else if(mPayLoadBufLen > 0) + if(mPayLoadBufLen > 0) send_payload(); + else if(mPayLoadBufLen == DHCONNECT_WEBSOCKET_API_ERROR) + error(data, len); + else // if we have data to send, we can do it + check_queue(); } diff --git a/firmware-src/sources/dhconnector_websocket.h b/firmware-src/sources/dhconnector_websocket.h index 7283278..1df1a8e 100644 --- a/firmware-src/sources/dhconnector_websocket.h +++ b/firmware-src/sources/dhconnector_websocket.h @@ -14,7 +14,18 @@ typedef void (*dhconnector_websocket_send_proto)(const char *data, unsigned int /** Function prototype for error callback. */ typedef void (*dhconnector_websocket_error)(); +/** + * \brief Initialize devicehive WebSocket protocol exchange + * \param[in] send_func Pointer to function to call to send data. + * \param[in] err_func Pointer to function to call on error. + */ void dhconnector_websocket_start(dhconnector_websocket_send_proto send_func, dhconnector_websocket_error err_func); + +/** + * \brief Parse received from server data. + * \param[in] data Pointer to data. + * \param[in] len Number of bytes in data. + */ void dhconnector_websocket_parse(const char *data, unsigned int len); #endif /* _DHCONNECTOR_WEBSOCKET_H_ */ diff --git a/firmware-src/sources/dhconnector_websocket_api.c b/firmware-src/sources/dhconnector_websocket_api.c index 7d1e203..3f8ebf1 100644 --- a/firmware-src/sources/dhconnector_websocket_api.c +++ b/firmware-src/sources/dhconnector_websocket_api.c @@ -24,7 +24,6 @@ #include "user_config.h" #include "dhcommands.h" #include "dhsender.h" -#include "dhsender_queue.h" int ICACHE_FLASH_ATTR dhconnector_websocket_api_start(char *buf, unsigned int maxlen) { RO_DATA char template[] = @@ -35,26 +34,16 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_start(char *buf, unsigned int ma return snprintf(buf, maxlen, template, dhsettings_get_devicehive_accesskey()); } -LOCAL int check_bad_status(int status, const char *in, unsigned int inlen) { - if(status) { - dhdebug("Action bad return status: "); - char b[inlen + 1]; - os_memcpy(b, in, inlen); - b[inlen] = 0; - dhdebug("%s", b); - } - return status; -} - int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsigned int inlen, char *out, unsigned int outmaxlen) { int type; int status_not_success = 1; char action[32]; char command[128]; const char *params; - unsigned int paramslen; - unsigned int id; + unsigned int paramslen = 0; + unsigned int id = 0; action[0] = 0; + command[0] = 0; struct jsonparse_state jparser; jsonparse_setup(&jparser, in, inlen); while (jparser.pos < jparser.len) { @@ -73,22 +62,23 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsi jsonparse_next(&jparser); if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) jsonparse_copy_value(&jparser, command, sizeof(command)); - } - } else if(jsonparse_strcmp_value(&jparser, "id") == 0) { - jsonparse_next(&jparser); - if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) - id = jsonparse_get_value_as_ulong(&jparser); - } else if(jsonparse_strcmp_value(&jparser, "parameters") == 0) { - jsonparse_next(&jparser); - if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) { - // there is an issue with extracting subjson with jparser->vstart or jparser_copy_value - params = &jparser.json[jparser.pos - 1]; - if(*params == '{') { - int end = jparser.pos; - while(end < jparser.len && jparser.json[end] != '}') { - end++; + } else if(jsonparse_strcmp_value(&jparser, "id") == 0) { + jsonparse_next(&jparser); + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) + id = jsonparse_get_value_as_ulong(&jparser); + } else if(jsonparse_strcmp_value(&jparser, "parameters") == 0) { + jsonparse_next(&jparser); + if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) { + // there is an issue with extracting subjson with jparser->vstart or jparser_copy_value + params = &jparser.json[jparser.pos - 1]; + if(*params == '{') { + int end = jparser.pos; + while(end < jparser.len && jparser.json[end] != '}') { + end++; + } + paramslen = end - jparser.pos + 2; + jparser.pos += paramslen; } - paramslen = end - jparser.pos + 2; } } } else if(type == JSON_TYPE_ERROR) { @@ -127,7 +117,8 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsi "}" "}"; char dk[9]; - if(check_bad_status(status_not_success, in, inlen)) { + if(status_not_success) { + dhdebug("Failed to authenticate"); return DHCONNECT_WEBSOCKET_API_ERROR; } snprintf(dk, sizeof(dk), "%s", dhsettings_get_devicehive_accesskey()); @@ -140,7 +131,8 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsi "\"action\":\"command/subscribe\"," "\"deviceGuids\":[\"%s\"]" "}"; - if(check_bad_status(status_not_success, in, inlen)) { + if(status_not_success) { + dhdebug("Failed to save device"); return DHCONNECT_WEBSOCKET_API_ERROR; } return snprintf(out, outmaxlen, template, diff --git a/firmware-src/sources/dhconnector_websocket_api.h b/firmware-src/sources/dhconnector_websocket_api.h index 7a920e2..27269ef 100644 --- a/firmware-src/sources/dhconnector_websocket_api.h +++ b/firmware-src/sources/dhconnector_websocket_api.h @@ -11,7 +11,21 @@ #define DHCONNECT_WEBSOCKET_API_ERROR -1 +/** + * \brief Initialize communication with DeviceHive server + * \param[out] data Pointer to store data which should be sent to server. + * \param[in] maxlen Maximum size of specified buffer in bytes. + * \return Number of copied bytes. + */ int dhconnector_websocket_api_start(char *buf, unsigned int maxlen); +/** + * \brief Exchange data with server. + * \param[in] in Data received from server. + * \param[in] inlen Number of bytes received from server. + * \param[in] out Pointer to store data which should be sent to server. + * \param[in] outmaxlen Maximum size of specified buffer in bytes. + * \return Number of copied bytes or DHCONNECT_WEBSOCKET_API_ERROR on error. + */ int dhconnector_websocket_api_communicate(const char *in, unsigned int inlen, char *out, unsigned int outmaxlen); #endif /* _DHCONNECTOR_WEBSOCKET_API_H_ */ diff --git a/firmware-src/sources/dhsender.c b/firmware-src/sources/dhsender.c index 9a83cdb..1246814 100644 --- a/firmware-src/sources/dhsender.c +++ b/firmware-src/sources/dhsender.c @@ -30,13 +30,13 @@ LOCAL SENDER_JSON_DATA mDataToSend; LOCAL unsigned int isCurrentNotification; LOCAL int mSenderTook = 0; +dhsender_new_item_cb mNewItemCb = NULL; -SENDER_JSON_DATA * ICACHE_FLASH_ATTR dhsender_next(void *arg) { +SENDER_JSON_DATA * ICACHE_FLASH_ATTR dhsender_next() { if(mSenderTook == 0) { if(dhsender_queue_take(&mDataToSend, &isCurrentNotification) == 0) return NULL; mSenderTook = DHSENDER_RETRY_COUNT; - dhdebug("Sender start"); } return &mDataToSend; } @@ -58,12 +58,17 @@ void ICACHE_FLASH_ATTR dhsender_current_success() { mSenderTook = 0; } +void dhsender_set_cb(dhsender_new_item_cb new_item) { + mNewItemCb = new_item; +} + void ICACHE_FLASH_ATTR dhsender_response(CommandResultArgument cid, RESPONCE_STATUS status, REQUEST_DATA_TYPE data_type, ...) { va_list ap; va_start(ap, data_type); dhstatistic_inc_responces_count(); if(dhsender_queue_add(status == DHSTATUS_ERROR ? RT_RESPONCE_ERROR : RT_RESPONCE_OK, RNT_NOTIFICATION_NONE, data_type, cid.id, ap)) { - dhsender_next(NULL); + if(mNewItemCb) + mNewItemCb(); } else { dhstatistic_inc_responces_dropped_count(); dhdebug("ERROR: No memory for response"); @@ -76,7 +81,8 @@ void ICACHE_FLASH_ATTR dhsender_notification(REQUEST_NOTIFICATION_TYPE type, REQ va_start(ap, data_type); dhstatistic_inc_notifications_count(); if(dhsender_queue_add(RT_NOTIFICATION, type, data_type, 0, ap)) { - dhsender_next(NULL); + if(mNewItemCb) + mNewItemCb(); } else { dhstatistic_inc_notifications_dropped_count(); dhdebug("ERROR: No memory for notification"); diff --git a/firmware-src/sources/dhsender.h b/firmware-src/sources/dhsender.h index 5531d35..acf912a 100644 --- a/firmware-src/sources/dhsender.h +++ b/firmware-src/sources/dhsender.h @@ -16,6 +16,9 @@ #include "dhsender_data.h" +/** Function prototype for new item in queue callback. */ +typedef void (*dhsender_new_item_cb)(); + /** * \brief Notify that current data was failed to send. */ @@ -32,6 +35,12 @@ void dhsender_current_success(); */ SENDER_JSON_DATA *dhsender_next(); +/** + * \brief Set callbacks. + * \param[in] new_item Pointer to a function which should be called on adding new item to queue. + */ +void dhsender_set_cb(dhsender_new_item_cb new_item); + /** * \brief Send command response. * \param[in] cid Command id that response should be sent. diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index cf8bb26..19d963c 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -97,9 +97,9 @@ int ICACHE_FLASH_ATTR dhsender_data_to_json(char *buf, unsigned int buf_len, unsigned int data_len, unsigned int pin) { switch(data_type) { case RDT_FORMAT_STRING: - return snprintf(buf, buf_len, "%s", data->array); + return snprintf(buf, buf_len, "\"%s\"", data->array); case RDT_CONST_STRING: - return snprintf(buf, buf_len, "%s", data->string); + return snprintf(buf, buf_len, "\"%s\"", data->string); case RDT_DATA_WITH_LEN: { const unsigned int pos = snprintf(buf, buf_len, "{\"data\":\""); diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index aadc427..f2d9740 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -12,6 +12,7 @@ #include #include "user_config.h" #include "dhsettings.h" +#include "dhutils.h" /** Data type that should be read from arguments and how it will be formatted in response or notification. */ typedef enum { @@ -77,10 +78,13 @@ typedef union { GPIO_DATA gpio; ///< GPIO data. } SENDERDATA; + +/** Maximum size for JSON */ +#define SENDER_JSON_MAX_LENGTH ROUND_KB(3 * INTERFACES_BUF_SIZE + DHSETTINGS_DEVICEID_MAX_LENGTH) /** Struct for passing JSON. */ -typedef union { - char json[((3 * INTERFACES_BUF_SIZE + DHSETTINGS_DEVICEID_MAX_LENGTH) / 1024 + 1) * 1024]; ///< JSON string - unsigned int jsonlen; ///< Length of JSON +typedef struct { + char json[SENDER_JSON_MAX_LENGTH]; ///< JSON string + unsigned int jsonlen; ///< Length of JSON } SENDER_JSON_DATA; /** diff --git a/firmware-src/sources/dhsender_queue.c b/firmware-src/sources/dhsender_queue.c index 3be4e0d..9f07b19 100644 --- a/firmware-src/sources/dhsender_queue.c +++ b/firmware-src/sources/dhsender_queue.c @@ -141,12 +141,15 @@ int ICACHE_FLASH_ATTR dhsender_queue_take(SENDER_JSON_DATA *out, unsigned int *i return 0; } - if(dhsender_data_to_json(&out->json[pos], sizeof(out->json) - pos, + + int rl = dhsender_data_to_json(&out->json[pos], sizeof(out->json) - pos, item.notification_type == RNT_NOTIFICATION_GPIO, item.data_type, - &item.data, item.data_len, item.pin) < 0) { + &item.data, item.data_len, item.pin); + if(rl < 0) { pos += snprintf(&out->json[pos], sizeof(out->json) - pos, "Failed to convert data to json"); item.type = RT_RESPONCE_ERROR; } + pos += rl; pos += snprintf(&out->json[pos], sizeof(out->json) - pos, "}}"); out->jsonlen = pos; diff --git a/firmware-src/sources/dhutils.h b/firmware-src/sources/dhutils.h index 22d9fcd..ad374c2 100644 --- a/firmware-src/sources/dhutils.h +++ b/firmware-src/sources/dhutils.h @@ -9,6 +9,12 @@ #ifndef _DHUTILS_H_ #define _DHUTILS_H_ +/** Find maximum value */ +#define MAX(x, y) (((x) < (y)) ? (x) : (y)) + +/** Round value to KiB */ +#define ROUND_KB(x) (((x) / 1024 + 1) * 1024) + /** * \brief Convert string to float. * \details Read string till first non digit character or null terminated char. From d8ad3aa8bfe666dd3b91de3619087bf0b3a3be42 Mon Sep 17 00:00:00 2001 From: Nikolay Khabarov <2xl@mail.ru> Date: Mon, 20 Mar 2017 18:16:07 +0300 Subject: [PATCH 08/83] style fix --- esp-utils/common/serialport_posix.cpp | 10 +-- esp-utils/common/serialport_win.cpp | 4 +- esp-utils/common/terminal_win.cpp | 2 +- esp-utils/esp-flasher.cpp | 46 +++++------ esp-utils/esp-terminal.cpp | 2 +- firmware-src/pages/base64.html | 4 +- firmware-src/sources/base64.c | 2 +- firmware-src/sources/devices/bmp280.c | 2 +- firmware-src/sources/devices/dht.c | 16 ++-- firmware-src/sources/devices/max6675.c | 4 +- firmware-src/sources/dhcommand_parser.c | 4 +- firmware-src/sources/dhcommands.c | 92 +++++++++++----------- firmware-src/sources/dhgpio.c | 2 +- firmware-src/sources/dhi2c.c | 2 +- firmware-src/sources/dhonewire.c | 4 +- firmware-src/sources/dhrequest.c | 16 ++-- firmware-src/sources/dhsettings.c | 4 +- firmware-src/sources/dhspi.c | 14 ++-- firmware-src/sources/dhterminal.c | 6 +- firmware-src/sources/dhterminal_commands.c | 10 +-- firmware-src/sources/dhuart.c | 2 +- firmware-src/sources/dhutils.c | 32 ++++---- firmware-src/sources/httpd.c | 4 +- firmware-src/sources/rand.c | 2 +- firmware-src/sources/snprintf.c | 4 +- firmware-src/sources/uploadable_api.c | 4 +- 26 files changed, 147 insertions(+), 147 deletions(-) diff --git a/esp-utils/common/serialport_posix.cpp b/esp-utils/common/serialport_posix.cpp index c323b5e..5f0915f 100644 --- a/esp-utils/common/serialport_posix.cpp +++ b/esp-utils/common/serialport_posix.cpp @@ -60,7 +60,7 @@ SerialPort *SerialPort::open(const char *port) { { struct termios tio; memset(&tio,0,sizeof(tio)); - if ( tcgetattr ( comp, &tio ) != 0 ) { + if( tcgetattr ( comp, &tio ) != 0 ) { close(comp); return 0; } @@ -77,7 +77,7 @@ SerialPort *SerialPort::open(const char *port) { tcflush(comp, TCIOFLUSH); - if ( tcsetattr ( comp, TCSANOW, &tio ) != 0) { + if( tcsetattr ( comp, TCSANOW, &tio ) != 0) { close(comp); return 0; } @@ -118,7 +118,7 @@ void SerialPort::sleep(unsigned int ms) { usleep(ms*1000); } -#if ( defined(__APPLE__) || defined(__MACH__) ) +#if( defined(__APPLE__) || defined(__MACH__) ) const static char TTYUSB_PATTERN[] = "tty."; #else const static char TTYUSB_PATTERN[] = "ttyUSB"; @@ -160,7 +160,7 @@ unsigned int SerialPort::getTick() { void SerialPort::setRts(bool val) { int flag; if(ioctl(mCom, TIOCMGET, &flag) != -1) { - if (val) + if(val) flag |= TIOCM_RTS; else flag &= ~TIOCM_RTS; @@ -171,7 +171,7 @@ void SerialPort::setRts(bool val) { void SerialPort::setDtr(bool val) { int flag; if(ioctl(mCom, TIOCMGET, &flag) != -1) { - if (val) + if(val) flag |= TIOCM_DTR; else flag &= ~TIOCM_DTR; diff --git a/esp-utils/common/serialport_win.cpp b/esp-utils/common/serialport_win.cpp index 0e166d6..b6f7c4d 100644 --- a/esp-utils/common/serialport_win.cpp +++ b/esp-utils/common/serialport_win.cpp @@ -59,7 +59,7 @@ SerialPort *SerialPort::open(const char *port) { char namebuff[MAX_PATH]; snprintf(namebuff, sizeof namebuff, "\\\\.\\%s", port); HANDLE hCOM=CreateFileA(namebuff,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); - if (hCOM!=INVALID_HANDLE_VALUE) + if(hCOM!=INVALID_HANDLE_VALUE) { DCB cdcb; if( GetCommState(hCOM,&cdcb)==0 ) { @@ -88,7 +88,7 @@ SerialPort *SerialPort::open(const char *port) { SerialPort *comport = new SerialPort(hCOM); DWORD dwThreadId; - if ( (comport->mThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, (LPVOID)comport, 0, &dwThreadId)) == NULL) + if( (comport->mThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, (LPVOID)comport, 0, &dwThreadId)) == NULL) { delete comport; return 0; diff --git a/esp-utils/common/terminal_win.cpp b/esp-utils/common/terminal_win.cpp index cc9e524..62815cd 100644 --- a/esp-utils/common/terminal_win.cpp +++ b/esp-utils/common/terminal_win.cpp @@ -70,7 +70,7 @@ void Terminal::put(char c) { } else if(escRecieving) { escSequence[escSequencePos++] = c; escSequence[escSequencePos] = 0; - if (escSequencePos == 1 && c == '[') + if(escSequencePos == 1 && c == '[') return; if((c >= 0x40 && c <= 0x7e) || escSequencePos >= sizeof(escSequence) - 1) { if(strcmp(escSequence, "[C") == 0) { // Right diff --git a/esp-utils/esp-flasher.cpp b/esp-utils/esp-flasher.cpp index 83c2d01..d759224 100644 --- a/esp-utils/esp-flasher.cpp +++ b/esp-utils/esp-flasher.cpp @@ -57,16 +57,16 @@ void SerialPortRecieved(SerialPort *port, const char *text, unsigned int len) { for (unsigned int i = 0; i < len; i++) { uint8_t c = text[i]; //printf("0x%02X \r\n", (uint32_t)c); - if (recivedPos >= sizeof(recivedBuf)) + if(recivedPos >= sizeof(recivedBuf)) break; - if (recivedEscape) { - if (c == 0xdc) { + if(recivedEscape) { + if(c == 0xdc) { recivedBuf[recivedPos++] = 0xc0; - } else if (c == 0xdd) { + } else if(c == 0xdd) { recivedBuf[recivedPos++] = 0xdb; } recivedEscape = false; - } else if (c == 0xdb) { + } else if(c == 0xdb) { recivedEscape = true; } else { recivedBuf[recivedPos++] = c; @@ -114,15 +114,15 @@ bool flash_send(SerialPort *port, ESP_REQUEST_HEADER *hdr, void *body, bool prin oBuf[oBufPos++] = 0xc0; for (unsigned int i = 0; i < sizeof(ESP_REQUEST_HEADER) + hdr->size; i++) { uint8_t c; - if (i >= sizeof(ESP_REQUEST_HEADER)) { + if(i >= sizeof(ESP_REQUEST_HEADER)) { c = ((uint8_t *) body)[i - sizeof(ESP_REQUEST_HEADER)]; } else { c = hdrp[i]; } - if (c == 0xdb) { + if(c == 0xdb) { oBuf[oBufPos++] = 0xdb; oBuf[oBufPos++] = 0xdd; - } else if (c == 0xc0) { + } else if(c == 0xc0) { oBuf[oBufPos++] = 0xdb; oBuf[oBufPos++] = 0xdc; } else { @@ -137,30 +137,30 @@ bool flash_send(SerialPort *port, ESP_REQUEST_HEADER *hdr, void *body, bool prin // printf("\r\n"); port->send(oBuf, oBufPos); - if (!port->waitAnswer(5, TIMEOUT)) { + if(!port->waitAnswer(5, TIMEOUT)) { if(printErrors) printf("\r\nNo answer from device\r\n"); return false; } - if (recivedBuf[0] != 0xc0 && recivedBuf[1] != 0x01 + if(recivedBuf[0] != 0xc0 && recivedBuf[1] != 0x01 && recivedBuf[1] != hdr->command) { if(printErrors) printf("\r\nWrong answer\r\n"); return false; } uint32_t asize = (uint32_t) recivedBuf[3] | (uint32_t) (recivedBuf[4] << 8); - if (!port->waitAnswer(asize + 10, TIMEOUT)) { + if(!port->waitAnswer(asize + 10, TIMEOUT)) { if(printErrors) printf("\r\nAnswer not completed\r\n"); return false; } port->waitTransmitionEnd(100); - if (asize != 2 || recivedBuf[asize + 9] != 0xc0) { + if(asize != 2 || recivedBuf[asize + 9] != 0xc0) { if(printErrors) printf("\r\nWrong body length\r\n"); return false; } - if (recivedBuf[asize + 7] != 0x0) { + if(recivedBuf[asize + 7] != 0x0) { if(printErrors) printf("\r\nOperation 0x%02X failed, code: 0x%02X\r\n", recivedBuf[2], recivedBuf[asize + 8]); @@ -176,7 +176,7 @@ bool flash_start(SerialPort *port, uint32_t blocks_count, uint32_t size, uint32_ // workaround for SPIEraseArea const uint32_t sectors_count = ceil((double) size / (double) ESP_SECTOR_SIZE); uint32_t fix = 16 - address / ESP_SECTOR_SIZE % 16; - if (sectors_count < fix) + if(sectors_count < fix) fix = sectors_count; pbody[0] = htole32(((sectors_count < 2 * fix) ? (sectors_count + 1) / 2 : (sectors_count - fix)) * ESP_SECTOR_SIZE); @@ -189,7 +189,7 @@ bool flash_start(SerialPort *port, uint32_t blocks_count, uint32_t size, uint32_ rh.size = htole16(sizeof(pbody)); rh.cs = esp_checksum(pbody, sizeof(pbody)); - if (!flash_send(port, &rh, &pbody, true)) + if(!flash_send(port, &rh, &pbody, true)) return false; return true; @@ -197,14 +197,14 @@ bool flash_start(SerialPort *port, uint32_t blocks_count, uint32_t size, uint32_ /* Data should be aligned per 4096 bytes */ bool flash_mem(SerialPort *port, uint8_t * buf, uint32_t size, uint32_t address) { - if (size % 4096 || address % 4096) { + if(size % 4096 || address % 4096) { printf("\r\nINTERNAL ERROR: data isn't align by 4096 bytes - %d\r\n", size); return false; } uint32_t blocks_count = ceil((double) size / (double) ESP_BLOCK_SIZE); ESP_REQUEST_HEADER rh; - if (!flash_start(port, blocks_count, size, address)) { + if(!flash_start(port, blocks_count, size, address)) { printf("\r\nFailed to enter flash mode\r\n"); return false; } @@ -219,7 +219,7 @@ bool flash_mem(SerialPort *port, uint8_t * buf, uint32_t size, uint32_t address) data32[2] = 0; data32[3] = 0; uint32_t bl = size - seq * ESP_BLOCK_SIZE; - if (bl < ESP_BLOCK_SIZE) { + if(bl < ESP_BLOCK_SIZE) { memcpy(data, &buf[seq * ESP_BLOCK_SIZE], bl); memset(&data[bl], 0xff, ESP_BLOCK_SIZE - bl); } else { @@ -229,7 +229,7 @@ bool flash_mem(SerialPort *port, uint8_t * buf, uint32_t size, uint32_t address) rh.command = 0x03; // flash data rh.size = htole16(sizeof(buffer)); rh.cs = esp_checksum(data, ESP_BLOCK_SIZE); - if (!flash_send(port, &rh, buffer, true)) { + if(!flash_send(port, &rh, buffer, true)) { printf("\r\nFailed to flash\r\n"); return false; } @@ -241,7 +241,7 @@ bool flash_mem(SerialPort *port, uint8_t * buf, uint32_t size, uint32_t address) bool flash_file(SerialPort *port, char *file, uint32_t address, char *incremental) { const uint32_t FLASH_ALIGN = 4096; FILE* fd = fopen(file, "rb"); - if (!fd) { + if(!fd) { printf("\r\nFailed to open file %s\r\n", file); return false; } @@ -257,7 +257,7 @@ bool flash_file(SerialPort *port, char *file, uint32_t address, char *incrementa unsigned int rb = fread(data, 1, size, fd); fclose (fd); - if (rb != size) { + if(rb != size) { delete [] data; printf("\r\nFailed to read image file\r\n"); return false; @@ -348,7 +348,7 @@ bool flash_done(SerialPort *port) { rh.command = 0x04; // flash done rh.size = htole16(sizeof(reboot)); rh.cs = esp_checksum(&reboot, sizeof(reboot)); - if (!flash_send(port, &rh, &reboot, true)) { + if(!flash_send(port, &rh, &reboot, true)) { printf("\r\nFailed to finish flash\r\n"); return false; } @@ -366,7 +366,7 @@ bool flash_sync(SerialPort *port, bool printErrors) { rh.command = 0x08; // sync rh.size = htole16(sizeof(body)); rh.cs = esp_checksum((void*)body, sizeof(body)); - if (!flash_send(port, &rh, (void*)body, printErrors)) { + if(!flash_send(port, &rh, (void*)body, printErrors)) { if(printErrors) printf("\r\nFailed to sync device\r\n"); return false; diff --git a/esp-utils/esp-terminal.cpp b/esp-utils/esp-terminal.cpp index 23ff26f..ee8dd4d 100644 --- a/esp-utils/esp-terminal.cpp +++ b/esp-utils/esp-terminal.cpp @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) { break; char c[5]; term->get(c); - if (c[0] == 0x11) { + if(c[0] == 0x11) { printf("\r\n"); break; } diff --git a/firmware-src/pages/base64.html b/firmware-src/pages/base64.html index 46850c8..b863945 100644 --- a/firmware-src/pages/base64.html +++ b/firmware-src/pages/base64.html @@ -13,7 +13,7 @@ var res = ""; for (var i = 0; i < data.length; i++) { h = data.charCodeAt(i).toString(16); - if (h.length == 1) + if(h.length == 1) res += "0" + h; else res += h; @@ -23,7 +23,7 @@ function fromhex() { hex = document.form.hex.value.replace(/0x/g, "").replace(/ /g, "").replace(/,/g, ""); - if (hex.length % 2 > 0) { + if(hex.length % 2 > 0) { document.form.string.value = ""; document.form.base64.value = ""; printLength(null); diff --git a/firmware-src/sources/base64.c b/firmware-src/sources/base64.c index aa72728..514b171 100644 --- a/firmware-src/sources/base64.c +++ b/firmware-src/sources/base64.c @@ -20,7 +20,7 @@ LOCAL signed char ICACHE_FLASH_ATTR reverse_base64_table(char c) { if(c > 'z') return -1; return c - 'a' + 26; - } else if (c >= 'A') { + } else if(c >= 'A') { if(c > 'Z') return -1; return c - 'A'; diff --git a/firmware-src/sources/devices/bmp280.c b/firmware-src/sources/devices/bmp280.c index e09f5a1..5d4b438 100644 --- a/firmware-src/sources/devices/bmp280.c +++ b/firmware-src/sources/devices/bmp280.c @@ -102,7 +102,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, fl v2 = v2 / 4.0 + P4 * 65536.0; v1 = (P3 * v1 * v1 / 524288.0 + P2 * v1) / 524288.0; v1 = (1.0 + v1 / 32768.0) * P1; - if (v1 == 0.0) { + if(v1 == 0.0) { return DHI2C_DEVICE_ERROR; } double p = 1048576.0 - raw_pressure; diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 7dfe325..41d0209 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -16,16 +16,16 @@ #define DHT_PACKET_SIZE 5 LOCAL char * ICACHE_FLASH_ATTR dht_read(int pin, char *buf) { - if (pin != DHT_NO_PIN) { - if (!dhonewire_set_pin(pin)) { + if(pin != DHT_NO_PIN) { + if(!dhonewire_set_pin(pin)) { return "Failed to set up onewire pin"; } } - if (dhonewire_dht_read(buf, DHT_PACKET_SIZE) != DHT_PACKET_SIZE ) { + if(dhonewire_dht_read(buf, DHT_PACKET_SIZE) != DHT_PACKET_SIZE ) { return "Failed to read data"; } char cs = ((int)buf[0] + (int)buf[1] + (int)buf[2] + (int)buf[3]) & 0xFF; - if (cs != buf[4]) { + if(cs != buf[4]) { return "Bad checksum"; } return 0; @@ -34,10 +34,10 @@ LOCAL char * ICACHE_FLASH_ATTR dht_read(int pin, char *buf) { char * ICACHE_FLASH_ATTR dht11_read(int pin, int *humidity, int *temperature) { unsigned char buf[DHT_PACKET_SIZE]; char *r = dht_read(pin, buf); - if (r) + if(r) return r; *humidity = buf[0]; - if (temperature) + if(temperature) *temperature = buf[2]; return NULL; } @@ -45,11 +45,11 @@ char * ICACHE_FLASH_ATTR dht11_read(int pin, int *humidity, int *temperature) { char * ICACHE_FLASH_ATTR dht22_read(int pin, float *humidity, float *temperature) { unsigned char buf[DHT_PACKET_SIZE]; char *r = dht_read(pin, buf); - if (r) + if(r) return r; *humidity = signedInt16be_sm(buf, 0) / 10.0f; - if (temperature) + if(temperature) *temperature = signedInt16be_sm(buf, 2) / 10.0f; return NULL; } diff --git a/firmware-src/sources/devices/max6675.c b/firmware-src/sources/devices/max6675.c index be2cee6..a178d44 100644 --- a/firmware-src/sources/devices/max6675.c +++ b/firmware-src/sources/devices/max6675.c @@ -36,9 +36,9 @@ char * ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) { dhspi_read((char *)&buf, sizeof(buf)); - if ((buf[0] & 0x80) || (buf[1] & 0x02)) + if((buf[0] & 0x80) || (buf[1] & 0x02)) return "Protocol error"; - if (buf[1] & 0x04) + if(buf[1] & 0x04) return "Thermocouple is not connected"; buf[1] &= 0xF8; diff --git a/firmware-src/sources/dhcommand_parser.c b/firmware-src/sources/dhcommand_parser.c index a74eb72..fad60e2 100644 --- a/firmware-src/sources/dhcommand_parser.c +++ b/firmware-src/sources/dhcommand_parser.c @@ -96,7 +96,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int load_defaults(out, timeout); while (jparser.pos < jparser.len) { type = jsonparse_next(&jparser); - if (type == JSON_TYPE_PAIR_NAME) { + if(type == JSON_TYPE_PAIR_NAME) { if(strcmp_value(&jparser, "mode") == 0) { if((fields & AF_UARTMODE) == 0 && (fields & AF_SPIMODE) == 0) return UNEXPECTED; @@ -233,7 +233,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int return UNEXPECTED; jsonparse_next(&jparser); if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) { - if (jparser.vlen > sizeof(out->data) - 1) + if(jparser.vlen > sizeof(out->data) - 1) return "Text is too long"; os_memcpy(out->data, &jparser.json[jparser.vstart], jparser.vlen); out->data[jparser.vlen] = 0; diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 1ae0f81..ba06528 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -143,9 +143,9 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co dhdebug("Got command: %s %d", command, cb->data.id); if( os_strcmp(command, "gpio/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, 0, AF_SET | AF_CLEAR, &fields); - if (parse_res) + if(parse_res) responce_error(cb, parse_res); - else if ( (fields & (AF_SET | AF_CLEAR)) == 0) + else if( (fields & (AF_SET | AF_CLEAR)) == 0) responce_error(cb, "Dummy request"); else if(dhgpio_write(parse_pins.pins_to_set, parse_pins.pins_to_clear)) responce_ok(cb); @@ -155,7 +155,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co int init = 1; if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, 0, AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); - if (parse_res) { + if(parse_res) { responce_error(cb, parse_res); init = 0; return; @@ -163,16 +163,16 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co init = dhgpio_initialize(parse_pins.pins_to_init, parse_pins.pins_to_pullup, parse_pins.pins_to_nopull); } } - if (init) { + if(init) { cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, dhgpio_read(), system_get_time(), DHGPIO_SUITABLE_PINS); } else { responce_error(cb, "Wrong initialization parameters"); } } else if( os_strcmp(command, "gpio/int") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); - if (parse_res) + if(parse_res) responce_error(cb, parse_res); - else if (fields == 0) + else if(fields == 0) responce_error(cb, "Wrong action"); else if(parse_pins.timeout < GPIONOTIFICATION_MIN_TIMEOUT_MS || parse_pins.timeout > 0x7fffff) responce_error(cb, "Timeout is wrong"); @@ -184,10 +184,10 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "adc/read") == 0) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_READ, &fields); - if (parse_res) { + if(parse_res) { responce_error(cb, parse_res); return; - } else if (parse_pins.pins_to_read != DHADC_SUITABLE_PINS) { + } else if(parse_pins.pins_to_read != DHADC_SUITABLE_PINS) { responce_error(cb, "Unknown ADC channel"); return; } @@ -196,12 +196,12 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "adc/int") == 0) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_VALUES, &fields); - if (responce_error(cb, parse_res)) { + if(responce_error(cb, parse_res)) { return; } else if(parse_pins.pin_value_readed != 0x1) { responce_error(cb, "Wrong adc channel"); return; - } else if ((parse_pins.storage.uint_values[0] < ADCNOTIFICATION_MIN_TIMEOUT_MS && parse_pins.storage.uint_values[0] != 0) || parse_pins.storage.uint_values[0] > 0x7fffff) { + } else if((parse_pins.storage.uint_values[0] < ADCNOTIFICATION_MIN_TIMEOUT_MS && parse_pins.storage.uint_values[0] != 0) || parse_pins.storage.uint_values[0] > 0x7fffff) { responce_error(cb, "Wrong period"); return; } else { @@ -213,7 +213,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_error(cb, "Wrong parameters"); } else if( os_strcmp(command, "pwm/control") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_VALUES | AF_PERIOD | AF_COUNT, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(dhpwm_set_pwm(&parse_pins.storage.uint_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : dhpwm_get_period_us(), parse_pins.count)) responce_ok(cb); @@ -285,7 +285,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_ok(cb); } else if( os_strcmp(command, "i2c/master/read") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if((fields & AF_COUNT) == 0) parse_pins.count = 2; @@ -304,14 +304,14 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } } res = i2c_status_tochar(dhi2c_read(parse_pins.address, parse_pins.data, parse_pins.count)); - if (res) { + if(res) { responce_error(cb, res); return; } cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); } else if( os_strcmp(command, "i2c/master/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if((fields & AF_DATA) == 0) { responce_error(cb, "Data not specified"); @@ -324,7 +324,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_ok(cb); } else if( os_strcmp(command, "spi/master/read") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if((fields & AF_COUNT) == 0) parse_pins.count = 2; @@ -340,7 +340,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); } else if( os_strcmp(command, "spi/master/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(spi_init(cb, fields, &parse_pins)) return; @@ -352,7 +352,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_ok(cb); } else if( os_strcmp(command, "onewire/master/read") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA | AF_COUNT, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if((fields & AF_COUNT) == 0 || parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { responce_error(cb, "Wrong read size"); @@ -372,7 +372,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); } else if( os_strcmp(command, "onewire/master/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(onewire_init(cb, fields, &parse_pins)) return; @@ -384,7 +384,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( (check = os_strcmp(command, "onewire/master/search")) == 0 || os_strcmp(command, "onewire/master/alarm") == 0) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(onewire_init(cb, fields, &parse_pins)) return; @@ -396,9 +396,9 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_error(cb, "Error during search"); } else if( os_strcmp(command, "onewire/master/int") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); - if (parse_res) + if(parse_res) responce_error(cb, parse_res); - else if (fields == 0) + else if(fields == 0) responce_error(cb, "Wrong action"); else if(dhonewire_int(parse_pins.pins_to_presence, parse_pins.pins_to_disable)) responce_ok(cb); @@ -407,7 +407,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "onewire/dht/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(onewire_init(cb, fields, &parse_pins)) return; @@ -475,7 +475,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/bmp180/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) bmp180_set_address(parse_pins.address); @@ -492,7 +492,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/bmp280/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) bmp280_set_address(parse_pins.address); @@ -509,7 +509,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/bh1750/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) bh1750_set_address(parse_pins.address); @@ -525,7 +525,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/mpu6050/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) mpu6050_set_address(parse_pins.address); @@ -545,7 +545,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/hmc5883l/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) hmc5883l_set_address(parse_pins.address); @@ -572,7 +572,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/pcf8574/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_PULLUP, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) pcf8574_set_address(parse_pins.address); @@ -592,12 +592,12 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, pins, system_get_time(), PCF8574_SUITABLE_PINS); } else if( os_strcmp(command, "devices/pcf8574/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_SET | AF_CLEAR, &fields); - if (responce_error(cb, parse_res)) { + if(responce_error(cb, parse_res)) { return; - } else if ( (fields & (AF_SET | AF_CLEAR)) == 0) { + } else if( (fields & (AF_SET | AF_CLEAR)) == 0) { responce_error(cb, "Dummy request"); return; - } else if ( (parse_pins.pins_to_set | parse_pins.pins_to_clear | PCF8574_SUITABLE_PINS) + } else if( (parse_pins.pins_to_set | parse_pins.pins_to_clear | PCF8574_SUITABLE_PINS) != PCF8574_SUITABLE_PINS ) { responce_error(cb, "Unsuitable pin"); return; @@ -614,7 +614,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_ok(cb); } else if( os_strcmp(command, "devices/pcf8574/hd44780/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_DATA | AF_TEXT_DATA, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { responce_error(cb, "Text not specified"); @@ -643,7 +643,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/lm75/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) lm75_set_address(parse_pins.address); @@ -659,7 +659,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/si7021/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) si7021_set_address(parse_pins.address); @@ -676,7 +676,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/ads1115/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) ads1115_set_address(parse_pins.address); @@ -693,7 +693,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/pcf8591/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) pcf8591_set_address(parse_pins.address); @@ -714,7 +714,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co values[0], values[1], values[2], values[3]); } else if( os_strcmp(command, "devices/pcf8591/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(parse_pins.pin_value_readed != 1) { responce_error(cb, "Unsuitable pin"); @@ -736,7 +736,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_ok(cb); } else if( os_strcmp(command, "devices/mcp4725/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(parse_pins.pin_value_readed != 1) { responce_error(cb, "Unsuitable pin"); @@ -759,7 +759,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/ina219/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) ina219_set_address(parse_pins.address); @@ -784,7 +784,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/mfrc522/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_CS) { if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { @@ -819,7 +819,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( (check = os_strcmp(command, "devices/mfrc522/mifare/read")) == 0 || os_strcmp(command, "devices/mfrc522/mifare/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_ADDRESS | AF_KEY | (check ? AF_DATA : 0), &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_CS) { if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { @@ -885,7 +885,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co responce_error(cb, MFRC522_GetStatusCodeName(result)); } else if( os_strcmp(command, "devices/pca9685/control") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCA9685_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_FLOATVALUES | AF_PERIOD, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) pca9685_set_address(parse_pins.address); @@ -901,7 +901,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if( os_strcmp(command, "devices/mlx90614/read") == 0 ) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) mlx90614_set_address(parse_pins.address); @@ -918,7 +918,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if(os_strcmp(command, "devices/max6675/read") == 0) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; } float temperature; @@ -929,7 +929,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } else if(os_strcmp(command, "devices/max31855/read") == 0) { if(paramslen) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; } float temperature; @@ -939,7 +939,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); } else if( os_strcmp(command, "devices/tm1637/write") == 0 ) { parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); - if (responce_error(cb, parse_res)) + if(responce_error(cb, parse_res)) return; if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { responce_error(cb, "Text not specified"); diff --git a/firmware-src/sources/dhgpio.c b/firmware-src/sources/dhgpio.c index 62f7c56..4ad1f8b 100644 --- a/firmware-src/sources/dhgpio.c +++ b/firmware-src/sources/dhgpio.c @@ -78,7 +78,7 @@ void ICACHE_FLASH_ATTR dhgpio_open_drain(unsigned int pin_mask_set_od, unsigned if(pin & pin_mask_set_od) { const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE); GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(i)), reg); - } else if (pin & pin_mask_unset_od) { + } else if(pin & pin_mask_unset_od) { const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE); GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(i)), reg); } diff --git a/firmware-src/sources/dhi2c.c b/firmware-src/sources/dhi2c.c index bc8f9a7..3679eb0 100644 --- a/firmware-src/sources/dhi2c.c +++ b/firmware-src/sources/dhi2c.c @@ -118,7 +118,7 @@ LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_writebyte(unsigned char byte) { res = dhi2c_set_pin(mSCLPin, 0); if(res != DHI2C_OK) return res; - if (ackbit) + if(ackbit) return DHI2C_NOACK; return DHI2C_OK; } diff --git a/firmware-src/sources/dhonewire.c b/firmware-src/sources/dhonewire.c index f0c3b1d..37035e7 100644 --- a/firmware-src/sources/dhonewire.c +++ b/firmware-src/sources/dhonewire.c @@ -77,7 +77,7 @@ LOCAL int ICACHE_FLASH_ATTR dhonewire_reset(unsigned int pin, unsigned int reset if((gpio_input_get() & pin) == 0) presence = 1; } - } else if (exit_on_presence) { + } else if(exit_on_presence) { if(presence) { if(gpio_input_get() & pin) return 1; @@ -149,7 +149,7 @@ LOCAL unsigned int ICACHE_FLASH_ATTR dhonewire_check_crc(char *data) { for (i = 0; i < 8; i++) { char b = data[i]; for (j = 0; j < 8; j++) { - if ((seed ^ b) & 0x01) + if((seed ^ b) & 0x01) seed = (seed >> 1) ^ 0x8C; else seed >>= 1; diff --git a/firmware-src/sources/dhrequest.c b/firmware-src/sources/dhrequest.c index dac5124..02dcacf 100644 --- a/firmware-src/sources/dhrequest.c +++ b/firmware-src/sources/dhrequest.c @@ -40,13 +40,13 @@ const char * ICACHE_FLASH_ATTR dhrequest_parse_url(const char *url, char *host, const char *fr = url; while (*fr != ':') { fr++; - if (*fr == 0) { + if(*fr == 0) { return NULL; } } for(i = 0; i < 2; i++) { fr++; - if (*fr != '/') + if(*fr != '/') return NULL; } fr++; @@ -57,19 +57,19 @@ const char * ICACHE_FLASH_ATTR dhrequest_parse_url(const char *url, char *host, // read port if present int p = 0; - if (*fr == ':') { + if(*fr == ':') { unsigned char d; fr++; while ((d = *fr - 0x30) < 10) { fr++; p = p * 10 + d; - if (p > 0xFFFF) + if(p > 0xFFFF) break; } } - if (p && p < 0xFFFF) + if(p && p < 0xFFFF) *port = p; - else if (os_strncmp(url, "https", 5) == 0 || os_strncmp(url, "wss", 3) == 0) + else if(os_strncmp(url, "https", 5) == 0 || os_strncmp(url, "wss", 3) == 0) *port = 443; // HTTPS default port else *port = 80; //HTTP default port @@ -84,7 +84,7 @@ HTTP_REQUEST * ICACHE_FLASH_ATTR dhrequest_create_info(const char *api) { char host[DHREQUEST_HOST_MAX_BUF_LEN]; int port; const char *path = dhrequest_parse_url(api, host, &port); - if (path == NULL) + if(path == NULL) return NULL; buf->len = snprintf(buf->data, sizeof(sbuf) - sizeof(unsigned int), HTTP_INFO_REQUEST_PATTERN, path, host); dhdebug("Info request created, %d/%d", buf->len + 1, sizeof(sbuf) - sizeof(unsigned int)); @@ -97,7 +97,7 @@ HTTP_REQUEST * ICACHE_FLASH_ATTR dhrequest_create_wsrequest(const char *api, con char host[DHREQUEST_HOST_MAX_BUF_LEN]; int port; const char *path = dhrequest_parse_url(url, host, &port); - if (path == NULL) + if(path == NULL) return NULL; buf->len = snprintf(buf->data, sizeof(sbuf) - sizeof(unsigned int), HTTP_WS_REQUEST_PATTERN, path, host, api); dhdebug("WS request created, %d/%d", buf->len + 1, sizeof(sbuf) - sizeof(unsigned int)); diff --git a/firmware-src/sources/dhsettings.c b/firmware-src/sources/dhsettings.c index 97328e6..7d50b7a 100644 --- a/firmware-src/sources/dhsettings.c +++ b/firmware-src/sources/dhsettings.c @@ -55,7 +55,7 @@ int ICACHE_FLASH_ATTR dhsettings_init(int *exist) { SpiFlashOpResult res; res = spi_flash_read(ESP_SETTINGS_MAIN_SEC * SPI_FLASH_SEC_SIZE, (uint32 *)settings, sizeof(DH_SETTINGS)); int read = 1; - if (res != SPI_FLASH_RESULT_OK) { + if(res != SPI_FLASH_RESULT_OK) { dhdebug("Could not read settings from main storage %d, recover from backup", res); read = 0; } else if(getStorageCrc(settings) != settings->crc) { @@ -64,7 +64,7 @@ int ICACHE_FLASH_ATTR dhsettings_init(int *exist) { } if(read == 0) { res = spi_flash_read(ESP_SETTINGS_BACKUP_SEC * SPI_FLASH_SEC_SIZE, (uint32 *)settings, sizeof(DH_SETTINGS)); - if (res != SPI_FLASH_RESULT_OK) { + if(res != SPI_FLASH_RESULT_OK) { dhdebug("Could not read settings from backup storage %d", res); } else if(getStorageCrc(settings) != settings->crc) { dhdebug("Backup storage data corrupted or never saved, using empty settings"); diff --git a/firmware-src/sources/dhspi.c b/firmware-src/sources/dhspi.c index 5f1532b..5793eee 100644 --- a/firmware-src/sources/dhspi.c +++ b/firmware-src/sources/dhspi.c @@ -50,14 +50,14 @@ LOCAL unsigned int mSPICSPin = DHSPI_NOCS; LOCAL unsigned char mSPIMode = 0; LOCAL void ICACHE_FLASH_ATTR dhspi_cs_enable() { - if (mSPICSPin == DHSPI_NOCS) + if(mSPICSPin == DHSPI_NOCS) return; dhgpio_write(0, (1 << mSPICSPin)); os_delay_us(DHSPI_CS_DELAY_US); } LOCAL void ICACHE_FLASH_ATTR dhspi_cs_disable() { - if (mSPICSPin == DHSPI_NOCS) + if(mSPICSPin == DHSPI_NOCS) return; dhgpio_write((1 << mSPICSPin), 0); os_delay_us(DHSPI_CS_DELAY_US); @@ -77,14 +77,14 @@ LOCAL void ICACHE_FLASH_ATTR dhspi_reinit() { WRITE_PERI_REG( SPI_CLOCK, // 1 MHz ((15 & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) | ((4 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) | ((1 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) | ((3 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); - if (mSPIMode & 0x1) { // CPHA + if(mSPIMode & 0x1) { // CPHA SET_PERI_REG_MASK(SPI_USER, SPI_CK_OUT_EDGE); CLEAR_PERI_REG_MASK(SPI_USER, SPI_CK_I_EDGE); } else { SET_PERI_REG_MASK(SPI_USER, SPI_CK_I_EDGE); CLEAR_PERI_REG_MASK(SPI_USER, SPI_CK_OUT_EDGE); } - if (mSPIMode & 0x2) { // CPOL + if(mSPIMode & 0x2) { // CPOL SET_PERI_REG_MASK(SPI_CTRL2, SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_HIGH_MODE_S); CLEAR_PERI_REG_MASK(SPI_CTRL2, @@ -103,14 +103,14 @@ LOCAL void ICACHE_FLASH_ATTR dhspi_reinit() { } int ICACHE_FLASH_ATTR dhspi_set_mode(unsigned int mode) { - if (mode > 3) + if(mode > 3) return 0; mSPIMode = mode; return 1; } int ICACHE_FLASH_ATTR dhspi_set_cs_pin(unsigned int cs_pin) { - if (cs_pin != DHSPI_NOCS + if(cs_pin != DHSPI_NOCS && (cs_pin == 12 || cs_pin == 13 || cs_pin == 14 || cs_pin > DHGPIO_MAXGPIONUM || ((1 << cs_pin) & DHGPIO_SUITABLE_PINS) == 0)) @@ -132,7 +132,7 @@ void ICACHE_FLASH_ATTR dhspi_write(const char *buf, unsigned int len, SET_PERI_REG_MASK(SPI_BASE, SPI_USR); } - if (disable_cs) + if(disable_cs) dhspi_cs_disable(); } diff --git a/firmware-src/sources/dhterminal.c b/firmware-src/sources/dhterminal.c index e081709..c7c6f80 100644 --- a/firmware-src/sources/dhterminal.c +++ b/firmware-src/sources/dhterminal.c @@ -45,7 +45,7 @@ LOCAL os_timer_t mUsageTimer; LOCAL int isInUse = 0; LOCAL void ICACHE_FLASH_ATTR printWelcome() { - if (mMode == SM_NORMAL_MODE) { + if(mMode == SM_NORMAL_MODE) { dhuart_send_str("$ "); } else if(mMode == SM_INPUT_MODE || mMode == SM_HIDDEN_INPUT_MODE) { dhuart_send_str("> "); @@ -160,7 +160,7 @@ LOCAL void ICACHE_FLASH_ATTR dhterminal_reset() { mDebugBuff[0] = 0; mDebugBuffPos = 0; } - if (mMode == SM_AWATING_MODE) + if(mMode == SM_AWATING_MODE) os_timer_disarm(&mAwatingTimer); dhterminal_set_mode(SM_NORMAL_MODE, 0, 0, 0, 0); mHistoryScrollBufPos = mHistoryBuffPos; @@ -189,7 +189,7 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { int i; if(mMode == SM_DEBUG_MODE || mMode == SM_OUTPUT_MODE || mMode == SM_AWATING_MODE) { if(c == 'Q' || c == 'q' || c == 0x3 /*Ctrl+C*/) { - if (c == 0x3) + if(c == 0x3) dhuart_send_str("^C\r\n"); dhterminal_reset(); } else if(c == '\n' && mMode == SM_DEBUG_MODE) { diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index 3cfd5b8..1f750c0 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -43,9 +43,9 @@ LOCAL void ICACHE_FLASH_ATTR printBytes(char *buff, unsigned long long bytes) { snprintf(buff, 16, "%f TiB", bytes/1099511627776.0); else if(bytes > 1073741824) snprintf(buff, 16, "%f GiB", bytes/1073741824.0); - else if (bytes > 1048576) + else if(bytes > 1048576) snprintf(buff, 16, "%f MiB", bytes/1048576.0); - else if (bytes > 1024) + else if(bytes > 1024) snprintf(buff, 16, "%f KiB", bytes/1024.0); else snprintf(buff, 16, "%u B", (unsigned long)bytes); @@ -338,7 +338,7 @@ void ICACHE_FLASH_ATTR dhterminal_commands_echo(const char *args) { LOCAL void ICACHE_FLASH_ATTR nslookup_res(const char *name, ip_addr_t *ip, void *arg) { char ipstr[16]; - if (ip == NULL) { + if(ip == NULL) { dhuart_send_line("FAILED"); } else { sprintIp(ipstr, ip); @@ -436,7 +436,7 @@ LOCAL void ICACHE_FLASH_ATTR ping_done_cb(void* arg, void *pdata) { LOCAL void ICACHE_FLASH_ATTR ping_res_cb(const char *name, ip_addr_t *ip, void *arg) { nslookup_res(name, ip, arg); - if (ip) { + if(ip) { mCurrentPinopt.ip = ip->addr; mCurrentPinopt.count = 4; mCurrentPinopt.coarse_time = 1; @@ -453,7 +453,7 @@ LOCAL void ICACHE_FLASH_ATTR ping_res_cb(const char *name, ip_addr_t *ip, void * LOCAL void ICACHE_FLASH_ATTR ping_nslookup_cb(const char *name, ip_addr_t *ip, void *arg) { if(dhterminal_get_mode() == SM_OUTPUT_MODE) { ping_res_cb(name, ip, arg); - if (ip == 0) { + if(ip == 0) { mIsCommandWorking = 0; dhterminal_set_mode(SM_NORMAL_MODE, 0, 0, 0, 0); } diff --git a/firmware-src/sources/dhuart.c b/firmware-src/sources/dhuart.c index 6fcf897..d43c4ab 100644 --- a/firmware-src/sources/dhuart.c +++ b/firmware-src/sources/dhuart.c @@ -63,7 +63,7 @@ LOCAL ICACHE_FLASH_ATTR void arm_buf_timer() { } LOCAL void dhuart_intr_handler(void *arg) { - if (READ_PERI_REG(UART_INTERUPTION_STATE_REGISTER) & BIT(0)) { + if(READ_PERI_REG(UART_INTERUPTION_STATE_REGISTER) & BIT(0)) { const char rcvChar = READ_PERI_REG(UART_BASE) & 0xFF; WRITE_PERI_REG(UART_INTERUPTION_REGISTER, BIT(0)); switch(mDataMode) { diff --git a/firmware-src/sources/dhutils.c b/firmware-src/sources/dhutils.c index a5518a9..25cbe4f 100644 --- a/firmware-src/sources/dhutils.c +++ b/firmware-src/sources/dhutils.c @@ -20,15 +20,15 @@ int ICACHE_FLASH_ATTR strToFloat(const char *ptr, float *result) { char found = 0; int pos = 0; while (1) { - if (ptr[pos] == '+') { + if(ptr[pos] == '+') { sign = 1.0f; - } else if (ptr[pos] == '-') { + } else if(ptr[pos] == '-') { sign = -1.0f; - } else if (ptr[pos] == '.' || ptr[pos] == ',') { + } else if(ptr[pos] == '.' || ptr[pos] == ',') { fract = 0.1f; - } else if (ptr[pos] >= '0' && ptr[pos] <= '9') { + } else if(ptr[pos] >= '0' && ptr[pos] <= '9') { const unsigned char v = ptr[pos] - 0x30; - if (fract == 1.0L) { + if(fract == 1.0L) { res *= 10.0f; res += v; } else { @@ -37,7 +37,7 @@ int ICACHE_FLASH_ATTR strToFloat(const char *ptr, float *result) { } found = 1; } else { - if (found) { + if(found) { *result = res * sign; return pos; } @@ -95,16 +95,16 @@ int ICACHE_FLASH_ATTR byteToHex(unsigned char byte, char *hexout) { } LOCAL int ICACHE_FLASH_ATTR hexchar(const char c) { - if (c > 0x60) { + if(c > 0x60) { if(c > 0x66) return -1; return c - 0x57; - } else if (c > 0x40) { - if (c > 0x46) + } else if(c > 0x40) { + if(c > 0x46) return -1; return c - 0x37; - } else if (c > 0x2F) { - if (c > 0x39) + } else if(c > 0x2F) { + if(c > 0x39) return -1; return c - 0x30; } else @@ -128,9 +128,9 @@ int ICACHE_FLASH_ATTR hexToByte(const char *hex, unsigned char *byteout) { const char *ICACHE_FLASH_ATTR find_http_responce_code(const char *data, unsigned short len) { unsigned short pos = sizeof(uint32); - if (len > sizeof(uint32) && *(uint32 *) data == 0x50545448) { // HTTP + if(len > sizeof(uint32) && *(uint32 *) data == 0x50545448) { // HTTP while (pos < len) - if (data[pos++] == ' ') + if(data[pos++] == ' ') break; return &data[pos]; } @@ -143,14 +143,14 @@ unsigned int ICACHE_FLASH_ATTR unsignedInt16be(const char *buf, int pos) { int ICACHE_FLASH_ATTR signedInt16be(const char *buf, int pos) { int r = unsignedInt16be(buf, pos); - if (r <= 0x7FFF) + if(r <= 0x7FFF) return r; return r - 0x10000; } int ICACHE_FLASH_ATTR signedInt16be_sm(const char *buf, int pos) { int r = unsignedInt16be(buf, pos); - if (r <= 0x7FFF) + if(r <= 0x7FFF) return r; return -(r & 0x7FFF); } @@ -161,7 +161,7 @@ unsigned int ICACHE_FLASH_ATTR unsignedInt16le(const char *buf, int pos) { int ICACHE_FLASH_ATTR signedInt16le(const char *buf, int pos) { int r = unsignedInt16le(buf, pos); - if (r <= 0x7FFF) + if(r <= 0x7FFF) return r; return r - 0x10000; } diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index 7e05270..e94e85a 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -48,7 +48,7 @@ LOCAL HttpRequestCb mPostHttpRequestCb = 0; LOCAL CONTENT_ITEM mContentQueue[MAX_CONNECTIONS] = {0}; LOCAL int ICACHE_FLASH_ATTR is_remote_equal(const esp_tcp *tcp, CONTENT_ITEM *item) { - if (os_memcmp(tcp->remote_ip, item->remote_ip, sizeof(tcp->remote_ip)) == 0 + if(os_memcmp(tcp->remote_ip, item->remote_ip, sizeof(tcp->remote_ip)) == 0 && tcp->remote_port == item->remote_port) { return 1; } @@ -283,7 +283,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned } } - if (res != HRCS_NOT_FINISHED) { + if(res != HRCS_NOT_FINISHED) { dhstatistic_inc_httpd_requests_count(); } diff --git a/firmware-src/sources/rand.c b/firmware-src/sources/rand.c index 32e9115..38921d5 100644 --- a/firmware-src/sources/rand.c +++ b/firmware-src/sources/rand.c @@ -35,7 +35,7 @@ unsigned int ICACHE_FLASH_ATTR rand_generate_key(char *buf) { // removing unsuitable chars if(c == '"') c = '}'; // 0x7D - else if (c == '\\') + else if(c == '\\') c = '~'; // 0x7E buf[bufpos++] = c; } diff --git a/firmware-src/sources/snprintf.c b/firmware-src/sources/snprintf.c index cad8de4..9fec3ce 100644 --- a/firmware-src/sources/snprintf.c +++ b/firmware-src/sources/snprintf.c @@ -23,10 +23,10 @@ int ICACHE_FLASH_ATTR vsnprintf(char *pString, size_t length, const char *pForma /* Phase string */ while ( (pf = irom_char(pFormat)) != 0 && (pString-pOriginalStr) < length){ - if (pf != '%'){ + if(pf != '%'){ *pString++ = pf; pFormat++; - } else if (irom_char(pFormat + 1) == '%'){ + } else if(irom_char(pFormat + 1) == '%'){ *pString++ = '%'; pFormat += 2; } else { diff --git a/firmware-src/sources/uploadable_api.c b/firmware-src/sources/uploadable_api.c index 06ebccf..960564c 100644 --- a/firmware-src/sources/uploadable_api.c +++ b/firmware-src/sources/uploadable_api.c @@ -32,10 +32,10 @@ HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR uploadable_api_handle(const char *path, c if(os_strcmp(p, "begin") == 0) { if(content_in->len == 0) res = uploadable_page_begin(); - } else if (os_strcmp(p, "finish") == 0) { + } else if(os_strcmp(p, "finish") == 0) { if(content_in->len == 0) res = uploadable_page_finish(); - } else if (os_strcmp(p, "put") == 0) { + } else if(os_strcmp(p, "put") == 0) { if(content_in->len) res = uploadable_page_put(content_in->data, content_in->len); } else { From 3b3c2933df4ab5ae096deac1bcaf492e049a37b2 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 12 Apr 2017 16:06:26 +0300 Subject: [PATCH 09/83] fix bug in ROUND_KB() macro for values multiple of 1024 the result was invalid. For example ROUND_KB(1024) was 2048. --- firmware-src/sources/dhutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware-src/sources/dhutils.h b/firmware-src/sources/dhutils.h index ad374c2..2525b62 100644 --- a/firmware-src/sources/dhutils.h +++ b/firmware-src/sources/dhutils.h @@ -13,7 +13,7 @@ #define MAX(x, y) (((x) < (y)) ? (x) : (y)) /** Round value to KiB */ -#define ROUND_KB(x) (((x) / 1024 + 1) * 1024) +#define ROUND_KB(x) ((((x) + 1023) / 1024) * 1024) /** * \brief Convert string to float. From ec82adc4e0a82e2de21d4c7daad26daf1c9b7d59 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 13 Apr 2017 16:12:25 +0300 Subject: [PATCH 10/83] review the irom.h module there is no more `ifrom(p)` macro, just use `if (is_irom(p))` instead. the signature of `irom_read()` and `irom_cmp()` functions have been changed. the ROM pointer goes last for all functions. there is new IROM_FLASH_ALIGNMENT constant defined as `sizeof(uint32_t)`. --- firmware-src/sources/devices/mfrc522.c | 9 +- firmware-src/sources/httpd.c | 4 +- firmware-src/sources/irom.c | 122 +++++++++++++++++-------- firmware-src/sources/irom.h | 104 ++++++++++++++------- firmware-src/sources/uploadable_page.c | 12 +-- 5 files changed, 164 insertions(+), 87 deletions(-) diff --git a/firmware-src/sources/devices/mfrc522.c b/firmware-src/sources/devices/mfrc522.c index bf6a4b6..892884b 100644 --- a/firmware-src/sources/devices/mfrc522.c +++ b/firmware-src/sources/devices/mfrc522.c @@ -342,12 +342,9 @@ bool ICACHE_FLASH_ATTR MFRC522_PCD_PerformSelfTest() { } // Verify that the results match up to our expectations - for (i = 0; i < 64; i++) { - if (result[i] != irom_char(&(reference[i]))) { - return false; - } - } - + if (0 != irom_cmp(result, 64, reference)) + return false; + // Test passed; all is good. return true; } // End PCD_PerformSelfTest() diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index e94e85a..34deb9d 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -57,9 +57,9 @@ LOCAL int ICACHE_FLASH_ATTR is_remote_equal(const esp_tcp *tcp, CONTENT_ITEM *it LOCAL void ICACHE_FLASH_ATTR send_res(struct espconn *conn, const char *data, int len) { sint8 res; - ifrom(data) { + if (is_irom(data)) { char buf[len]; - irom_read(buf, data, len); + irom_read(buf, len, data); res = espconn_send(conn, buf, len); } else { res = espconn_send(conn, (char *)data, len); diff --git a/firmware-src/sources/irom.c b/firmware-src/sources/irom.c index 2e182b9..0b0b7cf 100644 --- a/firmware-src/sources/irom.c +++ b/firmware-src/sources/irom.c @@ -1,58 +1,100 @@ +/** @file + * @brief Helper module to work with ROM memory. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "irom.h" + /* - * irom.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: Helper module to work with rom. - * + * irom_byte() implementation. */ +uint8 irom_byte(const void *ptr) +{ + if (!is_irom(ptr)) + { + // for RAM pointers there is no restrictions + // to access this memory directly + return *(const uint8_t*)ptr; + } -#include "irom.h" + union { + uint32_t u; // unsigned integer + uint8_t b[4]; // bytes + } tmp; -typedef union { - uint32_t uint; - uint8_t chars[4]; -} FourChars; + // access to ROM memory should be 4-bytes aligned! + // so read the whole 4-bytes at aligned address + tmp.u = *(const uint32_t*)((uint32_t)ptr & ~(IROM_FLASH_ALIGNMENT-1)); -char irom_char(const char *rostr) { - FourChars t; - t.uint = *(uint32_t *)((uint32_t)rostr & ~0b11); - return t.chars[(uint32_t)rostr & 0b11]; + // and then, get the requested byte + return tmp.b[(uint32_t)ptr & (IROM_FLASH_ALIGNMENT-1)]; } -void ICACHE_FLASH_ATTR irom_read(char *buf, const char *addr, unsigned int len) { - while(len) { - if(((uint32_t)addr & 0b11) || len < 4) { - *buf = irom_char(addr); - buf++; - addr++; - len--; + +/* + * irom_read() implementation. + */ +void ICACHE_FLASH_ATTR irom_read(void *ram_buf, + size_t buf_len, + const void *rom_ptr) +{ + // typed pointers + const uint8_t *rom = (const uint8_t*)rom_ptr; + uint8_t *ram = ( uint8_t*)ram_buf; + + while (buf_len > 0) { + if (((uint32_t)rom & (IROM_FLASH_ALIGNMENT-1)) || buf_len < sizeof(uint32_t)) { + // if ROM address is not algned or + // we have less than 4 bytes to copy, + // then process byte-to-byte... + *ram = irom_byte(rom); + buf_len -= 1; + ram += 1; + rom += 1; } else { - *((uint32_t *)buf) = *((uint32_t *)addr); - buf += 4; - addr += 4; - len -= 4; + // ... otherwise process 4-bytes at once + *((uint32_t*)ram) = *((const uint32_t *)rom); + buf_len -= sizeof(uint32_t); + ram += sizeof(uint32_t); + rom += sizeof(uint32_t); } } } -int ICACHE_FLASH_ATTR irom_cmp(char *buf, const char *addr, unsigned int len) { - while(len) { - if(((uint32_t)addr & 0b11) || len < 4) { - if(*buf != irom_char(addr)) + +/* + * irom_cmp() implementation. + */ +int ICACHE_FLASH_ATTR irom_cmp(const void *ram_buf, + size_t buf_len, + const void *rom_ptr) +{ + // typed pointers + const uint8_t *rom = (const uint8_t*)rom_ptr; + uint8_t *ram = ( uint8_t*)ram_buf; + + while (buf_len > 0) { + if (((uint32_t)rom & (IROM_FLASH_ALIGNMENT-1)) || buf_len < sizeof(uint32_t)) { + // if ROM address is not algned or + // we have less than 4 bytes to compare, + // then process byte-to-byte... + const uint8_t b = irom_byte(rom); + if (*ram != b) return 1; - buf++; - addr++; - len--; + + buf_len -= 1; + ram += 1; + rom += 1; } else { - if(*((uint32_t *)buf) != *((uint32_t *)addr)) + // ... otherwise process 4-bytes at once + if (*((const uint32_t*)ram) != *((const uint32_t *)rom)) return 1; - buf += 4; - addr += 4; - len -= 4; + + buf_len -= sizeof(uint32_t); + ram += sizeof(uint32_t); + rom += sizeof(uint32_t); } } - return 0; + + return 0; // equal } diff --git a/firmware-src/sources/irom.h b/firmware-src/sources/irom.h index f866334..5a9864f 100644 --- a/firmware-src/sources/irom.h +++ b/firmware-src/sources/irom.h @@ -1,15 +1,14 @@ -/** - * \file irom.h - * \brief Module for working with irom - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT - * \details ESP8266 stores read only variables in RAM by default. It's - * possible to force compliller to store data in ROM, but reading - * from ROM is possible only per 32 bits and should be 4 bytes - * aligned. That's why direct access to this memory via system - * function causes chip to reboot. This module gives access to - * this data in easy way. +/** @file + * @brief Helper module to work with ROM memory. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + * + * ESP8266 stores read only variables in RAM by default. It's + * possible to force compiler to store data in ROM, but reading + * from ROM is possible only per 32 bits and should be 4 bytes + * aligned. That's why direct access to this memory via system + * function causes chip to reboot. This module gives access to + * this data in easy way. */ #ifndef _IROM_H_ @@ -17,38 +16,79 @@ #include -/** Address which is mapped to ROM */ +/** + * @brief ROM base address. + */ #define IROM_FLASH_BASE_ADDRESS 0x40200000 -/** Store data in ROM memory. Access to this data will be slower, but amount - * of free RAM will be bigger. Never read such variables directly, except 32 bits.*/ + +/** + * @brief ROM alignment. + */ +#define IROM_FLASH_ALIGNMENT sizeof(uint32_t) + + +/** + * @brief Compile time attribute to store data in ROM memory. + * + * Access to this data will be slower, but amount + * of free RAM will be bigger. + * + * @warning Never read such variables directly, except 32 bits. + */ #define RO_DATA const ICACHE_RODATA_ATTR STORE_ATTR static -/** Checks if pointer stored in ROM */ -#define ifrom(data) if((uint32_t)data >= IROM_FLASH_BASE_ADDRESS) /** - * \brief Read single char from ROM. - * \param[in] buf Point to data in ROM. - * \return Char. + * @brief Check if pointer is stored in ROM. + * @param[in] ptr Pointer to check. + * @return Non-zero if pointer is from ROM area. */ -char irom_char(const char *rostr); +static inline bool is_irom(const void *ptr) +{ + return (uint32_t)ptr >= IROM_FLASH_BASE_ADDRESS; +} + + +/** + * @brief Read single byte from ROM. + * @param[in] rom_ptr Pointer to data in ROM. + * @return One byte from ROM. + */ +uint8_t irom_byte(const void *rom_ptr); + /** - * \brief Read multiple bytes from ROM. - * \param[out] buf Point where to store data in RAM. - * \param[in] addr Pointer to data in ROM. - * \param[in] len Number of bytes to read. + * @brief Read single char from ROM. + * @param[in] rom_ptr Pointer to data in ROM. + * @return One char from ROM. */ -void irom_read(char *buf, const char *addr, unsigned int len); +static inline char irom_char(const void *rom_ptr) +{ + return irom_byte(rom_ptr); +} + + +/** + * @brief Read multiple bytes from ROM. + * @param[in,out] ram_buf Pointer in RAM where data will be stored. + * @param[in] buf_len Number of bytes to read. + * @param[in] rom_ptr Pointer to data in ROM. + */ +void irom_read(void *ram_buf, + size_t buf_len, + const void *rom_ptr); + /** - * \brief Compare some data with ROM memory. - * \param[in] buf Data in RAM to compare. - * \param[in] addr Pointer to data in ROM. - * \param[in] len Number of bytes to compare. - * \return Zero value if data is equal, non zero otherwise. + * @brief Compare some data with ROM. + * @param[in] ram_buf Pointer to data in RAM to compare. + * @param[in] buf_len Number of bytes to compare. + * @param[in] rom_ptr Pointer to data in ROM. + * @return Zero if data is equal, non-zero otherwise. */ -int irom_cmp(char *buf, const char *addr, unsigned int len); +int irom_cmp(const void *ram_buf, + size_t buf_len, + const void *rom_ptr); #endif /* _IROM_H_ */ diff --git a/firmware-src/sources/uploadable_page.c b/firmware-src/sources/uploadable_page.c index 5aff6cf..a8790e5 100644 --- a/firmware-src/sources/uploadable_page.c +++ b/firmware-src/sources/uploadable_page.c @@ -76,7 +76,7 @@ LOCAL SpiFlashOpResult ICACHE_FLASH_ATTR write_zero_byte(unsigned int sector) { return SPI_FLASH_RESULT_ERR; } uint8_t data[4]; - irom_read(data, (char *)(IROM_FLASH_BASE_ADDRESS + sector * SPI_FLASH_SEC_SIZE), sizeof(data)); + irom_read(data, sizeof(data), (const void *)(IROM_FLASH_BASE_ADDRESS + sector*SPI_FLASH_SEC_SIZE)); // since zero is going to be written here, there is no need in erase operation data[0] = 0; return spi_flash_write(sector * SPI_FLASH_SEC_SIZE, (uint32 *)data, sizeof(data)); @@ -117,15 +117,13 @@ LOCAL UP_STATUS ICACHE_FLASH_ATTR flash_data() { } if((SPI_FLASH_SEC_SIZE - mBufferPos) > 0) { - irom_read(&mBuffer[mBufferPos], (const char *) - (mFlashingSector * SPI_FLASH_SEC_SIZE + mBufferPos + IROM_FLASH_BASE_ADDRESS), - SPI_FLASH_SEC_SIZE - mBufferPos); + irom_read(&mBuffer[mBufferPos], SPI_FLASH_SEC_SIZE - mBufferPos, + (const void *)(mFlashingSector * SPI_FLASH_SEC_SIZE + mBufferPos + IROM_FLASH_BASE_ADDRESS)); mBufferPos = SPI_FLASH_SEC_SIZE; } - if(irom_cmp(mBuffer, (const char *) - (mFlashingSector * SPI_FLASH_SEC_SIZE + IROM_FLASH_BASE_ADDRESS), - SPI_FLASH_SEC_SIZE) == 0) { + if (0 == irom_cmp(mBuffer, SPI_FLASH_SEC_SIZE, + (const void *)(mFlashingSector * SPI_FLASH_SEC_SIZE + IROM_FLASH_BASE_ADDRESS))) { mFlashingSector++; return UP_STATUS_OK; } From 930700135e588be1af4e5cc6a36459025027d759 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 13 Apr 2017 17:50:56 +0300 Subject: [PATCH 11/83] review hexchar() function just use char constants to be clear --- firmware-src/sources/dhutils.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/firmware-src/sources/dhutils.c b/firmware-src/sources/dhutils.c index 25cbe4f..fffb3a8 100644 --- a/firmware-src/sources/dhutils.c +++ b/firmware-src/sources/dhutils.c @@ -94,21 +94,25 @@ int ICACHE_FLASH_ATTR byteToHex(unsigned char byte, char *hexout) { return 2; } -LOCAL int ICACHE_FLASH_ATTR hexchar(const char c) { - if(c > 0x60) { - if(c > 0x66) - return -1; - return c - 0x57; - } else if(c > 0x40) { - if(c > 0x46) - return -1; - return c - 0x37; - } else if(c > 0x2F) { - if(c > 0x39) - return -1; - return c - 0x30; - } else - return -1; +/** + * @brief Convert hexadecimal character into decimal value. + * + * - ['A'..'Z'] are converted to [10..15] + * - ['a'..'z'] are converted to [10..15] + * - ['0'..'9'] are converted to [0..9] + * + * @param[in] ch Character to convert. + * @return Decimal value in range [0..15] or `-1` in case of error. + */ +LOCAL int ICACHE_FLASH_ATTR hexchar(const char ch) { + if ('a' <= ch && ch <= 'f') + return 10 + (ch - 'a'); + if ('A' <= ch && ch <= 'F') + return 10 + (ch - 'A'); + if ('0' <= ch && ch <= '9') + return (ch - '0'); + + return -1; // unknown character } int ICACHE_FLASH_ATTR hexToByte(const char *hex, unsigned char *byteout) { From a0886556f8e31ba61b68e0754bd16cd1280a318c Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 13 Apr 2017 19:03:16 +0300 Subject: [PATCH 12/83] review the dhstatistic.h module rename structure to DHStat use global statistics instance use set of static inline functions to modify statistics --- firmware-src/sources/dhconnector.c | 18 +-- firmware-src/sources/dhnotification.c | 8 +- firmware-src/sources/dhsender.c | 12 +- firmware-src/sources/dhstatistic.c | 162 ++++++++++++++++----- firmware-src/sources/dhstatistic.h | 138 +++++++++++------- firmware-src/sources/dhterminal_commands.c | 2 +- firmware-src/sources/httpd.c | 16 +- firmware-src/sources/rest.c | 4 +- 8 files changed, 237 insertions(+), 123 deletions(-) diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index 9e725a7..86b02df 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -49,7 +49,7 @@ LOCAL void ICACHE_FLASH_ATTR network_error_cb(void *arg, sint8 err) { dhesperrors_espconn_result("Connector error occurred:", err); mConnectionState = CS_DISCONNECT; arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); - dhstatistic_inc_network_errors_count(); + dhstat_got_network_error(); } LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { @@ -79,7 +79,7 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { } LOCAL void ICACHE_FLASH_ATTR ws_error() { - dhstatistic_inc_server_errors_count(); + dhstat_got_server_error(); // close connection and restart everything on error espconn_disconnect(&mDHConnector); } @@ -90,11 +90,11 @@ LOCAL void ICACHE_FLASH_ATTR ws_send(const char *data, unsigned int len) { if(espconn_send(&mDHConnector, (uint8 *)data, len) != ESPCONN_OK) ws_error(); else - dhstatistic_add_bytes_sent(len); + dhstat_add_bytes_sent(len); } LOCAL void ICACHE_FLASH_ATTR network_recv_cb(void *arg, char *data, unsigned short len) { - dhstatistic_add_bytes_received(len); + dhstat_add_bytes_received(len); if(mConnectionState == CS_OPERATE) { dhconnector_websocket_parse(data, len); return; @@ -134,12 +134,12 @@ LOCAL void ICACHE_FLASH_ATTR network_recv_cb(void *arg, char *data, unsigned sho dhdebug("Connector HTTP response bad status %c%c%c", rc[0],rc[1],rc[2]); dhdebug_ram(data); dhdebug("--------------------------------------"); - dhstatistic_inc_server_errors_count(); + dhstat_got_server_error(); } } else { mConnectionState = CS_DISCONNECT; dhdebug("Connector HTTP magic number is wrong"); - dhstatistic_inc_server_errors_count(); + dhstat_got_server_error(); } espconn_disconnect(&mDHConnector); } @@ -184,7 +184,7 @@ LOCAL void network_connect_cb(void *arg) { dhesperrors_espconn_result("network_connect_cb failed:", res); espconn_disconnect(&mDHConnector); } else { - dhstatistic_add_bytes_sent(request->len); + dhstat_add_bytes_sent(request->len); } } @@ -228,7 +228,7 @@ LOCAL void ICACHE_FLASH_ATTR resolve_cb(const char *name, ip_addr_t *ip, void *a dhdebug("Resolve %s failed. Trying again...", name); mConnectionState = CS_DISCONNECT; arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); - dhstatistic_inc_network_errors_count(); + dhstat_got_network_error(); return; } unsigned char *bip = (unsigned char *) ip; @@ -330,7 +330,7 @@ LOCAL void ICACHE_FLASH_ATTR wifi_state_cb(System_Event_t *event) { } else if(event->event == EVENT_STAMODE_DISCONNECTED) { os_timer_disarm(&mRetryTimer); dhesperrors_disconnect_reason("WiFi disconnected", event->event_info.disconnected.reason); - dhstatistic_inc_wifi_lost_count(); + dhstat_got_wifi_lost(); mdnsd_stop(); } else { dhesperrors_wifi_state("WiFi event", event->event); diff --git a/firmware-src/sources/dhnotification.c b/firmware-src/sources/dhnotification.c index 7ff6ad6..f516633 100644 --- a/firmware-src/sources/dhnotification.c +++ b/firmware-src/sources/dhnotification.c @@ -25,7 +25,7 @@ void ICACHE_FLASH_ATTR dhgpio_int_timeout(unsigned int caused_pins) { if(dhmem_isblock()) { - dhstatistic_inc_notifications_dropped_count(); + dhstat_got_notification_dropped(); return; } dhsender_notification(RNT_NOTIFICATION_GPIO, RDT_GPIO, caused_pins, dhgpio_read(), system_get_time(), DHGPIO_SUITABLE_PINS); @@ -33,7 +33,7 @@ void ICACHE_FLASH_ATTR dhgpio_int_timeout(unsigned int caused_pins) { void ICACHE_FLASH_ATTR dhadc_loop_value(float value){ if(dhmem_isblock()) { - dhstatistic_inc_notifications_dropped_count(); + dhstat_got_notification_dropped(); return; } dhsender_notification(RNT_NOTIFICATION_ADC, RDT_FLOAT, value); @@ -41,7 +41,7 @@ void ICACHE_FLASH_ATTR dhadc_loop_value(float value){ void ICACHE_FLASH_ATTR dhuart_buf_rcv(const char *buf, unsigned int len) { if(dhmem_isblock()) { - dhstatistic_inc_notifications_dropped_count(); + dhstat_got_notification_dropped(); return; } dhsender_notification(RNT_NOTIFICATION_UART, RDT_DATA_WITH_LEN, buf, len); @@ -49,7 +49,7 @@ void ICACHE_FLASH_ATTR dhuart_buf_rcv(const char *buf, unsigned int len) { void ICACHE_FLASH_ATTR dhonewire_search_result(unsigned int pin_number, char *buf, unsigned long len) { if(dhmem_isblock()) { - dhstatistic_inc_notifications_dropped_count(); + dhstat_got_notification_dropped(); return; } dhsender_notification(RNT_NOTIFICATION_ONEWIRE, RDT_SEARCH64, pin_number, buf, len); diff --git a/firmware-src/sources/dhsender.c b/firmware-src/sources/dhsender.c index 1246814..0a5c2d7 100644 --- a/firmware-src/sources/dhsender.c +++ b/firmware-src/sources/dhsender.c @@ -46,9 +46,9 @@ void ICACHE_FLASH_ATTR dhsender_current_fail() { if(mSenderTook == 1) { dhdebug("WARNING: Request is not delivered after %u attempts", DHSENDER_RETRY_COUNT); if(isCurrentNotification) - dhstatistic_inc_notifications_dropped_count(); + dhstat_got_notification_dropped(); else - dhstatistic_inc_responces_dropped_count(); + dhstat_got_responce_dropped(); } mSenderTook--; } @@ -65,12 +65,12 @@ void dhsender_set_cb(dhsender_new_item_cb new_item) { void ICACHE_FLASH_ATTR dhsender_response(CommandResultArgument cid, RESPONCE_STATUS status, REQUEST_DATA_TYPE data_type, ...) { va_list ap; va_start(ap, data_type); - dhstatistic_inc_responces_count(); + dhstat_got_responce(); if(dhsender_queue_add(status == DHSTATUS_ERROR ? RT_RESPONCE_ERROR : RT_RESPONCE_OK, RNT_NOTIFICATION_NONE, data_type, cid.id, ap)) { if(mNewItemCb) mNewItemCb(); } else { - dhstatistic_inc_responces_dropped_count(); + dhstat_got_responce_dropped(); dhdebug("ERROR: No memory for response"); } va_end(ap); @@ -79,12 +79,12 @@ void ICACHE_FLASH_ATTR dhsender_response(CommandResultArgument cid, RESPONCE_STA void ICACHE_FLASH_ATTR dhsender_notification(REQUEST_NOTIFICATION_TYPE type, REQUEST_DATA_TYPE data_type, ...) { va_list ap; va_start(ap, data_type); - dhstatistic_inc_notifications_count(); + dhstat_got_notification(); if(dhsender_queue_add(RT_NOTIFICATION, type, data_type, 0, ap)) { if(mNewItemCb) mNewItemCb(); } else { - dhstatistic_inc_notifications_dropped_count(); + dhstat_got_notification_dropped(); dhdebug("ERROR: No memory for notification"); } va_end(ap); diff --git a/firmware-src/sources/dhstatistic.c b/firmware-src/sources/dhstatistic.c index 440d3e9..ab0268b 100644 --- a/firmware-src/sources/dhstatistic.c +++ b/firmware-src/sources/dhstatistic.c @@ -1,71 +1,153 @@ -/* - * dhstatistic.c - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: Module for collecting statistic - * +/** + * @file + * @brief Module to collect various statistic data. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#include #include "dhstatistic.h" +#include + + +// global statistics instance +static struct DHStat g_stat = {0}; -LOCAL DHSTATISTIC mStatistic = {0}; -void ICACHE_FLASH_ATTR dhstatistic_add_bytes_sent(unsigned int bytes) { - mStatistic.bytesSent += bytes; +/* + * @brief Get global statistics. + */ +const struct DHStat* ICACHE_FLASH_ATTR dhstat_get() +{ + return &g_stat; } -void ICACHE_FLASH_ATTR dhstatistic_add_bytes_received(unsigned int bytes) { - mStatistic.bytesReceived += bytes; + +/* + * @brief Add some number of bytes sent. + * @param[in] stat Statistics to update. + * @param[in] no_bytes Number of bytes sent. + */ +void ICACHE_FLASH_ATTR dhstat_add_bytes_sent(unsigned int no_bytes) +{ + g_stat.bytesSent += no_bytes; } -void ICACHE_FLASH_ATTR dhstatistic_inc_network_errors_count() { - mStatistic.networkErrors++; + +/* + * @brief Add some number of bytes received. + * @param[in] stat Statistics to update. + * @param[in] no_bytes Number of bytes received. + */ +void ICACHE_FLASH_ATTR dhstat_add_bytes_received(unsigned int no_bytes) +{ + g_stat.bytesReceived += no_bytes; } -void dhstatistic_inc_httpd_requests_count() { - mStatistic.httpdRequestsCount++; + +/* + * @brief Increment number of network errors. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_network_error(void) +{ + g_stat.networkErrors += 1; } -void dhstatistic_inc_httpd_errors_count() { - mStatistic.httpdErrorsCount++; + +/* + * @brief Increment number of REST requests. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_httpd_request(void) +{ + g_stat.httpdRequestsCount++; } -void ICACHE_FLASH_ATTR dhstatistic_inc_wifi_lost_count() { - mStatistic.wifiLosts++; + +/* + * @brief Increment number of REST errors. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_httpd_error(void) +{ + g_stat.httpdErrorsCount++; } -void ICACHE_FLASH_ATTR dhstatistic_inc_server_errors_count() { - mStatistic.serverErrors++; + +/* + * @brief Increment number of Wi-Fi disconnections. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_wifi_lost(void) +{ + g_stat.wifiLosts++; } -void ICACHE_FLASH_ATTR dhstatistic_inc_notifications_count() { - mStatistic.notificationsTotal++; + +/* + * @brief Increment number of server errors. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_server_error(void) +{ + g_stat.serverErrors++; } -void ICACHE_FLASH_ATTR dhstatistic_inc_notifications_dropped_count() { - mStatistic.notificationsDroppedCount++; + +/* + * @brief Increment number of notifications. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_notification(void) +{ + g_stat.notificationsTotal++; } -void ICACHE_FLASH_ATTR dhstatistic_inc_responces_count() { - mStatistic.responcesTotal++; + +/* + * @brief Increment number of dropped notifications. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_notification_dropped(void) +{ + g_stat.notificationsDroppedCount++; } -void ICACHE_FLASH_ATTR dhstatistic_inc_responces_dropped_count() { - mStatistic.responcesDroppedCount++; + +/* + * @brief Increment number of responses. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_responce(void) +{ + g_stat.responcesTotal++; } -void dhstatistic_inc_local_rest_requests_count() { - mStatistic.localRestRequestsCount++; + +/* + * @brief Increment number of dropped responses. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_responce_dropped(void) +{ + g_stat.responcesDroppedCount++; } -void dhstatistic_inc_local_rest_responses_errors() { - mStatistic.localRestResponcesErrors++; + +/* + * @brief Increment number REST requests. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_local_rest_request(void) +{ + g_stat.localRestRequestsCount++; } -const DHSTATISTIC* ICACHE_FLASH_ATTR dhstatistic_get_statistic() { - return &mStatistic; + +/* + * @brief Increment number of REST requests which were answered with error. + * @param[in] stat Statistics to update. + */ +void ICACHE_FLASH_ATTR dhstat_got_local_rest_response_error(void) +{ + g_stat.localRestResponcesErrors++; } diff --git a/firmware-src/sources/dhstatistic.h b/firmware-src/sources/dhstatistic.h index 9a57e40..50143e6 100644 --- a/firmware-src/sources/dhstatistic.h +++ b/firmware-src/sources/dhstatistic.h @@ -1,102 +1,134 @@ /** - * \file dhstatistic.h - * \brief Module fo collecting statistic data - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT + * @file + * @brief Module to collect various statistic data. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - #ifndef _DHSTATISTIC_H_ #define _DHSTATISTIC_H_ -/** Struct will all statistic data*/ -typedef struct { - unsigned long long bytesSent; ///< Total bytes sent. - unsigned long long bytesReceived; ///< Total bytes received. - unsigned int networkErrors; ///< Number of network errors. - unsigned int httpdRequestsCount; ///< Number of REST requests. - unsigned int httpdErrorsCount; ///< Number of REST errors. - unsigned int wifiLosts; ///< Number of Wi-Fi disconnects. - unsigned int serverErrors; ///< Number of errors from server. - unsigned int notificationsTotal; ///< Attempts number of creating notifications. - unsigned int responcesTotal; ///< Attempts number of creating responses. - unsigned int notificationsDroppedCount; ///< Number of dropped notifications. - unsigned int responcesDroppedCount; ///< Number of dropped responses. - unsigned int localRestRequestsCount; ///< Number of requests received via local REST. - unsigned int localRestResponcesErrors; ///< Number of errors in responses to local REST. -} DHSTATISTIC; /** - * \brief Add some numver of sent bytes. - * \param[in] bytes Number of bytes to add. + * @brief Various statistic data. */ -void dhstatistic_add_bytes_sent(unsigned int bytes); +struct DHStat { + unsigned long long bytesSent; ///< Total bytes sent. + unsigned long long bytesReceived; ///< Total bytes received. + unsigned int networkErrors; ///< Number of network errors. + + unsigned int httpdRequestsCount; ///< Number of REST requests. + unsigned int httpdErrorsCount; ///< Number of REST errors. + + unsigned int wifiLosts; ///< Number of Wi-Fi disconnects. + + unsigned int serverErrors; ///< Number of errors from server. + unsigned int notificationsTotal; ///< Number of attempts to create notifications. + unsigned int responcesTotal; ///< Number of attempts to create responses. + unsigned int notificationsDroppedCount; ///< Number of dropped notifications. + unsigned int responcesDroppedCount; ///< Number of dropped responses. + + unsigned int localRestRequestsCount; ///< Number of requests received via local REST. + unsigned int localRestResponcesErrors; ///< Number of errors in responses to local REST. +}; + /** - * \brief Add some numver of received bytes. - * \param[in] bytes Number of bytes to add. + * @brief Get global statistics. */ -void dhstatistic_add_bytes_received(unsigned int bytes); +const struct DHStat* dhstat_get(); + /** - * \brief Increment number of network errors. + * @brief Add some number of bytes sent. + * @param[in] stat Statistics to update. + * @param[in] no_bytes Number of bytes sent. */ -void dhstatistic_inc_network_errors_count(); +void dhstat_add_bytes_sent(unsigned int no_bytes); + /** - * \brief Increment number of REST requests. + * @brief Add some number of bytes received. + * @param[in] stat Statistics to update. + * @param[in] no_bytes Number of bytes received. */ -void dhstatistic_inc_httpd_requests_count(); +void dhstat_add_bytes_received(unsigned int no_bytes); + /** - * \brief Increment number of REST errors. + * @brief Increment number of network errors. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_httpd_errors_count(); +void dhstat_got_network_error(void); + /** - * \brief Increment number of Wi-Fi disconnections. + * @brief Increment number of REST requests. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_wifi_lost_count(); +void dhstat_got_httpd_request(void); + /** - * \brief Increment number of server errors. + * @brief Increment number of REST errors. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_server_errors_count(); +void dhstat_got_httpd_error(void); + /** - * \brief Increment number of notifications. + * @brief Increment number of Wi-Fi disconnections. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_notifications_count(); +void dhstat_got_wifi_lost(void); + /** - * \brief Increment number of dropped notifications. + * @brief Increment number of server errors. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_notifications_dropped_count(); +void dhstat_got_server_error(void); + /** - * \brief Increment number of responses. + * @brief Increment number of notifications. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_responces_count(); +void dhstat_got_notification(void); + /** - * \brief Increment number of dropped responses. + * @brief Increment number of dropped notifications. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_responces_dropped_count(); +void dhstat_got_notification_dropped(void); + /** - * \brief Increment number REST requests. + * @brief Increment number of responses. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_local_rest_requests_count(); +void dhstat_got_responce(void); + /** - * \brief Increment number of REST requests which were answered with error. + * @brief Increment number of dropped responses. + * @param[in] stat Statistics to update. */ -void dhstatistic_inc_local_rest_responses_errors(); +void dhstat_got_responce_dropped(void); + /** - * \brief Return statistic. - * \return Pointer to DHSTATISTIC with data. + * @brief Increment number REST requests. + * @param[in] stat Statistics to update. */ -const DHSTATISTIC* dhstatistic_get_statistic(); +void dhstat_got_local_rest_request(void); + + +/** + * @brief Increment number of REST requests which were answered with error. + * @param[in] stat Statistics to update. + */ +void dhstat_got_local_rest_response_error(void); + #endif /* _DHSTATISTIC_H_ */ diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index 1f750c0..b96cb27 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -95,7 +95,7 @@ void ICACHE_FLASH_ATTR dhterminal_commands_status(const char *args) { uint8 mac[6]; char digitBuff[32]; - const DHSTATISTIC *stat = dhstatistic_get_statistic(); + const struct DHStat *stat = dhstat_get(); dhuart_send_str("Network adapter "); if(!wifi_get_macaddr(STATION_IF, mac)) { diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index 34deb9d..6a92ad7 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -65,10 +65,10 @@ LOCAL void ICACHE_FLASH_ATTR send_res(struct espconn *conn, const char *data, in res = espconn_send(conn, (char *)data, len); } if(res) { - dhstatistic_inc_network_errors_count(); + dhstat_got_network_error(); dhesperrors_espconn_result("Httpd espconn_send returned:", res); } else { - dhstatistic_add_bytes_sent(len); + dhstat_add_bytes_sent(len); } } @@ -236,7 +236,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned answer.content.len = 0; answer.free_content = 0; answer.ok = 1; - dhstatistic_add_bytes_received(len); + dhstat_add_bytes_received(len); HTTP_RESPONSE_STATUS res = HRCS_INTERNAL_ERROR; if(conn == mCurrentPost) { @@ -256,7 +256,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned char redirect[sizeof(redirectresponse) - 2 + redirect_host_len]; snprintf(redirect, sizeof(redirect), redirectresponse, mRedirectHost); send_res(conn, redirect, sizeof(redirect) - 1); - dhstatistic_inc_httpd_requests_count(); + dhstat_got_httpd_request(); return; } break; @@ -284,7 +284,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned } if(res != HRCS_NOT_FINISHED) { - dhstatistic_inc_httpd_requests_count(); + dhstat_got_httpd_request(); } switch (res) { @@ -303,7 +303,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned if(is_remote_equal(conn->proto.tcp, &mContentQueue[i])) { dhdebug("Httpd duplicate responses"); send_res(conn, internal, sizeof(internal) - 1); - dhstatistic_inc_httpd_errors_count(); + dhstat_got_httpd_error(); return; } else if(mContentQueue[i].remote_port == 0) { item = &mContentQueue[i]; @@ -321,7 +321,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned if(item == 0) { dhdebug("Httpd no place for responses"); send_res(conn, internal, sizeof(internal) - 1); - dhstatistic_inc_httpd_errors_count(); + dhstat_got_httpd_error(); return; } const char *content_type = plain; @@ -378,7 +378,7 @@ LOCAL void ICACHE_FLASH_ATTR dhap_httpd_recv_cb(void *arg, char *data, unsigned dhdebug("Httpd internal error"); send_res(conn, internal, sizeof(internal) - 1); } - dhstatistic_inc_httpd_errors_count(); + dhstat_got_httpd_error(); } LOCAL void ICACHE_FLASH_ATTR dhap_httpd_reconnect_cb(void *arg, sint8 err) { diff --git a/firmware-src/sources/rest.c b/firmware-src/sources/rest.c index b3c5385..2cf402c 100644 --- a/firmware-src/sources/rest.c +++ b/firmware-src/sources/rest.c @@ -62,14 +62,14 @@ LOCAL void ICACHE_FLASH_ATTR rest_command_callback(CommandResultArgument cid, } } if(answer->ok == 0) - dhstatistic_inc_local_rest_responses_errors(); + dhstat_got_local_rest_response_error(); va_end(ap); } HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR rest_handle(const char *path, const char *key, HTTP_CONTENT *content_in, HTTP_ANSWER *answer) { static const char cint[] = "/int"; - dhstatistic_inc_local_rest_requests_count(); + dhstat_got_local_rest_request(); if(path[0] == 0) { answer->content.data = desription; answer->content.len = sizeof(desription) - 1; From f965235af8ad1155bbdce64f2f6cce83d503f4bb Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 13 Apr 2017 22:00:20 +0300 Subject: [PATCH 13/83] review hexToByte() and byteToHex() functions --- firmware-src/sources/dhutils.c | 66 +++++++++++++++++++++------------- firmware-src/sources/dhutils.h | 29 +++++++++------ 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/firmware-src/sources/dhutils.c b/firmware-src/sources/dhutils.c index fffb3a8..26108fa 100644 --- a/firmware-src/sources/dhutils.c +++ b/firmware-src/sources/dhutils.c @@ -8,10 +8,8 @@ * Description: utils for firmware * */ - -#include -#include #include "dhutils.h" +#include int ICACHE_FLASH_ATTR strToFloat(const char *ptr, float *result) { float res = 0.0f; @@ -86,16 +84,26 @@ int ICACHE_FLASH_ATTR strToInt(const char *ptr, int *result) { return pos; } -int ICACHE_FLASH_ATTR byteToHex(unsigned char byte, char *hexout) { - const unsigned char b0 = byte / 0x10; - const unsigned char b1 = byte & 0xF; - hexout[0] = (b0 < 10) ? b0 + '0' : (b0 - 10 + 'A'); - hexout[1] = (b1 < 10) ? b1 + '0' : (b1 - 10 + 'A'); +/* + * byteToHex() implementation. + */ +int ICACHE_FLASH_ATTR byteToHex(uint8_t val, char *hex_out) +{ + const int b0 = (val >> 4) & 0x0F; // high nibble + const int b1 = val & 0x0F; // low nibble + + // WARNING: there is no (hex_out != 0) check! + hex_out[0] = (b0 < 10) ? (b0 + '0') : (b0 - 10 + 'A'); + hex_out[1] = (b1 < 10) ? (b1 + '0') : (b1 - 10 + 'A'); + return 2; } + /** - * @brief Convert hexadecimal character into decimal value. + * @brief Convert hexadecimal character into nibble. + * + * [Nibble](https://en.wikipedia.org/wiki/Nibble) is a 4-bits value. * * - ['A'..'Z'] are converted to [10..15] * - ['a'..'z'] are converted to [10..15] @@ -104,32 +112,42 @@ int ICACHE_FLASH_ATTR byteToHex(unsigned char byte, char *hexout) { * @param[in] ch Character to convert. * @return Decimal value in range [0..15] or `-1` in case of error. */ -LOCAL int ICACHE_FLASH_ATTR hexchar(const char ch) { +static inline int hex2nibble(char ch) +{ if ('a' <= ch && ch <= 'f') - return 10 + (ch - 'a'); + return ch - 'a' + 10; if ('A' <= ch && ch <= 'F') - return 10 + (ch - 'A'); + return ch - 'A' + 10; if ('0' <= ch && ch <= '9') return (ch - '0'); return -1; // unknown character } -int ICACHE_FLASH_ATTR hexToByte(const char *hex, unsigned char *byteout) { - const int b0 = hexchar(hex[0]); - if(b0 != -1) { - const int b1 = hexchar(hex[1]); - if(b1 == -1) { - *byteout = b0; - return 1; - } else { - *byteout = b0 * 0x10 + b1; - return 2; - } + +/* + * hexToByte() implementation. + */ +int ICACHE_FLASH_ATTR hexToByte(const char *hex, uint8_t *val_out) +{ + // high nibble + const int b0 = hex2nibble(hex[0]); + if (b0 < 0) + return 0; + + // low nibble + const int b1 = hex2nibble(hex[1]); + if (b1 < 0) { + *val_out = b0; // WARNING: no (val_out != 0) check + return 1; } - return 0; + + // WARNING: no (val_out != 0) check + *val_out = (b0<<4) | b1; + return 2; } + const char *ICACHE_FLASH_ATTR find_http_responce_code(const char *data, unsigned short len) { unsigned short pos = sizeof(uint32); if(len > sizeof(uint32) && *(uint32 *) data == 0x50545448) { // HTTP diff --git a/firmware-src/sources/dhutils.h b/firmware-src/sources/dhutils.h index 2525b62..058de00 100644 --- a/firmware-src/sources/dhutils.h +++ b/firmware-src/sources/dhutils.h @@ -9,6 +9,9 @@ #ifndef _DHUTILS_H_ #define _DHUTILS_H_ +#include + + /** Find maximum value */ #define MAX(x, y) (((x) < (y)) ? (x) : (y)) @@ -42,21 +45,27 @@ int strToUInt(const char *ptr, unsigned int *result); */ int strToInt(const char *ptr, int *result); + /** - * \brief Convert byte value to two hex chars. - * \param[in] byte Value for convert. - * \param[out] hexout Pointer to two chars buffer for output. - * \return Number of written chars. Always 2. + * @brief Convert byte value to hexadecimal string. + * + * Output is in the range `[0..9A..F]`. + * + * @param[in] val Value for convert. + * @param[out] hex_out Pointer to output buffer. Should be at least 2 characters in length. + * @return Number of characters written. Always 2. */ -int byteToHex(unsigned char byte, char *hexout); +int byteToHex(uint8_t val, char *hex_out); + /** - * \brief Convert string to byte. - * \param[in] hex String to convert. - * \param[out] byteout Pointer to one char for output. - * \return Number of characters that was used from string: 1, 2 or 0 on error. + * @brief Convert hexadecimal string to byte. + * @param[in] hex String to convert. Should be at least 2 characters in length. + * @param[out] val_out Pointer to byte where output result is stored. + * @return Number of characters that was used from string: 1, 2 or 0 on error. */ -int hexToByte(const char *hex, unsigned char *byteout); +int hexToByte(const char *hex, uint8_t *val_out); + /** * \brief Util function to find out response code in HTTP response. From 738d3bd3b4a59ed61821d055d45c57f675fd58e3 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 14 Apr 2017 00:06:38 +0300 Subject: [PATCH 14/83] review the base64.h module --- firmware-src/sources/base64.c | 227 ++++++++++++++++++++-------------- firmware-src/sources/base64.h | 82 ++++++------ 2 files changed, 181 insertions(+), 128 deletions(-) diff --git a/firmware-src/sources/base64.c b/firmware-src/sources/base64.c index 514b171..a5a7f71 100644 --- a/firmware-src/sources/base64.c +++ b/firmware-src/sources/base64.c @@ -1,123 +1,164 @@ -/* - * base64.c - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: Base64 implementation. - * +/** + * @file + * @brief Base64 encode/decode. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#include -#include "user_config.h" #include "base64.h" +#include "user_config.h" #ifdef DATAENCODEBASE64 -LOCAL signed char ICACHE_FLASH_ATTR reverse_base64_table(char c) { - if(c >= 'a') { - if(c > 'z') - return -1; - return c - 'a' + 26; - } else if(c >= 'A') { - if(c > 'Z') - return -1; - return c - 'A'; - } else if(c >= '0') { - if(c > '9') - return -1; - return c - '0' + 52; - } else if(c == '+') { +/** + * @brief Base64 decoding table. + * @param[in] ch Input character. + * @return 6-bits integer or -1 in case of error. + */ +static int ICACHE_FLASH_ATTR reverse_base64_table(int ch) +{ + if (ch >= 'A' && ch <= 'Z') + return ch - 'A'; + if (ch >= 'a' && ch <= 'z') + return ch - 'a' + 26; + if (ch >= '0' && ch <= '9') + return ch - '0' + 52; + if (ch == '+') return 62; - } else if(c == '/') { + if (ch == '/') return 63; - } - return -1; + + return -1; // bad input } -LOCAL char ICACHE_FLASH_ATTR base64_table(uint32_t c, unsigned int offset) { + +/** + * @brief Base64 encoding table. + * @param[in] reg Shift register. + * @param[in] off Offset. + */ +static inline int ICACHE_FLASH_ATTR base64_table(uint32_t reg, int offset) +{ static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - return table[(c >> offset) & 0x3F]; + return table[(reg >> offset) & 0x3F]; // 6-bits } -unsigned int ICACHE_FLASH_ATTR base64_encode_length(unsigned int datalen) { - return (datalen + 2) / 3 * 4; + +/* + * base64_encode_length() implementation. + */ +size_t ICACHE_FLASH_ATTR base64_encode_length(size_t data_len) +{ + return (data_len + 2)/3 * 4; // round_up(len/3)*4 } -int ICACHE_FLASH_ATTR base64_encode(const char *data, unsigned int datalen, char *out, unsigned int outlen) { - if( base64_encode_length(datalen) > outlen || datalen == 0) + +/* + * base64_encode() implementation. + */ +int ICACHE_FLASH_ATTR base64_encode(const void *data_, size_t data_len, + char *text, size_t text_len) +{ + if (!data_len) + return 0; // nothing to encode + + // check we have enough space for output + if (base64_encode_length(data_len) > text_len) return 0; - int datapos = 0; - int outpos = 0; - uint32_t pc; - while(datapos < datalen) { - pc = data[datapos++] << 16; - out[outpos++] = base64_table(pc, 18); - if(datapos < datalen) { - pc |= (uint32_t)data[datapos++] << 8; - out[outpos++] = base64_table(pc, 12); - if(datapos < datalen) { - pc |= (uint32_t)data[datapos++]; - out[outpos++] = base64_table(pc, 6); - out[outpos++] = base64_table(pc, 0); + + const uint8_t *data = (const uint8_t*)data_; + char* const text_base = text; + + while (data_len != 0) + { + uint32_t reg = ((uint32_t)*data++) << 16; data_len--; + *text++ = base64_table(reg, 18); + if (data_len != 0) { + reg |= ((uint32_t)*data++) << 8; data_len--; + *text++ = base64_table(reg, 12); + if (data_len != 0) { + reg |= (uint32_t)*data++; data_len--; + *text++ = base64_table(reg, 6); + *text++ = base64_table(reg, 0); } else { - out[outpos++] = base64_table(pc, 6); - out[outpos++] = '='; + *text++ = base64_table(reg, 6); + *text++ = '='; // padding break; } } else { - out[outpos++] = base64_table(pc, 12); - out[outpos++] = '='; - out[outpos++] = '='; + *text++ = base64_table(reg, 12); + *text++ = '='; // padding + *text++ = '='; // padding break; } } - return outpos; + + return text - text_base; } -unsigned int ICACHE_FLASH_ATTR base64_decode_length(const char *data, unsigned int datalen) { - if(datalen % 4 || datalen == 0) - return 0; - int len = datalen * 3 / 4; - if(data[datalen - 1] == '=') - len--; - if(data[datalen - 2] == '=') - len--; - return len; + +/* + * base64_decode_length() implementation. + */ +size_t ICACHE_FLASH_ATTR base64_decode_length(const char *text, size_t text_len) +{ + if (!text_len) + return 0; // nothing to decode + if (text_len%4) + return 0; // bad text + + size_t data_len = (text_len/4) * 3; + if (text[text_len-1] == '=') + data_len--; + if (text[text_len-2] == '=') + data_len--; + + return data_len; } -int ICACHE_FLASH_ATTR base64_decode(const char *data, unsigned int datalen, char *out, unsigned int outlen) { - int el = base64_decode_length(data, datalen); - if(outlen < el || el == 0) + +/* + * base64_decode() implementation. + */ +int ICACHE_FLASH_ATTR base64_decode(const char *text, size_t text_len, + void *data_base, size_t data_len) +{ + if (!text_len || text_len%4) + return 0; // nothing to decode + + // check we have enough space for output + if (base64_decode_length(text, text_len) > data_len) return 0; - int datapos = 0; - int outpos = 0; - signed char t[4]; - uint32_t r; - while(datapos < datalen) { - t[0] = reverse_base64_table(data[datapos++]); - t[1] = reverse_base64_table(data[datapos++]); - t[2] = reverse_base64_table(data[datapos++]); - t[3] = reverse_base64_table(data[datapos++]); - if(t[0] == -1 || t[1] == -1) - return 0; - r = t[0] << 18 | (t[1] << 12); - out[outpos++] = (r >> 16) & 0xFF; - if(t[2] != -1) - r |= (t[2] << 6); - else if(datapos < datalen) - return 0; - if(t[3] != -1) - r |= t[3] ; - else if(datapos < datalen) - return 0; - if(t[2] != -1) - out[outpos++] = (r >> 8) & 0xFF; - if(t[3] != -1) - out[outpos++] = r & 0xFF; + + uint8_t *data = (uint8_t*)data_base; + while (text_len != 0) { + const int t0 = reverse_base64_table(*text++); text_len--; + const int t1 = reverse_base64_table(*text++); text_len--; + if (t0 < 0 || t1 < 0) + return 0; // bad data + uint32_t reg = ((uint32_t)t0 << 18) + | ((uint32_t)t1 << 12); + *data++ = (reg >> 16) & 0xFF; + + const int ch2 = *text++; text_len--; + if (ch2 == '=') + break; + const int t2 = reverse_base64_table(ch2); + if (t2 < 0) + return 0; // bad data + reg |= ((uint32_t)t2 << 6); + *data++ = (reg >> 8) & 0xFF; + + const int ch3 = *text++; text_len--; + if (ch3 == '=') + break; + const int t3 = reverse_base64_table(ch3); + if (t3 < 0) + return 0; // bad data + reg |= ((uint32_t)t3); + *data++ = reg & 0xFF; } - return outpos; + + return data - (uint8_t*)data_base; } -#endif //DATAENCODEBASE64 +#endif // DATAENCODEBASE64 diff --git a/firmware-src/sources/base64.h b/firmware-src/sources/base64.h index 19c6ecc..9bed6f4 100644 --- a/firmware-src/sources/base64.h +++ b/firmware-src/sources/base64.h @@ -1,55 +1,67 @@ /** - * \file base64.h - * \brief Base64 encode/decode implementation. - * \author Nikolay Khabarov - * \date 2015 - * \copyright Public Domain + * @file + * @brief Base64 encode/decode. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - #ifndef _DATAENCODEBASE64_H_ #define _DATAENCODEBASE64_H_ -#include "user_config.h" +#include -#ifdef DATAENCODEBASE64 /** - * \brief Encode binary data to text with Base64. - * \details Function check if output buffer enough for text and start writing to it only this check. Return zero immediately otherwise. - * \param[in] data Pointer to binary data. - * \param[in] datalen Data size in bytes. - * \param[out] out Pointer to output buffer. - * \param[in] outlen Output buffer size in bytes. - * \return Number of chars that was copied to output buffer. + * @brief Encode binary data to text using `Base64` encoding. + * + * Function checks if length of output buffer is enough to store `Base64` + * output text. If output buffer length is too small nothing is written. + * + * @param[in] data Pointer to binary data. + * @param[in] data_len Binary data length in bytes. + * @param[out] text Pointer to output buffer. + * @param[in] text_len Output buffer length in bytes. + * @return Number of bytes written to output buffer. */ -int base64_encode(const char *data, unsigned int datalen, char *out, unsigned int outlen); +int base64_encode(const void *data, + size_t data_len, + char *text, + size_t text_len); + /** - * \brief Report how many bytes will take encoded data. - * \param[in] datalen Binary data size in bytes. - * \return Base64 encoded size in bytes. + * @brief Estimate how many bytes will take `Base64` encoded data. + * @param[in] data_len Binary data length in bytes. + * @return `Base64` encoded text length in bytes. */ -unsigned int base64_encode_length(unsigned int datalen); +size_t base64_encode_length(size_t data_len); + /** - * \brief Decode text with Base64 to binary data. - * \details Function check if output buffer enough for data and start writing to it only this check. Return zero immediately otherwise. - * \param[in] data Pointer to Base64 encoded text. - * \param[in] datalen Base64 encoded text size in bytes. - * \param[out] out Pointer to output buffer. - * \param[in] outlen Output buffer size in bytes. - * \return Number of bytes that was copied to output buffer. + * @brief Decode text to binary data using `Base64` encoding. + * + * Function checks if length of output buffer is enough to store `Base64` + * decoded data. If output buffer length is too small nothing is written. + * @param[in] text Pointer to `Base64` encoded text. + * @param[in] text_len Encoded text length in bytes. Should be multiple of 4. + * @param[out] data Pointer to output binary data buffer. + * @param[in] data_len Output buffer length in bytes. + * @return Number of bytes written to output buffer. */ -int base64_decode(const char *data, unsigned int datalen, char *out, unsigned int outlen); +int base64_decode(const char *text, + size_t text_len, + void *data, + size_t data_len); + /** - * \brief Report how many bytes will take decoded data. - * \param[in] data Pointer to Base64 encoded text. - * \param[in] datalen Base64 encoded text size in bytes. - * \return Decoded binary data size in bytes. + * @brief Estimate how many bytes will take base64 decoded data. + * + * Encoded data is used to check padding characters at the end. + * + * @param[in] text Pointer to base64 encoded text. + * @param[in] text_len Encoded text length in bytes. + * @return Decoded binary data length in bytes. */ -unsigned int base64_decode_length(const char *data, unsigned int datalen); - -#endif //DATAENCODEBASE64 +size_t base64_decode_length(const char *text, size_t text_len); #endif /* _DATAENCODEBASE64_H_ */ From a2c0112b081119188d890c5933e35403608faf9f Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 14 Apr 2017 19:10:21 +0300 Subject: [PATCH 15/83] refactor if/else if bloack of code use table of name and handler function instead. P.S. firmware now is ~700 bytes bigger :( --- firmware-src/sources/dhcommands.c | 1980 ++++++++++++++++++----------- 1 file changed, 1270 insertions(+), 710 deletions(-) diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index ba06528..faad217 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -135,591 +135,948 @@ LOCAL int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, return 0; } -void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) { +#if 1 // GPIO commands + +/** + * @brief Do "gpio/write" command. + */ +static void ICACHE_FLASH_ATTR do_gpio_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; - char *parse_res; - unsigned int check; - dhdebug("Got command: %s %d", command, cb->data.id); - if( os_strcmp(command, "gpio/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, 0, AF_SET | AF_CLEAR, &fields); - if(parse_res) + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHGPIO_SUITABLE_PINS, + 0, AF_SET | AF_CLEAR, &fields); + + if (parse_res) + responce_error(cb, parse_res); + else if( (fields & (AF_SET | AF_CLEAR)) == 0) + responce_error(cb, "Dummy request"); + else if(dhgpio_write(parse_pins.pins_to_set, parse_pins.pins_to_clear)) + responce_ok(cb); + else + responce_error(cb, "Unsuitable pin"); +} + + +/** + * @brief Do "gpio/read" command. + */ +static void ICACHE_FLASH_ATTR do_gpio_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + int init = 1; + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHGPIO_SUITABLE_PINS, 0, + AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); + + if(parse_res) { responce_error(cb, parse_res); - else if( (fields & (AF_SET | AF_CLEAR)) == 0) - responce_error(cb, "Dummy request"); - else if(dhgpio_write(parse_pins.pins_to_set, parse_pins.pins_to_clear)) - responce_ok(cb); - else - responce_error(cb, "Unsuitable pin"); - } else if( os_strcmp(command, "gpio/read") == 0 ) { - int init = 1; - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, 0, AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); - if(parse_res) { - responce_error(cb, parse_res); - init = 0; - return; - } else { - init = dhgpio_initialize(parse_pins.pins_to_init, parse_pins.pins_to_pullup, parse_pins.pins_to_nopull); - } - } - if(init) { - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, dhgpio_read(), system_get_time(), DHGPIO_SUITABLE_PINS); + // ? init = 0; + return; } else { - responce_error(cb, "Wrong initialization parameters"); + init = dhgpio_initialize(parse_pins.pins_to_init, parse_pins.pins_to_pullup, parse_pins.pins_to_nopull); } - } else if( os_strcmp(command, "gpio/int") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); - if(parse_res) + } + + if(init) { + cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, dhgpio_read(), system_get_time(), DHGPIO_SUITABLE_PINS); + } else { + responce_error(cb, "Wrong initialization parameters"); + } +} + + +/** + * @brief Do "gpio/int" command. + */ +static void ICACHE_FLASH_ATTR do_gpio_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), + AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); + + if(parse_res) + responce_error(cb, parse_res); + else if(fields == 0) + responce_error(cb, "Wrong action"); + else if(parse_pins.timeout < GPIONOTIFICATION_MIN_TIMEOUT_MS || parse_pins.timeout > 0x7fffff) + responce_error(cb, "Timeout is wrong"); + else if(dhgpio_int(parse_pins.pins_to_disable, parse_pins.pins_to_rising, parse_pins.pins_to_falling, \ + parse_pins.pins_to_both, parse_pins.timeout)) + responce_ok(cb); + else + responce_error(cb, "Unsuitable pin"); +} + +#endif // GPIO commands + +#if 1 // ADC and PWM commands + +/** + * @brief Do "adc/read" command. + */ +static void ICACHE_FLASH_ATTR do_adc_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, AF_READ, &fields); + if(parse_res) { responce_error(cb, parse_res); - else if(fields == 0) - responce_error(cb, "Wrong action"); - else if(parse_pins.timeout < GPIONOTIFICATION_MIN_TIMEOUT_MS || parse_pins.timeout > 0x7fffff) - responce_error(cb, "Timeout is wrong"); - else if(dhgpio_int(parse_pins.pins_to_disable, parse_pins.pins_to_rising, parse_pins.pins_to_falling, \ - parse_pins.pins_to_both, parse_pins.timeout)) - responce_ok(cb); - else - responce_error(cb, "Unsuitable pin"); - } else if( os_strcmp(command, "adc/read") == 0) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_READ, &fields); - if(parse_res) { - responce_error(cb, parse_res); - return; - } else if(parse_pins.pins_to_read != DHADC_SUITABLE_PINS) { - responce_error(cb, "Unknown ADC channel"); - return; - } - } - cb->callback(cb->data, DHSTATUS_OK, RDT_FLOAT, dhadc_get_value()); - } else if( os_strcmp(command, "adc/int") == 0) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_VALUES, &fields); - if(responce_error(cb, parse_res)) { - return; - } else if(parse_pins.pin_value_readed != 0x1) { - responce_error(cb, "Wrong adc channel"); - return; - } else if((parse_pins.storage.uint_values[0] < ADCNOTIFICATION_MIN_TIMEOUT_MS && parse_pins.storage.uint_values[0] != 0) || parse_pins.storage.uint_values[0] > 0x7fffff) { - responce_error(cb, "Wrong period"); - return; - } else { - dhadc_loop(parse_pins.storage.uint_values[0]); - responce_ok(cb); - return; - } + return; + } else if(parse_pins.pins_to_read != DHADC_SUITABLE_PINS) { + responce_error(cb, "Unknown ADC channel"); + return; } - responce_error(cb, "Wrong parameters"); - } else if( os_strcmp(command, "pwm/control") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_VALUES | AF_PERIOD | AF_COUNT, &fields); - if(responce_error(cb, parse_res)) + } + + cb->callback(cb->data, DHSTATUS_OK, RDT_FLOAT, dhadc_get_value()); +} + + +/** + * @brief Do "adc/int" command. + */ +static void ICACHE_FLASH_ATTR do_adc_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_VALUES, &fields); + if(responce_error(cb, parse_res)) { return; - if(dhpwm_set_pwm(&parse_pins.storage.uint_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : dhpwm_get_period_us(), parse_pins.count)) + } else if(parse_pins.pin_value_readed != 0x1) { + responce_error(cb, "Wrong adc channel"); + return; + } else if((parse_pins.storage.uint_values[0] < ADCNOTIFICATION_MIN_TIMEOUT_MS && parse_pins.storage.uint_values[0] != 0) || parse_pins.storage.uint_values[0] > 0x7fffff) { + responce_error(cb, "Wrong period"); + return; + } else { + dhadc_loop(parse_pins.storage.uint_values[0]); responce_ok(cb); - else - responce_error(cb, "Wrong parameters"); - } else if( os_strcmp(command, "uart/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_UARTMODE | AF_DATA, &fields); + return; + } + } + responce_error(cb, "Wrong parameters"); +} + + +/** + * @brief Do "pwm/control" command. + */ +static void ICACHE_FLASH_ATTR do_pwm_control(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_VALUES | AF_PERIOD | AF_COUNT, &fields); + if(responce_error(cb, parse_res)) + return; + if(dhpwm_set_pwm(&parse_pins.storage.uint_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : dhpwm_get_period_us(), parse_pins.count)) + responce_ok(cb); + else + responce_error(cb, "Wrong parameters"); +} + +#endif // ADC and PWM commands + +#if 1 // UART commands + +/** + * @brief Do "uart/write" command. + */ +static void ICACHE_FLASH_ATTR do_uart_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_UARTMODE | AF_DATA, &fields); + if(responce_error(cb, parse_res)) + return; + if(uart_init(cb, fields, &parse_pins, 0)) + return; + dhuart_set_mode(DUM_PER_BUF); + dhuart_send_buf(parse_pins.data, parse_pins.data_len); + responce_ok(cb); +} + + +/** + * @brief Do "uart/read" command. + */ +static void ICACHE_FLASH_ATTR do_uart_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); if(responce_error(cb, parse_res)) return; if(uart_init(cb, fields, &parse_pins, 0)) return; - dhuart_set_mode(DUM_PER_BUF); - dhuart_send_buf(parse_pins.data, parse_pins.data_len); - responce_ok(cb); - } else if( os_strcmp(command, "uart/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); - if(responce_error(cb, parse_res)) - return; - if(uart_init(cb, fields, &parse_pins, 0)) - return; - if(fields & AF_TIMEOUT) { - if(parse_pins.timeout > 1000) { - responce_error(cb, "Timeout is too long"); - return; - } - if((fields & AF_DATA) == 0) { - responce_error(cb, "Timeout can be specified only with data"); - return; - } - } - } - if(fields & AF_DATA) { - dhuart_set_mode(DUM_PER_BUF); - dhuart_send_buf(parse_pins.data, parse_pins.data_len); - system_soft_wdt_feed(); - delay_ms((fields & AF_TIMEOUT) ? parse_pins.timeout : 250); - system_soft_wdt_feed(); - } - char *buf; - int len = dhuart_get_buf(&buf); - if(len > INTERFACES_BUF_SIZE) - len = INTERFACES_BUF_SIZE; - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, buf, len); - dhuart_set_mode(DUM_PER_BUF); - } else if( os_strcmp(command, "uart/int") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, dhuart_get_callback_timeout(), AF_UARTMODE | AF_TIMEOUT, &fields); - if(responce_error(cb, parse_res)) - return; - if((fields & AF_TIMEOUT) && parse_pins.timeout > 5000) { + if(fields & AF_TIMEOUT) { + if(parse_pins.timeout > 1000) { responce_error(cb, "Timeout is too long"); return; } - if(uart_init(cb, fields, &parse_pins, 1)) + if((fields & AF_DATA) == 0) { + responce_error(cb, "Timeout can be specified only with data"); return; - if(fields & AF_TIMEOUT) - dhuart_set_callback_timeout(parse_pins.timeout); + } } + } + if(fields & AF_DATA) { dhuart_set_mode(DUM_PER_BUF); - dhuart_enable_buf_interrupt(1); - responce_ok(cb); - } else if( os_strcmp(command, "uart/terminal") == 0 ) { - if(paramslen) { - responce_error(cb, "Command does not have parameters"); - return; - } - dhterminal_init(); - responce_ok(cb); - } else if( os_strcmp(command, "i2c/master/read") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); + dhuart_send_buf(parse_pins.data, parse_pins.data_len); + system_soft_wdt_feed(); + delay_ms((fields & AF_TIMEOUT) ? parse_pins.timeout : 250); + system_soft_wdt_feed(); + } + char *buf; + int len = dhuart_get_buf(&buf); + if(len > INTERFACES_BUF_SIZE) + len = INTERFACES_BUF_SIZE; + cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, buf, len); + dhuart_set_mode(DUM_PER_BUF); +} + + +/** + * @brief Do "uart/int" command. + */ +static void ICACHE_FLASH_ATTR do_uart_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, dhuart_get_callback_timeout(), + AF_UARTMODE | AF_TIMEOUT, &fields); if(responce_error(cb, parse_res)) return; - if((fields & AF_COUNT) == 0) - parse_pins.count = 2; - if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - responce_error(cb, "Wrong read size"); + if((fields & AF_TIMEOUT) && parse_pins.timeout > 5000) { + responce_error(cb, "Timeout is too long"); return; } - if(i2c_init(cb, fields, &parse_pins)) + if(uart_init(cb, fields, &parse_pins, 1)) return; - char *res; - if(fields & AF_DATA) { - res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 0)); - if(res) { - responce_error(cb, res); - return; - } - } - res = i2c_status_tochar(dhi2c_read(parse_pins.address, parse_pins.data, parse_pins.count)); + if(fields & AF_TIMEOUT) + dhuart_set_callback_timeout(parse_pins.timeout); + } + dhuart_set_mode(DUM_PER_BUF); + dhuart_enable_buf_interrupt(1); + responce_ok(cb); +} + + +/** + * @brief Do "uart/terminal" command. + */ +static void ICACHE_FLASH_ATTR do_uart_terminal(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + responce_error(cb, "Command does not have parameters"); + return; + } + dhterminal_init(); + responce_ok(cb); +} + +#endif // UART commands + +#if 1 // I2C commands + +/** + * @brief Do "i2c/master/read" command. + */ +static void ICACHE_FLASH_ATTR do_i2c_master_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); + if (responce_error(cb, parse_res)) + return; + if((fields & AF_COUNT) == 0) + parse_pins.count = 2; + if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { + responce_error(cb, "Wrong read size"); + return; + } + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res; + if(fields & AF_DATA) { + res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 0)); if(res) { responce_error(cb, res); return; } - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); - } else if( os_strcmp(command, "i2c/master/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); - return; - } - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 1)); - if(responce_error(cb, res) == 0) - responce_ok(cb); - } else if( os_strcmp(command, "spi/master/read") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); - if(responce_error(cb, parse_res)) - return; - if((fields & AF_COUNT) == 0) - parse_pins.count = 2; - if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - responce_error(cb, "Wrong read size"); - return; - } - if(spi_init(cb, fields, &parse_pins)) - return; - if(fields & AF_DATA) - dhspi_write(parse_pins.data, parse_pins.data_len, 0); - dhspi_read(parse_pins.data, parse_pins.count); - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); - } else if( os_strcmp(command, "spi/master/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA, &fields); + } + res = i2c_status_tochar(dhi2c_read(parse_pins.address, parse_pins.data, parse_pins.count)); + if(res) { + responce_error(cb, res); + return; + } + cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); +} + + +/** + * @brief Do "i2c/master/write" command. + */ +static void ICACHE_FLASH_ATTR do_i2c_master_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) + return; + if((fields & AF_DATA) == 0) { + responce_error(cb, "Data not specified"); + return; + } + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 1)); + if(responce_error(cb, res) == 0) + responce_ok(cb); +} + +#endif // I2C commands + +#if 1 // SPI commands + +/** + * @brief Do "spi/master/read" command. + */ +static void ICACHE_FLASH_ATTR do_spi_master_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); + if(responce_error(cb, parse_res)) + return; + if((fields & AF_COUNT) == 0) + parse_pins.count = 2; + if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { + responce_error(cb, "Wrong read size"); + return; + } + if(spi_init(cb, fields, &parse_pins)) + return; + if(fields & AF_DATA) + dhspi_write(parse_pins.data, parse_pins.data_len, 0); + dhspi_read(parse_pins.data, parse_pins.count); + cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); +} + + +/** + * @brief Do "spi/master/write" command. + */ +static void ICACHE_FLASH_ATTR do_spi_master_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_CS | AF_SPIMODE | AF_DATA, &fields); + if(responce_error(cb, parse_res)) + return; + if(spi_init(cb, fields, &parse_pins)) + return; + if((fields & AF_DATA) == 0) { + responce_error(cb, "Data not specified"); + return; + } + dhspi_write(parse_pins.data, parse_pins.data_len, 1); + responce_ok(cb); +} + +#endif // SPI commands + +#if 1 // onewire commands + +/** + * @brief Do "onewire/master/read" command. + */ +static void ICACHE_FLASH_ATTR do_onewire_master_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_PIN | AF_DATA | AF_COUNT, &fields); + if(responce_error(cb, parse_res)) + return; + if((fields & AF_COUNT) == 0 || parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { + responce_error(cb, "Wrong read size"); + return; + } + if((fields & AF_DATA) == 0) { + responce_error(cb, "Command for reading is not specified"); + return; + } + if(onewire_init(cb, fields, &parse_pins)) + return; + if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { + responce_error(cb, "No response"); + return; + } + dhonewire_read(parse_pins.data, parse_pins.count); + cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); +} + + +/** + * @brief Do "onewire/master/write" commands. + */ +static void ICACHE_FLASH_ATTR do_onewire_master_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char * parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_PIN | AF_DATA, &fields); + if(responce_error(cb, parse_res)) + return; + if(onewire_init(cb, fields, &parse_pins)) + return; + if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { + responce_error(cb, "No response"); + return; + } + responce_ok(cb); +} + +/** + * Do "onewire/master/search" or "onewire/master/alarm" commands. + */ +static void ICACHE_FLASH_ATTR do_onewire_master_search(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); if(responce_error(cb, parse_res)) return; - if(spi_init(cb, fields, &parse_pins)) - return; - if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); + if(onewire_init(cb, fields, &parse_pins)) return; - } - dhspi_write(parse_pins.data, parse_pins.data_len, 1); + } + parse_pins.data_len = sizeof(parse_pins.data) ; + + int check = os_strcmp(command, "onewire/master/search"); + if(dhonewire_search(parse_pins.data, (unsigned long *)&parse_pins.data_len, (check == 0) ? 0xF0 : 0xEC, dhonewire_get_pin())) + cb->callback(cb->data, DHSTATUS_OK, RDT_SEARCH64, dhonewire_get_pin(), parse_pins.data, parse_pins.data_len); + else + responce_error(cb, "Error during search"); +} + + +/** + * @brief Do "onewire/master/int" command. + */ +static void ICACHE_FLASH_ATTR do_onewire_master_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); + if(parse_res) + responce_error(cb, parse_res); + else if(fields == 0) + responce_error(cb, "Wrong action"); + else if(dhonewire_int(parse_pins.pins_to_presence, parse_pins.pins_to_disable)) responce_ok(cb); - } else if( os_strcmp(command, "onewire/master/read") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA | AF_COUNT, &fields); + else + responce_error(cb, "Unsuitable pin"); +} + + +/** + * @brief Do "onewire/dht/read" command. + */ +static void ICACHE_FLASH_ATTR do_onewire_dht_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); if(responce_error(cb, parse_res)) return; - if((fields & AF_COUNT) == 0 || parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - responce_error(cb, "Wrong read size"); - return; - } - if((fields & AF_DATA) == 0) { - responce_error(cb, "Command for reading is not specified"); - return; - } if(onewire_init(cb, fields, &parse_pins)) return; - if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { - responce_error(cb, "No response"); - return; - } - dhonewire_read(parse_pins.data, parse_pins.count); + } + parse_pins.count = dhonewire_dht_read(parse_pins.data, sizeof(parse_pins.data)); + if(parse_pins.count) cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); - } else if( os_strcmp(command, "onewire/master/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); + else + responce_error(cb, "No response"); +} + + +/** + * @brief Do "onewire/ws2812b/write" command. + */ +static void ICACHE_FLASH_ATTR do_onewire_ws2812b_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); + if(responce_error(cb, parse_res)) + return; + if((fields & AF_DATA) == 0) { + responce_error(cb, "Data not specified"); + return; + } + if(onewire_init(cb, fields, &parse_pins)) + return; + dhonewire_ws2812b_write(parse_pins.data, parse_pins.data_len); + responce_ok(cb); +} + +#endif // onewire commands + +#if 1 // devices commands + +/** + * @brief Do "devices/ds18b20/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_ds18b20_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char * parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); if(responce_error(cb, parse_res)) return; if(onewire_init(cb, fields, &parse_pins)) return; - if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { - responce_error(cb, "No response"); - return; - } - responce_ok(cb); - } else if( (check = os_strcmp(command, "onewire/master/search")) == 0 || os_strcmp(command, "onewire/master/alarm") == 0) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) - return; - if(onewire_init(cb, fields, &parse_pins)) - return; - } - parse_pins.data_len = sizeof(parse_pins.data) ; - if(dhonewire_search(parse_pins.data, (unsigned long *)&parse_pins.data_len, (check == 0) ? 0xF0 : 0xEC, dhonewire_get_pin())) - cb->callback(cb->data, DHSTATUS_OK, RDT_SEARCH64, dhonewire_get_pin(), parse_pins.data, parse_pins.data_len); - else - responce_error(cb, "Error during search"); - } else if( os_strcmp(command, "onewire/master/int") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); - if(parse_res) - responce_error(cb, parse_res); - else if(fields == 0) - responce_error(cb, "Wrong action"); - else if(dhonewire_int(parse_pins.pins_to_presence, parse_pins.pins_to_disable)) - responce_ok(cb); - else - responce_error(cb, "Unsuitable pin"); - } else if( os_strcmp(command, "onewire/dht/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) - return; - if(onewire_init(cb, fields, &parse_pins)) - return; - } - parse_pins.count = dhonewire_dht_read(parse_pins.data, sizeof(parse_pins.data)); - if(parse_pins.count) - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); - else - responce_error(cb, "No response"); - } else if( os_strcmp(command, "onewire/ws2812b/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); + } + float temperature; + char *res = ds18b20_read(DS18B20_NO_PIN, &temperature); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); +} + + +/** + * @brief Do "devices/dht11/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_dht11_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); if(responce_error(cb, parse_res)) return; - if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); - return; - } if(onewire_init(cb, fields, &parse_pins)) return; - dhonewire_ws2812b_write(parse_pins.data, parse_pins.data_len); - responce_ok(cb); - } else if( os_strcmp(command, "devices/ds18b20/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) - return; - if(onewire_init(cb, fields, &parse_pins)) - return; - } - float temperature; - char *res = ds18b20_read(DS18B20_NO_PIN, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } else if( os_strcmp(command, "devices/dht11/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) - return; - if(onewire_init(cb, fields, &parse_pins)) - return; - } + } - int temperature; - int humidity; - char *res = dht11_read(DHT_NO_PIN, &humidity, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); - } else if( os_strcmp(command, "devices/dht22/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) - return; - if(onewire_init(cb, fields, &parse_pins)) - return; - } + int temperature; + int humidity; + char *res = dht11_read(DHT_NO_PIN, &humidity, &temperature); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); +} - float temperature; - float humidity; - char *res = dht22_read(DHT_NO_PIN, &humidity, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); - } else if( os_strcmp(command, "devices/bmp180/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - bmp180_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float temperature; - int pressure; - char *res = i2c_status_tochar(bmp180_read(BMP180_NO_PIN, BMP180_NO_PIN, &pressure, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); - } else if( os_strcmp(command, "devices/bmp280/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - bmp280_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float temperature; - float pressure; - char *res = i2c_status_tochar(bmp280_read(BMP280_NO_PIN, BMP280_NO_PIN, &pressure, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); - } else if( os_strcmp(command, "devices/bh1750/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - bh1750_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float illuminance; - char *res = i2c_status_tochar(bh1750_read(BH1750_NO_PIN, BH1750_NO_PIN, &illuminance)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); - } else if( os_strcmp(command, "devices/mpu6050/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - mpu6050_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - MPU6050_XYZ acc; - MPU6050_XYZ gyro; - float temperature; - char *res = i2c_status_tochar(mpu6050_read(MPU6050_NO_PIN, MPU6050_NO_PIN, &acc, &gyro, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", - temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); - } else if( os_strcmp(command, "devices/hmc5883l/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - hmc5883l_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - HMC5883L_XYZ compass; - char *res = i2c_status_tochar(hmc5883l_read(HMC5883L_NO_PIN, HMC5883L_NO_PIN, &compass)); - if(responce_error(cb, res)) - return; - char floatbufx[10] = "NaN"; - char floatbufy[10] = "NaN"; - char floatbufz[10] = "NaN"; - if(compass.X != HMC5883l_OVERFLOWED) - snprintf(floatbufx, sizeof(floatbufx), "%f", compass.X); - if(compass.Y != HMC5883l_OVERFLOWED) - snprintf(floatbufy, sizeof(floatbufy), "%f", compass.Y); - if(compass.Z != HMC5883l_OVERFLOWED) - snprintf(floatbufz, sizeof(floatbufz), "%f", compass.Z); - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"magnetometer\":{\"X\":%s, \"Y\":%s, \"Z\":%s}}", - floatbufx, floatbufy, floatbufz); - } else if( os_strcmp(command, "devices/pcf8574/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_PULLUP, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - pcf8574_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - if(fields & AF_PULLUP) { - char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_pullup, 0)); - if(responce_error(cb, res)) - return; - } - unsigned int pins; - char *res = i2c_status_tochar(pcf8574_read(PCF8574_NO_PIN, PCF8574_NO_PIN, &pins)); - if(responce_error(cb, res)) + +/** + * @brief Do "devices/dht22/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if(responce_error(cb, parse_res)) return; - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, pins, system_get_time(), PCF8574_SUITABLE_PINS); - } else if( os_strcmp(command, "devices/pcf8574/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_SET | AF_CLEAR, &fields); - if(responce_error(cb, parse_res)) { + if(onewire_init(cb, fields, &parse_pins)) return; - } else if( (fields & (AF_SET | AF_CLEAR)) == 0) { - responce_error(cb, "Dummy request"); + } + + float temperature; + float humidity; + char *res = dht22_read(DHT_NO_PIN, &humidity, &temperature); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); +} + +/** + * @brief Do "devices/bmp180/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_bmp180_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) return; - } else if( (parse_pins.pins_to_set | parse_pins.pins_to_clear | PCF8574_SUITABLE_PINS) - != PCF8574_SUITABLE_PINS ) { - responce_error(cb, "Unsuitable pin"); + if(fields & AF_ADDRESS) + bmp180_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float temperature; + int pressure; + char *res = i2c_status_tochar(bmp180_read(BMP180_NO_PIN, BMP180_NO_PIN, &pressure, &temperature)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); +} + +/** + * @brief Do "devices/bmp280/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) return; - } if(fields & AF_ADDRESS) - pcf8574_set_address(parse_pins.address); - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + bmp280_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float temperature; + float pressure; + char *res = i2c_status_tochar(bmp280_read(BMP280_NO_PIN, BMP280_NO_PIN, &pressure, &temperature)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); +} + + +/** + * @brief Do "devices/bh1750/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_bh1750_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) return; - char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, - parse_pins.pins_to_set, parse_pins.pins_to_clear)); - if(responce_error(cb, res)) + if(fields & AF_ADDRESS) + bh1750_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float illuminance; + char *res = i2c_status_tochar(bh1750_read(BH1750_NO_PIN, BH1750_NO_PIN, &illuminance)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); +} + +/** + * @brief Do "devices/mpu6050/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) return; - responce_ok(cb); - } else if( os_strcmp(command, "devices/pcf8574/hd44780/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_DATA | AF_TEXT_DATA, &fields); + if(fields & AF_ADDRESS) + mpu6050_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + MPU6050_XYZ acc; + MPU6050_XYZ gyro; + float temperature; + char *res = i2c_status_tochar(mpu6050_read(MPU6050_NO_PIN, MPU6050_NO_PIN, &acc, &gyro, &temperature)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", + temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); +} + +/** + * @brief Do "devices/hmc5883l/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_hmc5883l_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); if(responce_error(cb, parse_res)) return; - if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { - responce_error(cb, "Text not specified"); + if(fields & AF_ADDRESS) + hmc5883l_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + HMC5883L_XYZ compass; + char *res = i2c_status_tochar(hmc5883l_read(HMC5883L_NO_PIN, HMC5883L_NO_PIN, &compass)); + if(responce_error(cb, res)) + return; + char floatbufx[10] = "NaN"; + char floatbufy[10] = "NaN"; + char floatbufz[10] = "NaN"; + if(compass.X != HMC5883l_OVERFLOWED) + snprintf(floatbufx, sizeof(floatbufx), "%f", compass.X); + if(compass.Y != HMC5883l_OVERFLOWED) + snprintf(floatbufy, sizeof(floatbufy), "%f", compass.Y); + if(compass.Z != HMC5883l_OVERFLOWED) + snprintf(floatbufz, sizeof(floatbufz), "%f", compass.Z); + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"magnetometer\":{\"X\":%s, \"Y\":%s, \"Z\":%s}}", + floatbufx, floatbufy, floatbufz); +} + +/** + * @brief Do "devices/pcf8574/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_pcf8574_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, PCF8574_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_PULLUP, &fields); + if(responce_error(cb, parse_res)) return; - } if(fields & AF_ADDRESS) pcf8574_set_address(parse_pins.address); - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res = i2c_status_tochar(pcf8574_hd44780_write(PCF8574_NO_PIN, PCF8574_NO_PIN, - parse_pins.data, parse_pins.data_len)); - if(responce_error(cb, res)) - return; - responce_ok(cb); - } else if( os_strcmp(command, "devices/mhz19/read") == 0 ) { - if(paramslen) { - responce_error(cb, "Command does not have parameters"); - return; - } - int co2; - char *res = mhz19_read(&co2); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"co2\":%d}", co2); - } else if( os_strcmp(command, "devices/lm75/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - lm75_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float temperature; - char *res = i2c_status_tochar(lm75_read(LM75_NO_PIN, LM75_NO_PIN, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } else if( os_strcmp(command, "devices/si7021/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - si7021_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float temperature; - float humidity; - char *res = i2c_status_tochar(si7021_read(SI7021_NO_PIN, SI7021_NO_PIN, &humidity, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); - } else if( os_strcmp(command, "devices/ads1115/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - ads1115_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float values[4]; - char *res = i2c_status_tochar(ads1115_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + if(fields & AF_PULLUP) { + char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_pullup, 0)); if(responce_error(cb, res)) return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", - values[0], values[1], values[2], values[3]); - } else if( os_strcmp(command, "devices/pcf8591/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - pcf8591_set_address(parse_pins.address); - if(fields & AF_REF) { - char *res = i2c_status_tochar(pcf8591_set_vref(parse_pins.ref)); - if(responce_error(cb, res)) - return; - } - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + } + unsigned int pins; + char *res = i2c_status_tochar(pcf8574_read(PCF8574_NO_PIN, PCF8574_NO_PIN, &pins)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, pins, system_get_time(), PCF8574_SUITABLE_PINS); +} + +/** + * @brief Do "devices/pcf8574/write" command. + */ +static void ICACHE_FLASH_ATTR do_devices_pcf8574_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, PCF8574_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_SET | AF_CLEAR, &fields); + if(responce_error(cb, parse_res)) { + return; + } else if( (fields & (AF_SET | AF_CLEAR)) == 0) { + responce_error(cb, "Dummy request"); + return; + } else if( (parse_pins.pins_to_set | parse_pins.pins_to_clear | PCF8574_SUITABLE_PINS) + != PCF8574_SUITABLE_PINS ) { + responce_error(cb, "Unsuitable pin"); + return; + } + if(fields & AF_ADDRESS) + pcf8574_set_address(parse_pins.address); + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, + parse_pins.pins_to_set, parse_pins.pins_to_clear)); + if(responce_error(cb, res)) + return; + responce_ok(cb); +} + +/** + * @brief Do "devices/pcf8574/hd44780/write" command. + */ +static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, PCF8574_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_DATA | AF_TEXT_DATA, &fields); + if(responce_error(cb, parse_res)) + return; + if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { + responce_error(cb, "Text not specified"); + return; + } + if(fields & AF_ADDRESS) + pcf8574_set_address(parse_pins.address); + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(pcf8574_hd44780_write(PCF8574_NO_PIN, PCF8574_NO_PIN, + parse_pins.data, parse_pins.data_len)); + if(responce_error(cb, res)) + return; + responce_ok(cb); +} + +/** + * @brief Do "devices/mhz19/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_mhz19_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + responce_error(cb, "Command does not have parameters"); + return; + } + int co2; + char *res = mhz19_read(&co2); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"co2\":%d}", co2); +} + + +/** + * @brief Do "devices/lm75/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_lm75_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) return; - float values[4]; - char *res = i2c_status_tochar(pcf8591_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); - if(responce_error(cb, res)) + if(fields & AF_ADDRESS) + lm75_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float temperature; + char *res = i2c_status_tochar(lm75_read(LM75_NO_PIN, LM75_NO_PIN, &temperature)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); +} + + +/** + * @brief Do "devices/si7021/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if(responce_error(cb, parse_res)) return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", - values[0], values[1], values[2], values[3]); - } else if( os_strcmp(command, "devices/pcf8591/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); + if(fields & AF_ADDRESS) + si7021_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float temperature; + float humidity; + char *res = i2c_status_tochar(si7021_read(SI7021_NO_PIN, SI7021_NO_PIN, &humidity, &temperature)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); +} + +/** + * @brief Do "devices/ads1115/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_ads1115_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if(responce_error(cb, parse_res)) return; - if(parse_pins.pin_value_readed != 1) { - responce_error(cb, "Unsuitable pin"); + if(fields & AF_ADDRESS) + ads1115_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float values[4]; + char *res = i2c_status_tochar(ads1115_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", + values[0], values[1], values[2], values[3]); +} + +/** + * @brief Do "devices/pcf8591/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); + if(responce_error(cb, parse_res)) return; - } if(fields & AF_ADDRESS) pcf8591_set_address(parse_pins.address); if(fields & AF_REF) { @@ -727,98 +1084,128 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co if(responce_error(cb, res)) return; } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float values[4]; + char *res = i2c_status_tochar(pcf8591_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", + values[0], values[1], values[2], values[3]); +} + + +/** + * @brief Do "devices/pcf8591/write" command. + */ +static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); + if(responce_error(cb, parse_res)) + return; + if(parse_pins.pin_value_readed != 1) { + responce_error(cb, "Unsuitable pin"); + return; + } + if(fields & AF_ADDRESS) + pcf8591_set_address(parse_pins.address); + if(fields & AF_REF) { + char *res = i2c_status_tochar(pcf8591_set_vref(parse_pins.ref)); + if(responce_error(cb, res)) return; - char *res = i2c_status_tochar(pcf8591_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(pcf8591_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); + if(responce_error(cb, res)) + return; + responce_ok(cb); +} + +/** + * @brief Do "devices/mcp4725/write" command. + */ +static void ICACHE_FLASH_ATTR do_devices_mcp4725_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); + if(responce_error(cb, parse_res)) + return; + if(parse_pins.pin_value_readed != 1) { + responce_error(cb, "Unsuitable pin"); + return; + } + if(fields & AF_ADDRESS) + mcp4725_set_address(parse_pins.address); + if(fields & AF_REF) { + char *res = i2c_status_tochar(mcp4725_set_vref(parse_pins.ref)); if(responce_error(cb, res)) return; - responce_ok(cb); - } else if( os_strcmp(command, "devices/mcp4725/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(mcp4725_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); + if(responce_error(cb, res)) + return; + responce_ok(cb); +} + +/** + * @brief Do "devices/ina219/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); if(responce_error(cb, parse_res)) return; - if(parse_pins.pin_value_readed != 1) { - responce_error(cb, "Unsuitable pin"); - return; - } if(fields & AF_ADDRESS) - mcp4725_set_address(parse_pins.address); + ina219_set_address(parse_pins.address); if(fields & AF_REF) { - char *res = i2c_status_tochar(mcp4725_set_vref(parse_pins.ref)); + char *res = i2c_status_tochar(ina219_set_shunt(parse_pins.ref)); if(responce_error(cb, res)) return; } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res = i2c_status_tochar(mcp4725_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); - if(responce_error(cb, res)) - return; - responce_ok(cb); - } else if( os_strcmp(command, "devices/ina219/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - ina219_set_address(parse_pins.address); - if(fields & AF_REF) { - char *res = i2c_status_tochar(ina219_set_shunt(parse_pins.ref)); - if(responce_error(cb, res)) - return; - } - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float voltage; - float current; - float power; - char *res = i2c_status_tochar(ina219_read(ADS1115_NO_PIN, ADS1115_NO_PIN, &voltage, ¤t, &power)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"voltage\":%f, \"current\":%f, \"power\":%f}", - voltage, current, power); - } else if( os_strcmp(command, "devices/mfrc522/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_CS) { - if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { - responce_error(cb, "Unsuitable pin"); - return; - } - } - } - MFRC522_PCD_Init(); - uint8_t bufferATQA[2]; - uint8_t bufferSize = sizeof(bufferATQA); - MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); - if(result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { - MFRC522_Uid *uid = MFRC522_Get_Uid(); - result = MFRC522_PICC_Select(uid, 0); - if(result == MFRC522_STATUS_OK) { - char hexbuf[uid->size * 2 + 1]; - unsigned int i; - for(i = 0; i < uid->size; i++) - byteToHex(uid->uidByte[i], &hexbuf[i * 2]); - hexbuf[sizeof(hexbuf) - 1] = 0; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"uid\":\"0x%s\", \"type\":\"%s\"}", hexbuf, - MFRC522_PICC_GetTypeName(MFRC522_PICC_GetType(uid->sak))); - MFRC522_PCD_AntennaOff(); - return; - } - } - MFRC522_PICC_HaltA(); - MFRC522_PCD_AntennaOff(); - responce_error(cb, MFRC522_GetStatusCodeName(result)); - } else if( (check = os_strcmp(command, "devices/mfrc522/mifare/read")) == 0 || - os_strcmp(command, "devices/mfrc522/mifare/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_ADDRESS | AF_KEY | (check ? AF_DATA : 0), &fields); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float voltage; + float current; + float power; + char *res = i2c_status_tochar(ina219_read(ADS1115_NO_PIN, ADS1115_NO_PIN, &voltage, ¤t, &power)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"voltage\":%f, \"current\":%f, \"power\":%f}", + voltage, current, power); +} + +/** + * @brief Do "devices/mfrc522/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_mfrc522_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + if(paramslen) { + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); if(responce_error(cb, parse_res)) return; if(fields & AF_CS) { @@ -827,133 +1214,306 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co return; } } - if((fields & AF_ADDRESS) == 0) { - responce_error(cb, "Block address not specified"); + } + MFRC522_PCD_Init(); + uint8_t bufferATQA[2]; + uint8_t bufferSize = sizeof(bufferATQA); + MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); + if(result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { + MFRC522_Uid *uid = MFRC522_Get_Uid(); + result = MFRC522_PICC_Select(uid, 0); + if(result == MFRC522_STATUS_OK) { + char hexbuf[uid->size * 2 + 1]; + unsigned int i; + for(i = 0; i < uid->size; i++) + byteToHex(uid->uidByte[i], &hexbuf[i * 2]); + hexbuf[sizeof(hexbuf) - 1] = 0; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"uid\":\"0x%s\", \"type\":\"%s\"}", hexbuf, + MFRC522_PICC_GetTypeName(MFRC522_PICC_GetType(uid->sak))); + MFRC522_PCD_AntennaOff(); return; } - if((fields & AF_KEY) == 0) { - // default key - os_memset(parse_pins.storage.key.key_data, 0xFF, MF_KEY_SIZE); - parse_pins.storage.key.key_len = MF_KEY_SIZE; - } else if(parse_pins.storage.key.key_len != MF_KEY_SIZE) { - responce_error(cb, "Wrong key length"); + } + MFRC522_PICC_HaltA(); + MFRC522_PCD_AntennaOff(); + responce_error(cb, MFRC522_GetStatusCodeName(result)); +} + +/** + * @brief Do "devices/mfrc522/mifare/read" and "devices/mfrc522/mifare/write" commands. + */ +static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + const int check = os_strcmp(command, "devices/mfrc522/mifare/read"); + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_CS | AF_ADDRESS | AF_KEY | (check ? AF_DATA : 0), &fields); + if(responce_error(cb, parse_res)) + return; + if(fields & AF_CS) { + if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { + responce_error(cb, "Unsuitable pin"); return; } - if(check) { - if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); - return; - } else if(parse_pins.data_len != 16) { - responce_error(cb, "Data length should be 16 bytes"); - return; - } + } + if((fields & AF_ADDRESS) == 0) { + responce_error(cb, "Block address not specified"); + return; + } + if((fields & AF_KEY) == 0) { + // default key + os_memset(parse_pins.storage.key.key_data, 0xFF, MF_KEY_SIZE); + parse_pins.storage.key.key_len = MF_KEY_SIZE; + } else if(parse_pins.storage.key.key_len != MF_KEY_SIZE) { + responce_error(cb, "Wrong key length"); + return; + } + if(check) { + if((fields & AF_DATA) == 0) { + responce_error(cb, "Data not specified"); + return; + } else if(parse_pins.data_len != 16) { + responce_error(cb, "Data length should be 16 bytes"); + return; } - MFRC522_PCD_Init(); - uint8_t bufferATQA[2]; - uint8_t bufferSize = sizeof(bufferATQA); - MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); - if(result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { - MFRC522_Uid *uid = MFRC522_Get_Uid(); - result = MFRC522_PICC_Select(uid, 0); - MIFARE_Key key; - os_memcpy(key.keyByte, parse_pins.storage.key.key_data, MF_KEY_SIZE); + } + MFRC522_PCD_Init(); + uint8_t bufferATQA[2]; + uint8_t bufferSize = sizeof(bufferATQA); + MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); + if(result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { + MFRC522_Uid *uid = MFRC522_Get_Uid(); + result = MFRC522_PICC_Select(uid, 0); + MIFARE_Key key; + os_memcpy(key.keyByte, parse_pins.storage.key.key_data, MF_KEY_SIZE); + if(result == MFRC522_STATUS_OK) { + result = MFRC522_PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, parse_pins.address, &key, uid); if(result == MFRC522_STATUS_OK) { - result = MFRC522_PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, parse_pins.address, &key, uid); + uint8_t len = (sizeof(parse_pins.data) > 0xFF) ? 0xFF : sizeof(parse_pins.data); + if(check) + result = MFRC522_MIFARE_Write(parse_pins.address, parse_pins.data, parse_pins.data_len); + else + result = MFRC522_MIFARE_Read(parse_pins.address, parse_pins.data, &len); if(result == MFRC522_STATUS_OK) { - uint8_t len = (sizeof(parse_pins.data) > 0xFF) ? 0xFF : sizeof(parse_pins.data); + parse_pins.count = len; if(check) - result = MFRC522_MIFARE_Write(parse_pins.address, parse_pins.data, parse_pins.data_len); + responce_ok(cb); else - result = MFRC522_MIFARE_Read(parse_pins.address, parse_pins.data, &len); - if(result == MFRC522_STATUS_OK) { - parse_pins.count = len; - if(check) - responce_ok(cb); - else - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); - MFRC522_PICC_HaltA(); - MFRC522_PCD_StopCrypto1(); - MFRC522_PCD_AntennaOff(); - return; - } + cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); + MFRC522_PICC_HaltA(); + MFRC522_PCD_StopCrypto1(); + MFRC522_PCD_AntennaOff(); + return; } } } - MFRC522_PICC_HaltA(); - MFRC522_PCD_StopCrypto1(); - MFRC522_PCD_AntennaOff(); - responce_error(cb, MFRC522_GetStatusCodeName(result)); - } else if( os_strcmp(command, "devices/pca9685/control") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCA9685_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_FLOATVALUES | AF_PERIOD, &fields); + } + MFRC522_PICC_HaltA(); + MFRC522_PCD_StopCrypto1(); + MFRC522_PCD_AntennaOff(); + responce_error(cb, MFRC522_GetStatusCodeName(result)); +} + +/** + * @brief Do "devices/pca9685/control" command. + */ +static void ICACHE_FLASH_ATTR do_devices_pca9685_control(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, PCA9685_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_FLOATVALUES | AF_PERIOD, &fields); + if(responce_error(cb, parse_res)) + return; + if(fields & AF_ADDRESS) + pca9685_set_address(parse_pins.address); + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(pca9685_control(PCA9685_NO_PIN, PCA9685_NO_PIN, + parse_pins.storage.float_values, parse_pins.pin_value_readed, + (fields & AF_PERIOD) ? parse_pins.periodus : PCA9685_NO_PERIOD)); + if(responce_error(cb, res)) + return; + responce_ok(cb); +} + +/** + * @brief Do "devices/mlx90614/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); if(responce_error(cb, parse_res)) return; if(fields & AF_ADDRESS) - pca9685_set_address(parse_pins.address); - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res = i2c_status_tochar(pca9685_control(PCA9685_NO_PIN, PCA9685_NO_PIN, - parse_pins.storage.float_values, parse_pins.pin_value_readed, - (fields & AF_PERIOD) ? parse_pins.periodus : PCA9685_NO_PERIOD)); - if(responce_error(cb, res)) - return; - responce_ok(cb); - } else if( os_strcmp(command, "devices/mlx90614/read") == 0 ) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) - return; - if(fields & AF_ADDRESS) - mlx90614_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - float ambient; - float object; - char *res = i2c_status_tochar(mlx90614_read(MLX90614_NO_PIN, MLX90614_NO_PIN, &ambient, &object)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"ambient\":%f, \"object\":%f}", ambient, object); - } else if(os_strcmp(command, "devices/max6675/read") == 0) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if(responce_error(cb, parse_res)) - return; - } - float temperature; - char *res = max6675_read((fields & AF_CS) ? parse_pins.CS : MAX6675_NO_PIN, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } else if(os_strcmp(command, "devices/max31855/read") == 0) { - if(paramslen) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if(responce_error(cb, parse_res)) - return; - } - float temperature; - char *res = max31855_read((fields & AF_CS) ? parse_pins.CS : MAX31855_NO_PIN, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } else if( os_strcmp(command, "devices/tm1637/write") == 0 ) { - parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); + mlx90614_set_address(parse_pins.address); + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + float ambient; + float object; + char *res = i2c_status_tochar(mlx90614_read(MLX90614_NO_PIN, MLX90614_NO_PIN, &ambient, &object)); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"ambient\":%f, \"object\":%f}", ambient, object); +} + +/** + * @brief Do "devices/max6675/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_max6675_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); if(responce_error(cb, parse_res)) return; - if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { - responce_error(cb, "Text not specified"); + } + float temperature; + char *res = max6675_read((fields & AF_CS) ? parse_pins.CS : MAX6675_NO_PIN, &temperature); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); +} + +/** + * @brief Do "devices/max31855/read" command. + */ +static void ICACHE_FLASH_ATTR do_devices_max31855_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); + if(responce_error(cb, parse_res)) return; + } + float temperature; + char *res = max31855_read((fields & AF_CS) ? parse_pins.CS : MAX31855_NO_PIN, &temperature); + if(responce_error(cb, res)) + return; + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); +} + +/** + * @brief Do "devices/tm1637/write" command. + */ +static void ICACHE_FLASH_ATTR do_devices_tm1637_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + char *parse_res = parse_params_pins_set(params, paramslen, + &parse_pins, DHADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); + if(responce_error(cb, parse_res)) + return; + if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { + responce_error(cb, "Text not specified"); + return; + } + fields |= AF_ADDRESS; + if(i2c_init(cb, fields, &parse_pins)) + return; + char *res = i2c_status_tochar(tm1636_write(TM1636_NO_PIN, TM1636_NO_PIN, + parse_pins.data, parse_pins.data_len)); + if(responce_error(cb, res)) + return; + responce_ok(cb); +} + +#endif // devices commands + +RO_DATA struct { + const char *name; + void (*func)(COMMAND_RESULT*, const char*, const char*, unsigned int); +} g_command_table[] = +{ + {"gpio/write", do_gpio_write}, + {"gpio/read", do_gpio_read}, + {"gpio/int", do_gpio_int}, + + {"adc/read", do_adc_read}, + {"adc/int", do_adc_int}, + {"pwm/control", do_pwm_control}, + + {"uart/write", do_uart_write}, + {"uart/read", do_uart_read}, + {"uart/int", do_uart_int}, + {"uart/terminal", do_uart_terminal}, + + { "i2c/master/read", do_i2c_master_read}, + { "i2c/master/write", do_i2c_master_write}, + + { "spi/master/read", do_spi_master_read}, + { "spi/master/write", do_spi_master_write}, + + { "onewire/master/read", do_onewire_master_read}, + { "onewire/master/write", do_onewire_master_write}, + { "onewire/master/search", do_onewire_master_search}, + { "onewire/master/alarm", do_onewire_master_search}, + { "onewire/master/int", do_onewire_master_int}, + { "onewire/dht/read", do_onewire_dht_read}, + { "onewire/ws2812b/write", do_onewire_ws2812b_write}, + + { "devices/ds18b20/read", do_devices_ds18b20_read}, + { "devices/dht11/read", do_devices_dht11_read}, + { "devices/dht22/read", do_devices_dht22_read}, + { "devices/bmp180/read", do_devices_bmp180_read}, + { "devices/bmp280/read", do_devices_bmp280_read}, + { "devices/bh1750/read", do_devices_bh1750_read}, + { "devices/mpu6050/read", do_devices_mpu6050_read}, + { "devices/hmc5883l/read", do_devices_hmc5883l_read}, + { "devices/pcf8574/read", do_devices_pcf8574_read}, + { "devices/pcf8574/write", do_devices_pcf8574_write}, + { "devices/pcf8574/hd44780/write", do_devices_pcf8574_hd44780_write}, + { "devices/mhz19/read", do_devices_mhz19_read}, + { "devices/lm75/read", do_devices_lm75_read}, + { "devices/si7021/read", do_devices_si7021_read}, + { "devices/ads1115/read", do_devices_ads1115_read}, + { "devices/pcf8591/read", do_devices_pcf8591_read}, + { "devices/pcf8591/write", do_devices_pcf8591_write}, + { "devices/mcp4725/write", do_devices_mcp4725_write}, + { "devices/ina219/read", do_devices_ina219_read}, + { "devices/mfrc522/read", do_devices_mfrc522_read}, + { "devices/mfrc522/mifare/read", do_devices_mfrc522_mifare_read_write}, + { "devices/mfrc522/mifare/write", do_devices_mfrc522_mifare_read_write}, + { "devices/pca9685/control", do_devices_pca9685_control}, + { "devices/mlx90614/read", do_devices_mlx90614_read}, + { "devices/max6675/read", do_devices_max6675_read}, + { "devices/max31855/read", do_devices_max31855_read}, + { "devices/tm1637/write", do_devices_tm1637_write} +}; + + +/** + * @brief Number of commands in the table. + */ +#define NUM_OF_COMMANDS (sizeof(g_command_table)/sizeof(g_command_table[0])) + + +void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) { + int i; + + dhdebug("Got command: %s %d", command, cb->data.id); + for (i = 0; i < NUM_OF_COMMANDS; ++i) { + if (0 == os_strcmp(command, g_command_table[i].name)) { + g_command_table[i].func(cb, command, params, paramslen); + return; // done } - fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res = i2c_status_tochar(tm1636_write(TM1636_NO_PIN, TM1636_NO_PIN, - parse_pins.data, parse_pins.data_len)); - if(responce_error(cb, res)) - return; - responce_ok(cb); - } else { - responce_error(cb, "Unknown command"); } + + responce_error(cb, "Unknown command"); } From 070060c078a6133782af1ea1908d4549ab2abb8b Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 14 Apr 2017 20:08:40 +0300 Subject: [PATCH 16/83] introduce swab.h module to change byte order (firmware size is 400548 instead of 400676) --- firmware-src/sources/devices/dht.c | 1 + firmware-src/sources/dhutils.c | 31 +---- firmware-src/sources/dhutils.h | 73 ++++++---- firmware-src/sources/dhzc_dnsd.c | 3 +- firmware-src/sources/dns.c | 39 +----- firmware-src/sources/dns.h | 20 --- firmware-src/sources/mdnsd.c | 7 +- firmware-src/sources/swab.c | 32 +++++ firmware-src/sources/swab.h | 209 +++++++++++++++++++++++++++++ 9 files changed, 300 insertions(+), 115 deletions(-) create mode 100644 firmware-src/sources/swab.c create mode 100644 firmware-src/sources/swab.h diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 41d0209..d736ef9 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -12,6 +12,7 @@ #include "dht.h" #include "dhonewire.h" #include "dhdebug.h" +#include "dhutils.h" #define DHT_PACKET_SIZE 5 diff --git a/firmware-src/sources/dhutils.c b/firmware-src/sources/dhutils.c index 26108fa..2819708 100644 --- a/firmware-src/sources/dhutils.c +++ b/firmware-src/sources/dhutils.c @@ -112,7 +112,7 @@ int ICACHE_FLASH_ATTR byteToHex(uint8_t val, char *hex_out) * @param[in] ch Character to convert. * @return Decimal value in range [0..15] or `-1` in case of error. */ -static inline int hex2nibble(char ch) +static inline int hex2nibble(int ch) { if ('a' <= ch && ch <= 'f') return ch - 'a' + 10; @@ -159,35 +159,6 @@ const char *ICACHE_FLASH_ATTR find_http_responce_code(const char *data, unsigned return NULL; } -unsigned int ICACHE_FLASH_ATTR unsignedInt16be(const char *buf, int pos) { - return ((int)buf[pos] * 0x100 + (int)buf[pos + 1]); -} - -int ICACHE_FLASH_ATTR signedInt16be(const char *buf, int pos) { - int r = unsignedInt16be(buf, pos); - if(r <= 0x7FFF) - return r; - return r - 0x10000; -} - -int ICACHE_FLASH_ATTR signedInt16be_sm(const char *buf, int pos) { - int r = unsignedInt16be(buf, pos); - if(r <= 0x7FFF) - return r; - return -(r & 0x7FFF); -} - -unsigned int ICACHE_FLASH_ATTR unsignedInt16le(const char *buf, int pos) { - return ((int)buf[pos] + (int)buf[pos + 1] * 0x100); -} - -int ICACHE_FLASH_ATTR signedInt16le(const char *buf, int pos) { - int r = unsignedInt16le(buf, pos); - if(r <= 0x7FFF) - return r; - return r - 0x10000; -} - void ICACHE_FLASH_ATTR delay_ms(unsigned int ms) { while( ms >= 65) { os_delay_us(65000); diff --git a/firmware-src/sources/dhutils.h b/firmware-src/sources/dhutils.h index 058de00..0483c1a 100644 --- a/firmware-src/sources/dhutils.h +++ b/firmware-src/sources/dhutils.h @@ -9,7 +9,7 @@ #ifndef _DHUTILS_H_ #define _DHUTILS_H_ -#include +#include "swab.h" /** Find maximum value */ @@ -75,48 +75,67 @@ int hexToByte(const char *hex, uint8_t *val_out); */ const char *find_http_responce_code(const char *data, unsigned short len); + /** - * \brief Read unsigned 16 bit integer from pointer. Big endian. - * \param[in] buf Pointer to data. - * \param[in] pos Offset in data. - * \return Result value. + * @brief Read unsigned 16-bits integer from pointer. Big-endian. + * @param[in] buf Pointer to data. + * @param[in] pos Offset in data. + * @return Result value. */ -unsigned int unsignedInt16be(const char *buf, int pos); +static inline unsigned int unsignedInt16be(const char *buf, int pos) { + return betoh_u16(*(const uint16_t*)(buf + pos)); +} + /** - * \brief Read signed 16 bit integer from pointer. Big endian. - * \param[in] buf Pointer to data. - * \param[in] pos Offset in data. - * \return Result value. + * @brief Read signed 16-bits integer from pointer. Big-endian. + * @param[in] buf Pointer to data. + * @param[in] pos Offset in data. + * @return Result value. */ -int signedInt16be(const char *buf, int pos); +static inline int signedInt16be(const char *buf, int pos) { + return (int16_t)betoh_u16(*(const uint16_t*)(buf + pos)); +} + /** - * \brief Read signed 16 bit integer from pointer in sign-magnitude representation. Big endian. - * \param[in] buf Pointer to data. - * \param[in] pos Offset in data. - * \return Result value. + * @brief Read signed 16-bits integer from pointer in sign-magnitude representation. Big-endian. + * @param[in] buf Pointer to data. + * @param[in] pos Offset in data. + * @return Result value. */ -int signedInt16be_sm(const char *buf, int pos); +static inline int signedInt16be_sm(const char *buf, int pos) { + int r = unsignedInt16be(buf, pos); + if(r <= 0x7FFF) + return r; + return -(r & 0x7FFF); +} + /** - * \brief Read unsigned 16 bit integer from pointer. Big endian. - * \param[in] buf Pointer to data. - * \param[in] pos Offset in data. - * \return Result value. + * @brief Read unsigned 16-bits integer from pointer. Little-endian. + * @param[in] buf Pointer to data. + * @param[in] pos Offset in data. + * @return Result value. */ -unsigned int unsignedInt16le(const char *buf, int pos); +static inline unsigned int unsignedInt16le(const char *buf, int pos) { + return letoh_u16(*(const uint16_t*)(buf + pos)); +} + /** - * \brief Read signed 16 bit integer from pointer. Big endian. - * \param[in] buf Pointer to data. - * \param[in] pos Offset in data. - * \return Result value. + * @brief Read signed 16-bits integer from pointer. Little-endian. + * @param[in] buf Pointer to data. + * @param[in] pos Offset in data. + * @return Result value. */ -int signedInt16le(const char *buf, int pos); +static inline int signedInt16le(const char *buf, int pos) { + return (int16_t)letoh_u16(*(const uint16_t*)(buf + pos)); +} + /** - * \brief Delay in milliseconds. + * @brief Delay in milliseconds. */ void delay_ms(unsigned int ms); diff --git a/firmware-src/sources/dhzc_dnsd.c b/firmware-src/sources/dhzc_dnsd.c index 3c82009..efee27f 100644 --- a/firmware-src/sources/dhzc_dnsd.c +++ b/firmware-src/sources/dhzc_dnsd.c @@ -14,6 +14,7 @@ #include #include #include "dns.h" +#include "swab.h" #include "dhdebug.h" #include "dhzc_dnsd.h" @@ -27,7 +28,7 @@ LOCAL char *mDNSAnswerBuffer; LOCAL int ICACHE_FLASH_ATTR dnsd_answer(char *data, unsigned int len) { // always add response with host address data to the end DNS_HEADER *header = (DNS_HEADER *)data; - header->answersNumber = htobe_16(1); + header->answersNumber = htobe_u16(1); header->authoritiesNumber = 0; header->resourcesNumber = 0; header->flags.responseFlag = 1; diff --git a/firmware-src/sources/dns.c b/firmware-src/sources/dns.c index 6546d25..e358d61 100644 --- a/firmware-src/sources/dns.c +++ b/firmware-src/sources/dns.c @@ -9,40 +9,11 @@ #include "dns.h" +#include "swab.h" #include const uint8_t LOCAL_DOMAIN[] = "local"; -uint32_t ICACHE_FLASH_ATTR htobe_32(uint32_t n) { - uint32_t res; - uint8_t *p = (uint8_t *)&res; - p[3] = n & 0xFF; - n >>= 8; - p[2] = n & 0xFF; - n >>= 8; - p[1] = n & 0xFF; - n >>= 8; - p[0] = n & 0xFF; - return res; -} - -uint16_t ICACHE_FLASH_ATTR htobe_16(uint16_t n) { - uint16_t res; - uint8_t *p = (uint8_t *)&res; - p[1] = n & 0xFF; - n >>= 8; - p[0] = n & 0xFF; - return res; -} - -uint16_t ICACHE_FLASH_ATTR betoh_16(uint16_t n) { - uint16_t res; - uint8_t *p = (uint8_t *)&n; - res = p[0]; - res <<= 8; - res |= p[1]; - return res; -} LOCAL uint32_t to_fqdn(uint8_t *buf, const uint8_t *d) { uint32_t pos; pos = 1; @@ -95,9 +66,9 @@ uint32_t ICACHE_FLASH_ATTR dns_add_answer(uint8_t *buf, const uint8_t *name1, } } DNS_ANSWER *resp = (DNS_ANSWER *)&buf[pos]; - resp->type = htobe_16(type); - resp->class = htobe_16(1); // IN - class - resp->ttl = htobe_32(ttl); + resp->type = htobe_u16(type); + resp->class = htobe_u16(1); // IN - class + resp->ttl = htobe_u32(ttl); // resp->size see below pos += sizeof(DNS_ANSWER); uint32_t datapos = pos; @@ -115,7 +86,7 @@ uint32_t ICACHE_FLASH_ATTR dns_add_answer(uint8_t *buf, const uint8_t *name1, pos--; pos += to_fqdn_local(&buf[pos], data3); } - resp->size = htobe_16(pos - datapos); + resp->size = htobe_u16(pos - datapos); return pos; } diff --git a/firmware-src/sources/dns.h b/firmware-src/sources/dns.h index ea65cb2..0d3fb81 100644 --- a/firmware-src/sources/dns.h +++ b/firmware-src/sources/dns.h @@ -79,26 +79,6 @@ typedef enum { DNS_TYPE_SRV = 0x21 } DNS_TYPE; -/** - * \brief Convert host 32 bit value to 32 bit big endian value - * \param[in] n Host value. - * \return Big endian value. - */ -uint32_t htobe_32(uint32_t n); - -/** - * \brief Convert host 16 bit value to 16 bit big endian value - * \param[in] n Host value. - * \return Big endian value. - */ -uint16_t htobe_16(uint16_t n); - -/** - * \brief Convert 16 bit big endian value to host 16 bit value - * \param[in] n Big endian value. - * \return Host value. - */ -uint16_t betoh_16(uint16_t n); /** * \brief Fill response with one record. diff --git a/firmware-src/sources/mdnsd.c b/firmware-src/sources/mdnsd.c index 33cfc49..7b5f308 100644 --- a/firmware-src/sources/mdnsd.c +++ b/firmware-src/sources/mdnsd.c @@ -15,6 +15,7 @@ #include #include "mdnsd.h" #include "dns.h" +#include "swab.h" #include "snprintf.h" #include "dhdebug.h" #include "user_config.h" @@ -54,7 +55,7 @@ LOCAL void ICACHE_FLASH_ATTR mdnsd_recv_cb(void *arg, char *data, unsigned short uint8_t responsebuff[MDNS_MAX_PACKET_LENGTH]; DNS_HEADER *response = (DNS_HEADER *)responsebuff; - uint16_t qd = betoh_16(request->questionsNumber); + uint16_t qd = betoh_u16(request->questionsNumber); uint32_t i; uint32_t offset = 0; uint32_t data_len = len - sizeof(DNS_HEADER); @@ -104,7 +105,7 @@ LOCAL void ICACHE_FLASH_ATTR mdnsd_recv_cb(void *arg, char *data, unsigned short case DNS_TYPE_SRV: if(dns_cmp_fqdn_str(&request->data[offset], mName, MDNS_SERVICE)) { SRV_DATA srv; - srv.port = htobe_16( MDNS_SERVICE_PORT ); + srv.port = htobe_u16( MDNS_SERVICE_PORT ); srv.priority = 0; srv.weigth = 0; alen += dns_add_answer(&response->data[alen], mName, @@ -142,7 +143,7 @@ LOCAL void ICACHE_FLASH_ATTR mdnsd_recv_cb(void *arg, char *data, unsigned short os_memset(response, 0, sizeof(DNS_HEADER)); response->flags.authoritiveAnswer = 1; response->flags.responseFlag = 1; - response->answersNumber = htobe_16(answersNumber); + response->answersNumber = htobe_u16(answersNumber); announce(responsebuff, alen + sizeof(DNS_HEADER)); } } diff --git a/firmware-src/sources/swab.c b/firmware-src/sources/swab.c new file mode 100644 index 0000000..651d7ca --- /dev/null +++ b/firmware-src/sources/swab.c @@ -0,0 +1,32 @@ +/** @file + * @brief Helper module to work with big-endian/little-endian numbers. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Sergey Polichnoy + */ +#include "swab.h" + + +/** + * @brief Swap byte-order of 32-bits value. + * @param[in] x Input value: `0xAABBCCDD`. + * @return Output value: `0xDDCCBBAA`. + */ +uint32_t ICACHE_FLASH_ATTR swab_u32(uint32_t x) +{ + return (((x>>24)&0xFF) << 0) + | (((x>>16)&0xFF) << 8) + | (((x>>8)&0xFF) << 16) + | (((x>>0)&0xFF) << 24); +} + + +/** + * @brief Swap byte-order of 16-bits value. + * @param[in] x Input value: `0xAABB`. + * @return Output value: `0xBBAA`. + */ +uint16_t ICACHE_FLASH_ATTR swab_u16(uint16_t x) +{ + return (((x>>8)&0xFF) << 0) + | (((x>>0)&0xFF) << 8); +} diff --git a/firmware-src/sources/swab.h b/firmware-src/sources/swab.h new file mode 100644 index 0000000..d3cf7eb --- /dev/null +++ b/firmware-src/sources/swab.h @@ -0,0 +1,209 @@ +/** @file + * @brief Helper module to work with big-endian/little-endian numbers. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Sergey Polichnoy + */ +#ifndef _SWAB_H_ +#define _SWAB_H_ + +#include + + +/** + * @brief Swap byte-order of 32-bits value. + * @param[in] x Input value: `0xAABBCCDD`. + * @return Output value: `0xDDCCBBAA`. + */ +uint32_t swab_u32(uint32_t x); + + +/** + * @brief Swap byte-order of 16-bits value. + * @param[in] x Input value: `0xAABB`. + * @return Output value: `0xBBAA`. + */ +uint16_t swab_u16(uint16_t x); + + +#if 1 // CPU is little-endian + +/** + * @brief Convert host to big-endian (32-bits). + * @param[in] h Host value. + * @return Big-endian value. + */ +static inline uint32_t htobe_u32(uint32_t h) +{ + return swab_u32(h); +} + + +/** + * @brief Convert big-endian to host (32 bits). + * @param[in] be Big-endian value. + * @return Host value. + */ +static inline uint32_t betoh_u32(uint32_t be) +{ + return swab_u32(be); +} + + +/** + * @brief Convert host to big-endian (16 bits). + * @param[in] h Host value. + * @return Big-endian value. + */ +static inline uint16_t htobe_u16(uint16_t h) +{ + return swab_u16(h); +} + + +/** + * @brief Convert big-endian to host (16 bits). + * @param[in] be Big-endian value. + * @return Host value. + */ +static inline uint16_t betoh_u16(uint16_t be) +{ + return swab_u16(be); +} + + + +/** + * @brief Convert host to little-endian (32-bits). + * @param[in] h Host value. + * @return Little-endian value. + */ +static inline uint32_t htole_u32(uint32_t h) +{ + return h; +} + + +/** + * @brief Convert little-endian to host (32 bits). + * @param[in] le Little-endian value. + * @return Host value. + */ +static inline uint32_t letoh_u32(uint32_t le) +{ + return le; +} + + +/** + * @brief Convert host to little-endian (16 bits). + * @param[in] h Host value. + * @return Little-endian value. + */ +static inline uint16_t htole_u16(uint16_t h) +{ + return h; +} + + +/** + * @brief Convert little-endian to host (16 bits). + * @param[in] le Little-endian value. + * @return Host value. + */ +static inline uint16_t letoh_u16(uint16_t le) +{ + return le; +} + +#else // CPU is big-endian + +/** + * @brief Convert host to big-endian (32-bits). + * @param[in] h Host value. + * @return Big-endian value. + */ +static inline uint32_t htobe_u32(uint32_t h) +{ + return h; +} + + +/** + * @brief Convert big-endian to host (32 bits). + * @param[in] be Big-endian value. + * @return Host value. + */ +static inline uint32_t betoh_u16(uint32_t be) +{ + return be; +} + + +/** + * @brief Convert host to big-endian (16 bits). + * @param[in] h Host value. + * @return Big-endian value. + */ +static inline uint16_t htobe_u16(uint16_t h) +{ + return h; +} + + +/** + * @brief Convert big-endian to host (16 bits). + * @param[in] be Big-endian value. + * @return Host value. + */ +static inline uint16_t betoh_u16(uint16_t be) +{ + return be; +} + + +/** + * @brief Convert host to little-endian (32-bits). + * @param[in] h Host value. + * @return Little-endian value. + */ +static inline uint32_t htole_u32(uint32_t h) +{ + return swab_u32(h); +} + + +/** + * @brief Convert little-endian to host (32 bits). + * @param[in] le Little-endian value. + * @return Host value. + */ +static inline uint32_t letoh_u32(uint32_t le) +{ + return swab_u32(le); +} + + +/** + * @brief Convert host to little-endian (16 bits). + * @param[in] h Host value. + * @return Little-endian value. + */ +static inline uint16_t htole_u16(uint16_t h) +{ + return swab_u16(h); +} + + +/** + * @brief Convert little-endian to host (16 bits). + * @param[in] le Little-endian value. + * @return Host value. + */ +static inline uint16_t letoh_u16(uint16_t le) +{ + return swab_u16(le); +} + +#endif // CPU + +#endif /* _SWAB_H_ */ From f77641997f6dc306d9d9ae60d5f15f9e1c58f696 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 18 Apr 2017 14:46:47 +0300 Subject: [PATCH 17/83] fix tests: do not check output on spi/master/read some boards return 0x00, some 0xff. --- firmware-tests/requests.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware-tests/requests.html b/firmware-tests/requests.html index d5b3940..8f685da 100644 --- a/firmware-tests/requests.html +++ b/firmware-tests/requests.html @@ -136,14 +136,14 @@ addtest("i2c/master/write", {"address":"EE","data":"AA==","SDA":0,"SCL":0}, false, "Wrong parameters"); addtest("i2c/master/write", {"address":"0xFF","data":"AA==","SDA":0,"SCL":2}, false, "ACK response not detected"); addtest("i2c/master/write", {"address":"0xFF","data":"AA==","SDA":0,"SCL":22}, false, "Wrong parameters"); - addtest("spi/master/read", {"count": 1}, true, {"data":"/w=="}); - addtest("spi/master/read", {"count": 1, "CS":"x"}, true, {"data":"/w=="}); - addtest("spi/master/read", {"count": 3}, true, {"data":"////"}); + addtest("spi/master/read", {"count": 1}, true, null); + addtest("spi/master/read", {"count": 1, "CS":"x"}, true, null); + addtest("spi/master/read", {"count": 3}, true, null); addtest("spi/master/read", {"count": 3,"CS":333}, false, "Wrong CS pin"); addtest("spi/master/read", null, false, "No parameters specified"); addtest("spi/master/read", {"count": 3,"gfdgfd":333}, false, "Wrong argument"); addtest("spi/master/read", {"count": 3,"mode":4}, false, "Wrong SPI mode"); - addtest("spi/master/read", {"count": 2,"mode":0, "data":"YWI=", "CS":"2"}, true, {"data":"//8="}); + addtest("spi/master/read", {"count": 2,"mode":0, "data":"YWI=", "CS":"2"}, true, null); addtest("spi/master/read", {"count": 2,"mode":0, "data":"123"}, false, "Data is broken"); addtest("spi/master/read", {"count": 1024}, false, "Wrong read size"); addtest("spi/master/write", {"mode":0, "data":"AA==", "CS":2}, true, ""); From 84e4956156b7dc1530342aea09a6b6f0149b9213 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 18 Apr 2017 16:46:24 +0300 Subject: [PATCH 18/83] important to use void for functions with no arguments `void foo(void);` --- firmware-src/sources/custom_firmware.c | 2 +- firmware-src/sources/dhadc.c | 2 +- firmware-src/sources/dhadc.h | 2 +- firmware-src/sources/dhap.c | 2 +- firmware-src/sources/dhconnector.c | 8 +++--- firmware-src/sources/dhconnector.h | 6 ++--- firmware-src/sources/dhconnector_websocket.c | 6 ++--- firmware-src/sources/dhconnector_websocket.h | 2 +- firmware-src/sources/dhgpio.c | 27 ++++--------------- firmware-src/sources/dhgpio.h | 25 ++++++++++++++--- firmware-src/sources/dhi2c.c | 6 ++--- firmware-src/sources/dhi2c.h | 2 +- firmware-src/sources/dhmem.c | 16 ++++------- firmware-src/sources/dhmem.h | 10 +++---- firmware-src/sources/dhonewire.c | 6 ++--- firmware-src/sources/dhonewire.h | 2 +- firmware-src/sources/dhpwm.c | 8 +++--- firmware-src/sources/dhpwm.h | 2 +- firmware-src/sources/dhsender.c | 6 ++--- firmware-src/sources/dhsender.h | 8 +++--- firmware-src/sources/dhsender_queue.c | 4 +-- firmware-src/sources/dhsender_queue.h | 4 +-- firmware-src/sources/dhsettings.c | 14 +++++----- firmware-src/sources/dhsettings.h | 14 +++++----- firmware-src/sources/dhstatistic.c | 2 +- firmware-src/sources/dhstatistic.h | 2 +- firmware-src/sources/dhterminal.c | 16 +++++------ firmware-src/sources/dhterminal.h | 10 +++---- firmware-src/sources/dhterminal_commandline.c | 2 +- firmware-src/sources/dhterminal_commands.c | 2 +- firmware-src/sources/dhterminal_commands.h | 2 +- firmware-src/sources/dhterminal_configure.c | 2 +- firmware-src/sources/dhterminal_configure.h | 2 +- firmware-src/sources/dhuart.c | 10 +++---- firmware-src/sources/dhuart.h | 4 +-- firmware-src/sources/dhzc_dnsd.c | 2 +- firmware-src/sources/dhzc_dnsd.h | 2 +- firmware-src/sources/dhzc_web.c | 2 +- firmware-src/sources/dhzc_web.h | 2 +- firmware-src/sources/mdnsd.c | 2 +- firmware-src/sources/mdnsd.h | 2 +- firmware-src/sources/rand.c | 2 +- firmware-src/sources/rand.h | 2 +- firmware-src/sources/webserver.c | 2 +- firmware-src/sources/webserver.h | 2 +- 45 files changed, 126 insertions(+), 132 deletions(-) diff --git a/firmware-src/sources/custom_firmware.c b/firmware-src/sources/custom_firmware.c index 6014b2a..8750741 100644 --- a/firmware-src/sources/custom_firmware.c +++ b/firmware-src/sources/custom_firmware.c @@ -15,7 +15,7 @@ #include "c_types.h" #include "osapi.h" -HTTP_REQUEST * ICACHE_FLASH_ATTR custom_firmware_request() { +HTTP_REQUEST * ICACHE_FLASH_ATTR custom_firmware_request(void) { // reimplement this method to return actual HTTP_REQUEST to make custom notification firmware return 0; } diff --git a/firmware-src/sources/dhadc.c b/firmware-src/sources/dhadc.c index f19017f..e892332 100644 --- a/firmware-src/sources/dhadc.c +++ b/firmware-src/sources/dhadc.c @@ -14,7 +14,7 @@ LOCAL os_timer_t mADCTimer; -float ICACHE_FLASH_ATTR dhadc_get_value(){ +float ICACHE_FLASH_ATTR dhadc_get_value(void){ return system_adc_read()/1024.0f; } diff --git a/firmware-src/sources/dhadc.h b/firmware-src/sources/dhadc.h index e84a6f7..102a0d1 100644 --- a/firmware-src/sources/dhadc.h +++ b/firmware-src/sources/dhadc.h @@ -16,7 +16,7 @@ * \brief Get ADC value. * \return Voltage in volts. */ -float dhadc_get_value(); +float dhadc_get_value(void); /** * \brief Start loop measurement with some interval. diff --git a/firmware-src/sources/dhap.c b/firmware-src/sources/dhap.c index f713d63..551a746 100644 --- a/firmware-src/sources/dhap.c +++ b/firmware-src/sources/dhap.c @@ -65,6 +65,6 @@ void ICACHE_FLASH_ATTR dhap_init(const char *ssid, const char *password) { dhdebug("Access point is initialized at %d.%d.%d.%d", bip[0], bip[1], bip[2], bip[3]); } -const struct ip_info * dhap_get_ip_info() { +const struct ip_info * dhap_get_ip_info(void) { return ipinfo; } diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index 86b02df..9bf4c7a 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -78,7 +78,7 @@ LOCAL void ICACHE_FLASH_ATTR parse_json(struct jsonparse_state *jparser) { } } -LOCAL void ICACHE_FLASH_ATTR ws_error() { +LOCAL void ICACHE_FLASH_ATTR ws_error(void) { dhstat_got_server_error(); // close connection and restart everything on error espconn_disconnect(&mDHConnector); @@ -260,7 +260,7 @@ LOCAL void ICACHE_FLASH_ATTR start_resolve_dh_server(const char *server) { } } -void ICACHE_FLASH_ATTR dhmem_unblock_cb() { +void ICACHE_FLASH_ATTR dhmem_unblock_cb(void) { if(mNeedRecover) { set_state(mConnectionState); mNeedRecover = 0; @@ -337,7 +337,7 @@ LOCAL void ICACHE_FLASH_ATTR wifi_state_cb(System_Event_t *event) { } } -void ICACHE_FLASH_ATTR dhconnector_init() { +void ICACHE_FLASH_ATTR dhconnector_init(void) { mConnectionState = CS_DISCONNECT; wifi_set_opmode(STATION_MODE); @@ -369,6 +369,6 @@ void ICACHE_FLASH_ATTR dhconnector_init() { wifi_set_event_handler_cb(wifi_state_cb); } -CONNECTION_STATE ICACHE_FLASH_ATTR dhconnector_get_state() { +CONNECTION_STATE ICACHE_FLASH_ATTR dhconnector_get_state(void) { return mConnectionState; } diff --git a/firmware-src/sources/dhconnector.h b/firmware-src/sources/dhconnector.h index f09e774..d8eaccd 100644 --- a/firmware-src/sources/dhconnector.h +++ b/firmware-src/sources/dhconnector.h @@ -24,18 +24,18 @@ typedef enum { /** * \brief Initializes connector, parameters are taken from permanent storage. */ -void dhconnector_init(); +void dhconnector_init(void); /** * \brief Get connector current state. * \return Current state value from CONNECTION_STATE enum. */ -CONNECTION_STATE dhconnector_get_state(); +CONNECTION_STATE dhconnector_get_state(void); /** * \brief Callback for custom firmware. If callback returns non null request, it will be sent instead poll request. * \return HTTP request for DH server or null to keep normal mode. */ -HTTP_REQUEST *custom_firmware_request(); +HTTP_REQUEST *custom_firmware_request(void); #endif /* _DHCONNECTOR_H_ */ diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c index 62c3c3b..96fa36a 100644 --- a/firmware-src/sources/dhconnector_websocket.c +++ b/firmware-src/sources/dhconnector_websocket.c @@ -46,7 +46,7 @@ LOCAL void ICACHE_FLASH_ATTR error(data, len) { dhdebug("%s", b); } -LOCAL void ICACHE_FLASH_ATTR mask() { +LOCAL void ICACHE_FLASH_ATTR mask(void) { uint32_t *mask = (uint32_t *)&mBuf[WEBSOCKET_HEADER_MAX_SIZE]; *mask = rand(); int i, j; @@ -57,7 +57,7 @@ LOCAL void ICACHE_FLASH_ATTR mask() { } } -LOCAL void ICACHE_FLASH_ATTR send_payload() { +LOCAL void ICACHE_FLASH_ATTR send_payload(void) { if(mPayLoadBufLen <= 0) { return; } else if(mPayLoadBufLen < 126) { @@ -75,7 +75,7 @@ LOCAL void ICACHE_FLASH_ATTR send_payload() { } } -LOCAL void ICACHE_FLASH_ATTR check_queue() { +LOCAL void ICACHE_FLASH_ATTR check_queue(void) { dhsender_current_success(); SENDER_JSON_DATA *data = dhsender_next(); if(data) { diff --git a/firmware-src/sources/dhconnector_websocket.h b/firmware-src/sources/dhconnector_websocket.h index 1df1a8e..0cecbe8 100644 --- a/firmware-src/sources/dhconnector_websocket.h +++ b/firmware-src/sources/dhconnector_websocket.h @@ -12,7 +12,7 @@ /** Function prototype for sending data. */ typedef void (*dhconnector_websocket_send_proto)(const char *data, unsigned int len); /** Function prototype for error callback. */ -typedef void (*dhconnector_websocket_error)(); +typedef void (*dhconnector_websocket_error)(void); /** * \brief Initialize devicehive WebSocket protocol exchange diff --git a/firmware-src/sources/dhgpio.c b/firmware-src/sources/dhgpio.c index 4ad1f8b..a8b3015 100644 --- a/firmware-src/sources/dhgpio.c +++ b/firmware-src/sources/dhgpio.c @@ -9,6 +9,7 @@ * Description: GPIO module * */ +#include "dhgpio.h" #include #include @@ -17,27 +18,9 @@ #include "user_config.h" #include "dhdebug.h" #include "dhnotification.h" -#include "dhgpio.h" #include "dhpwm.h" #include "dhmem.h" -#define PIN_GPIOO (1 << 0) -#define PIN_GPIO1 (1 << 1) -#define PIN_GPIO2 (1 << 2) -#define PIN_GPIO3 (1 << 3) -#define PIN_GPIO4 (1 << 4) -#define PIN_GPIO5 (1 << 5) -#define PIN_GPIO6 (1 << 6) -#define PIN_GPIO7 (1 << 7) -#define PIN_GPIO8 (1 << 8) -#define PIN_GPIO9 (1 << 9) -#define PIN_GPIO10 (1 << 10) -#define PIN_GPIO11 (1 << 11) -#define PIN_GPIO12 (1 << 12) -#define PIN_GPIO13 (1 << 13) -#define PIN_GPIO14 (1 << 14) -#define PIN_GPIO15 (1 << 15) - LOCAL os_timer_t mGPIOTimer; LOCAL unsigned int mGPIOTimerTimeout = 250; LOCAL unsigned int mTriggeredIntrPins = 0; @@ -72,7 +55,7 @@ void ICACHE_FLASH_ATTR dhgpio_prepare_pins(unsigned int pin_mask, int disable_pw void ICACHE_FLASH_ATTR dhgpio_open_drain(unsigned int pin_mask_set_od, unsigned int pin_mask_unset_od) { int i; for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - unsigned int pin = 1 << i; + unsigned int pin = BIT(i); if(pin & DHGPIO_SUITABLE_PINS == 0) continue; if(pin & pin_mask_set_od) { @@ -153,7 +136,7 @@ int ICACHE_FLASH_ATTR dhgpio_initialize(unsigned int init_mask, unsigned int pol return 1; } -unsigned int ICACHE_FLASH_ATTR dhgpio_read() { +unsigned int ICACHE_FLASH_ATTR dhgpio_read(void) { return gpio_input_get() & DHGPIO_SUITABLE_PINS; } @@ -223,11 +206,11 @@ int ICACHE_FLASH_ATTR dhgpio_int(unsigned int disable_mask, unsigned int rising_ return 1; } -unsigned int ICACHE_FLASH_ATTR dhgpio_get_timeout() { +unsigned int ICACHE_FLASH_ATTR dhgpio_get_timeout(void) { return mGPIOTimerTimeout; } -void ICACHE_FLASH_ATTR dhgpio_init() { +void ICACHE_FLASH_ATTR dhgpio_init(void) { ETS_GPIO_INTR_ATTACH(gpio_intr, NULL); ETS_GPIO_INTR_ENABLE(); } diff --git a/firmware-src/sources/dhgpio.h b/firmware-src/sources/dhgpio.h index 3d3f395..2e256ee 100644 --- a/firmware-src/sources/dhgpio.h +++ b/firmware-src/sources/dhgpio.h @@ -9,15 +9,34 @@ #ifndef _DHGPIO_H_ #define _DHGPIO_H_ +#include + /** Bitwise pin mask for pin that can be used. */ #define DHGPIO_SUITABLE_PINS 0b1111000000111111 // GPIO0-GPIO5, GPIO12-GPIO15 /** Last pin number. */ #define DHGPIO_MAXGPIONUM 15 +#define PIN_GPIOO BIT(0) +#define PIN_GPIO1 BIT(1) +#define PIN_GPIO2 BIT(2) +#define PIN_GPIO3 BIT(3) +#define PIN_GPIO4 BIT(4) +#define PIN_GPIO5 BIT(5) +#define PIN_GPIO6 BIT(6) +#define PIN_GPIO7 BIT(7) +#define PIN_GPIO8 BIT(8) +#define PIN_GPIO9 BIT(9) +#define PIN_GPIO10 BIT(10) +#define PIN_GPIO11 BIT(11) +#define PIN_GPIO12 BIT(12) +#define PIN_GPIO13 BIT(13) +#define PIN_GPIO14 BIT(14) +#define PIN_GPIO15 BIT(15) + /** * \brief Initialize GPIO. */ -void dhgpio_init(); +void dhgpio_init(void); /** * \brief Prepare pins for using as GPIO. @@ -61,7 +80,7 @@ int dhgpio_initialize(unsigned int init_mask, unsigned int pollup_mask, unsigned * \brief Read GPIO pins state * \return Bitwise bit mask of input. */ -unsigned int dhgpio_read(); +unsigned int dhgpio_read(void); /** * \brief Enable GPIO interruption. @@ -78,7 +97,7 @@ int dhgpio_int(unsigned int disable_mask, unsigned int rising_mask, unsigned int * \brief Get current GPIO inerruption timeout. * \return Timeout in milliseconds. */ -unsigned int dhgpio_get_timeout(); +unsigned int dhgpio_get_timeout(void); /** * \brief Interruption callback. diff --git a/firmware-src/sources/dhi2c.c b/firmware-src/sources/dhi2c.c index 3679eb0..4f86672 100644 --- a/firmware-src/sources/dhi2c.c +++ b/firmware-src/sources/dhi2c.c @@ -35,7 +35,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_init(unsigned int sda_pin, unsigned int scl return DHI2C_OK; } -void ICACHE_FLASH_ATTR dhi2c_reinit() { +void ICACHE_FLASH_ATTR dhi2c_reinit(void) { dhgpio_open_drain(mSDAPin | mSCLPin, 0); dhgpio_prepare_pins(mSDAPin | mSCLPin, 1); dhgpio_pull(mSDAPin | mSCLPin, 0); @@ -60,7 +60,7 @@ LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_set_pin(unsigned int pin_mask, int va return DHI2C_BUS_BUSY; } -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_start() { +LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_start(void) { DHI2C_STATUS res; res = dhi2c_set_pin(mSDAPin, 1); if(res != DHI2C_OK) @@ -77,7 +77,7 @@ LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_start() { return DHI2C_OK; } -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_stop() { +LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_stop(void) { DHI2C_STATUS res; res = dhi2c_set_pin(mSDAPin, 0); if(res != DHI2C_OK) diff --git a/firmware-src/sources/dhi2c.h b/firmware-src/sources/dhi2c.h index ee2cdd6..0902742 100644 --- a/firmware-src/sources/dhi2c.h +++ b/firmware-src/sources/dhi2c.h @@ -29,7 +29,7 @@ DHI2C_STATUS dhi2c_init(unsigned int sda_pin, unsigned int scl_pin); /** * \brief Prepare last successfully prepared pins for usage with I2C. */ -void dhi2c_reinit(); +void dhi2c_reinit(void); /** * \brief Write data to I2C bus. diff --git a/firmware-src/sources/dhmem.c b/firmware-src/sources/dhmem.c index d37ec49..f16b9bc 100644 --- a/firmware-src/sources/dhmem.c +++ b/firmware-src/sources/dhmem.c @@ -8,30 +8,24 @@ * Description: Memory observer module * */ - -#define DHREQUEST_RAM_RESERVE 7168 -#define DHRECOVER_RAM_SIZE 12288 +#include "dhmem.h" #include #include -#include -#include "dhmem.h" -#include "dhdebug.h" -#include "dhsender_queue.h" -LOCAL unsigned int mGlobalBlock = 0; +static int mGlobalBlock = 0; -void ICACHE_FLASH_ATTR dhmem_block() { +void ICACHE_FLASH_ATTR dhmem_block(void) { mGlobalBlock = 1; ETS_GPIO_INTR_DISABLE(); } -void ICACHE_FLASH_ATTR dhmem_unblock() { +void ICACHE_FLASH_ATTR dhmem_unblock(void) { mGlobalBlock = 0; dhmem_unblock_cb(); ETS_GPIO_INTR_ENABLE(); } -int ICACHE_FLASH_ATTR dhmem_isblock() { +int ICACHE_FLASH_ATTR dhmem_isblock(void) { return mGlobalBlock; } diff --git a/firmware-src/sources/dhmem.h b/firmware-src/sources/dhmem.h index 5f9181f..e05799b 100644 --- a/firmware-src/sources/dhmem.h +++ b/firmware-src/sources/dhmem.h @@ -10,27 +10,25 @@ #ifndef _DHMEM_H_ #define _DHMEM_H_ -#include "dhrequest.h" - /** * \brief Activate memory save mode */ -void dhmem_block(); +void dhmem_block(void); /** * \brief Deactivate memory save mode */ -void dhmem_unblock(); +void dhmem_unblock(void); /** * \brief Check memory status good and new request allocation is possible. * \return Non zero if memory status is bad and allocation of new requests should be blocked. Zero otherwise. */ -int dhmem_isblock(); +int dhmem_isblock(void); /** * \brief Callback that will be called when allocation is possible again. */ -extern void dhmem_unblock_cb(); +void dhmem_unblock_cb(void); #endif /* _DHMEM_H_ */ diff --git a/firmware-src/sources/dhonewire.c b/firmware-src/sources/dhonewire.c index 37035e7..db227b1 100644 --- a/firmware-src/sources/dhonewire.c +++ b/firmware-src/sources/dhonewire.c @@ -31,12 +31,12 @@ LOCAL os_timer_t mOWIntTimer; #define ONEWIRE_DHT_RESET_LENGTH_US 25000 #define ONEWIRE_DHT_TIMEOUT_US 200 -LOCAL ICACHE_FLASH_ATTR lock_int() { +LOCAL ICACHE_FLASH_ATTR lock_int(void) { if(mIntPins) dhgpio_subscribe_extra_int(mIntPins, 0, 0, 0); } -LOCAL ICACHE_FLASH_ATTR unlock_int() { +LOCAL ICACHE_FLASH_ATTR unlock_int(void) { GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, mIntPins); dhgpio_subscribe_extra_int(0, 0, mIntPins, 0); } @@ -48,7 +48,7 @@ int ICACHE_FLASH_ATTR dhonewire_set_pin(unsigned int pin) { return 1; } -int ICACHE_FLASH_ATTR dhonewire_get_pin() { +int ICACHE_FLASH_ATTR dhonewire_get_pin(void) { return mOneWirePin; } diff --git a/firmware-src/sources/dhonewire.h b/firmware-src/sources/dhonewire.h index 08408b5..9f1c406 100644 --- a/firmware-src/sources/dhonewire.h +++ b/firmware-src/sources/dhonewire.h @@ -21,7 +21,7 @@ int dhonewire_set_pin(unsigned int pin); * \brief Get pin that configured for onewire. * \return Pin number. */ -int dhonewire_get_pin(); +int dhonewire_get_pin(void); /** * \brief Write data to onewire bus. diff --git a/firmware-src/sources/dhpwm.c b/firmware-src/sources/dhpwm.c index cb9f00b..af8890f 100644 --- a/firmware-src/sources/dhpwm.c +++ b/firmware-src/sources/dhpwm.c @@ -35,12 +35,12 @@ LOCAL unsigned char mPwmInUse = 0; LOCAL unsigned int mTotalCount = 0; LOCAL uint32 mUsedPins = 0; -void ICACHE_FLASH_ATTR disarm_pwm_timer() { +void ICACHE_FLASH_ATTR disarm_pwm_timer(void) { TM1_EDGE_INT_DISABLE(); ETS_FRC1_INTR_DISABLE(); } -void on_timer() { +void on_timer(void) { if(mCounter == 0) { if(mTotalCount) { mTotalCount--; @@ -68,7 +68,7 @@ void on_timer() { mCounter = 0; } -void ICACHE_FLASH_ATTR arm_pwm_timer() { +void ICACHE_FLASH_ATTR arm_pwm_timer(void) { // use mFrequency mPwmInUse = 1; mCounter = 1; @@ -119,7 +119,7 @@ int ICACHE_FLASH_ATTR dhpwm_set_pwm(unsigned int *pinsduty, unsigned int pinsmas return 1; } -unsigned int ICACHE_FLASH_ATTR dhpwm_get_period_us() { +unsigned int ICACHE_FLASH_ATTR dhpwm_get_period_us(void) { return mPeriodUs; } diff --git a/firmware-src/sources/dhpwm.h b/firmware-src/sources/dhpwm.h index 9564a2f..ccdad94 100644 --- a/firmware-src/sources/dhpwm.h +++ b/firmware-src/sources/dhpwm.h @@ -29,7 +29,7 @@ int dhpwm_set_pwm(unsigned int *pinsduty, unsigned int pinsmask, unsigned int pe * \brief Get current PWM period. * \return PWM period in microseconds. */ -unsigned int dhpwm_get_period_us(); +unsigned int dhpwm_get_period_us(void); /** * \brief Stops PWM for specified pins. diff --git a/firmware-src/sources/dhsender.c b/firmware-src/sources/dhsender.c index 0a5c2d7..54ca2fd 100644 --- a/firmware-src/sources/dhsender.c +++ b/firmware-src/sources/dhsender.c @@ -32,7 +32,7 @@ LOCAL unsigned int isCurrentNotification; LOCAL int mSenderTook = 0; dhsender_new_item_cb mNewItemCb = NULL; -SENDER_JSON_DATA * ICACHE_FLASH_ATTR dhsender_next() { +SENDER_JSON_DATA * ICACHE_FLASH_ATTR dhsender_next(void) { if(mSenderTook == 0) { if(dhsender_queue_take(&mDataToSend, &isCurrentNotification) == 0) return NULL; @@ -41,7 +41,7 @@ SENDER_JSON_DATA * ICACHE_FLASH_ATTR dhsender_next() { return &mDataToSend; } -void ICACHE_FLASH_ATTR dhsender_current_fail() { +void ICACHE_FLASH_ATTR dhsender_current_fail(void) { if(mSenderTook) { if(mSenderTook == 1) { dhdebug("WARNING: Request is not delivered after %u attempts", DHSENDER_RETRY_COUNT); @@ -54,7 +54,7 @@ void ICACHE_FLASH_ATTR dhsender_current_fail() { } } -void ICACHE_FLASH_ATTR dhsender_current_success() { +void ICACHE_FLASH_ATTR dhsender_current_success(void) { mSenderTook = 0; } diff --git a/firmware-src/sources/dhsender.h b/firmware-src/sources/dhsender.h index acf912a..5411f8e 100644 --- a/firmware-src/sources/dhsender.h +++ b/firmware-src/sources/dhsender.h @@ -17,23 +17,23 @@ #include "dhsender_data.h" /** Function prototype for new item in queue callback. */ -typedef void (*dhsender_new_item_cb)(); +typedef void (*dhsender_new_item_cb)(void); /** * \brief Notify that current data was failed to send. */ -void dhsender_current_fail(); +void dhsender_current_fail(void); /** * \brief Notify that current data was sent. */ -void dhsender_current_success(); +void dhsender_current_success(void); /** * \brief Get next struct SENDER_JSON_DATA which should be sent. * \return Pointer to SENDER_JSON_DATA or NULL if there is no data to send. */ -SENDER_JSON_DATA *dhsender_next(); +SENDER_JSON_DATA *dhsender_next(void); /** * \brief Set callbacks. diff --git a/firmware-src/sources/dhsender_queue.c b/firmware-src/sources/dhsender_queue.c index 9f07b19..1ffd942 100644 --- a/firmware-src/sources/dhsender_queue.c +++ b/firmware-src/sources/dhsender_queue.c @@ -156,11 +156,11 @@ int ICACHE_FLASH_ATTR dhsender_queue_take(SENDER_JSON_DATA *out, unsigned int *i return 1; } -unsigned int ICACHE_FLASH_ATTR dhsender_queue_length() { +unsigned int ICACHE_FLASH_ATTR dhsender_queue_length(void) { return mQueueSize; } -void ICACHE_FLASH_ATTR dhsender_queue_init() { +void ICACHE_FLASH_ATTR dhsender_queue_init(void) { mQueueMaxSize = (system_get_free_heap_size() - MEMORY_RESERVER) / sizeof(DHSENDER_QUEUE); if(mQueueMaxSize > MAX_QUEUE_LENGTH) mQueueMaxSize = MAX_QUEUE_LENGTH; diff --git a/firmware-src/sources/dhsender_queue.h b/firmware-src/sources/dhsender_queue.h index 56acf37..519f61f 100644 --- a/firmware-src/sources/dhsender_queue.h +++ b/firmware-src/sources/dhsender_queue.h @@ -36,11 +36,11 @@ int dhsender_queue_take(SENDER_JSON_DATA *out, unsigned int *is_notification); * \brief Getting current queue size. * \return Number of item currently in queue. */ -unsigned int dhsender_queue_length(); +unsigned int dhsender_queue_length(void); /** * \brief Initialize queue. */ -void dhsender_queue_init(); +void dhsender_queue_init(void); #endif /* _DHSENDER_QUEUE_H_ */ diff --git a/firmware-src/sources/dhsettings.c b/firmware-src/sources/dhsettings.c index 7d50b7a..0308ac7 100644 --- a/firmware-src/sources/dhsettings.c +++ b/firmware-src/sources/dhsettings.c @@ -118,7 +118,7 @@ LOCAL int ICACHE_FLASH_ATTR dhsettings_write(const DH_SETTINGS_DATA * data) { } -int ICACHE_FLASH_ATTR dhsettings_commit() { +int ICACHE_FLASH_ATTR dhsettings_commit(void) { return dhsettings_write(&mSettingsData); } @@ -134,27 +134,27 @@ int ICACHE_FLASH_ATTR dhsettings_clear(int force) { return dhsettings_write(NULL); } -WIFI_MODE ICACHE_FLASH_ATTR dhsettings_get_wifi_mode() { +WIFI_MODE ICACHE_FLASH_ATTR dhsettings_get_wifi_mode(void) { return mSettingsData.mode; } -const char * ICACHE_FLASH_ATTR dhsettings_get_wifi_ssid() { +const char * ICACHE_FLASH_ATTR dhsettings_get_wifi_ssid(void) { return mSettingsData.ssid; } -const char * ICACHE_FLASH_ATTR dhsettings_get_wifi_password() { +const char * ICACHE_FLASH_ATTR dhsettings_get_wifi_password(void) { return mSettingsData.password; } -const char * ICACHE_FLASH_ATTR dhsettings_get_devicehive_server() { +const char * ICACHE_FLASH_ATTR dhsettings_get_devicehive_server(void) { return mSettingsData.server; } -const char * ICACHE_FLASH_ATTR dhsettings_get_devicehive_deviceid() { +const char * ICACHE_FLASH_ATTR dhsettings_get_devicehive_deviceid(void) { return mSettingsData.deviceId; } -const char * ICACHE_FLASH_ATTR dhsettings_get_devicehive_accesskey() { +const char * ICACHE_FLASH_ATTR dhsettings_get_devicehive_accesskey(void) { return mSettingsData.accessKey; } diff --git a/firmware-src/sources/dhsettings.h b/firmware-src/sources/dhsettings.h index 803165c..49f4506 100644 --- a/firmware-src/sources/dhsettings.h +++ b/firmware-src/sources/dhsettings.h @@ -38,7 +38,7 @@ int dhsettings_init(int *saved); * \brief Saves values to permanent storage. * \return Non zero value on success. Zero on error. */ -int dhsettings_commit(); +int dhsettings_commit(void); /** * \brief Destroy data in permanent storage. @@ -51,37 +51,37 @@ int dhsettings_clear(int force); * \brief Get Wi-Fi mode. * \return One of DH_MODE enum value. */ -WIFI_MODE dhsettings_get_wifi_mode(); +WIFI_MODE dhsettings_get_wifi_mode(void); /** * \brief Get Wi-Fi SSID. * \return Pointer to buffer with null terminated string. */ -const char *dhsettings_get_wifi_ssid(); +const char *dhsettings_get_wifi_ssid(void); /** * \brief Get Wi-Fi password. * \return Pointer to buffer with null terminated string. */ -const char *dhsettings_get_wifi_password(); +const char *dhsettings_get_wifi_password(void); /** * \brief Get DeviceHive server. * \return Pointer to buffer with null terminated string. */ -const char *dhsettings_get_devicehive_server(); +const char *dhsettings_get_devicehive_server(void); /** * \brief Get DeviceHive DeviceId. * \return Pointer to buffer with null terminated string. */ -const char *dhsettings_get_devicehive_deviceid(); +const char *dhsettings_get_devicehive_deviceid(void); /** * \brief Get DeviceHive AccessKey. * \return Pointer to buffer with null terminated string. */ -const char *dhsettings_get_devicehive_accesskey(); +const char *dhsettings_get_devicehive_accesskey(void); /** * \brief Set Wi-Fi mode. diff --git a/firmware-src/sources/dhstatistic.c b/firmware-src/sources/dhstatistic.c index ab0268b..2247c1c 100644 --- a/firmware-src/sources/dhstatistic.c +++ b/firmware-src/sources/dhstatistic.c @@ -15,7 +15,7 @@ static struct DHStat g_stat = {0}; /* * @brief Get global statistics. */ -const struct DHStat* ICACHE_FLASH_ATTR dhstat_get() +const struct DHStat* ICACHE_FLASH_ATTR dhstat_get(void) { return &g_stat; } diff --git a/firmware-src/sources/dhstatistic.h b/firmware-src/sources/dhstatistic.h index 50143e6..bf0ab3a 100644 --- a/firmware-src/sources/dhstatistic.h +++ b/firmware-src/sources/dhstatistic.h @@ -35,7 +35,7 @@ struct DHStat { /** * @brief Get global statistics. */ -const struct DHStat* dhstat_get(); +const struct DHStat* dhstat_get(void); /** diff --git a/firmware-src/sources/dhterminal.c b/firmware-src/sources/dhterminal.c index c7c6f80..a190014 100644 --- a/firmware-src/sources/dhterminal.c +++ b/firmware-src/sources/dhterminal.c @@ -44,7 +44,7 @@ LOCAL int mInputLimiter = sizeof(mRcvBuff); LOCAL os_timer_t mUsageTimer; LOCAL int isInUse = 0; -LOCAL void ICACHE_FLASH_ATTR printWelcome() { +LOCAL void ICACHE_FLASH_ATTR printWelcome(void) { if(mMode == SM_NORMAL_MODE) { dhuart_send_str("$ "); } else if(mMode == SM_INPUT_MODE || mMode == SM_HIDDEN_INPUT_MODE) { @@ -61,15 +61,15 @@ void ICACHE_FLASH_ATTR dhterminal_set_input(const char *line) { dhuart_send_str(mRcvBuff); } -const char * ICACHE_FLASH_ATTR dhterminal_get_history() { +const char * ICACHE_FLASH_ATTR dhterminal_get_history(void) { return mHistoryBuff; } -const char * ICACHE_FLASH_ATTR dhterminal_get_debug_ouput() { +const char * ICACHE_FLASH_ATTR dhterminal_get_debug_ouput(void) { return mDebugBuff; } -DHTERMINAL_MODE ICACHE_FLASH_ATTR dhterminal_get_mode() { +DHTERMINAL_MODE ICACHE_FLASH_ATTR dhterminal_get_mode(void) { return mMode; } @@ -95,7 +95,7 @@ void ICACHE_FLASH_ATTR dhterminal_set_mode(DHTERMINAL_MODE mode, Input_Call_Back } } -LOCAL void ICACHE_FLASH_ATTR trimRcvBuff() { +LOCAL void ICACHE_FLASH_ATTR trimRcvBuff(void) { char *pos = mRcvBuff; char *from = mRcvBuff; char last = ' '; @@ -155,7 +155,7 @@ LOCAL void ICACHE_FLASH_ATTR do_command(void *arg) { } } -LOCAL void ICACHE_FLASH_ATTR dhterminal_reset() { +LOCAL void ICACHE_FLASH_ATTR dhterminal_reset(void) { if(mMode == SM_DEBUG_MODE) { mDebugBuff[0] = 0; mDebugBuffPos = 0; @@ -335,13 +335,13 @@ void dhterminal_debug(const char *pFormat, va_list ap) { } } -void ICACHE_FLASH_ATTR dhterminal_init() { +void ICACHE_FLASH_ATTR dhterminal_init(void) { dhuart_init(UART_BAUND_RATE, 8, 'N', 1); dhuart_set_mode(DUM_PER_BYTE); dhuart_send_str("\r\n**********************************\r\nUart terminal ready.\r\n"); dhterminal_reset(); } -int ICACHE_FLASH_ATTR dhterminal_is_in_use() { +int ICACHE_FLASH_ATTR dhterminal_is_in_use(void) { return isInUse; } diff --git a/firmware-src/sources/dhterminal.h b/firmware-src/sources/dhterminal.h index aa007a7..889ecd0 100644 --- a/firmware-src/sources/dhterminal.h +++ b/firmware-src/sources/dhterminal.h @@ -31,7 +31,7 @@ typedef int (*Input_Filter_Call_Back)(char c); /** * \brief Initializes terminal. */ -void dhterminal_init(); +void dhterminal_init(void); /** * \brief Print data in debug. @@ -45,19 +45,19 @@ void dhterminal_debug(const char *pFormat, va_list ap); * \brief Get terminal history. * \return Pointer to char array. Each command ends with null terminated char, whole buffer ends with two null terminated chars. */ -const char *dhterminal_get_history(); +const char *dhterminal_get_history(void); /** * \brief Get debug lines buffer. * \return Pointer to buffer that end with null terminated char. */ -const char *dhterminal_get_debug_ouput(); +const char *dhterminal_get_debug_ouput(void); /** * \brief Get current mode. * \return Current mode. */ -DHTERMINAL_MODE dhterminal_get_mode(); +DHTERMINAL_MODE dhterminal_get_mode(void); /** * \brief Set current mode. @@ -80,6 +80,6 @@ void dhterminal_set_input(const char *line); * \brief Check if terminal is in use by user * \return Non zero if terminal is in use, zero otherwise */ -int dhterminal_is_in_use(); +int dhterminal_is_in_use(void); #endif /* _DHTERMINAL_H_ */ diff --git a/firmware-src/sources/dhterminal_commandline.c b/firmware-src/sources/dhterminal_commandline.c index 0872ba5..a4c1fa6 100644 --- a/firmware-src/sources/dhterminal_commandline.c +++ b/firmware-src/sources/dhterminal_commandline.c @@ -39,7 +39,7 @@ static const DHCOMMAND mCommands[] = { {"help", "print help", command_help} }; -void ICACHE_FLASH_ATTR command_help() { +void ICACHE_FLASH_ATTR command_help(void) { dhuart_send_line("Welcome to the DeviceHive firmware. List of accepted command:\r\n"); int i; for(i = 0; i < sizeof(mCommands)/sizeof(DHCOMMAND); i++ ) { diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index b96cb27..31f48e4 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -29,7 +29,7 @@ int mIsCommandWorking = 0; char mHostBuffer[80]; -int ICACHE_FLASH_ATTR dhterminal_commands_is_busy() { +int ICACHE_FLASH_ATTR dhterminal_commands_is_busy(void) { return mIsCommandWorking; } diff --git a/firmware-src/sources/dhterminal_commands.h b/firmware-src/sources/dhterminal_commands.h index f18d03c..99aeae4 100644 --- a/firmware-src/sources/dhterminal_commands.h +++ b/firmware-src/sources/dhterminal_commands.h @@ -13,7 +13,7 @@ * \brief Check if command is currently working. * \return Non zero value if command is working or zero value if nothing in progress. */ -int dhterminal_commands_is_busy(); +int dhterminal_commands_is_busy(void); /** * \brief Print firmware version. diff --git a/firmware-src/sources/dhterminal_configure.c b/firmware-src/sources/dhterminal_configure.c index a49a881..0fa032f 100644 --- a/firmware-src/sources/dhterminal_configure.c +++ b/firmware-src/sources/dhterminal_configure.c @@ -99,7 +99,7 @@ LOCAL int ICACHE_FLASH_ATTR configure_mode_filter(char c) { return 0; } -void ICACHE_FLASH_ATTR dhterminal_configure_start() { +void ICACHE_FLASH_ATTR dhterminal_configure_start(void) { dhuart_send_line("Welcome to the DeviceHive setup utility. Use Ctrl+C to interrupt."); dhuart_send_line("Choose Wi-Fi mode: '0' - WiFi client, '1' - WiFi Access Point."); dhterminal_set_mode(SM_INPUT_MODE, get_mode_cb, 0, configure_mode_filter, 1); diff --git a/firmware-src/sources/dhterminal_configure.h b/firmware-src/sources/dhterminal_configure.h index 6c9e8f2..d32bf71 100644 --- a/firmware-src/sources/dhterminal_configure.h +++ b/firmware-src/sources/dhterminal_configure.h @@ -12,6 +12,6 @@ /** * \brief Start configuration util in terminal. */ -void dhterminal_configure_start(); +void dhterminal_configure_start(void); #endif /* _DHSERIAL_CONFIGURE_H_ */ diff --git a/firmware-src/sources/dhuart.c b/firmware-src/sources/dhuart.c index d43c4ab..0da14ae 100644 --- a/firmware-src/sources/dhuart.c +++ b/firmware-src/sources/dhuart.c @@ -37,7 +37,7 @@ LOCAL unsigned char mBufInterrupt = 0; LOCAL os_timer_t mRecoverLEDTimer; LOCAL char mKeepLED = 0; -LOCAL ICACHE_FLASH_ATTR void arm_buf_timer(); +LOCAL ICACHE_FLASH_ATTR void arm_buf_timer(void); LOCAL void ICACHE_FLASH_ATTR buf_timeout(void *arg) { unsigned int sz = mUartBufPos; @@ -56,7 +56,7 @@ LOCAL void ICACHE_FLASH_ATTR buf_timeout(void *arg) { arm_buf_timer(); } -LOCAL ICACHE_FLASH_ATTR void arm_buf_timer() { +LOCAL ICACHE_FLASH_ATTR void arm_buf_timer(void) { os_timer_disarm(&mUartTimer); os_timer_setfn(&mUartTimer, (os_timer_func_t *)buf_timeout, NULL); os_timer_arm(&mUartTimer, (mUartTimerTimeout == 0 | mUartBufPos >= INTERFACES_BUF_SIZE) ? 1 :mUartTimerTimeout, 0); @@ -121,7 +121,7 @@ LOCAL void ICACHE_FLASH_ATTR led_recover(void *arg) { ETS_INTR_UNLOCK(); } -LOCAL void ICACHE_FLASH_ATTR led_off() { +LOCAL void ICACHE_FLASH_ATTR led_off(void) { gpio_output_set(0, 0, 0, 0b0110); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); os_delay_us(10000); @@ -188,7 +188,7 @@ void ICACHE_FLASH_ATTR dhuart_set_mode(DHUART_DATA_MODE mode) { } } -unsigned int ICACHE_FLASH_ATTR dhuart_get_callback_timeout() { +unsigned int ICACHE_FLASH_ATTR dhuart_get_callback_timeout(void) { return mUartTimerTimeout; } @@ -201,7 +201,7 @@ unsigned int ICACHE_FLASH_ATTR dhuart_get_buf(char ** buf) { return mUartBufPos; } -void ICACHE_FLASH_ATTR dhuart_reset_buf() { +void ICACHE_FLASH_ATTR dhuart_reset_buf(void) { mUartBufPos = 0; } diff --git a/firmware-src/sources/dhuart.h b/firmware-src/sources/dhuart.h index 713e562..914e526 100644 --- a/firmware-src/sources/dhuart.h +++ b/firmware-src/sources/dhuart.h @@ -91,7 +91,7 @@ unsigned int dhuart_get_buf(char ** buf); /** * \brief Clean up buffer. */ -void dhuart_reset_buf(); +void dhuart_reset_buf(void); /** * \brief Enable or disable DUM_PER_BUF callbacks. @@ -104,7 +104,7 @@ void dhuart_enable_buf_interrupt(int enable); * \brief Get current timeout value. * \return Timeout value in milliseconds. */ -unsigned int dhuart_get_callback_timeout(); +unsigned int dhuart_get_callback_timeout(void); /** * \brief Callback declaration for DUM_PER_BYTE mode. diff --git a/firmware-src/sources/dhzc_dnsd.c b/firmware-src/sources/dhzc_dnsd.c index efee27f..06c5911 100644 --- a/firmware-src/sources/dhzc_dnsd.c +++ b/firmware-src/sources/dhzc_dnsd.c @@ -121,7 +121,7 @@ LOCAL void ICACHE_FLASH_ATTR dhzc_dnsd_connect_cb(void *arg) { dhdebug("dnsd connected"); } -void ICACHE_FLASH_ATTR dhzc_dnsd_init() { +void ICACHE_FLASH_ATTR dhzc_dnsd_init(void) { mDNSAnswerBuffer = (char *)os_malloc(DNS_ANSWER_BUF_SIZE); esp_tcp *dnsdTcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); diff --git a/firmware-src/sources/dhzc_dnsd.h b/firmware-src/sources/dhzc_dnsd.h index 2c8aa77..226211a 100644 --- a/firmware-src/sources/dhzc_dnsd.h +++ b/firmware-src/sources/dhzc_dnsd.h @@ -13,6 +13,6 @@ /** * \brief Initialize DNSD daemon. */ -void dhzc_dnsd_init(); +void dhzc_dnsd_init(void); #endif /* _DHAP_DNS_H_ */ diff --git a/firmware-src/sources/dhzc_web.c b/firmware-src/sources/dhzc_web.c index f5ff786..cb24907 100644 --- a/firmware-src/sources/dhzc_web.c +++ b/firmware-src/sources/dhzc_web.c @@ -90,7 +90,7 @@ LOCAL HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR post_cb(const char *path, return HRCS_ANSWERED_HTML; } -void ICACHE_FLASH_ATTR dhzc_web_init() { +void ICACHE_FLASH_ATTR dhzc_web_init(void) { httpd_redirect(WEB_CONF_HOST); httpd_init(get_cb, post_cb); } diff --git a/firmware-src/sources/dhzc_web.h b/firmware-src/sources/dhzc_web.h index bd4403a..20dcac5 100644 --- a/firmware-src/sources/dhzc_web.h +++ b/firmware-src/sources/dhzc_web.h @@ -12,6 +12,6 @@ /** * \brief Initialize HTTP daemon */ -void dhzc_web_init(); +void dhzc_web_init(void); #endif /* _DHZC_WEB_H_ */ diff --git a/firmware-src/sources/mdnsd.c b/firmware-src/sources/mdnsd.c index 7b5f308..d49cb2c 100644 --- a/firmware-src/sources/mdnsd.c +++ b/firmware-src/sources/mdnsd.c @@ -188,7 +188,7 @@ int ICACHE_FLASH_ATTR mdnsd_start(const char *name, unsigned long addr) { return 1; } -void ICACHE_FLASH_ATTR mdnsd_stop() { +void ICACHE_FLASH_ATTR mdnsd_stop(void) { if(mMDNSdConn.proto.udp) { espconn_disconnect(&mMDNSdConn); espconn_delete(&mMDNSdConn); diff --git a/firmware-src/sources/mdnsd.h b/firmware-src/sources/mdnsd.h index d20ca17..a71f451 100644 --- a/firmware-src/sources/mdnsd.h +++ b/firmware-src/sources/mdnsd.h @@ -22,6 +22,6 @@ int mdnsd_start(const char *name, unsigned long addr); /** * \brief Stops mDNS daemon. */ -void mdnsd_stop(); +void mdnsd_stop(void); #endif /* _MDNS_H_ */ diff --git a/firmware-src/sources/rand.c b/firmware-src/sources/rand.c index 38921d5..b59614c 100644 --- a/firmware-src/sources/rand.c +++ b/firmware-src/sources/rand.c @@ -15,7 +15,7 @@ static unsigned long seed = 0; -int ICACHE_FLASH_ATTR rand() { +int ICACHE_FLASH_ATTR rand(void) { if(seed == 0) { seed = system_get_time(); } diff --git a/firmware-src/sources/rand.h b/firmware-src/sources/rand.h index 8688ec1..f46bf8f 100644 --- a/firmware-src/sources/rand.h +++ b/firmware-src/sources/rand.h @@ -17,7 +17,7 @@ * \brief Generate random value. * \return Value in range of 0..(RAND_MAX - 1). */ -int rand(); +int rand(void); /** * \brief Generate random device key. diff --git a/firmware-src/sources/webserver.c b/firmware-src/sources/webserver.c index cc3074f..62ab1f4 100644 --- a/firmware-src/sources/webserver.c +++ b/firmware-src/sources/webserver.c @@ -76,6 +76,6 @@ LOCAL HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR post_cb(const char *path, return uploadable_api_handle(path, key, content_in, answer); } -void ICACHE_FLASH_ATTR webserver_init() { +void ICACHE_FLASH_ATTR webserver_init(void) { httpd_init(get_cb, post_cb); } diff --git a/firmware-src/sources/webserver.h b/firmware-src/sources/webserver.h index 827a1b7..a6daf83 100644 --- a/firmware-src/sources/webserver.h +++ b/firmware-src/sources/webserver.h @@ -12,6 +12,6 @@ /** * \brief Initialize web server */ -void webserver_init(); +void webserver_init(void); #endif /* WEBSERVER_H_ */ From 58a6a8d1d202533f17239e672c0f6cfbe9a6d801 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 13:53:50 +0300 Subject: [PATCH 19/83] bugfix: wrong address in dhsettings_clear() --- firmware-src/sources/dhsettings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware-src/sources/dhsettings.c b/firmware-src/sources/dhsettings.c index 0308ac7..485eca4 100644 --- a/firmware-src/sources/dhsettings.c +++ b/firmware-src/sources/dhsettings.c @@ -123,7 +123,7 @@ int ICACHE_FLASH_ATTR dhsettings_commit(void) { } int ICACHE_FLASH_ATTR dhsettings_clear(int force) { - os_memset(mSettingsData, 0, sizeof(mSettingsData)); + os_memset(&mSettingsData, 0, sizeof(mSettingsData)); if(force) { if(spi_flash_erase_sector(ESP_SETTINGS_MAIN_SEC) == SPI_FLASH_RESULT_OK && spi_flash_erase_sector(ESP_SETTINGS_BACKUP_SEC) == SPI_FLASH_RESULT_OK) { From 25fce7d6a89c3f87dc0211d6091b40660ae4b1a5 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 14:33:32 +0300 Subject: [PATCH 20/83] rearrange include files, add missing ESP declarations - missed ESP functions are declared in sdk/est_forward.h file - local files should be included via `#include "file.h"` - SDK files should be included via `#include ` - local files should be included first --- firmware-src/sources/crc32.h | 1 + firmware-src/sources/custom_firmware.c | 10 +--- firmware-src/sources/devices/ads1115.c | 6 +- firmware-src/sources/devices/bh1750.c | 6 +- firmware-src/sources/devices/bmp180.c | 6 +- firmware-src/sources/devices/bmp280.c | 5 +- firmware-src/sources/devices/dht.c | 6 +- firmware-src/sources/devices/ds18b20.c | 6 +- firmware-src/sources/devices/hmc5883l.c | 6 +- firmware-src/sources/devices/ina219.c | 7 ++- firmware-src/sources/devices/lm75.c | 6 +- firmware-src/sources/devices/max31855.c | 7 ++- firmware-src/sources/devices/max6675.c | 6 +- firmware-src/sources/devices/mcp4725.c | 6 +- firmware-src/sources/devices/mfrc522.c | 4 +- firmware-src/sources/devices/mfrc522.h | 1 - firmware-src/sources/devices/mhz19.c | 6 +- firmware-src/sources/devices/mlx90614.c | 6 +- firmware-src/sources/devices/mpu6050.c | 6 +- firmware-src/sources/devices/pca9685.c | 6 +- firmware-src/sources/devices/pcf8574.c | 6 +- .../sources/devices/pcf8574_hd44780.c | 5 +- firmware-src/sources/devices/pcf8591.c | 7 ++- firmware-src/sources/devices/si7021.c | 6 +- firmware-src/sources/devices/tm1637.c | 7 ++- firmware-src/sources/dhadc.c | 6 +- firmware-src/sources/dhap.c | 13 +++-- firmware-src/sources/dhcommand_parser.c | 7 ++- firmware-src/sources/dhcommand_parser.h | 1 + firmware-src/sources/dhcommands.c | 11 ++-- firmware-src/sources/dhconnector.c | 19 ++++--- firmware-src/sources/dhconnector_websocket.c | 12 ++-- .../sources/dhconnector_websocket_api.c | 16 +++--- firmware-src/sources/dhdata.c | 2 - firmware-src/sources/dhesperrors.c | 4 +- firmware-src/sources/dhesperrors.h | 2 + firmware-src/sources/dhgpio.c | 11 ++-- firmware-src/sources/dhi2c.c | 7 ++- firmware-src/sources/dhmem.c | 1 + firmware-src/sources/dhnotification.c | 13 +++-- firmware-src/sources/dhonewire.c | 10 ++-- firmware-src/sources/dhpwm.c | 9 +-- firmware-src/sources/dhrequest.c | 11 ++-- firmware-src/sources/dhsender.c | 16 +++--- firmware-src/sources/dhsender.h | 4 +- firmware-src/sources/dhsender_data.c | 7 ++- firmware-src/sources/dhsender_data.h | 3 +- firmware-src/sources/dhsender_queue.c | 12 ++-- firmware-src/sources/dhsender_queue.h | 3 +- firmware-src/sources/dhsettings.c | 10 ++-- firmware-src/sources/dhspi.c | 6 +- firmware-src/sources/dhterminal.c | 12 ++-- firmware-src/sources/dhterminal.h | 1 + firmware-src/sources/dhterminal_commandline.c | 8 ++- firmware-src/sources/dhterminal_commands.c | 15 ++--- firmware-src/sources/dhterminal_configure.c | 7 ++- firmware-src/sources/dhuart.c | 7 ++- firmware-src/sources/dhutils.c | 2 + firmware-src/sources/dhzc_dnsd.c | 9 +-- firmware-src/sources/dhzc_pages.c | 12 ++-- firmware-src/sources/dhzc_post.c | 7 ++- firmware-src/sources/dhzc_web.c | 13 +++-- firmware-src/sources/dns.c | 3 - firmware-src/sources/httpd.c | 14 +++-- firmware-src/sources/main.c | 15 +++-- firmware-src/sources/mdnsd.c | 13 +++-- firmware-src/sources/rand.c | 5 +- firmware-src/sources/rest.c | 12 ++-- firmware-src/sources/snprintf.c | 4 +- firmware-src/sources/snprintf.h | 1 + firmware-src/sources/uploadable_api.c | 5 +- firmware-src/sources/uploadable_page.c | 8 ++- firmware-src/sources/webserver.c | 7 ++- sdk/include/ets_forward.h | 56 +++++++++++++++++++ 74 files changed, 358 insertions(+), 238 deletions(-) create mode 100644 sdk/include/ets_forward.h diff --git a/firmware-src/sources/crc32.h b/firmware-src/sources/crc32.h index 5e51947..d8902bd 100644 --- a/firmware-src/sources/crc32.h +++ b/firmware-src/sources/crc32.h @@ -8,6 +8,7 @@ #ifndef _CRC32_H_ #define _CRC32_H_ + #include /** diff --git a/firmware-src/sources/custom_firmware.c b/firmware-src/sources/custom_firmware.c index 8750741..11abf23 100644 --- a/firmware-src/sources/custom_firmware.c +++ b/firmware-src/sources/custom_firmware.c @@ -6,14 +6,10 @@ * Author: Nikolay Khabarov * */ - -#include "dhdebug.h" -#include "dhgpio.h" #include "dhrequest.h" -#include "dhconnector.h" -#include "snprintf.h" -#include "c_types.h" -#include "osapi.h" +#include "dhdebug.h" + +#include HTTP_REQUEST * ICACHE_FLASH_ATTR custom_firmware_request(void) { // reimplement this method to return actual HTTP_REQUEST to make custom notification firmware diff --git a/firmware-src/sources/devices/ads1115.c b/firmware-src/sources/devices/ads1115.c index 129c515..3485342 100644 --- a/firmware-src/sources/devices/ads1115.c +++ b/firmware-src/sources/devices/ads1115.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "ads1115.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = ADS1115_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float *values) { diff --git a/firmware-src/sources/devices/bh1750.c b/firmware-src/sources/devices/bh1750.c index d44aefa..df5f832 100644 --- a/firmware-src/sources/devices/bh1750.c +++ b/firmware-src/sources/devices/bh1750.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "bh1750.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = BH1750_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR bh1750_read(int sda, int scl, float *illuminance) { diff --git a/firmware-src/sources/devices/bmp180.c b/firmware-src/sources/devices/bmp180.c index ead88f0..230297f 100644 --- a/firmware-src/sources/devices/bmp180.c +++ b/firmware-src/sources/devices/bmp180.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "bmp180.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = BMP180_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, float *temperature) { diff --git a/firmware-src/sources/devices/bmp280.c b/firmware-src/sources/devices/bmp280.c index 5d4b438..b9baf8e 100644 --- a/firmware-src/sources/devices/bmp280.c +++ b/firmware-src/sources/devices/bmp280.c @@ -7,13 +7,14 @@ * */ -#include -#include #include "bmp280.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = BMP280_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, float *temperature) { diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index d736ef9..3769872 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "dht.h" #include "dhonewire.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + #define DHT_PACKET_SIZE 5 LOCAL char * ICACHE_FLASH_ATTR dht_read(int pin, char *buf) { diff --git a/firmware-src/sources/devices/ds18b20.c b/firmware-src/sources/devices/ds18b20.c index c7ccb4f..8f83ef4 100644 --- a/firmware-src/sources/devices/ds18b20.c +++ b/firmware-src/sources/devices/ds18b20.c @@ -6,13 +6,13 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "ds18b20.h" #include "dhonewire.h" #include "dhutils.h" +#include +#include + char * ICACHE_FLASH_ATTR ds18b20_read(int pin, float *temperature) { char in_buf[8]; char out_buf[2]; diff --git a/firmware-src/sources/devices/hmc5883l.c b/firmware-src/sources/devices/hmc5883l.c index 31d9c10..7a44d47 100644 --- a/firmware-src/sources/devices/hmc5883l.c +++ b/firmware-src/sources/devices/hmc5883l.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "hmc5883l.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + #define HMC5883l_OVERFLOWED_RAW -4096 static int mAddress = HMC5883L_DEFAULT_ADDRESS; diff --git a/firmware-src/sources/devices/ina219.c b/firmware-src/sources/devices/ina219.c index 69025ea..9c7a7bd 100644 --- a/firmware-src/sources/devices/ina219.c +++ b/firmware-src/sources/devices/ina219.c @@ -6,14 +6,15 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "ina219.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include +#include + static int mAddress = INA219_DEFAULT_ADDRESS; static float mResistance = 0.1f; diff --git a/firmware-src/sources/devices/lm75.c b/firmware-src/sources/devices/lm75.c index 3d72baa..acdba22 100644 --- a/firmware-src/sources/devices/lm75.c +++ b/firmware-src/sources/devices/lm75.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "lm75.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = LM75_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR lm75_read(int sda, int scl, float *temperature) { diff --git a/firmware-src/sources/devices/max31855.c b/firmware-src/sources/devices/max31855.c index 0b0081c..2de8120 100644 --- a/firmware-src/sources/devices/max31855.c +++ b/firmware-src/sources/devices/max31855.c @@ -6,12 +6,13 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "max31855.h" #include "dhspi.h" #include "dhutils.h" +#include "dhgpio.h" + +#include +#include static int mCSPin = 15; diff --git a/firmware-src/sources/devices/max6675.c b/firmware-src/sources/devices/max6675.c index a178d44..5dd9be2 100644 --- a/firmware-src/sources/devices/max6675.c +++ b/firmware-src/sources/devices/max6675.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "max6675.h" #include "dhspi.h" #include "dhgpio.h" #include "dhutils.h" +#include +#include + static int mCSPin = 15; char * ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) { diff --git a/firmware-src/sources/devices/mcp4725.c b/firmware-src/sources/devices/mcp4725.c index cc0017f..ac3c00f 100644 --- a/firmware-src/sources/devices/mcp4725.c +++ b/firmware-src/sources/devices/mcp4725.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "mcp4725.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = MCP4725_DEFAULT_ADDRESS; static float mVoltage = 3.3f; diff --git a/firmware-src/sources/devices/mfrc522.c b/firmware-src/sources/devices/mfrc522.c index 892884b..8980e2e 100644 --- a/firmware-src/sources/devices/mfrc522.c +++ b/firmware-src/sources/devices/mfrc522.c @@ -5,11 +5,13 @@ */ #include "mfrc522.h" -#include #include "dhspi.h" #include "dhdebug.h" #include "snprintf.h" +#include +#include + static int _chipSelectPin = 15; // pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low) // Member variables static MFRC522_Uid uid; // Used by MFRC522_PICC_ReadCardSerial(). diff --git a/firmware-src/sources/devices/mfrc522.h b/firmware-src/sources/devices/mfrc522.h index 5a239f1..e758496 100644 --- a/firmware-src/sources/devices/mfrc522.h +++ b/firmware-src/sources/devices/mfrc522.h @@ -76,7 +76,6 @@ #ifndef MFRC522_h #define MFRC522_h -#include #include "irom.h" // Firmware data for self-test diff --git a/firmware-src/sources/devices/mhz19.c b/firmware-src/sources/devices/mhz19.c index 293df4a..99bf78c 100644 --- a/firmware-src/sources/devices/mhz19.c +++ b/firmware-src/sources/devices/mhz19.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "mhz19.h" #include "dhuart.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + const char request[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; char * ICACHE_FLASH_ATTR mhz19_read(int *co2) { diff --git a/firmware-src/sources/devices/mlx90614.c b/firmware-src/sources/devices/mlx90614.c index 717845e..05184df 100644 --- a/firmware-src/sources/devices/mlx90614.c +++ b/firmware-src/sources/devices/mlx90614.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "mlx90614.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = MLX90614_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, float *object) { diff --git a/firmware-src/sources/devices/mpu6050.c b/firmware-src/sources/devices/mpu6050.c index 4ef43e5..00ada01 100644 --- a/firmware-src/sources/devices/mpu6050.c +++ b/firmware-src/sources/devices/mpu6050.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "mpu6050.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = MPU6050_DEFAULT_ADDRESS; #define EARTH_GRAVITY_ACCELERATION 9.80665f diff --git a/firmware-src/sources/devices/pca9685.c b/firmware-src/sources/devices/pca9685.c index 5e0a817..2a33dba 100644 --- a/firmware-src/sources/devices/pca9685.c +++ b/firmware-src/sources/devices/pca9685.c @@ -6,15 +6,15 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "pca9685.h" #include "dhi2c.h" #include "dhgpio.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = PCA9685_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus) { diff --git a/firmware-src/sources/devices/pcf8574.c b/firmware-src/sources/devices/pcf8574.c index cbb3ef0..0c4e34d 100644 --- a/firmware-src/sources/devices/pcf8574.c +++ b/firmware-src/sources/devices/pcf8574.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "pcf8574.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = PCF8574_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_read(int sda, int scl, unsigned int *pins) { diff --git a/firmware-src/sources/devices/pcf8574_hd44780.c b/firmware-src/sources/devices/pcf8574_hd44780.c index fbe5c26..3a4c0ff 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.c +++ b/firmware-src/sources/devices/pcf8574_hd44780.c @@ -6,11 +6,12 @@ * Author: Nikolay Khabarov * */ +#include "pcf8574_hd44780.h" +#include "pcf8574.h" #include #include -#include "pcf8574_hd44780.h" -#include "pcf8574.h" +#include #define PIN_RS (1 << 0) #define PIN_RW (1 << 1) diff --git a/firmware-src/sources/devices/pcf8591.c b/firmware-src/sources/devices/pcf8591.c index cfb3d83..596bcd3 100644 --- a/firmware-src/sources/devices/pcf8591.c +++ b/firmware-src/sources/devices/pcf8591.c @@ -6,14 +6,15 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "pcf8591.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include +#include + static int mAddress = PCF8591_DEFAULT_ADDRESS; static float mVoltage = 3.3f; diff --git a/firmware-src/sources/devices/si7021.c b/firmware-src/sources/devices/si7021.c index c4ffbc2..7ce0830 100644 --- a/firmware-src/sources/devices/si7021.c +++ b/firmware-src/sources/devices/si7021.c @@ -6,14 +6,14 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "si7021.h" #include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include + static int mAddress = SI7021_DEFAULT_ADDRESS; DHI2C_STATUS ICACHE_FLASH_ATTR si7021_read(int sda, int scl, float *humidity, float *temperature) { diff --git a/firmware-src/sources/devices/tm1637.c b/firmware-src/sources/devices/tm1637.c index 35f440f..2ecb67c 100644 --- a/firmware-src/sources/devices/tm1637.c +++ b/firmware-src/sources/devices/tm1637.c @@ -6,14 +6,15 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "tm1636.h" #include "irom.h" #include "dhdebug.h" #include "dhutils.h" +#include +#include +#include + RO_DATA const unsigned char segments_table[] = { 0b11111100, // 0 0b01100000, // 1 diff --git a/firmware-src/sources/dhadc.c b/firmware-src/sources/dhadc.c index e892332..8d298bc 100644 --- a/firmware-src/sources/dhadc.c +++ b/firmware-src/sources/dhadc.c @@ -6,11 +6,13 @@ * Author: Nikolay Khabarov * */ +#include "dhadc.h" #include -#include #include -#include "dhadc.h" +#include +#include +#include LOCAL os_timer_t mADCTimer; diff --git a/firmware-src/sources/dhap.c b/firmware-src/sources/dhap.c index 551a746..83bdcbe 100644 --- a/firmware-src/sources/dhap.c +++ b/firmware-src/sources/dhap.c @@ -6,17 +6,20 @@ * Author: Nikolay Khabarov * */ +#include "dhap.h" +#include "snprintf.h" +#include "user_config.h" +#include "dhdebug.h" +#include "dhuart.h" #include #include #include #include #include -#include "dhap.h" -#include "snprintf.h" -#include "user_config.h" -#include "dhdebug.h" -#include "dhuart.h" +#include +#include + static struct ip_info *ipinfo = NULL; struct softap_config *apconfig = NULL; diff --git a/firmware-src/sources/dhcommand_parser.c b/firmware-src/sources/dhcommand_parser.c index fad60e2..11e7bb6 100644 --- a/firmware-src/sources/dhcommand_parser.c +++ b/firmware-src/sources/dhcommand_parser.c @@ -8,14 +8,15 @@ * Description: Module for parsing server commands * */ +#include "dhcommand_parser.h" +#include "dhutils.h" +#include "dhdata.h" #include #include #include #include -#include "dhcommand_parser.h" -#include "dhutils.h" -#include "dhdata.h" +#include static char * const UNEXPECTED = "Unexpected parameter"; static char * const NONINTEGER = "Non integer value"; diff --git a/firmware-src/sources/dhcommand_parser.h b/firmware-src/sources/dhcommand_parser.h index 8b7772f..c5b3394 100644 --- a/firmware-src/sources/dhcommand_parser.h +++ b/firmware-src/sources/dhcommand_parser.h @@ -10,6 +10,7 @@ #define _DHCOMMAND_PARSER_H_ #include + #include "dhgpio.h" #include "user_config.h" diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index faad217..2d3ecda 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -8,10 +8,6 @@ * Description: Module for executing server command * */ - -#include -#include -#include #include "dhcommands.h" #include "dhsender_queue.h" #include "dhgpio.h" @@ -25,6 +21,7 @@ #include "dhspi.h" #include "dhonewire.h" #include "dhdebug.h" +#include "dhpwm.h" #include "dhutils.h" #include "devices/ds18b20.h" #include "devices/dht.h" @@ -49,6 +46,12 @@ #include "devices/max31855.h" #include "devices/tm1636.h" +#include +#include +#include +#include +#include + #define GPIONOTIFICATION_MIN_TIMEOUT_MS 50 #define ADCNOTIFICATION_MIN_TIMEOUT_MS 250 diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index 9bf4c7a..94d2e80 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -8,15 +8,6 @@ * Description: Module for connecting to remote DeviceHive server * */ - -#include -#include -#include -#include -#include -#include -#include -#include "dhrequest.h" #include "dhconnector.h" #include "dhdebug.h" #include "dhmem.h" @@ -26,6 +17,16 @@ #include "dhstatistic.h" #include "mdnsd.h" #include "dhconnector_websocket.h" +#include "dhesperrors.h" + +#include +#include +#include +#include +#include +#include +#include +#include LOCAL CONNECTION_STATE mConnectionState; LOCAL struct espconn mDHConnector; diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c index 96fa36a..cd8dfb9 100644 --- a/firmware-src/sources/dhconnector_websocket.c +++ b/firmware-src/sources/dhconnector_websocket.c @@ -10,11 +10,6 @@ */ #include "dhconnector_websocket.h" -#include -#include -#include -#include -#include #include "dhsettings.h" #include "dhdebug.h" #include "rand.h" @@ -25,6 +20,13 @@ #include "dhsender_data.h" #include "dhsender.h" +#include +#include +#include +#include +#include +#include + #define PAYLOAD_BUF_SIZE (MAX( \ ROUND_KB(DHSETTINGS_DEVICEID_MAX_LENGTH + DHSETTINGS_ACCESSKEY_MAX_LENGTH + 512), \ SENDER_JSON_MAX_LENGTH)) diff --git a/firmware-src/sources/dhconnector_websocket_api.c b/firmware-src/sources/dhconnector_websocket_api.c index 3f8ebf1..a576bec 100644 --- a/firmware-src/sources/dhconnector_websocket_api.c +++ b/firmware-src/sources/dhconnector_websocket_api.c @@ -8,14 +8,7 @@ * Description: DeviceHive WebSocket protocol implementation * */ - #include "dhconnector_websocket_api.h" -#include -#include -#include -#include -#include -#include #include "dhsettings.h" #include "irom.h" #include "snprintf.h" @@ -25,6 +18,15 @@ #include "dhcommands.h" #include "dhsender.h" +#include +#include +#include +#include +#include +#include +#include + + int ICACHE_FLASH_ATTR dhconnector_websocket_api_start(char *buf, unsigned int maxlen) { RO_DATA char template[] = "{" diff --git a/firmware-src/sources/dhdata.c b/firmware-src/sources/dhdata.c index 121efae..7716c37 100644 --- a/firmware-src/sources/dhdata.c +++ b/firmware-src/sources/dhdata.c @@ -8,8 +8,6 @@ * Description: Data coder/encoder * */ - -#include #include "dhdata.h" #include "user_config.h" #include "dhutils.h" diff --git a/firmware-src/sources/dhesperrors.c b/firmware-src/sources/dhesperrors.c index 72e7248..0d660d0 100644 --- a/firmware-src/sources/dhesperrors.c +++ b/firmware-src/sources/dhesperrors.c @@ -8,12 +8,12 @@ * Description: Module for printing error description in debug output * */ +#include "dhesperrors.h" +#include "dhdebug.h" #include #include #include -#include "dhesperrors.h" -#include "dhdebug.h" void ICACHE_FLASH_ATTR dhesperrors_disconnect_reason(const char *descrption, uint8 reason) { char *errdescr = 0; diff --git a/firmware-src/sources/dhesperrors.h b/firmware-src/sources/dhesperrors.h index 4485780..7ceb7c0 100644 --- a/firmware-src/sources/dhesperrors.h +++ b/firmware-src/sources/dhesperrors.h @@ -9,6 +9,8 @@ #ifndef _DHESPERRORS_H_ #define _DHESPERRORS_H_ +#include + /** * \brief Print disconnect reason. * \param[in] descrption Text that will be printed before error description. diff --git a/firmware-src/sources/dhgpio.c b/firmware-src/sources/dhgpio.c index a8b3015..eae162d 100644 --- a/firmware-src/sources/dhgpio.c +++ b/firmware-src/sources/dhgpio.c @@ -10,17 +10,18 @@ * */ #include "dhgpio.h" - -#include -#include -#include -#include #include "user_config.h" #include "dhdebug.h" #include "dhnotification.h" #include "dhpwm.h" #include "dhmem.h" +#include +#include +#include +#include +#include + LOCAL os_timer_t mGPIOTimer; LOCAL unsigned int mGPIOTimerTimeout = 250; LOCAL unsigned int mTriggeredIntrPins = 0; diff --git a/firmware-src/sources/dhi2c.c b/firmware-src/sources/dhi2c.c index 4f86672..f91f58e 100644 --- a/firmware-src/sources/dhi2c.c +++ b/firmware-src/sources/dhi2c.c @@ -8,14 +8,15 @@ * Description: I2C module * */ +#include "dhi2c.h" +#include "dhgpio.h" +#include "user_config.h" #include #include #include #include -#include "dhi2c.h" -#include "dhgpio.h" -#include "user_config.h" +#include #define I2C_DELAY_US 5 #define I2C_ERROR_TIMEOUT_US 50000 diff --git a/firmware-src/sources/dhmem.c b/firmware-src/sources/dhmem.c index f16b9bc..85bb0f5 100644 --- a/firmware-src/sources/dhmem.c +++ b/firmware-src/sources/dhmem.c @@ -12,6 +12,7 @@ #include #include +#include static int mGlobalBlock = 0; diff --git a/firmware-src/sources/dhnotification.c b/firmware-src/sources/dhnotification.c index f516633..343a2be 100644 --- a/firmware-src/sources/dhnotification.c +++ b/firmware-src/sources/dhnotification.c @@ -8,20 +8,21 @@ * Description: Module for catching hardware events and preparing notification to DeviceHive server * */ - -#include -#include -#include - +#include "dhnotification.h" #include "dhsender.h" #include "dhgpio.h" #include "dhadc.h" -#include "dhnotification.h" #include "user_config.h" #include "snprintf.h" #include "dhdata.h" #include "dhdebug.h" #include "dhstatistic.h" +#include "dhmem.h" + +#include +#include +#include +#include void ICACHE_FLASH_ATTR dhgpio_int_timeout(unsigned int caused_pins) { if(dhmem_isblock()) { diff --git a/firmware-src/sources/dhonewire.c b/firmware-src/sources/dhonewire.c index db227b1..e82e846 100644 --- a/firmware-src/sources/dhonewire.c +++ b/firmware-src/sources/dhonewire.c @@ -8,16 +8,18 @@ * Description: Software onewire implementation * */ +#include "dhonewire.h" +#include "dhgpio.h" +#include "user_config.h" +#include "dhdebug.h" #include #include #include #include #include -#include "dhonewire.h" -#include "dhgpio.h" -#include "user_config.h" -#include "dhdebug.h" +#include +#include LOCAL unsigned int mOneWirePin = 0; LOCAL unsigned int mIntPins = 0; diff --git a/firmware-src/sources/dhpwm.c b/firmware-src/sources/dhpwm.c index af8890f..1724725 100644 --- a/firmware-src/sources/dhpwm.c +++ b/firmware-src/sources/dhpwm.c @@ -6,15 +6,16 @@ * Author: Nikolay Khabarov * */ +#include "dhpwm.h" +#include "dhgpio.h" +#include "dhdebug.h" +#include "user_config.h" #include #include #include #include -#include "dhpwm.h" -#include "dhgpio.h" -#include "dhdebug.h" -#include "user_config.h" +#include #define FRC1_ENABLE_TIMER BIT7 #define FRC1_AUTO_LOAD BIT6 diff --git a/firmware-src/sources/dhrequest.c b/firmware-src/sources/dhrequest.c index 02dcacf..3dcdaed 100644 --- a/firmware-src/sources/dhrequest.c +++ b/firmware-src/sources/dhrequest.c @@ -8,17 +8,18 @@ * Description: Module for creating HTTP requests for DeviceHive server * */ +#include "dhrequest.h" +#include "user_config.h" +#include "dhdebug.h" +#include "snprintf.h" +#include "dhsettings.h" #include #include #include #include +#include #include -#include "dhrequest.h" -#include "user_config.h" -#include "dhdebug.h" -#include "snprintf.h" -#include "dhsettings.h" RO_DATA char HTTP_INFO_REQUEST_PATTERN[] = "GET %s/info HTTP/1.1\r\n" diff --git a/firmware-src/sources/dhsender.c b/firmware-src/sources/dhsender.c index 54ca2fd..cf00ce0 100644 --- a/firmware-src/sources/dhsender.c +++ b/firmware-src/sources/dhsender.c @@ -9,6 +9,15 @@ * */ +#include "user_config.h" +#include "dhsender.h" +#include "dhsender_queue.h" +#include "dhrequest.h" +#include "dhdebug.h" +#include "dhesperrors.h" +#include "dhutils.h" +#include "dhstatistic.h" + #include #include #include @@ -17,13 +26,6 @@ #include #include #include -#include "user_config.h" -#include "dhsender.h" -#include "dhrequest.h" -#include "dhdebug.h" -#include "dhesperrors.h" -#include "dhutils.h" -#include "dhstatistic.h" #define DHSENDER_RETRY_COUNT 5 diff --git a/firmware-src/sources/dhsender.h b/firmware-src/sources/dhsender.h index 5411f8e..2ae9c51 100644 --- a/firmware-src/sources/dhsender.h +++ b/firmware-src/sources/dhsender.h @@ -12,10 +12,10 @@ #ifndef _DHSENDER_H_ #define _DHSENDER_H_ -#include - #include "dhsender_data.h" +#include + /** Function prototype for new item in queue callback. */ typedef void (*dhsender_new_item_cb)(void); diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index 19d963c..150ea42 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -8,14 +8,15 @@ * Description: Helper function for sender data * */ - -#include -#include #include "dhsender_data.h" +#include "dhdata.h" #include "dhdebug.h" #include "dhgpio.h" #include "snprintf.h" +#include +#include + void ICACHE_FLASH_ATTR dhsender_data_parse_va(va_list ap, REQUEST_DATA_TYPE *data_type, SENDERDATA *data, unsigned int *data_len, unsigned int *pin) { diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index f2d9740..37b2c00 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -9,11 +9,12 @@ #ifndef _DHSENDER_DATA_H_ #define _DHSENDER_DATA_H_ -#include #include "user_config.h" #include "dhsettings.h" #include "dhutils.h" +#include + /** Data type that should be read from arguments and how it will be formatted in response or notification. */ typedef enum { RDT_CONST_STRING, ///< Constant pointer to char should be passed. Will be formatted as string. diff --git a/firmware-src/sources/dhsender_queue.c b/firmware-src/sources/dhsender_queue.c index 1ffd942..2e86dd6 100644 --- a/firmware-src/sources/dhsender_queue.c +++ b/firmware-src/sources/dhsender_queue.c @@ -8,11 +8,6 @@ * Description: Queue for dhsender * */ - -#include -#include -#include -#include #include "dhsender_queue.h" #include "user_config.h" #include "dhdebug.h" @@ -21,6 +16,13 @@ #include "dhmem.h" #include "dhsender_data.h" +#include +#include +#include +#include +#include +#include + LOCAL const char STATUS_OK[] = "OK"; LOCAL const char STATUS_ERROR[] = "Error"; LOCAL unsigned int mQueueMaxSize; diff --git a/firmware-src/sources/dhsender_queue.h b/firmware-src/sources/dhsender_queue.h index 519f61f..49ef5ce 100644 --- a/firmware-src/sources/dhsender_queue.h +++ b/firmware-src/sources/dhsender_queue.h @@ -9,9 +9,10 @@ #ifndef _DHSENDER_QUEUE_H_ #define _DHSENDER_QUEUE_H_ -#include #include "dhsender_data.h" +#include + /** * \brief Add new request for dhsender in queue. * \param[in] type Request type, see REQUEST_TYPE enum. diff --git a/firmware-src/sources/dhsettings.c b/firmware-src/sources/dhsettings.c index 485eca4..8f6602e 100644 --- a/firmware-src/sources/dhsettings.c +++ b/firmware-src/sources/dhsettings.c @@ -8,15 +8,17 @@ * Description: Module for storing settings in flash * */ +#include "dhsettings.h" +#include "snprintf.h" +#include "crc32.h" +#include "dhdebug.h" #include #include #include #include -#include "dhsettings.h" -#include "snprintf.h" -#include "crc32.h" -#include "dhdebug.h" +#include +#include // using main and backup storage to keep old setting in case of power loss during writing #define ESP_SETTINGS_MAIN_SEC 0x7A diff --git a/firmware-src/sources/dhspi.c b/firmware-src/sources/dhspi.c index 5793eee..0296cbc 100644 --- a/firmware-src/sources/dhspi.c +++ b/firmware-src/sources/dhspi.c @@ -8,12 +8,14 @@ * Description: SPI implementation * */ +#include "dhspi.h" +#include "dhgpio.h" #include #include #include -#include "dhspi.h" -#include "dhgpio.h" +#include +#include #define FUNC_HSPI 2 #define SPI_BASE 0x60000100 // HSPI diff --git a/firmware-src/sources/dhterminal.c b/firmware-src/sources/dhterminal.c index a190014..626618f 100644 --- a/firmware-src/sources/dhterminal.c +++ b/firmware-src/sources/dhterminal.c @@ -8,11 +8,6 @@ * Description: UART terminal implementation * */ - -#include -#include -#include -#include #include "dhterminal.h" #include "dhuart.h" #include "user_config.h" @@ -20,6 +15,13 @@ #include "dhterminal_commandline.h" #include "dhterminal_commands.h" +#include +#include +#include +#include +#include +#include + #define DEBUG_BUFF_SPACE_FOR_ONE_LINE 128 LOCAL DHTERMINAL_MODE mMode = SM_NORMAL_MODE; LOCAL char mDebugBuff[1024] = {0}; diff --git a/firmware-src/sources/dhterminal.h b/firmware-src/sources/dhterminal.h index 889ecd0..3ecc39b 100644 --- a/firmware-src/sources/dhterminal.h +++ b/firmware-src/sources/dhterminal.h @@ -8,6 +8,7 @@ #ifndef _DHTERMINAL_H_ #define _DHTERMINAL_H_ + #include /** Current terminal mode. */ diff --git a/firmware-src/sources/dhterminal_commandline.c b/firmware-src/sources/dhterminal_commandline.c index a4c1fa6..4856e31 100644 --- a/firmware-src/sources/dhterminal_commandline.c +++ b/firmware-src/sources/dhterminal_commandline.c @@ -8,12 +8,14 @@ * Description: Command line interpreter * */ - -#include -#include #include "dhterminal_commandline.h" #include "dhterminal_commands.h" #include "snprintf.h" +#include "dhuart.h" + +#include +#include +#include typedef void (*CommandFunc)(const char *arg); diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index 31f48e4..41edc62 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -8,17 +8,11 @@ * Description: Commandline command implementation * */ - -#include -#include -#include -#include -#include +#include "dhterminal_commands.h" #include "dhterminal.h" #include "dhuart.h" #include "snprintf.h" #include "dhconnector.h" -#include "dhterminal_commands.h" #include "dhsettings.h" #include "dhterminal_configure.h" #include "dhutils.h" @@ -26,6 +20,13 @@ #include "dhstatistic.h" #include "dhsender_queue.h" +#include +#include +#include +#include +#include +#include + int mIsCommandWorking = 0; char mHostBuffer[80]; diff --git a/firmware-src/sources/dhterminal_configure.c b/firmware-src/sources/dhterminal_configure.c index 0fa032f..a99c55b 100644 --- a/firmware-src/sources/dhterminal_configure.c +++ b/firmware-src/sources/dhterminal_configure.c @@ -8,9 +8,6 @@ * Description: 'configure' command implementation * */ - -#include -#include #include "dhterminal_configure.h" #include "dhuart.h" #include "dhterminal.h" @@ -20,6 +17,10 @@ #include "dhutils.h" #include "user_config.h" +#include +#include +#include + LOCAL char mComleaterBuff[48]; LOCAL void ICACHE_FLASH_ATTR get_accesskey_cb(const char *key) { diff --git a/firmware-src/sources/dhuart.c b/firmware-src/sources/dhuart.c index 0da14ae..1dda8f8 100644 --- a/firmware-src/sources/dhuart.c +++ b/firmware-src/sources/dhuart.c @@ -8,15 +8,16 @@ * Description: uart hal for esp8266 * */ +#include "dhuart.h" +#include "user_config.h" +#include "dhdebug.h" #include #include #include #include #include -#include "dhuart.h" -#include "user_config.h" -#include "dhdebug.h" +#include #define UART_BASE 0x60000000 #define UART_INTERUPTION_STATE_REGISTER (UART_BASE + 0x08) diff --git a/firmware-src/sources/dhutils.c b/firmware-src/sources/dhutils.c index 2819708..e77c063 100644 --- a/firmware-src/sources/dhutils.c +++ b/firmware-src/sources/dhutils.c @@ -9,7 +9,9 @@ * */ #include "dhutils.h" + #include +#include int ICACHE_FLASH_ATTR strToFloat(const char *ptr, float *result) { float res = 0.0f; diff --git a/firmware-src/sources/dhzc_dnsd.c b/firmware-src/sources/dhzc_dnsd.c index 06c5911..35f9aba 100644 --- a/firmware-src/sources/dhzc_dnsd.c +++ b/firmware-src/sources/dhzc_dnsd.c @@ -6,6 +6,10 @@ * Author: Nikolay Khabarov * */ +#include "dhzc_dnsd.h" +#include "dns.h" +#include "swab.h" +#include "dhdebug.h" #include #include @@ -13,10 +17,7 @@ #include #include #include -#include "dns.h" -#include "swab.h" -#include "dhdebug.h" -#include "dhzc_dnsd.h" +#include #define MAX_CONNECTIONS 2 diff --git a/firmware-src/sources/dhzc_pages.c b/firmware-src/sources/dhzc_pages.c index fdaacfd..5e9a03c 100644 --- a/firmware-src/sources/dhzc_pages.c +++ b/firmware-src/sources/dhzc_pages.c @@ -6,17 +6,19 @@ * Author: Nikolay Khabarov * */ - -#include -#include -#include +#include "dhzc_pages.h" #include "snprintf.h" #include "dhsettings.h" -#include "dhzc_pages.h" #include "rand.h" #include "user_config.h" #include "irom.h" +#include +#include +#include +#include +#include + #define DHZC_PAGE_TITLE_META "DeviceHive ESP8266 Configuration" #define DHZC_PAGE_MAX_SIZE 4096 diff --git a/firmware-src/sources/dhzc_post.c b/firmware-src/sources/dhzc_post.c index 5af21d7..462e94f 100644 --- a/firmware-src/sources/dhzc_post.c +++ b/firmware-src/sources/dhzc_post.c @@ -6,14 +6,15 @@ * Author: Nikolay Khabarov * */ +#include "dhzc_post.h" +#include "dhsettings.h" +#include "dhutils.h" #include #include #include #include -#include "dhsettings.h" -#include "dhutils.h" -#include "dhzc_post.h" +#include typedef int (*Char_Test)(char c); diff --git a/firmware-src/sources/dhzc_web.c b/firmware-src/sources/dhzc_web.c index cb24907..4060ffe 100644 --- a/firmware-src/sources/dhzc_web.c +++ b/firmware-src/sources/dhzc_web.c @@ -6,12 +6,7 @@ * Author: Nikolay Khabarov * */ - -#include "httpd.h" - -#include -#include -#include +#include "dhzc_web.h" #include "httpd.h" #include "dhdebug.h" #include "dhuart.h" @@ -19,6 +14,12 @@ #include "dhsettings.h" #include "dhzc_pages.h" #include "dhzc_post.h" +#include "httpd.h" + +#include +#include +#include +#include #define WEB_CONF_HOST "devicehive.config" #define RECONFIGURE_DELAY_MS 5000 diff --git a/firmware-src/sources/dns.c b/firmware-src/sources/dns.c index e358d61..fdc41d2 100644 --- a/firmware-src/sources/dns.c +++ b/firmware-src/sources/dns.c @@ -6,11 +6,8 @@ * Author: Nikolay Khabarov * */ - - #include "dns.h" #include "swab.h" -#include const uint8_t LOCAL_DOMAIN[] = "local"; diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index 6a92ad7..735521b 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -8,12 +8,6 @@ */ #include "httpd.h" - -#include -#include -#include -#include -#include #include "dhdebug.h" #include "dhesperrors.h" #include "dhsettings.h" @@ -24,6 +18,14 @@ #include "dhzc_post.h" #include "irom.h" #include "user_config.h" +#include "dhutils.h" + +#include +#include +#include +#include +#include +#include #define MAX_CONNECTIONS 5 #define POST_BUF_SIZE 2048 diff --git a/firmware-src/sources/main.c b/firmware-src/sources/main.c index 05dc465..a042699 100644 --- a/firmware-src/sources/main.c +++ b/firmware-src/sources/main.c @@ -8,17 +8,12 @@ * Description: DeviceHive firmware for ESP8266 * */ - -#include -#include -#include -#include -#include "gpio.h" #include "dhdebug.h" #include "dhuart.h" #include "dhsender_queue.h" #include "dhterminal.h" #include "dhsettings.h" +#include "dhconnector.h" #include "dhap.h" #include "dhgpio.h" #include "webserver.h" @@ -26,6 +21,14 @@ #include "uploadable_page.h" #include "dhzc_dnsd.h" #include "dhzc_web.h" +#include "mdnsd.h" + +#include +#include +#include +#include +#include +#include typedef struct { unsigned int magic; diff --git a/firmware-src/sources/mdnsd.c b/firmware-src/sources/mdnsd.c index d49cb2c..7be8797 100644 --- a/firmware-src/sources/mdnsd.c +++ b/firmware-src/sources/mdnsd.c @@ -6,6 +6,12 @@ * Author: Nikolay Khabarov * */ +#include "mdnsd.h" +#include "dns.h" +#include "swab.h" +#include "snprintf.h" +#include "dhdebug.h" +#include "user_config.h" #include #include @@ -13,12 +19,7 @@ #include #include #include -#include "mdnsd.h" -#include "dns.h" -#include "swab.h" -#include "snprintf.h" -#include "dhdebug.h" -#include "user_config.h" +#include #define MDNS_TTL (60 * 60) #define MDNS_MAX_PACKET_LENGTH 1024 diff --git a/firmware-src/sources/rand.c b/firmware-src/sources/rand.c index b59614c..ec8e4c6 100644 --- a/firmware-src/sources/rand.c +++ b/firmware-src/sources/rand.c @@ -8,11 +8,12 @@ * Description: Typical random implementation * */ - -#include #include "rand.h" #include "snprintf.h" +#include + + static unsigned long seed = 0; int ICACHE_FLASH_ATTR rand(void) { diff --git a/firmware-src/sources/rest.c b/firmware-src/sources/rest.c index 2cf402c..6ca43e7 100644 --- a/firmware-src/sources/rest.c +++ b/firmware-src/sources/rest.c @@ -6,11 +6,6 @@ * Author: Nikolay Khabarov * */ - -#include -#include -#include -#include #include "rest.h" #include "dhsettings.h" #include "dhcommands.h" @@ -19,6 +14,13 @@ #include "irom.h" #include "dhstatistic.h" +#include +#include +#include +#include +#include +#include + RO_DATA char desription[] = "This is firmware RESTfull API endpoint. "\ "Please follow the firmware manual to use it.
DeviceHive Firmware v"FIRMWARE_VERSION"
"\ diff --git a/firmware-src/sources/snprintf.c b/firmware-src/sources/snprintf.c index 9fec3ce..b1f85a0 100644 --- a/firmware-src/sources/snprintf.c +++ b/firmware-src/sources/snprintf.c @@ -10,10 +10,10 @@ */ #include "snprintf.h" - -#include "c_types.h" // ICACHE_FLASH_ATTR #include "irom.h" +#include // ICACHE_FLASH_ATTR + int ICACHE_FLASH_ATTR vsnprintf(char *pString, size_t length, const char *pFormat, va_list ap) { char digitBuffer[32]; diff --git a/firmware-src/sources/snprintf.h b/firmware-src/sources/snprintf.h index 33d435e..46cec0b 100644 --- a/firmware-src/sources/snprintf.h +++ b/firmware-src/sources/snprintf.h @@ -8,6 +8,7 @@ #ifndef _SNPRINTF_H_ #define _SNPRINTF_H_ + #include #include diff --git a/firmware-src/sources/uploadable_api.c b/firmware-src/sources/uploadable_api.c index 960564c..e077006 100644 --- a/firmware-src/sources/uploadable_api.c +++ b/firmware-src/sources/uploadable_api.c @@ -8,11 +8,12 @@ */ #include "uploadable_api.h" +#include "dhsettings.h" +#include "uploadable_page.h" #include #include -#include "dhsettings.h" -#include "uploadable_page.h" +#include HTTP_RESPONSE_STATUS ICACHE_FLASH_ATTR uploadable_api_handle(const char *path, const char *key, HTTP_CONTENT *content_in, HTTP_ANSWER *answer) { diff --git a/firmware-src/sources/uploadable_page.c b/firmware-src/sources/uploadable_page.c index a8790e5..1dcab8d 100644 --- a/firmware-src/sources/uploadable_page.c +++ b/firmware-src/sources/uploadable_page.c @@ -6,15 +6,17 @@ * Author: Nikolay Khabarov * */ +#include "uploadable_page.h" +#include "dhdebug.h" +#include "irom.h" #include #include #include #include +#include #include -#include "irom.h" -#include "uploadable_page.h" -#include "dhdebug.h" +#include /** Uploadable web page maximum length and ROM addresses. */ #define UPLOADABLE_PAGE_START_SECTOR 0x68 diff --git a/firmware-src/sources/webserver.c b/firmware-src/sources/webserver.c index 62ab1f4..25349f8 100644 --- a/firmware-src/sources/webserver.c +++ b/firmware-src/sources/webserver.c @@ -6,9 +6,6 @@ * Author: Nikolay Khabarov * */ - -#include -#include #include "webserver.h" #include "httpd.h" #include "rest.h" @@ -17,6 +14,10 @@ #include "uploadable_api.h" #include "irom.h" +#include +#include +#include + LOCAL int ICACHE_FLASH_ATTR check_rest(HTTP_RESPONSE_STATUS *res, const char *path, const char *key, HTTP_CONTENT *content_in, HTTP_ANSWER *answer) { static const char api[] = "/api"; diff --git a/sdk/include/ets_forward.h b/sdk/include/ets_forward.h new file mode 100644 index 0000000..26e408f --- /dev/null +++ b/sdk/include/ets_forward.h @@ -0,0 +1,56 @@ +#ifndef _ETS_FORWARD_H_ +#define _ETS_FORWARD_H_ + +#include +#include + +#include +#include + +void ets_install_putc1(void*); +void ets_isr_attach(int, void*, void*); +void ets_isr_mask(uint32_t); +void ets_isr_unmask(uint32_t); +void ets_intr_lock(void); +void ets_intr_unlock(void); + +// memory +int ets_memcmp(const void*, const void*, size_t); +void *ets_memcpy(void*, const void*, size_t); +void *ets_memset(void*, int, size_t); +void *ets_memmove(void*, const void*, size_t); +void ets_bzero(void*, size_t); + +// sprintf +int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +int os_printf_plus(const char *format, ...) __attribute__ ((format (printf, 1, 2))); + +// strings +int ets_strcmp(const char*, const char*); +int ets_strncmp(const char*, const char*, size_t); +char* ets_strcpy(char*, const char*); +char* ets_strncpy(char*, const char*, size_t); +size_t ets_strlen(const char*); +char *ets_strstr(const char*, const char*); +int ets_str2macaddr(void *, void *); +// int atoi(const char*); + +// timer +void ets_timer_arm_new(os_timer_t*, int, int, int); +void ets_timer_disarm(os_timer_t*); +void ets_timer_setfn(os_timer_t*, ETSTimerFunc*, void*); + +void ets_update_cpu_frequency(int freqmhz); +void uart_div_modify(int no, unsigned int freq); +uint8 wifi_get_opmode(void); +uint32 system_get_time(void); +int rand(void); +void ets_delay_us(int ms); + +// memory allocation +void *pvPortMalloc(size_t, const char *file, int line); +void *pvPortZalloc(size_t, const char *file, int line); +void vPortFree(void *ptr, const char *file, int line); + +#endif // _ETS_FORWARD_H_ From e65b24ddf1974908db85fc059bc6ca034197db9d Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 14:41:44 +0300 Subject: [PATCH 21/83] enable all warnings (-Wall) and clean some of them --- firmware-src/Makefile | 2 +- firmware-src/sources/crc32.c | 2 +- firmware-src/sources/devices/mfrc522.c | 4 ++-- firmware-src/sources/dhcommands.c | 2 ++ firmware-src/sources/dhconnector.c | 8 +++----- firmware-src/sources/dhconnector_websocket.c | 2 +- firmware-src/sources/dhconnector_websocket_api.c | 2 +- firmware-src/sources/dhesperrors.c | 4 ++-- firmware-src/sources/dhesperrors.h | 4 +++- firmware-src/sources/dhgpio.c | 4 ++-- firmware-src/sources/dhonewire.c | 8 ++++---- firmware-src/sources/dhsender_data.c | 4 ++-- firmware-src/sources/dhsettings.c | 4 ++-- firmware-src/sources/dhterminal_commands.c | 4 ++-- firmware-src/sources/dhuart.c | 2 +- firmware-src/sources/httpd.c | 2 +- firmware-src/sources/irom.h | 6 ++++++ firmware-src/sources/mdnsd.c | 2 +- sdk/include/eagle_soc.h | 4 ++-- 19 files changed, 39 insertions(+), 31 deletions(-) diff --git a/firmware-src/Makefile b/firmware-src/Makefile index 3d7d0ff..42fdbd9 100644 --- a/firmware-src/Makefile +++ b/firmware-src/Makefile @@ -19,7 +19,7 @@ LIBS = $(addprefix -l,c gcc phy pp net80211 lwip wpa main json crypto) SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:%.c=%.o)) GITVER = $(shell git rev-parse HEAD 2> /dev/null || echo \"not a git repo\") -CFLAGS = -O2 -Wpointer-arith -Wundef -Werror -Wunused -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -nostdlib -std=gnu89 -DFIRMWARE_GIT_REVISION=\"$(GITVER)\" +CFLAGS = -O2 -Wall -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -nostdlib -std=gnu89 -DFIRMWARE_GIT_REVISION=\"$(GITVER)\" LDFLAGS = -u call_user_start -Wl,-static -nostdlib CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar diff --git a/firmware-src/sources/crc32.c b/firmware-src/sources/crc32.c index 4ba0363..60ad2a5 100644 --- a/firmware-src/sources/crc32.c +++ b/firmware-src/sources/crc32.c @@ -43,7 +43,7 @@ #include "crc32.h" #include "irom.h" -RO_DATA uint32_t crc32_tab[] = { +static const uint32_t crc32_tab[] DH_RO_ATTR = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, diff --git a/firmware-src/sources/devices/mfrc522.c b/firmware-src/sources/devices/mfrc522.c index 8980e2e..ec8faea 100644 --- a/firmware-src/sources/devices/mfrc522.c +++ b/firmware-src/sources/devices/mfrc522.c @@ -1430,7 +1430,7 @@ void ICACHE_FLASH_ATTR MFRC522_PICC_DumpMifareClassicSectorToSerial(MFRC522_Uid // The four CX bits are stored together in a nible cx and an inverted nible cx_. uint8_t c1, c2, c3; // Nibbles uint8_t c1_, c2_, c3_; // Inverted nibbles - bool invertedError; // True if one of the inverted nibbles did not match + bool invertedError = false; // True if one of the inverted nibbles did not match uint8_t g[4]; // Access bits for each of the four groups. uint8_t group; // 0-3 - active group for access bits bool firstInGroup; // True for the first block dumped in the group @@ -1701,7 +1701,7 @@ bool ICACHE_FLASH_ATTR MFRC522_MIFARE_SetUid(uint8_t *newUid, uint8_t uidSize, b } // Authenticate for reading - MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + MIFARE_Key key = {.keyByte = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; MFRC522_StatusCode status = MFRC522_PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, (uint8_t)1, &key, &uid); if (status != MFRC522_STATUS_OK) { diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 2d3ecda..7cac0c0 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -101,6 +101,8 @@ LOCAL char *ICACHE_FLASH_ATTR i2c_status_tochar(DHI2C_STATUS status) { return "Bus is busy"; case DHI2C_DEVICE_ERROR: return "Device error"; + case DHI2C_OK: + break; } return 0; } diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index 94d2e80..df0f099 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -146,7 +146,7 @@ LOCAL void ICACHE_FLASH_ATTR network_recv_cb(void *arg, char *data, unsigned sho } LOCAL void network_connect_cb(void *arg) { - HTTP_REQUEST *request; + HTTP_REQUEST *request = 0; uint32_t keepalive; espconn_set_opt(&mDHConnector, ESPCONN_KEEPALIVE); //set keepalive: 120s = 90 + 10 * 3 @@ -165,8 +165,7 @@ LOCAL void network_connect_cb(void *arg) { request = dhrequest_create_wsrequest(dhsettings_get_devicehive_server(), mWSUrl); dhdebug("Send web socket upgrade request..."); break; - // TODO TODO TODO - /*case CS_POLL: + /* TODO case CS_POLL: case CS_CUSTOM: request = custom_firmware_request(); if(request) { @@ -200,8 +199,7 @@ LOCAL void network_disconnect_cb(void *arg) { mConnectionState = CS_DISCONNECT; arm_repeat_timer(RETRY_CONNECTION_INTERVAL_MS); break; -/* TODO TODO TODO - case CS_CUSTOM: +/* TODO case CS_CUSTOM: if(dhterminal_is_in_use()) { dhdebug("Terminal is in use, no deep sleep"); arm_repeat_timer(CUSTOM_NOTIFICATION_INTERVAL_MS); diff --git a/firmware-src/sources/dhconnector_websocket.c b/firmware-src/sources/dhconnector_websocket.c index cd8dfb9..6094742 100644 --- a/firmware-src/sources/dhconnector_websocket.c +++ b/firmware-src/sources/dhconnector_websocket.c @@ -39,7 +39,7 @@ LOCAL char mBuf[PAYLOAD_BUF_SIZE + WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SI LOCAL char *mPayLoadBuf = &mBuf[WEBSOCKET_HEADER_MAX_SIZE + WEBSOCKET_MASK_SIZE]; LOCAL int mPayLoadBufLen = 0; -LOCAL void ICACHE_FLASH_ATTR error(data, len) { +LOCAL void ICACHE_FLASH_ATTR error(const char *data, unsigned int len) { mErrFunc(); dhsender_current_fail(); char b[len + 1]; diff --git a/firmware-src/sources/dhconnector_websocket_api.c b/firmware-src/sources/dhconnector_websocket_api.c index a576bec..58d715b 100644 --- a/firmware-src/sources/dhconnector_websocket_api.c +++ b/firmware-src/sources/dhconnector_websocket_api.c @@ -41,7 +41,7 @@ int ICACHE_FLASH_ATTR dhconnector_websocket_api_communicate(const char *in, unsi int status_not_success = 1; char action[32]; char command[128]; - const char *params; + const char *params = 0; unsigned int paramslen = 0; unsigned int id = 0; action[0] = 0; diff --git a/firmware-src/sources/dhesperrors.c b/firmware-src/sources/dhesperrors.c index 0d660d0..d9096ab 100644 --- a/firmware-src/sources/dhesperrors.c +++ b/firmware-src/sources/dhesperrors.c @@ -15,7 +15,7 @@ #include #include -void ICACHE_FLASH_ATTR dhesperrors_disconnect_reason(const char *descrption, uint8 reason) { +void ICACHE_FLASH_ATTR dhesperrors_disconnect_reason(const char *descrption, uint8_t reason) { char *errdescr = 0; switch(reason) { case REASON_UNSPECIFIED: @@ -149,7 +149,7 @@ void ICACHE_FLASH_ATTR dhesperrors_espconn_result(const char *descrption, int re dhdebug("%s %d", descrption, reason); } -void ICACHE_FLASH_ATTR dhesperrors_wifi_state(const char *descrption, uint8 reason) { +void ICACHE_FLASH_ATTR dhesperrors_wifi_state(const char *descrption, uint8_t reason) { char *errdescr = 0; switch(reason) { case EVENT_STAMODE_CONNECTED: diff --git a/firmware-src/sources/dhesperrors.h b/firmware-src/sources/dhesperrors.h index 7ceb7c0..3d1bdc7 100644 --- a/firmware-src/sources/dhesperrors.h +++ b/firmware-src/sources/dhesperrors.h @@ -16,7 +16,7 @@ * \param[in] descrption Text that will be printed before error description. * \param[in] reason Disconnect reason. */ -void dhesperrors_disconnect_reason(const char *descrption, uint8 reason); +void dhesperrors_disconnect_reason(const char *descrption, uint8_t reason); /** * \brief Print espconn result. @@ -25,4 +25,6 @@ void dhesperrors_disconnect_reason(const char *descrption, uint8 reason); */ void dhesperrors_espconn_result(const char *descrption, int reason); +void dhesperrors_wifi_state(const char *descrption, uint8_t reason); + #endif /* _DHESPERRORS_H_ */ diff --git a/firmware-src/sources/dhgpio.c b/firmware-src/sources/dhgpio.c index eae162d..729514c 100644 --- a/firmware-src/sources/dhgpio.c +++ b/firmware-src/sources/dhgpio.c @@ -57,7 +57,7 @@ void ICACHE_FLASH_ATTR dhgpio_open_drain(unsigned int pin_mask_set_od, unsigned int i; for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { unsigned int pin = BIT(i); - if(pin & DHGPIO_SUITABLE_PINS == 0) + if((pin & DHGPIO_SUITABLE_PINS) == 0) continue; if(pin & pin_mask_set_od) { const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE); @@ -185,7 +185,7 @@ LOCAL int ICACHE_FLASH_ATTR dhgpio_set_int(unsigned int disable_mask, unsigned i int i; for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { const unsigned int pin = 1 << i; - if(pin & DHGPIO_SUITABLE_PINS == 0) + if((pin & DHGPIO_SUITABLE_PINS) == 0) continue; else if(pin & disable_mask) gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_DISABLE); diff --git a/firmware-src/sources/dhonewire.c b/firmware-src/sources/dhonewire.c index e82e846..c203412 100644 --- a/firmware-src/sources/dhonewire.c +++ b/firmware-src/sources/dhonewire.c @@ -33,12 +33,12 @@ LOCAL os_timer_t mOWIntTimer; #define ONEWIRE_DHT_RESET_LENGTH_US 25000 #define ONEWIRE_DHT_TIMEOUT_US 200 -LOCAL ICACHE_FLASH_ATTR lock_int(void) { +LOCAL void ICACHE_FLASH_ATTR lock_int(void) { if(mIntPins) dhgpio_subscribe_extra_int(mIntPins, 0, 0, 0); } -LOCAL ICACHE_FLASH_ATTR unlock_int(void) { +LOCAL void ICACHE_FLASH_ATTR unlock_int(void) { GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, mIntPins); dhgpio_subscribe_extra_int(0, 0, mIntPins, 0); } @@ -66,7 +66,7 @@ LOCAL int ICACHE_FLASH_ATTR dhonewire_reset(unsigned int pin, unsigned int reset gpio_output_set(pin, 0, pin, 0); os_delay_us(500); } - if(gpio_input_get() & pin == 0) + if((gpio_input_get() & pin) == 0) return 0; // send RESET gpio_output_set(0, pin, pin, 0); @@ -186,7 +186,7 @@ int ICACHE_FLASH_ATTR dhonewire_search(char *buf, unsigned long *len, char comma ambiguity = -1; for(i = 0; i < bitCount; i++) { const int byte = i / 8; - if(gpio_input_get() & pin == 0) { + if((gpio_input_get() & pin) == 0) { unlock_int(); return 0; } diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index 150ea42..0713eec 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -65,7 +65,7 @@ LOCAL unsigned int ICACHE_FLASH_ATTR gpio_state(char *buf, unsigned int i; for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { const unsigned int pin = 1 << i; - const pinvalue = (state & pin) ? 1 : 0; + const int pinvalue = (state & pin) ? 1 : 0; if(suitable & pin) { len += snprintf(&buf[len], buflen - len, (i == 0) ? "\"%d\":%d" : ", \"%d\":%d", i, pinvalue); } @@ -80,7 +80,7 @@ LOCAL unsigned int ICACHE_FLASH_ATTR gpio_notification(char *buf, int comma = 0; for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { const unsigned int pin = 1 << i; - if(suitable & pin == 0) + if((suitable & pin) == 0) continue; if( pin & data->caused) { len += snprintf(&buf[len], buflen - len, comma?", \"%d\"":"\"%d\"", i); diff --git a/firmware-src/sources/dhsettings.c b/firmware-src/sources/dhsettings.c index 8f6602e..35f0b12 100644 --- a/firmware-src/sources/dhsettings.c +++ b/firmware-src/sources/dhsettings.c @@ -86,12 +86,12 @@ int ICACHE_FLASH_ATTR dhsettings_init(int *exist) { LOCAL int ICACHE_FLASH_ATTR dhsettings_write(const DH_SETTINGS_DATA * data) { int res = 1; - DH_SETTINGS *settings = (DH_SETTINGS *)os_malloc(sizeof(DH_SETTINGS)); + DH_SETTINGS *settings = (DH_SETTINGS *)os_malloc(sizeof(*settings)); if(settings == NULL) { dhdebug("Failed to write settings, no RAM."); return 0; } - os_memset(settings, 0x0, sizeof(DH_SETTINGS)); + os_memset(settings, 0x0, sizeof(*settings)); if(data) os_memcpy(&settings->data, data, sizeof(DH_SETTINGS_DATA)); settings->crc = getStorageCrc(settings); diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index 41edc62..ac146ae 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -49,7 +49,7 @@ LOCAL void ICACHE_FLASH_ATTR printBytes(char *buff, unsigned long long bytes) { else if(bytes > 1024) snprintf(buff, 16, "%f KiB", bytes/1024.0); else - snprintf(buff, 16, "%u B", (unsigned long)bytes); + snprintf(buff, 16, "%u B", (unsigned int)bytes); } LOCAL void ICACHE_FLASH_ATTR sprintMac(char *buff, const uint8 *mac) { @@ -231,7 +231,7 @@ LOCAL void ICACHE_FLASH_ATTR scan_done_cb (void *arg, STATUS status) { else dhuart_send_line("No wireless networks found."); while(link) { - char * auth; + char * auth = 0; switch(link->authmode) { case AUTH_OPEN: auth = "open"; diff --git a/firmware-src/sources/dhuart.c b/firmware-src/sources/dhuart.c index 1dda8f8..9987e57 100644 --- a/firmware-src/sources/dhuart.c +++ b/firmware-src/sources/dhuart.c @@ -60,7 +60,7 @@ LOCAL void ICACHE_FLASH_ATTR buf_timeout(void *arg) { LOCAL ICACHE_FLASH_ATTR void arm_buf_timer(void) { os_timer_disarm(&mUartTimer); os_timer_setfn(&mUartTimer, (os_timer_func_t *)buf_timeout, NULL); - os_timer_arm(&mUartTimer, (mUartTimerTimeout == 0 | mUartBufPos >= INTERFACES_BUF_SIZE) ? 1 :mUartTimerTimeout, 0); + os_timer_arm(&mUartTimer, (mUartTimerTimeout == 0 || mUartBufPos >= INTERFACES_BUF_SIZE) ? 1 :mUartTimerTimeout, 0); } LOCAL void dhuart_intr_handler(void *arg) { diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index 735521b..2ee143f 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -94,7 +94,7 @@ LOCAL int ICACHE_FLASH_ATTR dequeue(struct espconn *conn, int send) { } } if(mContentQueue[i].free_mem) { - os_free(mContentQueue[i].content.data); + os_free((void*)mContentQueue[i].content.data); } mContentQueue[i].remote_port = 0; return 1; diff --git a/firmware-src/sources/irom.h b/firmware-src/sources/irom.h index 5a9864f..f7dc32c 100644 --- a/firmware-src/sources/irom.h +++ b/firmware-src/sources/irom.h @@ -39,6 +39,12 @@ #define RO_DATA const ICACHE_RODATA_ATTR STORE_ATTR static +/** + * @brief Compile time attribute to store data in ROM memory. + */ +#define DH_RO_ATTR ICACHE_RODATA_ATTR STORE_ATTR + + /** * @brief Check if pointer is stored in ROM. * @param[in] ptr Pointer to check. diff --git a/firmware-src/sources/mdnsd.c b/firmware-src/sources/mdnsd.c index 7be8797..0a4de4c 100644 --- a/firmware-src/sources/mdnsd.c +++ b/firmware-src/sources/mdnsd.c @@ -32,7 +32,7 @@ LOCAL unsigned long mAddr; LOCAL struct espconn mMDNSdConn = { 0 }; LOCAL struct ip_addr mMDNSAddr = { 0 }; LOCAL esp_udp mDNSdUdp; -LOCAL mSendingInProgress = 0; +LOCAL int mSendingInProgress = 0; LOCAL struct ip_addr mMulticastIP = { MDNS_IP }; LOCAL void ICACHE_FLASH_ATTR announce(const uint8_t *data, uint32_t len) { diff --git a/sdk/include/eagle_soc.h b/sdk/include/eagle_soc.h index 8d0e877..9b542a9 100644 --- a/sdk/include/eagle_soc.h +++ b/sdk/include/eagle_soc.h @@ -269,8 +269,8 @@ #define PIN_FUNC_SELECT(PIN_NAME, FUNC) do { \ WRITE_PERI_REG(PIN_NAME, \ - READ_PERI_REG(PIN_NAME) \ - & (~(PERIPHS_IO_MUX_FUNC< Date: Wed, 19 Apr 2017 15:00:54 +0300 Subject: [PATCH 22/83] avoid using non-SDK headers: string.h, stdio.h, ctype.h --- firmware-src/Makefile | 6 ++---- firmware-src/sources/dhsender.c | 1 - firmware-src/sources/snprintf.c | 2 +- firmware-src/sources/snprintf.h | 2 +- sdk/include/osapi.h | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/firmware-src/Makefile b/firmware-src/Makefile index 42fdbd9..32fda53 100644 --- a/firmware-src/Makefile +++ b/firmware-src/Makefile @@ -2,18 +2,16 @@ # Author Nikolay Khabarov ifeq ($(OS),Windows_NT) CROSS_COMPILE ?= c:/Espressif/xtensa-lx106-elf/bin/xtensa-lx106-elf- - SINCLUDE = else CROSS_COMPILE ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin/xtensa-lx106-elf- - SINCLUDE = /usr/include endif -SDKPATH = ./../sdk +SDKPATH = $(CURDIR)/../sdk FIRMWARE = firmware/devicehive.bin OBJDIR = build TARGETAR = $(OBJDIR)/devicehive.a TARGETELF = $(OBJDIR)/devicehive.elf -INCLUDEDIRS = $(addprefix -I,$(SDKPATH)/include sources $(CURDIR) $(SINCLUDE)) +INCLUDEDIRS = $(addprefix -I,$(SDKPATH)/include $(CURDIR)/sources) LIBDIR = $(addprefix -L,$(SDKPATH)/lib) LIBS = $(addprefix -l,c gcc phy pp net80211 lwip wpa main json crypto) SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) diff --git a/firmware-src/sources/dhsender.c b/firmware-src/sources/dhsender.c index cf00ce0..ebed1d7 100644 --- a/firmware-src/sources/dhsender.c +++ b/firmware-src/sources/dhsender.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/firmware-src/sources/snprintf.c b/firmware-src/sources/snprintf.c index b1f85a0..9cbfcd1 100644 --- a/firmware-src/sources/snprintf.c +++ b/firmware-src/sources/snprintf.c @@ -99,7 +99,7 @@ int ICACHE_FLASH_ATTR vsnprintf(char *pString, size_t length, const char *pForma } break; default: - return EOF; + return -1; // EOF } pFormat++; diff --git a/firmware-src/sources/snprintf.h b/firmware-src/sources/snprintf.h index 46cec0b..dd57608 100644 --- a/firmware-src/sources/snprintf.h +++ b/firmware-src/sources/snprintf.h @@ -9,7 +9,7 @@ #ifndef _SNPRINTF_H_ #define _SNPRINTF_H_ -#include +#include #include /** diff --git a/sdk/include/osapi.h b/sdk/include/osapi.h index 4550067..57a4f3d 100644 --- a/sdk/include/osapi.h +++ b/sdk/include/osapi.h @@ -25,7 +25,7 @@ #ifndef _OSAPI_H_ #define _OSAPI_H_ -#include +#include #include "user_config.h" #define os_bzero ets_bzero From 21f5b5012082af47eba9cb4499d5f418bba46464 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 16:14:02 +0300 Subject: [PATCH 23/83] review the GPIO module - move GPIO module into DH/ subdirectory, `#include "DH/gpio.h" - module name prefix is `dh_gpio_` - !!! all GPIO functions return zero as "success" indicator !!! --- firmware-src/Makefile | 2 +- firmware-src/sources/DH/gpio.c | 341 ++++++++++++++++++++++++ firmware-src/sources/DH/gpio.h | 165 ++++++++++++ firmware-src/sources/devices/max31855.c | 4 +- firmware-src/sources/devices/max6675.c | 4 +- firmware-src/sources/devices/pca9685.c | 10 +- firmware-src/sources/dhcommand_parser.c | 10 +- firmware-src/sources/dhcommand_parser.h | 8 +- firmware-src/sources/dhcommands.c | 27 +- firmware-src/sources/dhgpio.c | 227 ---------------- firmware-src/sources/dhgpio.h | 124 --------- firmware-src/sources/dhi2c.c | 10 +- firmware-src/sources/dhnotification.c | 6 +- firmware-src/sources/dhonewire.c | 22 +- firmware-src/sources/dhpwm.c | 14 +- firmware-src/sources/dhsender_data.c | 13 +- firmware-src/sources/dhsender_queue.c | 1 - firmware-src/sources/dhspi.c | 16 +- firmware-src/sources/main.c | 6 +- 19 files changed, 584 insertions(+), 426 deletions(-) create mode 100644 firmware-src/sources/DH/gpio.c create mode 100644 firmware-src/sources/DH/gpio.h delete mode 100644 firmware-src/sources/dhgpio.c delete mode 100644 firmware-src/sources/dhgpio.h diff --git a/firmware-src/Makefile b/firmware-src/Makefile index 32fda53..ba6ca8a 100644 --- a/firmware-src/Makefile +++ b/firmware-src/Makefile @@ -14,7 +14,7 @@ TARGETELF = $(OBJDIR)/devicehive.elf INCLUDEDIRS = $(addprefix -I,$(SDKPATH)/include $(CURDIR)/sources) LIBDIR = $(addprefix -L,$(SDKPATH)/lib) LIBS = $(addprefix -l,c gcc phy pp net80211 lwip wpa main json crypto) -SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) +SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) $(wildcard sources/DH/*.c) OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:%.c=%.o)) GITVER = $(shell git rev-parse HEAD 2> /dev/null || echo \"not a git repo\") CFLAGS = -O2 -Wall -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -nostdlib -std=gnu89 -DFIRMWARE_GIT_REVISION=\"$(GITVER)\" diff --git a/firmware-src/sources/DH/gpio.c b/firmware-src/sources/DH/gpio.c new file mode 100644 index 0000000..60d05f9 --- /dev/null +++ b/firmware-src/sources/DH/gpio.c @@ -0,0 +1,341 @@ +/** + * @file + * @brief GPIO hardware access layer for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/gpio.h" + +#include "user_config.h" +#include "dhpwm.h" +#include "dhmem.h" + +#include +#include +#include +#include +#include + +// module variables +static os_timer_t mTimer; +static unsigned int mTimeoutMs = 250; +static unsigned char mTimerArmed = 0; +static DHGpioPinMask mTriggeredIntrPins = 0; +static DHGpioPinMask mExternalIntPins = 0; + + +static void timeout_cb(void *arg); +static void int_cb(void *arg); + + +/* + * dh_gpio_init() implementation. + */ +void ICACHE_FLASH_ATTR dh_gpio_init(void) +{ + ETS_GPIO_INTR_ATTACH(int_cb, NULL); + ETS_GPIO_INTR_ENABLE(); +} + + +/* + * dh_gpio_prepare_pins() implementation. + */ +void ICACHE_FLASH_ATTR dh_gpio_prepare_pins(DHGpioPinMask pins, bool disable_pwm) +{ + if (disable_pwm) + dhpwm_disable_pins(pins); + + // only suitable pins are checked: GPIO0..GPIO5 + if (pins & DH_GPIO_PIN(0)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); + if (pins & DH_GPIO_PIN(1)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); + if (pins & DH_GPIO_PIN(2)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); + if (pins & DH_GPIO_PIN(3)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3); + if (pins & DH_GPIO_PIN(4)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4); + if (pins & DH_GPIO_PIN(5)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5); + + // only suitable pins are checked: GPIO12..GPIO15 + if (pins & DH_GPIO_PIN(12)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); + if (pins & DH_GPIO_PIN(13)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); + if (pins & DH_GPIO_PIN(14)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); + if (pins & DH_GPIO_PIN(15)) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); +} + + +/* + * dh_gpio_open_drain() implementation. + */ +void ICACHE_FLASH_ATTR dh_gpio_open_drain(DHGpioPinMask pins_enable, DHGpioPinMask pins_disable) +{ + int i; + for (i = 0; i < DH_GPIO_PIN_COUNT; ++i) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); + if (!(pin & DH_GPIO_SUITABLE_PINS)) + continue; // skip unsuitable pins + + else if (pin & pins_enable) { + const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) + | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE); + + GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(i)), reg); + } else if (pin & pins_disable) { + const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) + | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE); + GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(i)), reg); + } + } +} + + +/* + * dh_gpio_pull() implementation. + */ +void ICACHE_FLASH_ATTR dh_gpio_pull_up(DHGpioPinMask pins_enable, DHGpioPinMask pins_disable) +{ + // enable suitable GPIO pins + if (pins_enable & DH_GPIO_PIN(0)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO0_U); + if (pins_enable & DH_GPIO_PIN(1)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_U0TXD_U); + if (pins_enable & DH_GPIO_PIN(2)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO2_U); + if (pins_enable & DH_GPIO_PIN(3)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_U0RXD_U); + if (pins_enable & DH_GPIO_PIN(4)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U); + if (pins_enable & DH_GPIO_PIN(5)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO5_U); + if (pins_enable & DH_GPIO_PIN(12)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDI_U); + if (pins_enable & DH_GPIO_PIN(13)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); + if (pins_enable & DH_GPIO_PIN(14)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_MTMS_U); + if (pins_enable & DH_GPIO_PIN(15)) + PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDO_U); + + // disable suitable GPIO pins + if (pins_disable & DH_GPIO_PIN(0)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U); + if (pins_disable & DH_GPIO_PIN(1)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + if (pins_disable & DH_GPIO_PIN(2)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); + if (pins_disable & DH_GPIO_PIN(3)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0RXD_U); + if (pins_disable & DH_GPIO_PIN(4)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO4_U); + if (pins_disable & DH_GPIO_PIN(5)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO5_U); + if (pins_disable & DH_GPIO_PIN(12)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); + if (pins_disable & DH_GPIO_PIN(13)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); + if (pins_disable & DH_GPIO_PIN(14)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); + if (pins_disable & DH_GPIO_PIN(15)) + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDO_U); +} + + +/* + * dh_gpio_write() implementation. + */ +int ICACHE_FLASH_ATTR dh_gpio_write(DHGpioPinMask pins_set, DHGpioPinMask pins_unset) +{ + const DHGpioPinMask pins = pins_set | pins_unset; + if (pins & ~DH_GPIO_SUITABLE_PINS) + return -1; // unsuitable pins + + dh_gpio_prepare_pins(pins, true/*disable_pwm*/); + dh_gpio_open_drain(0, pins); + dh_gpio_pull_up(0, pins); + gpio_output_set(pins_set, pins_unset, pins, 0); + return 0; // OK +} + + +/* + * dh_gpio_input() implementation. + */ +int ICACHE_FLASH_ATTR dh_gpio_input(DHGpioPinMask pins_init, + DHGpioPinMask pins_pullup, + DHGpioPinMask pins_nopull) +{ + const DHGpioPinMask pins = pins_init | pins_pullup | pins_nopull; + if (pins & ~DH_GPIO_SUITABLE_PINS) + return -1; // unsuitable pins + if (pins_pullup & pins_nopull) + return -2; // bad input parameters + + // initialize + dh_gpio_prepare_pins(pins, true/*disable_pwm*/); + gpio_output_set(0, 0, 0, pins); + + // pull-up + dh_gpio_pull_up(pins_pullup, pins_nopull); + + return 0; // OK +} + + +/* + * dh_gpio_read() implementation. + */ +DHGpioPinMask ICACHE_FLASH_ATTR dh_gpio_read(void) +{ + return gpio_input_get() & DH_GPIO_SUITABLE_PINS; +} + + +/** + * @brief Timeout callback. + */ +static void ICACHE_FLASH_ATTR timeout_cb(void *arg) +{ + // call external handler + dh_gpio_int_cb(mTriggeredIntrPins); + + mTriggeredIntrPins = 0; + mTimerArmed = 0; +} + +/** + * @brief Interruption handler. + */ +static void int_cb(void *arg) +{ + uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); + if (gpio_status & mExternalIntPins) { + dh_gpio_extra_int_cb(gpio_status & mExternalIntPins); + gpio_status &= ~mExternalIntPins; + if (!gpio_status) + return; + } + + mTriggeredIntrPins |= gpio_status; + if (mTimerArmed) + return; + + os_timer_disarm(&mTimer); + if (mTimeoutMs) { + mTimerArmed = 1; + os_timer_setfn(&mTimer, timeout_cb, NULL); + os_timer_arm(&mTimer, mTimeoutMs, 0); + } else { + timeout_cb(0); + } +} + + +/** + * @brief Enable GPIO interruption. + * @return Zero on success. + */ +static int ICACHE_FLASH_ATTR dh_gpio_set_int(DHGpioPinMask pins_disable, + DHGpioPinMask pins_rising, + DHGpioPinMask pins_falling, + DHGpioPinMask pins_both) +{ + DHGpioPinMask pins = pins_disable; + if (pins & pins_rising) + return -2; // bad input parameters + pins |= pins_rising; + if (pins & pins_falling) + return -2; // bad input parameters + pins |= pins_falling; + if (pins & pins_both) + return -2; // bad input parameters + pins |= pins_both; + if (pins & ~DH_GPIO_SUITABLE_PINS) + return -1; // unsuitable pins + + int i; + for (i = 0; i < DH_GPIO_PIN_COUNT; ++i) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); + if (!(pin & DH_GPIO_SUITABLE_PINS)) + continue; // skip unsuitable pins + + else if(pin & pins_disable) + gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_DISABLE); + else if(pin & pins_falling) + gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_POSEDGE); + else if(pin & pins_rising) + gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_NEGEDGE); + else if(pin & pins_both) + gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE); + } + + return 0; // OK +} + + +/* + * dh_gpio_subscribe_int() implementation. + */ +int ICACHE_FLASH_ATTR dh_gpio_subscribe_int(DHGpioPinMask pins_disable, + DHGpioPinMask pins_rising, + DHGpioPinMask pins_falling, + DHGpioPinMask pins_both, + unsigned int timeout_ms) +{ + const DHGpioPinMask pins = pins_disable | pins_rising | pins_falling | pins_both; + if (!!dh_gpio_subscribe_extra_int(pins, 0, 0, 0)) + return -1; // failed to disable all extra interruptions + + // subscribe + int r = dh_gpio_set_int(pins_disable, + pins_rising, + pins_falling, + pins_both); + if (0 == r) { + // OK, save timeout... + mTimeoutMs = timeout_ms; + } + + return r; +} + + +/* + * dh_gpio_get_timeout() implementation. + */ +unsigned int ICACHE_FLASH_ATTR dh_gpio_get_timeout(void) +{ + return mTimeoutMs; +} + + +/* + * dh_gpio_subscribe_extra_int() implementation. + */ +int ICACHE_FLASH_ATTR dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, + DHGpioPinMask pins_rising, + DHGpioPinMask pins_falling, + DHGpioPinMask pins_both) +{ + pins_disable &= mExternalIntPins; + int r = dh_gpio_set_int(pins_disable, + pins_rising, + pins_falling, + pins_both); + if (0 == r) { + // OK, update corresponding register + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, pins_disable); + mExternalIntPins |= pins_rising | pins_falling | pins_both; + mExternalIntPins &= ~pins_disable; + } + + return r; +} diff --git a/firmware-src/sources/DH/gpio.h b/firmware-src/sources/DH/gpio.h new file mode 100644 index 0000000..fd56e6a --- /dev/null +++ b/firmware-src/sources/DH/gpio.h @@ -0,0 +1,165 @@ +/** + * @file + * @brief GPIO hardware access layer for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DH_GPIO_H_ +#define _DH_GPIO_H_ + +#include + +/** + * @brief Pin mask type. + */ +typedef uint32_t DHGpioPinMask; + + +/** + * @brief Get pin mask. + * @param[in] num Pin number [0..DH_GPIO_PIN_COUNT). + */ +#define DH_GPIO_PIN(num) ((DHGpioPinMask)BIT(num)) + + +/** + * @brief Total number of GPIO pins. + */ +#define DH_GPIO_PIN_COUNT 16 + + +/** + * @brief Bitwise pin mask for pins that can be used. + * + * Pins: `GPIO0..GPIO5`, `GPIO12..GPIO15`. + */ +#define DH_GPIO_SUITABLE_PINS ( DH_GPIO_PIN(0) | DH_GPIO_PIN(1) | DH_GPIO_PIN(2) \ + | DH_GPIO_PIN(3) | DH_GPIO_PIN(4) | DH_GPIO_PIN(5) \ + | DH_GPIO_PIN(12)| DH_GPIO_PIN(13) \ + | DH_GPIO_PIN(14)| DH_GPIO_PIN(15) ) + + +/** + * @brief Initialize GPIO sub-system. + */ +void dh_gpio_init(void); + + +/** + * @brief Prepare pins for using as GPIO. + * + * Only suitable pins can be used. + * + * @param[in] pin_mask Bitwise pin mask to use as GPIO pins. + * @param[in] disable_pwm Flag to disable PWM if it was enabled before. + */ +void dh_gpio_prepare_pins(DHGpioPinMask pins, bool disable_pwm); + + +/** + * @brief Enable/disable open-drain switch for GPIO output. + * + * Only suitable pins can be used. + * + * @param[in] pins_enable Bitwise pin mask to enable. + * @param[in] pins_disable Bitwise pin mask to disable. + */ +void dh_gpio_open_drain(DHGpioPinMask pins_enable, + DHGpioPinMask pins_disable); + + +/** + * @brief Enable/disable pull-up GPIO pins. + * + * Only suitable pins can be used. + * + * @param[in] pins_enable Bitwise pin mask to enable. + * @param[in] pins_disable Bitwise pin mask to disable. + */ +void dh_gpio_pull_up(DHGpioPinMask pins_enable, + DHGpioPinMask pins_disable); + + +/** + * @brief Set GPIO outputs state. + * @param[in] pins_set Bitwise pin mask for switching to high level. + * @param[in] pins_unset Bitwise pin mask for switching to low level. + * @return Zero on success. + */ +int dh_gpio_write(DHGpioPinMask pins_set, + DHGpioPinMask pins_unset); + + +/** + * @brief Initializes GPIO pins for input. + * @param[in] pins_init Bitwise pin mask for pins that should be switched to input mode without touching pull up state. + * @param[in] pins_pullup Bitwise pin mask for pins that should be switched to input mode with enabled pull up. + * @param[in] pins_nopull Bitwise pin mask for pins that should be switched to input mode with disable pull up. + * @return Zero on success. + */ +int dh_gpio_input(DHGpioPinMask pins_init, + DHGpioPinMask pins_pullup, + DHGpioPinMask pins_nopull); + + +/** + * @brief Read GPIO pins state. + * @return Bitwise bit mask of input. + */ +DHGpioPinMask dh_gpio_read(void); + + +/** + * @brief Enable GPIO interruption. + * @param[in] pins_disable Bitwise pin mask for disabling interruption. + * @param[in] pins_rising Bitwise pin mask for rising edge interruption. + * @param[in] pins_falling Bitwise pin mask for falling edge interruption. + * @param[in] pins_both Bitwise pin mask for rising and falling edge interruption. + * @param[in] timeout_ms Timeout in milliseconds, that will pass after interruption occurred. + * During this period module will collect data about interruptions on other pins. + * @return Zero on success. + */ +int dh_gpio_subscribe_int(DHGpioPinMask pins_disable, + DHGpioPinMask pins_rising, + DHGpioPinMask pins_falling, + DHGpioPinMask pins_both, + unsigned int timeout_ms); + + +/** + * @brief Get current GPIO interruption timeout. + * @return Timeout in milliseconds. + */ +unsigned int dh_gpio_get_timeout(void); + + +/** + * @brief GPIO Interruption callback. + * @param[in] caused_pins Bitwise pin mask with pins that was trigger interruption. + */ +// TODO: consider to use callback function pointer +extern void dh_gpio_int_cb(DHGpioPinMask caused_pins); + + +/** + * @brief Enable GPIO extra interruption. + * @param[in] pins_disable Bitwise pin mask for disabling interruption. + * @param[in] pins_rising Bitwise pin mask for rising edge interruption. + * @param[in] pins_falling Bitwise pin mask for falling edge interruption. + * @param[in] pins_both Bitwise pin mask for rising and falling edge interruption. + * @return Zero on success. + */ +int dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, + DHGpioPinMask pins_rising, + DHGpioPinMask pins_falling, + DHGpioPinMask pins_both); + + +/** + * @brief Extra interruption callback. + * @param[in] caused_pins Bitwise pin mask with pins that was trigger interruption. + */ +// TODO: consider to use callback function pointer +extern void dh_gpio_extra_int_cb(DHGpioPinMask caused_pins); + +#endif /* _DH_GPIO_H_ */ diff --git a/firmware-src/sources/devices/max31855.c b/firmware-src/sources/devices/max31855.c index 2de8120..0891113 100644 --- a/firmware-src/sources/devices/max31855.c +++ b/firmware-src/sources/devices/max31855.c @@ -9,7 +9,7 @@ #include "max31855.h" #include "dhspi.h" #include "dhutils.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include #include @@ -31,7 +31,7 @@ char * ICACHE_FLASH_ATTR max31855_read(int pin, float *temperature) { dhspi_set_mode(SPI_CPOL0CPHA0); //start converting - dhgpio_write((1 << mCSPin), 0); + dh_gpio_write(DH_GPIO_PIN(mCSPin), 0); delay_ms(100); dhspi_read((char *)&buf, sizeof(buf)); diff --git a/firmware-src/sources/devices/max6675.c b/firmware-src/sources/devices/max6675.c index 5dd9be2..39d14ae 100644 --- a/firmware-src/sources/devices/max6675.c +++ b/firmware-src/sources/devices/max6675.c @@ -8,7 +8,7 @@ */ #include "max6675.h" #include "dhspi.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "dhutils.h" #include @@ -31,7 +31,7 @@ char * ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) { dhspi_set_mode(SPI_CPOL0CPHA0); //start converting - dhgpio_write((1 << mCSPin), 0); + dh_gpio_write(DH_GPIO_PIN(mCSPin), 0); delay_ms(250); dhspi_read((char *)&buf, sizeof(buf)); diff --git a/firmware-src/sources/devices/pca9685.c b/firmware-src/sources/devices/pca9685.c index 2a33dba..08d51e6 100644 --- a/firmware-src/sources/devices/pca9685.c +++ b/firmware-src/sources/devices/pca9685.c @@ -8,7 +8,7 @@ */ #include "pca9685.h" #include "dhi2c.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "dhdebug.h" #include "dhutils.h" @@ -22,8 +22,8 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty DHI2C_STATUS status; unsigned int i; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - if(pinsmask & (1 << i)) { + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { + if(pinsmask & DH_GPIO_PIN(i)) { if(pinsduty[i] > 100.0f || pinsduty[i] < 0.0f) return DHI2C_WRONG_PARAMETERS; } @@ -75,8 +75,8 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty buf[1] = 0; // LED_OFF_L buf[2] = 0; // LED_OFF_H unsigned short *v = (unsigned short *)&buf[3]; // LED_ON_HL - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - if(pinsmask & (1 << i)) { + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { + if(pinsmask & DH_GPIO_PIN(i)) { *v = pinsduty[i] * 40.95f; buf[0] = 0x06 + 4 * i; if((status = dhi2c_write(mAddress, buf, 5, 1)) != DHI2C_OK) { diff --git a/firmware-src/sources/dhcommand_parser.c b/firmware-src/sources/dhcommand_parser.c index 11e7bb6..6ef93e8 100644 --- a/firmware-src/sources/dhcommand_parser.c +++ b/firmware-src/sources/dhcommand_parser.c @@ -250,7 +250,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int pinnum = -1; } else { const int res = strToUInt(&jparser.json[jparser.vstart], &pinnum); - if(!res || pinnum < 0 || pinnum > DHGPIO_MAXGPIONUM || (pins_found & (1 << pinnum))) + if(!res || pinnum < 0 || pinnum >= DH_GPIO_PIN_COUNT || (pins_found & DH_GPIO_PIN(pinnum))) return "Wrong argument"; pins_found |= (1 << pinnum); pinmask = (1 << pinnum); @@ -282,7 +282,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int int i; if(pinnum > 0 ) out->storage.uint_values[pinnum] = 0; - else for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) + else for(i = 0; i < DH_GPIO_PIN_COUNT; i++) out->storage.uint_values[i] = 0; out->pin_value_readed |= pinmask; *readedfields |= AF_VALUES; @@ -291,7 +291,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int int i; if(pinnum > 0 ) out->storage.float_values[pinnum] = 0; - else for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) + else for(i = 0; i < DH_GPIO_PIN_COUNT; i++) out->storage.float_values[i] = 0; out->pin_value_readed |= pinmask; *readedfields |= AF_FLOATVALUES; @@ -332,7 +332,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int return NONFLOAT; if(pinnum > 0 ) out->storage.float_values[pinnum] = value; - else for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) + else for(i = 0; i < DH_GPIO_PIN_COUNT; i++) out->storage.float_values[i] = value; out->pin_value_readed |= pinmask; *readedfields |= AF_FLOATVALUES; @@ -342,7 +342,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int return NONINTEGER; if(pinnum > 0 ) out->storage.uint_values[pinnum] = value; - else for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) + else for(i = 0; i < DH_GPIO_PIN_COUNT; i++) out->storage.uint_values[i] = value; out->pin_value_readed |= pinmask; *readedfields |= AF_VALUES; diff --git a/firmware-src/sources/dhcommand_parser.h b/firmware-src/sources/dhcommand_parser.h index c5b3394..7db4e19 100644 --- a/firmware-src/sources/dhcommand_parser.h +++ b/firmware-src/sources/dhcommand_parser.h @@ -11,7 +11,7 @@ #include -#include "dhgpio.h" +#include "DH/gpio.h" #include "user_config.h" /** Structure with parsing result */ @@ -30,10 +30,10 @@ typedef struct { uint32_t periodus; ///< converted frequency field value. uint32_t count; ///< count field value. union { - uint32_t uint_values[DHGPIO_MAXGPIONUM + 1];///< Pin values. - float float_values[DHGPIO_MAXGPIONUM + 1]; ///< Pin values. + uint32_t uint_values[DH_GPIO_PIN_COUNT];///< Pin values. + float float_values[DH_GPIO_PIN_COUNT]; ///< Pin values. struct { - uint8_t key_data[DHGPIO_MAXGPIONUM * 4];///< Key for authentication. + uint8_t key_data[(DH_GPIO_PIN_COUNT-1) * 4];///< Key for authentication. uint8_t key_len; ///< Key length. } key; } storage; diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 7cac0c0..db603c9 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -10,7 +10,7 @@ */ #include "dhcommands.h" #include "dhsender_queue.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "dhadc.h" #include "dhnotification.h" #include "snprintf.h" @@ -150,14 +150,14 @@ static void ICACHE_FLASH_ATTR do_gpio_write(COMMAND_RESULT *cb, const char *comm gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHGPIO_SUITABLE_PINS, + &parse_pins, DH_GPIO_SUITABLE_PINS, 0, AF_SET | AF_CLEAR, &fields); if (parse_res) responce_error(cb, parse_res); else if( (fields & (AF_SET | AF_CLEAR)) == 0) responce_error(cb, "Dummy request"); - else if(dhgpio_write(parse_pins.pins_to_set, parse_pins.pins_to_clear)) + else if(dh_gpio_write(parse_pins.pins_to_set, parse_pins.pins_to_clear) == 0) responce_ok(cb); else responce_error(cb, "Unsuitable pin"); @@ -169,12 +169,12 @@ static void ICACHE_FLASH_ATTR do_gpio_write(COMMAND_RESULT *cb, const char *comm */ static void ICACHE_FLASH_ATTR do_gpio_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) { - int init = 1; + int init = 0; if(paramslen) { gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHGPIO_SUITABLE_PINS, 0, + &parse_pins, DH_GPIO_SUITABLE_PINS, 0, AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); if(parse_res) { @@ -182,12 +182,12 @@ static void ICACHE_FLASH_ATTR do_gpio_read(COMMAND_RESULT *cb, const char *comma // ? init = 0; return; } else { - init = dhgpio_initialize(parse_pins.pins_to_init, parse_pins.pins_to_pullup, parse_pins.pins_to_nopull); + init = dh_gpio_input(parse_pins.pins_to_init, parse_pins.pins_to_pullup, parse_pins.pins_to_nopull); } } - if(init) { - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, dhgpio_read(), system_get_time(), DHGPIO_SUITABLE_PINS); + if(init == 0) { + cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, dh_gpio_read(), system_get_time(), DH_GPIO_SUITABLE_PINS); } else { responce_error(cb, "Wrong initialization parameters"); } @@ -202,7 +202,7 @@ static void ICACHE_FLASH_ATTR do_gpio_int(COMMAND_RESULT *cb, const char *comman gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), + &parse_pins, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); if(parse_res) @@ -211,8 +211,11 @@ static void ICACHE_FLASH_ATTR do_gpio_int(COMMAND_RESULT *cb, const char *comman responce_error(cb, "Wrong action"); else if(parse_pins.timeout < GPIONOTIFICATION_MIN_TIMEOUT_MS || parse_pins.timeout > 0x7fffff) responce_error(cb, "Timeout is wrong"); - else if(dhgpio_int(parse_pins.pins_to_disable, parse_pins.pins_to_rising, parse_pins.pins_to_falling, \ - parse_pins.pins_to_both, parse_pins.timeout)) + else if(0 == dh_gpio_subscribe_int(parse_pins.pins_to_disable, + parse_pins.pins_to_rising, + parse_pins.pins_to_falling, + parse_pins.pins_to_both, + parse_pins.timeout)) responce_ok(cb); else responce_error(cb, "Unsuitable pin"); @@ -605,7 +608,7 @@ static void ICACHE_FLASH_ATTR do_onewire_master_int(COMMAND_RESULT *cb, const ch gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHGPIO_SUITABLE_PINS, dhgpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); if(parse_res) responce_error(cb, parse_res); else if(fields == 0) diff --git a/firmware-src/sources/dhgpio.c b/firmware-src/sources/dhgpio.c deleted file mode 100644 index 729514c..0000000 --- a/firmware-src/sources/dhgpio.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * dhgpio.c - * - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: GPIO module - * - */ -#include "dhgpio.h" -#include "user_config.h" -#include "dhdebug.h" -#include "dhnotification.h" -#include "dhpwm.h" -#include "dhmem.h" - -#include -#include -#include -#include -#include - -LOCAL os_timer_t mGPIOTimer; -LOCAL unsigned int mGPIOTimerTimeout = 250; -LOCAL unsigned int mTriggeredIntrPins = 0; -LOCAL unsigned char mGPIOTimerArmed = 0; -LOCAL unsigned int mExternalIntPins = 0; - -void ICACHE_FLASH_ATTR dhgpio_prepare_pins(unsigned int pin_mask, int disable_pwm) { - if(disable_pwm) - dhpwm_disable_pins(pin_mask); - if(pin_mask & PIN_GPIOO) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); - if(pin_mask & PIN_GPIO1) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); - if(pin_mask & PIN_GPIO2) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); - if(pin_mask & PIN_GPIO3) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3); - if(pin_mask & PIN_GPIO4) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4); - if(pin_mask & PIN_GPIO5) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5); - if(pin_mask & PIN_GPIO12) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); - if(pin_mask & PIN_GPIO13) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); - if(pin_mask & PIN_GPIO14) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14); - if(pin_mask & PIN_GPIO15) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); -} - -void ICACHE_FLASH_ATTR dhgpio_open_drain(unsigned int pin_mask_set_od, unsigned int pin_mask_unset_od) { - int i; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - unsigned int pin = BIT(i); - if((pin & DHGPIO_SUITABLE_PINS) == 0) - continue; - if(pin & pin_mask_set_od) { - const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE); - GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(i)), reg); - } else if(pin & pin_mask_unset_od) { - const unsigned int reg = GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(i))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE); - GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(i)), reg); - } - } -} - -void ICACHE_FLASH_ATTR dhgpio_pull(unsigned int pollup_mask, unsigned int nopoll_mask) { - if(pollup_mask & PIN_GPIOO) - PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO0_U); - if(pollup_mask & PIN_GPIO1) - PIN_PULLUP_EN(PERIPHS_IO_MUX_U0TXD_U); - if(pollup_mask & PIN_GPIO2) - PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO2_U); - if(pollup_mask & PIN_GPIO3) - PIN_PULLUP_EN(PERIPHS_IO_MUX_U0RXD_U); - if(pollup_mask & PIN_GPIO4) - PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U); - if(pollup_mask & PIN_GPIO5) - PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO5_U); - if(pollup_mask & PIN_GPIO12) - PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDI_U); - if(pollup_mask & PIN_GPIO13) - PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); - if(pollup_mask & PIN_GPIO14) - PIN_PULLUP_EN(PERIPHS_IO_MUX_MTMS_U); - if(pollup_mask & PIN_GPIO15) - PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDO_U); - - if(nopoll_mask & PIN_GPIOO) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U); - if(nopoll_mask & PIN_GPIO1) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); - if(nopoll_mask & PIN_GPIO2) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); - if(nopoll_mask & PIN_GPIO3) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0RXD_U); - if(nopoll_mask & PIN_GPIO4) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO4_U); - if(nopoll_mask & PIN_GPIO5) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO5_U); - if(nopoll_mask & PIN_GPIO12) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); - if(nopoll_mask & PIN_GPIO13) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); - if(nopoll_mask & PIN_GPIO14) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); - if(nopoll_mask & PIN_GPIO15) - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDO_U); -} - -int ICACHE_FLASH_ATTR dhgpio_write(unsigned int set_mask, unsigned int unset_mask) { - const unsigned int pins = set_mask | unset_mask; - if((pins | DHGPIO_SUITABLE_PINS) != DHGPIO_SUITABLE_PINS) - return 0; - dhgpio_prepare_pins(pins, 1); - dhgpio_open_drain(0, pins); - dhgpio_pull(0, pins); - gpio_output_set(set_mask, unset_mask, pins, 0); - return 1; -} - -int ICACHE_FLASH_ATTR dhgpio_initialize(unsigned int init_mask, unsigned int pollup_mask, unsigned int nopoll_mask) { - if(pollup_mask & nopoll_mask) - return 0; - if( (init_mask | pollup_mask | nopoll_mask | DHGPIO_SUITABLE_PINS) != DHGPIO_SUITABLE_PINS) - return 0; - // init - dhgpio_prepare_pins(init_mask | pollup_mask | nopoll_mask, 1); - gpio_output_set(0, 0, 0, init_mask | pollup_mask | nopoll_mask); - // pullup - dhgpio_pull(pollup_mask, nopoll_mask); - return 1; -} - -unsigned int ICACHE_FLASH_ATTR dhgpio_read(void) { - return gpio_input_get() & DHGPIO_SUITABLE_PINS; -} - -LOCAL ICACHE_FLASH_ATTR void gpio_timeout(void *arg) { - dhgpio_int_timeout(mTriggeredIntrPins); - mTriggeredIntrPins = 0; - mGPIOTimerArmed = 0; -} - -LOCAL void gpio_intr(void *arg) { - unsigned int gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status); - if(gpio_status & mExternalIntPins) { - dhgpio_extra_int(gpio_status & mExternalIntPins); - gpio_status &= ~mExternalIntPins; - if(gpio_status == 0) - return; - } - mTriggeredIntrPins |= gpio_status; - if(mGPIOTimerArmed) - return; - os_timer_disarm(&mGPIOTimer); - if(mGPIOTimerTimeout) { - mGPIOTimerArmed = 1; - os_timer_setfn(&mGPIOTimer, (os_timer_func_t *)gpio_timeout, NULL); - os_timer_arm(&mGPIOTimer, mGPIOTimerTimeout, 0); - } else { - gpio_timeout(0); - } -} - -LOCAL int ICACHE_FLASH_ATTR dhgpio_set_int(unsigned int disable_mask, unsigned int rising_mask, unsigned int falling_mask, unsigned int both_mask) { - unsigned int tmp = disable_mask; - if(tmp & rising_mask) - return 0; - tmp |= rising_mask; - if(tmp & falling_mask) - return 0; - tmp |= falling_mask; - if(tmp & both_mask) - return 0; - tmp |= both_mask; - if((tmp | DHGPIO_SUITABLE_PINS) != DHGPIO_SUITABLE_PINS) - return 0; - int i; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - const unsigned int pin = 1 << i; - if((pin & DHGPIO_SUITABLE_PINS) == 0) - continue; - else if(pin & disable_mask) - gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_DISABLE); - else if(pin & falling_mask) - gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_POSEDGE); - else if(pin & rising_mask) - gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_NEGEDGE); - else if(pin & both_mask) - gpio_pin_intr_state_set(GPIO_ID_PIN(i), GPIO_PIN_INTR_ANYEDGE); - } - return 1; -} - -int ICACHE_FLASH_ATTR dhgpio_int(unsigned int disable_mask, unsigned int rising_mask, unsigned int falling_mask, unsigned int both_mask, unsigned int timeout) { - dhgpio_subscribe_extra_int(disable_mask | rising_mask | falling_mask | both_mask, 0, 0, 0); - if(dhgpio_set_int(disable_mask, rising_mask, falling_mask, both_mask) == 0) - return 0; - mGPIOTimerTimeout = timeout; - return 1; -} - -unsigned int ICACHE_FLASH_ATTR dhgpio_get_timeout(void) { - return mGPIOTimerTimeout; -} - -void ICACHE_FLASH_ATTR dhgpio_init(void) { - ETS_GPIO_INTR_ATTACH(gpio_intr, NULL); - ETS_GPIO_INTR_ENABLE(); -} - -int ICACHE_FLASH_ATTR dhgpio_subscribe_extra_int(unsigned int disable_mask, unsigned int rising_mask, unsigned int falling_mask, unsigned int both_mask) { - disable_mask &= mExternalIntPins; - if(dhgpio_set_int(disable_mask, rising_mask, falling_mask, both_mask) == 0) - return 0; - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, disable_mask); - mExternalIntPins |= rising_mask | falling_mask | both_mask; - mExternalIntPins &= ~disable_mask; - return 1; -} diff --git a/firmware-src/sources/dhgpio.h b/firmware-src/sources/dhgpio.h deleted file mode 100644 index 2e256ee..0000000 --- a/firmware-src/sources/dhgpio.h +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file dhgpio.h - * \brief GPIO hardware access layer for ESP8266 firmware. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - */ - -#ifndef _DHGPIO_H_ -#define _DHGPIO_H_ - -#include - -/** Bitwise pin mask for pin that can be used. */ -#define DHGPIO_SUITABLE_PINS 0b1111000000111111 // GPIO0-GPIO5, GPIO12-GPIO15 -/** Last pin number. */ -#define DHGPIO_MAXGPIONUM 15 - -#define PIN_GPIOO BIT(0) -#define PIN_GPIO1 BIT(1) -#define PIN_GPIO2 BIT(2) -#define PIN_GPIO3 BIT(3) -#define PIN_GPIO4 BIT(4) -#define PIN_GPIO5 BIT(5) -#define PIN_GPIO6 BIT(6) -#define PIN_GPIO7 BIT(7) -#define PIN_GPIO8 BIT(8) -#define PIN_GPIO9 BIT(9) -#define PIN_GPIO10 BIT(10) -#define PIN_GPIO11 BIT(11) -#define PIN_GPIO12 BIT(12) -#define PIN_GPIO13 BIT(13) -#define PIN_GPIO14 BIT(14) -#define PIN_GPIO15 BIT(15) - -/** - * \brief Initialize GPIO. - */ -void dhgpio_init(void); - -/** - * \brief Prepare pins for using as GPIO. - * \param[in] pin_mask Bitwise pin mask. - * \param[in] disable_pwm Disable PWM if it was enabled before. - */ -void dhgpio_prepare_pins(unsigned int pin_mask, int disable_pwm); - -/** - * \brief Enabling/disabling pull up switch for GPIO output. - * \param[in] pin_mask_set_od Bitwise pin mask for enabling. - * \param[in] pin_mask_unset_od Bitwise pin mask for disabling. - */ -void dhgpio_open_drain(unsigned int pin_mask_set_od, unsigned int pin_mask_unset_od); - -/** - * \brief Enabling/disabling pull up GPIO pins. - * \param[in] pin_mask_pullup Bitwise pin mask for enabling. - * \param[in] pin_mask_disablepull Bitwise pin mask for disabling. - */ -void dhgpio_pull(unsigned int pin_mask_pullup, unsigned int pin_mask_disablepull); - -/** - * \brief Set GPIO outputs state. - * \param[in] set_mask Bitwise pin mask for switching to high level. - * \param[in] unset_mask Bitwise pin mask for switching to low level. - * \return Non zero value on success, zero on failure. - */ -int dhgpio_write(unsigned int set_mask, unsigned int unset_mask); - -/** - * \brief Initializes GPIO pins for input. - * \param[in] init_mask Bitwise pin mask for pins that should be switched to input mode without touching pull up state. - * \param[in] pollup_mask Bitwise pin mask for pins that should be switched to input mode with enabled pull up. - * \param[in] nopoll_mask Bitwise pin mask for pins that should be switched to input mode with disable pull up. - * \return Non zero value on success, zero on failure. - */ -int dhgpio_initialize(unsigned int init_mask, unsigned int pollup_mask, unsigned int nopoll_mask); - -/** - * \brief Read GPIO pins state - * \return Bitwise bit mask of input. - */ -unsigned int dhgpio_read(void); - -/** - * \brief Enable GPIO interruption. - * \param[in] disable_mask Bitwise pin mask for disabling interruption. - * \param[in] rising_mask Bitwise pin mask for rising edge interruption. - * \param[in] falling_mask Bitwise pin mask for falling edge interruption.. - * \param[in] both_mask Bitwise pin mask for rising and falling edge interruption. - * \param[in] timeout Timeout in milliseconds, that will pass after interruption occurred. During this period module will collect data about interruptions on other pins. - * \return Non zero value on success, zero on failure. - */ -int dhgpio_int(unsigned int disable_mask, unsigned int rising_mask, unsigned int falling_mask, unsigned int both_mask, unsigned int timeout); - -/** - * \brief Get current GPIO inerruption timeout. - * \return Timeout in milliseconds. - */ -unsigned int dhgpio_get_timeout(void); - -/** - * \brief Interruption callback. - * \param[in] caused_pins Bitwise pin mask with pins that was trigger interruption. - */ -extern void dhgpio_int_timeout(unsigned int caused_pins); - -/** - * \brief Enable GPIO extra interruption. - * \param[in] disable_mask Bitwise pin mask for disabling interruption. - * \param[in] rising_mask Bitwise pin mask for rising edge interruption. - * \param[in] falling_mask Bitwise pin mask for falling edge interruption.. - * \param[in] both_mask Bitwise pin mask for rising and falling edge interruption. - * \return Non zero value on success, zero on failur - */ -int dhgpio_subscribe_extra_int(unsigned int disable_mask, unsigned int rising_mask, unsigned int falling_mask, unsigned int both_mask); - -/** - * \brief Extra interruption callback. - * \param[in] caused_pins Bitwise pin mask with pins that was trigger interruption. - */ -extern void dhgpio_extra_int(unsigned int caused_pins); - -#endif /* _DHGPIO_H_ */ diff --git a/firmware-src/sources/dhi2c.c b/firmware-src/sources/dhi2c.c index f91f58e..f6e3249 100644 --- a/firmware-src/sources/dhi2c.c +++ b/firmware-src/sources/dhi2c.c @@ -9,7 +9,7 @@ * */ #include "dhi2c.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "user_config.h" #include @@ -27,7 +27,7 @@ LOCAL unsigned int mSCLPin = (1 << 2); DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_init(unsigned int sda_pin, unsigned int scl_pin) { const unsigned int SDA = (1 << sda_pin); const unsigned int SCL = (1 << scl_pin); - if((SDA & DHGPIO_SUITABLE_PINS) == 0 || (SCL & DHGPIO_SUITABLE_PINS) == 0 || SDA == SCL) + if((SDA & DH_GPIO_SUITABLE_PINS) == 0 || (SCL & DH_GPIO_SUITABLE_PINS) == 0 || SDA == SCL) return DHI2C_WRONG_PARAMETERS; mSDAPin = SDA; @@ -37,9 +37,9 @@ DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_init(unsigned int sda_pin, unsigned int scl } void ICACHE_FLASH_ATTR dhi2c_reinit(void) { - dhgpio_open_drain(mSDAPin | mSCLPin, 0); - dhgpio_prepare_pins(mSDAPin | mSCLPin, 1); - dhgpio_pull(mSDAPin | mSCLPin, 0); + dh_gpio_open_drain(mSDAPin | mSCLPin, 0); + dh_gpio_prepare_pins(mSDAPin | mSCLPin, 1); + dh_gpio_pull_up(mSDAPin | mSCLPin, 0); gpio_output_set(mSDAPin | mSCLPin, 0, mSDAPin | mSCLPin, 0); } diff --git a/firmware-src/sources/dhnotification.c b/firmware-src/sources/dhnotification.c index 343a2be..dd13e2f 100644 --- a/firmware-src/sources/dhnotification.c +++ b/firmware-src/sources/dhnotification.c @@ -10,7 +10,7 @@ */ #include "dhnotification.h" #include "dhsender.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "dhadc.h" #include "user_config.h" #include "snprintf.h" @@ -24,12 +24,12 @@ #include #include -void ICACHE_FLASH_ATTR dhgpio_int_timeout(unsigned int caused_pins) { +void ICACHE_FLASH_ATTR dh_gpio_int_cb(DHGpioPinMask caused_pins) { if(dhmem_isblock()) { dhstat_got_notification_dropped(); return; } - dhsender_notification(RNT_NOTIFICATION_GPIO, RDT_GPIO, caused_pins, dhgpio_read(), system_get_time(), DHGPIO_SUITABLE_PINS); + dhsender_notification(RNT_NOTIFICATION_GPIO, RDT_GPIO, caused_pins, dh_gpio_read(), system_get_time(), DH_GPIO_SUITABLE_PINS); } void ICACHE_FLASH_ATTR dhadc_loop_value(float value){ diff --git a/firmware-src/sources/dhonewire.c b/firmware-src/sources/dhonewire.c index c203412..552e332 100644 --- a/firmware-src/sources/dhonewire.c +++ b/firmware-src/sources/dhonewire.c @@ -9,7 +9,7 @@ * */ #include "dhonewire.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "user_config.h" #include "dhdebug.h" @@ -35,16 +35,16 @@ LOCAL os_timer_t mOWIntTimer; LOCAL void ICACHE_FLASH_ATTR lock_int(void) { if(mIntPins) - dhgpio_subscribe_extra_int(mIntPins, 0, 0, 0); + dh_gpio_subscribe_extra_int(mIntPins, 0, 0, 0); } LOCAL void ICACHE_FLASH_ATTR unlock_int(void) { GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, mIntPins); - dhgpio_subscribe_extra_int(0, 0, mIntPins, 0); + dh_gpio_subscribe_extra_int(0, 0, mIntPins, 0); } int ICACHE_FLASH_ATTR dhonewire_set_pin(unsigned int pin) { - if(((1 << pin) & DHGPIO_SUITABLE_PINS) == 0) + if((DH_GPIO_PIN(pin) & DH_GPIO_SUITABLE_PINS) == 0) return 0; mOneWirePin = pin; return 1; @@ -59,9 +59,9 @@ LOCAL int ICACHE_FLASH_ATTR dhonewire_reset(unsigned int pin, unsigned int reset const unsigned int pinstate = gpio_input_get() & pin; unsigned int i; unsigned int presence = 0; - dhgpio_open_drain(pin, 0); - dhgpio_pull(pin, 0); - dhgpio_prepare_pins(pin, 1); + dh_gpio_open_drain(pin, 0); + dh_gpio_pull_up(pin, 0); + dh_gpio_prepare_pins(pin, 1); if(pinstate == 0) { gpio_output_set(pin, 0, pin, 0); os_delay_us(500); @@ -237,8 +237,8 @@ int ICACHE_FLASH_ATTR dhonewire_search(char *buf, unsigned long *len, char comma LOCAL void ICACHE_FLASH_ATTR dhonewire_int_search(void *arg) { int i; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - const unsigned int pin = 1 << i; + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); if(pin & mWaitSearchPins) { char buf[INTERFACES_BUF_SIZE]; unsigned long len = sizeof(buf); @@ -265,7 +265,7 @@ LOCAL void ICACHE_FLASH_ATTR dhonewire_int_search(void *arg) { } } -void ICACHE_FLASH_ATTR dhgpio_extra_int(unsigned int caused_pins) { +void ICACHE_FLASH_ATTR dh_gpio_extra_int_cb(DHGpioPinMask caused_pins) { os_timer_disarm(&mOWIntTimer); mWaitSearchPins |= caused_pins; os_timer_setfn(&mOWIntTimer, (os_timer_func_t *)dhonewire_int_search, NULL); @@ -273,7 +273,7 @@ void ICACHE_FLASH_ATTR dhgpio_extra_int(unsigned int caused_pins) { } int ICACHE_FLASH_ATTR dhonewire_int(unsigned int search_pins, unsigned int disable_pins) { - if(dhgpio_subscribe_extra_int(disable_pins, 0, search_pins, 0) == 0) + if(!!dh_gpio_subscribe_extra_int(disable_pins, 0, search_pins, 0)) return 0; mIntPins |= search_pins; mIntPins &= ~disable_pins; diff --git a/firmware-src/sources/dhpwm.c b/firmware-src/sources/dhpwm.c index 1724725..c1c5c22 100644 --- a/firmware-src/sources/dhpwm.c +++ b/firmware-src/sources/dhpwm.c @@ -7,7 +7,7 @@ * */ #include "dhpwm.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "dhdebug.h" #include "user_config.h" @@ -90,11 +90,11 @@ void ICACHE_FLASH_ATTR arm_pwm_timer(void) { dhdebug("PWM enable with period %u us, timer %u/%u tacts", mPeriodUs, tacts, 1 << timer_div); } -int ICACHE_FLASH_ATTR dhpwm_set_pwm(unsigned int *pinsduty, unsigned int pinsmask, unsigned int periodus, unsigned int count) { +int ICACHE_FLASH_ATTR dhpwm_set_pwm(uint32_t *pinsduty, unsigned int pinsmask, unsigned int periodus, unsigned int count) { int i; - if((pinsmask | DHGPIO_SUITABLE_PINS) != DHGPIO_SUITABLE_PINS || periodus < 500 || periodus >= 2000004000) + if((pinsmask | DH_GPIO_SUITABLE_PINS) != DH_GPIO_SUITABLE_PINS || periodus < 500 || periodus >= 2000004000) return 0; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { if(pinsduty[i] > DHPWM_DEPTH) return 0; } @@ -102,8 +102,8 @@ int ICACHE_FLASH_ATTR dhpwm_set_pwm(unsigned int *pinsduty, unsigned int pinsmas mPeriodUs = periodus; mTotalCount = count; dhpwm_disable_pins(pinsmask); - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - if((pinsmask & (1 << i))) { + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { + if((pinsmask & DH_GPIO_PIN(i))) { dhdebug("PWM for %d pin, duty: %d", i, pinsduty[i]); if(pinsduty[i]) { mUsedPins |= (1 << i); @@ -113,7 +113,7 @@ int ICACHE_FLASH_ATTR dhpwm_set_pwm(unsigned int *pinsduty, unsigned int pinsmas } } } - dhgpio_prepare_pins(mUsedPins | mDisablePinOn[0], 0); + dh_gpio_prepare_pins(mUsedPins | mDisablePinOn[0], 0); gpio_output_set(mUsedPins, mDisablePinOn[0], mUsedPins | mDisablePinOn[0], 0); if(mUsedPins) arm_pwm_timer(); diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index 0713eec..d9a9ccb 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -11,7 +11,7 @@ #include "dhsender_data.h" #include "dhdata.h" #include "dhdebug.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "snprintf.h" #include @@ -63,8 +63,8 @@ LOCAL unsigned int ICACHE_FLASH_ATTR gpio_state(char *buf, unsigned int buflen, unsigned int state, unsigned int suitable) { unsigned int len = snprintf(buf, buflen, "{"); unsigned int i; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - const unsigned int pin = 1 << i; + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); const int pinvalue = (state & pin) ? 1 : 0; if(suitable & pin) { len += snprintf(&buf[len], buflen - len, (i == 0) ? "\"%d\":%d" : ", \"%d\":%d", i, pinvalue); @@ -78,9 +78,10 @@ LOCAL unsigned int ICACHE_FLASH_ATTR gpio_notification(char *buf, unsigned int len = snprintf(buf, buflen, "{\"caused\":["); unsigned int i; int comma = 0; - for(i = 0; i <= DHGPIO_MAXGPIONUM; i++) { - const unsigned int pin = 1 << i; - if((suitable & pin) == 0) + for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); + if(!(suitable & pin)) + continue; if( pin & data->caused) { len += snprintf(&buf[len], buflen - len, comma?", \"%d\"":"\"%d\"", i); diff --git a/firmware-src/sources/dhsender_queue.c b/firmware-src/sources/dhsender_queue.c index 2e86dd6..ca6bfbe 100644 --- a/firmware-src/sources/dhsender_queue.c +++ b/firmware-src/sources/dhsender_queue.c @@ -11,7 +11,6 @@ #include "dhsender_queue.h" #include "user_config.h" #include "dhdebug.h" -#include "dhgpio.h" #include "snprintf.h" #include "dhmem.h" #include "dhsender_data.h" diff --git a/firmware-src/sources/dhspi.c b/firmware-src/sources/dhspi.c index 0296cbc..2130554 100644 --- a/firmware-src/sources/dhspi.c +++ b/firmware-src/sources/dhspi.c @@ -9,7 +9,7 @@ * */ #include "dhspi.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include #include @@ -54,21 +54,21 @@ LOCAL unsigned char mSPIMode = 0; LOCAL void ICACHE_FLASH_ATTR dhspi_cs_enable() { if(mSPICSPin == DHSPI_NOCS) return; - dhgpio_write(0, (1 << mSPICSPin)); + dh_gpio_write(0, DH_GPIO_PIN(mSPICSPin)); os_delay_us(DHSPI_CS_DELAY_US); } LOCAL void ICACHE_FLASH_ATTR dhspi_cs_disable() { if(mSPICSPin == DHSPI_NOCS) return; - dhgpio_write((1 << mSPICSPin), 0); + dh_gpio_write(DH_GPIO_PIN(mSPICSPin), 0); os_delay_us(DHSPI_CS_DELAY_US); } LOCAL void ICACHE_FLASH_ATTR dhspi_reinit() { - const unsigned int spipins = (1 << 12) | (1 << 13) | (1 << 14); - dhgpio_open_drain(0, spipins); - dhgpio_pull(0, spipins); + const DHGpioPinMask spipins = DH_GPIO_PIN(12) | DH_GPIO_PIN(13) | DH_GPIO_PIN(14); + dh_gpio_open_drain(0, spipins); + dh_gpio_pull_up(0, spipins); gpio_output_set(0, 0, 0, spipins); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); @@ -114,8 +114,8 @@ int ICACHE_FLASH_ATTR dhspi_set_mode(unsigned int mode) { int ICACHE_FLASH_ATTR dhspi_set_cs_pin(unsigned int cs_pin) { if(cs_pin != DHSPI_NOCS && (cs_pin == 12 || cs_pin == 13 || cs_pin == 14 - || cs_pin > DHGPIO_MAXGPIONUM - || ((1 << cs_pin) & DHGPIO_SUITABLE_PINS) == 0)) + || cs_pin >= DH_GPIO_PIN_COUNT + || (DH_GPIO_PIN(cs_pin) & DH_GPIO_SUITABLE_PINS) == 0)) return 0; mSPICSPin = cs_pin; return 1; diff --git a/firmware-src/sources/main.c b/firmware-src/sources/main.c index a042699..c50c4cd 100644 --- a/firmware-src/sources/main.c +++ b/firmware-src/sources/main.c @@ -15,7 +15,7 @@ #include "dhsettings.h" #include "dhconnector.h" #include "dhap.h" -#include "dhgpio.h" +#include "DH/gpio.h" #include "webserver.h" #include "irom.h" #include "uploadable_page.h" @@ -118,7 +118,7 @@ void ICACHE_FLASH_ATTR system_init_done(void) { void user_init(void) { int ever_saved; - gpio_output_set(0, 0, 0, DHGPIO_SUITABLE_PINS); + gpio_output_set(0, 0, 0, DH_GPIO_SUITABLE_PINS); dhsettings_init(&ever_saved); if(ever_saved == 0) { // if first run on this chip uploadable_page_delete(); @@ -136,7 +136,7 @@ void user_init(void) { if(dhsettings_get_wifi_mode() == WIFI_MODE_CLIENT) { dhsender_queue_init(); dhconnector_init(); - dhgpio_init(); + dh_gpio_init(); } else if(dhsettings_get_wifi_mode() == WIFI_MODE_AP) { dhap_init(dhsettings_get_wifi_ssid(), dhsettings_get_wifi_password()); } From 66093e8967bc679f124e6f0d578ed2e5f4f87589 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 16:50:53 +0300 Subject: [PATCH 24/83] move GPIO commands into DH/cmd_gpio.h file --- firmware-src/sources/DH/cmd_gpio.c | 121 +++++++++++++++++++++++++++++ firmware-src/sources/DH/cmd_gpio.h | 34 ++++++++ firmware-src/sources/dhcommands.c | 92 ++-------------------- sdk/include/ets_forward.h | 1 - 4 files changed, 160 insertions(+), 88 deletions(-) create mode 100644 firmware-src/sources/DH/cmd_gpio.c create mode 100644 firmware-src/sources/DH/cmd_gpio.h diff --git a/firmware-src/sources/DH/cmd_gpio.c b/firmware-src/sources/DH/cmd_gpio.c new file mode 100644 index 0000000..3281240 --- /dev/null +++ b/firmware-src/sources/DH/cmd_gpio.c @@ -0,0 +1,121 @@ +/** + * @file + * @brief Handle GPIO commands. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/cmd_gpio.h" +#include "DH/gpio.h" + +#include "dhcommand_parser.h" +#include + +/** + * Minimum notification timeout, milliseconds. + */ +#define MIN_TIMEOUT_MS 50 + + +/** + * Maximum notification timeout, milliseconds. + */ +#define MAX_TIMEOUT_MS 0x7fffff + + +/* + * dh_handle_gpio_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cb, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, + 0, AF_SET | AF_CLEAR, &fields); + + if (err_msg != 0) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, err_msg); + } else if (!(fields & (AF_SET | AF_CLEAR))) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, "Dummy request"); + } else if (!!dh_gpio_write(info.pins_to_set, info.pins_to_clear)) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, "Unsuitable pin"); + } else { + cb->callback(cb->data, DHSTATUS_OK, + RDT_CONST_STRING, ""); // OK + } +} + + +/* + * dh_handle_gpio_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cb, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, 0, + AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); + + if (err_msg != 0) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, err_msg); + return; // FAILED + } + + // initialize GPIO as input + if (!!dh_gpio_input(info.pins_to_init, + info.pins_to_pullup, + info.pins_to_nopull)) { + cb->callback(cb->data, DHSTATUS_ERROR, RDT_CONST_STRING, + "Wrong initialization parameters"); + return; // FAILED + } + } + + // OK, read GPIO input + cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, + 0, dh_gpio_read(), system_get_time(), + DH_GPIO_SUITABLE_PINS); +} + + +/* + * dh_handle_gpio_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cb, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), + AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); + + if (err_msg != 0) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, err_msg); + } else if (fields == 0) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, "Wrong action"); + } else if (info.timeout < MIN_TIMEOUT_MS || info.timeout > MAX_TIMEOUT_MS) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, "Timeout out of range"); + } else if (!!dh_gpio_subscribe_int(info.pins_to_disable, + info.pins_to_rising, + info.pins_to_falling, + info.pins_to_both, + info.timeout)) { + cb->callback(cb->data, DHSTATUS_ERROR, + RDT_CONST_STRING, "Unsuitable pin"); + } else { + cb->callback(cb->data, DHSTATUS_OK, + RDT_CONST_STRING, ""); // OK + } +} diff --git a/firmware-src/sources/DH/cmd_gpio.h b/firmware-src/sources/DH/cmd_gpio.h new file mode 100644 index 0000000..32fc1bb --- /dev/null +++ b/firmware-src/sources/DH/cmd_gpio.h @@ -0,0 +1,34 @@ +/** + * @file + * @brief Handle GPIO commands. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DH_CMD_GPIO_H_ +#define _DH_CMD_GPIO_H_ + +#include "dhsender_data.h" + + +/** + * @brief Handle "gpio/write" command. + */ +void dh_handle_gpio_write(COMMAND_RESULT *cb, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "gpio/read" command. + */ +void dh_handle_gpio_read(COMMAND_RESULT *cb, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "gpio/int" command. + */ +void dh_handle_gpio_int(COMMAND_RESULT *cb, const char *command, + const char *params, unsigned int params_len); + + +#endif /* _DH_CMD_GPIO_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index db603c9..8ed522f 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -46,13 +46,14 @@ #include "devices/max31855.h" #include "devices/tm1636.h" +#include "DH/cmd_gpio.h" + #include #include #include #include #include -#define GPIONOTIFICATION_MIN_TIMEOUT_MS 50 #define ADCNOTIFICATION_MIN_TIMEOUT_MS 250 LOCAL void ICACHE_FLASH_ATTR responce_ok(COMMAND_RESULT *cb) { @@ -140,89 +141,6 @@ LOCAL int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, return 0; } -#if 1 // GPIO commands - -/** - * @brief Do "gpio/write" command. - */ -static void ICACHE_FLASH_ATTR do_gpio_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_GPIO_SUITABLE_PINS, - 0, AF_SET | AF_CLEAR, &fields); - - if (parse_res) - responce_error(cb, parse_res); - else if( (fields & (AF_SET | AF_CLEAR)) == 0) - responce_error(cb, "Dummy request"); - else if(dh_gpio_write(parse_pins.pins_to_set, parse_pins.pins_to_clear) == 0) - responce_ok(cb); - else - responce_error(cb, "Unsuitable pin"); -} - - -/** - * @brief Do "gpio/read" command. - */ -static void ICACHE_FLASH_ATTR do_gpio_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - int init = 0; - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_GPIO_SUITABLE_PINS, 0, - AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); - - if(parse_res) { - responce_error(cb, parse_res); - // ? init = 0; - return; - } else { - init = dh_gpio_input(parse_pins.pins_to_init, parse_pins.pins_to_pullup, parse_pins.pins_to_nopull); - } - } - - if(init == 0) { - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, dh_gpio_read(), system_get_time(), DH_GPIO_SUITABLE_PINS); - } else { - responce_error(cb, "Wrong initialization parameters"); - } -} - - -/** - * @brief Do "gpio/int" command. - */ -static void ICACHE_FLASH_ATTR do_gpio_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), - AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); - - if(parse_res) - responce_error(cb, parse_res); - else if(fields == 0) - responce_error(cb, "Wrong action"); - else if(parse_pins.timeout < GPIONOTIFICATION_MIN_TIMEOUT_MS || parse_pins.timeout > 0x7fffff) - responce_error(cb, "Timeout is wrong"); - else if(0 == dh_gpio_subscribe_int(parse_pins.pins_to_disable, - parse_pins.pins_to_rising, - parse_pins.pins_to_falling, - parse_pins.pins_to_both, - parse_pins.timeout)) - responce_ok(cb); - else - responce_error(cb, "Unsuitable pin"); -} - -#endif // GPIO commands - #if 1 // ADC and PWM commands /** @@ -1449,9 +1367,9 @@ RO_DATA struct { void (*func)(COMMAND_RESULT*, const char*, const char*, unsigned int); } g_command_table[] = { - {"gpio/write", do_gpio_write}, - {"gpio/read", do_gpio_read}, - {"gpio/int", do_gpio_int}, + {"gpio/write", dh_handle_gpio_write}, + {"gpio/read", dh_handle_gpio_read}, + {"gpio/int", dh_handle_gpio_int}, {"adc/read", do_adc_read}, {"adc/int", do_adc_int}, diff --git a/sdk/include/ets_forward.h b/sdk/include/ets_forward.h index 26e408f..d1118a9 100644 --- a/sdk/include/ets_forward.h +++ b/sdk/include/ets_forward.h @@ -44,7 +44,6 @@ void ets_timer_setfn(os_timer_t*, ETSTimerFunc*, void*); void ets_update_cpu_frequency(int freqmhz); void uart_div_modify(int no, unsigned int freq); uint8 wifi_get_opmode(void); -uint32 system_get_time(void); int rand(void); void ets_delay_us(int ms); From e4d70aacae0041aec9da0daa69a302b37938ce50 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 18:43:06 +0300 Subject: [PATCH 25/83] introduce helper function for command result use `dh_command_done()` instead of `response_ok()` and `dh_command_fail()` instead of `response_error()` firmware size is 398980 --- firmware-src/sources/DH/cmd_gpio.c | 45 +-- firmware-src/sources/DH/cmd_gpio.h | 6 +- firmware-src/sources/dhcommands.c | 517 +++++++++++++++++---------- firmware-src/sources/dhsender_data.c | 20 ++ firmware-src/sources/dhsender_data.h | 42 ++- 5 files changed, 404 insertions(+), 226 deletions(-) diff --git a/firmware-src/sources/DH/cmd_gpio.c b/firmware-src/sources/DH/cmd_gpio.c index 3281240..c197da3 100644 --- a/firmware-src/sources/DH/cmd_gpio.c +++ b/firmware-src/sources/DH/cmd_gpio.c @@ -25,7 +25,7 @@ /* * dh_handle_gpio_write() implementation. */ -void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cb, const char *command, +void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len) { gpio_command_params info; @@ -35,17 +35,13 @@ void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cb, const char *comm 0, AF_SET | AF_CLEAR, &fields); if (err_msg != 0) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, err_msg); + dh_command_fail(cmd_res, err_msg); } else if (!(fields & (AF_SET | AF_CLEAR))) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, "Dummy request"); + dh_command_fail(cmd_res, "Dummy request"); } else if (!!dh_gpio_write(info.pins_to_set, info.pins_to_clear)) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, "Unsuitable pin"); + dh_command_fail(cmd_res, "Unsuitable pin"); } else { - cb->callback(cb->data, DHSTATUS_OK, - RDT_CONST_STRING, ""); // OK + dh_command_done(cmd_res, ""); } } @@ -53,7 +49,7 @@ void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cb, const char *comm /* * dh_handle_gpio_read() implementation. */ -void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cb, const char *command, +void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len) { if (params_len) { @@ -64,8 +60,7 @@ void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cb, const char *comma AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); if (err_msg != 0) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, err_msg); + dh_command_fail(cmd_res, err_msg); return; // FAILED } @@ -73,23 +68,22 @@ void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cb, const char *comma if (!!dh_gpio_input(info.pins_to_init, info.pins_to_pullup, info.pins_to_nopull)) { - cb->callback(cb->data, DHSTATUS_ERROR, RDT_CONST_STRING, - "Wrong initialization parameters"); + dh_command_fail(cmd_res, "Wrong initialization parameters"); return; // FAILED } } // OK, read GPIO input - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, - 0, dh_gpio_read(), system_get_time(), - DH_GPIO_SUITABLE_PINS); + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_GPIO, + 0, dh_gpio_read(), system_get_time(), + DH_GPIO_SUITABLE_PINS); } /* * dh_handle_gpio_int() implementation. */ -void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cb, const char *command, +void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len) { gpio_command_params info; @@ -99,23 +93,18 @@ void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cb, const char *comman AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); if (err_msg != 0) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, err_msg); + dh_command_fail(cmd_res, err_msg); } else if (fields == 0) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, "Wrong action"); + dh_command_fail(cmd_res, "Wrong action"); } else if (info.timeout < MIN_TIMEOUT_MS || info.timeout > MAX_TIMEOUT_MS) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, "Timeout out of range"); + dh_command_fail(cmd_res, "Timeout out of range"); } else if (!!dh_gpio_subscribe_int(info.pins_to_disable, info.pins_to_rising, info.pins_to_falling, info.pins_to_both, info.timeout)) { - cb->callback(cb->data, DHSTATUS_ERROR, - RDT_CONST_STRING, "Unsuitable pin"); + dh_command_fail(cmd_res, "Unsuitable pin"); } else { - cb->callback(cb->data, DHSTATUS_OK, - RDT_CONST_STRING, ""); // OK + dh_command_done(cmd_res, ""); } } diff --git a/firmware-src/sources/DH/cmd_gpio.h b/firmware-src/sources/DH/cmd_gpio.h index 32fc1bb..8ecaa12 100644 --- a/firmware-src/sources/DH/cmd_gpio.h +++ b/firmware-src/sources/DH/cmd_gpio.h @@ -13,21 +13,21 @@ /** * @brief Handle "gpio/write" command. */ -void dh_handle_gpio_write(COMMAND_RESULT *cb, const char *command, +void dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); /** * @brief Handle "gpio/read" command. */ -void dh_handle_gpio_read(COMMAND_RESULT *cb, const char *command, +void dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); /** * @brief Handle "gpio/int" command. */ -void dh_handle_gpio_int(COMMAND_RESULT *cb, const char *command, +void dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 8ed522f..0483370 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -56,20 +56,10 @@ #define ADCNOTIFICATION_MIN_TIMEOUT_MS 250 -LOCAL void ICACHE_FLASH_ATTR responce_ok(COMMAND_RESULT *cb) { - cb->callback(cb->data, DHSTATUS_OK, RDT_CONST_STRING, ""); -} - -LOCAL const char * ICACHE_FLASH_ATTR responce_error(COMMAND_RESULT *cb, const char *str) { - if(str) - cb->callback(cb->data, DHSTATUS_ERROR, RDT_CONST_STRING, str); - return str; -} - LOCAL int ICACHE_FLASH_ATTR onewire_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { if(fields & AF_PIN) { if(dhonewire_set_pin(parse_pins->pin) == 0) { - responce_error(cb, "Wrong onewire pin"); + dh_command_fail(cb, "Wrong onewire pin"); return 1; } } @@ -79,13 +69,13 @@ LOCAL int ICACHE_FLASH_ATTR onewire_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fiel LOCAL int ICACHE_FLASH_ATTR spi_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { if(fields & AF_CS) { if(dhspi_set_cs_pin(parse_pins->CS) == 0) { - responce_error(cb, "Wrong CS pin"); + dh_command_fail(cb, "Wrong CS pin"); return 1; } } if(fields & AF_SPIMODE) { if(dhspi_set_mode(parse_pins->spi_mode) == 0) { - responce_error(cb, "Wrong SPI mode"); + dh_command_fail(cb, "Wrong SPI mode"); return 1; } } @@ -110,16 +100,18 @@ LOCAL char *ICACHE_FLASH_ATTR i2c_status_tochar(DHI2C_STATUS status) { LOCAL int ICACHE_FLASH_ATTR i2c_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { if((fields & AF_ADDRESS) == 0) { - responce_error(cb, "Address not specified"); + dh_command_fail(cb, "Address not specified"); return 1; } int init = ((fields & AF_SDA) ? 1 : 0) + ((fields & AF_SCL) ? 1 : 0); if(init == 2) { char *res = i2c_status_tochar(dhi2c_init(parse_pins->SDA, parse_pins->SCL)); - if(responce_error(cb, res)) + if (res != 0) { + dh_command_fail(cb, res); return 1; + } } else if(init == 1) { - responce_error(cb, "Only one pin specified"); + dh_command_fail(cb, "Only one pin specified"); return 1; } else { dhi2c_reinit(); @@ -131,10 +123,10 @@ LOCAL int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, if(fields & AF_UARTMODE) { if(parse_pins->uart_speed == 0 && isint) { dhuart_enable_buf_interrupt(0); - responce_ok(cb); + dh_command_done(cb, ""); return 1; } else if(!dhuart_init(parse_pins->uart_speed, parse_pins->uart_bits, parse_pins->uart_partity, parse_pins->uart_stopbits)) { - responce_error(cb, "Wrong UART mode"); + dh_command_fail(cb, "Wrong UART mode"); return 1; } } @@ -154,10 +146,10 @@ static void ICACHE_FLASH_ATTR do_adc_read(COMMAND_RESULT *cb, const char *comman char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_READ, &fields); if(parse_res) { - responce_error(cb, parse_res); + dh_command_fail(cb, parse_res); return; } else if(parse_pins.pins_to_read != DHADC_SUITABLE_PINS) { - responce_error(cb, "Unknown ADC channel"); + dh_command_fail(cb, "Unknown ADC channel"); return; } } @@ -177,21 +169,22 @@ static void ICACHE_FLASH_ATTR do_adc_int(COMMAND_RESULT *cb, const char *command char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_VALUES, &fields); - if(responce_error(cb, parse_res)) { + if(parse_res != 0) { + dh_command_fail(cb, parse_res); return; } else if(parse_pins.pin_value_readed != 0x1) { - responce_error(cb, "Wrong adc channel"); + dh_command_fail(cb, "Wrong adc channel"); return; } else if((parse_pins.storage.uint_values[0] < ADCNOTIFICATION_MIN_TIMEOUT_MS && parse_pins.storage.uint_values[0] != 0) || parse_pins.storage.uint_values[0] > 0x7fffff) { - responce_error(cb, "Wrong period"); + dh_command_fail(cb, "Wrong period"); return; } else { dhadc_loop(parse_pins.storage.uint_values[0]); - responce_ok(cb); + dh_command_done(cb, ""); return; } } - responce_error(cb, "Wrong parameters"); + dh_command_fail(cb, "Wrong parameters"); } @@ -205,12 +198,14 @@ static void ICACHE_FLASH_ATTR do_pwm_control(COMMAND_RESULT *cb, const char *com char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_VALUES | AF_PERIOD | AF_COUNT, &fields); - if(responce_error(cb, parse_res)) + if(parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(dhpwm_set_pwm(&parse_pins.storage.uint_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : dhpwm_get_period_us(), parse_pins.count)) - responce_ok(cb); + dh_command_done(cb, ""); else - responce_error(cb, "Wrong parameters"); + dh_command_fail(cb, "Wrong parameters"); } #endif // ADC and PWM commands @@ -227,13 +222,15 @@ static void ICACHE_FLASH_ATTR do_uart_write(COMMAND_RESULT *cb, const char *comm char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_UARTMODE | AF_DATA, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(uart_init(cb, fields, &parse_pins, 0)) return; dhuart_set_mode(DUM_PER_BUF); dhuart_send_buf(parse_pins.data, parse_pins.data_len); - responce_ok(cb); + dh_command_done(cb, ""); } @@ -248,17 +245,19 @@ static void ICACHE_FLASH_ATTR do_uart_read(COMMAND_RESULT *cb, const char *comma char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(uart_init(cb, fields, &parse_pins, 0)) return; if(fields & AF_TIMEOUT) { if(parse_pins.timeout > 1000) { - responce_error(cb, "Timeout is too long"); + dh_command_fail(cb, "Timeout is too long"); return; } if((fields & AF_DATA) == 0) { - responce_error(cb, "Timeout can be specified only with data"); + dh_command_fail(cb, "Timeout can be specified only with data"); return; } } @@ -290,10 +289,12 @@ static void ICACHE_FLASH_ATTR do_uart_int(COMMAND_RESULT *cb, const char *comman char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, dhuart_get_callback_timeout(), AF_UARTMODE | AF_TIMEOUT, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & AF_TIMEOUT) && parse_pins.timeout > 5000) { - responce_error(cb, "Timeout is too long"); + dh_command_fail(cb, "Timeout is too long"); return; } if(uart_init(cb, fields, &parse_pins, 1)) @@ -303,7 +304,7 @@ static void ICACHE_FLASH_ATTR do_uart_int(COMMAND_RESULT *cb, const char *comman } dhuart_set_mode(DUM_PER_BUF); dhuart_enable_buf_interrupt(1); - responce_ok(cb); + dh_command_done(cb, ""); } @@ -313,11 +314,11 @@ static void ICACHE_FLASH_ATTR do_uart_int(COMMAND_RESULT *cb, const char *comman static void ICACHE_FLASH_ATTR do_uart_terminal(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) { if(paramslen) { - responce_error(cb, "Command does not have parameters"); + dh_command_fail(cb, "Command does not have parameters"); return; } dhterminal_init(); - responce_ok(cb); + dh_command_done(cb, ""); } #endif // UART commands @@ -334,12 +335,14 @@ static void ICACHE_FLASH_ATTR do_i2c_master_read(COMMAND_RESULT *cb, const char char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); - if (responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & AF_COUNT) == 0) parse_pins.count = 2; if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - responce_error(cb, "Wrong read size"); + dh_command_fail(cb, "Wrong read size"); return; } if(i2c_init(cb, fields, &parse_pins)) @@ -348,16 +351,16 @@ static void ICACHE_FLASH_ATTR do_i2c_master_read(COMMAND_RESULT *cb, const char if(fields & AF_DATA) { res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 0)); if(res) { - responce_error(cb, res); + dh_command_fail(cb, res); return; } } res = i2c_status_tochar(dhi2c_read(parse_pins.address, parse_pins.data, parse_pins.count)); if(res) { - responce_error(cb, res); - return; + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); } - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); } @@ -371,17 +374,22 @@ static void ICACHE_FLASH_ATTR do_i2c_master_write(COMMAND_RESULT *cb, const char char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if(parse_res) { + dh_command_fail(cb, parse_res); return; + } if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); + dh_command_fail(cb, "Data not specified"); return; } if(i2c_init(cb, fields, &parse_pins)) return; char *res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 1)); - if(responce_error(cb, res) == 0) - responce_ok(cb); + if (res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } #endif // I2C commands @@ -398,12 +406,14 @@ static void ICACHE_FLASH_ATTR do_spi_master_read(COMMAND_RESULT *cb, const char char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); - if(responce_error(cb, parse_res)) + if(parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & AF_COUNT) == 0) parse_pins.count = 2; if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - responce_error(cb, "Wrong read size"); + dh_command_fail(cb, "Wrong read size"); return; } if(spi_init(cb, fields, &parse_pins)) @@ -425,16 +435,18 @@ static void ICACHE_FLASH_ATTR do_spi_master_write(COMMAND_RESULT *cb, const char char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(spi_init(cb, fields, &parse_pins)) return; if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); + dh_command_fail(cb, "Data not specified"); return; } dhspi_write(parse_pins.data, parse_pins.data_len, 1); - responce_ok(cb); + dh_command_done(cb, ""); } #endif // SPI commands @@ -451,20 +463,22 @@ static void ICACHE_FLASH_ATTR do_onewire_master_read(COMMAND_RESULT *cb, const c char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA | AF_COUNT, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & AF_COUNT) == 0 || parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - responce_error(cb, "Wrong read size"); + dh_command_fail(cb, "Wrong read size"); return; } if((fields & AF_DATA) == 0) { - responce_error(cb, "Command for reading is not specified"); + dh_command_fail(cb, "Command for reading is not specified"); return; } if(onewire_init(cb, fields, &parse_pins)) return; if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { - responce_error(cb, "No response"); + dh_command_fail(cb, "No response"); return; } dhonewire_read(parse_pins.data, parse_pins.count); @@ -482,15 +496,17 @@ static void ICACHE_FLASH_ATTR do_onewire_master_write(COMMAND_RESULT *cb, const char * parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(onewire_init(cb, fields, &parse_pins)) return; if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { - responce_error(cb, "No response"); + dh_command_fail(cb, "No response"); return; } - responce_ok(cb); + dh_command_done(cb, ""); } /** @@ -503,8 +519,10 @@ static void ICACHE_FLASH_ATTR do_onewire_master_search(COMMAND_RESULT *cb, const if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(onewire_init(cb, fields, &parse_pins)) return; } @@ -514,7 +532,7 @@ static void ICACHE_FLASH_ATTR do_onewire_master_search(COMMAND_RESULT *cb, const if(dhonewire_search(parse_pins.data, (unsigned long *)&parse_pins.data_len, (check == 0) ? 0xF0 : 0xEC, dhonewire_get_pin())) cb->callback(cb->data, DHSTATUS_OK, RDT_SEARCH64, dhonewire_get_pin(), parse_pins.data, parse_pins.data_len); else - responce_error(cb, "Error during search"); + dh_command_fail(cb, "Error during search"); } @@ -528,13 +546,13 @@ static void ICACHE_FLASH_ATTR do_onewire_master_int(COMMAND_RESULT *cb, const ch char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); if(parse_res) - responce_error(cb, parse_res); + dh_command_fail(cb, parse_res); else if(fields == 0) - responce_error(cb, "Wrong action"); + dh_command_fail(cb, "Wrong action"); else if(dhonewire_int(parse_pins.pins_to_presence, parse_pins.pins_to_disable)) - responce_ok(cb); + dh_command_done(cb, ""); else - responce_error(cb, "Unsuitable pin"); + dh_command_fail(cb, "Unsuitable pin"); } @@ -547,8 +565,10 @@ static void ICACHE_FLASH_ATTR do_onewire_dht_read(COMMAND_RESULT *cb, const char ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(onewire_init(cb, fields, &parse_pins)) return; } @@ -556,7 +576,7 @@ static void ICACHE_FLASH_ATTR do_onewire_dht_read(COMMAND_RESULT *cb, const char if(parse_pins.count) cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); else - responce_error(cb, "No response"); + dh_command_fail(cb, "No response"); } @@ -569,16 +589,18 @@ static void ICACHE_FLASH_ATTR do_onewire_ws2812b_write(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); + dh_command_fail(cb, "Data not specified"); return; } if(onewire_init(cb, fields, &parse_pins)) return; dhonewire_ws2812b_write(parse_pins.data, parse_pins.data_len); - responce_ok(cb); + dh_command_done(cb, ""); } #endif // onewire commands @@ -595,16 +617,20 @@ static void ICACHE_FLASH_ATTR do_devices_ds18b20_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; char * parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(onewire_init(cb, fields, &parse_pins)) return; } float temperature; char *res = ds18b20_read(DS18B20_NO_PIN, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + if(res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + } } @@ -618,8 +644,10 @@ static void ICACHE_FLASH_ATTR do_devices_dht11_read(COMMAND_RESULT *cb, const ch ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(onewire_init(cb, fields, &parse_pins)) return; } @@ -627,9 +655,11 @@ static void ICACHE_FLASH_ATTR do_devices_dht11_read(COMMAND_RESULT *cb, const ch int temperature; int humidity; char *res = dht11_read(DHT_NO_PIN, &humidity, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); + if(res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); + } } @@ -643,8 +673,10 @@ static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const ch ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(onewire_init(cb, fields, &parse_pins)) return; } @@ -652,9 +684,11 @@ static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const ch float temperature; float humidity; char *res = dht22_read(DHT_NO_PIN, &humidity, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); + } } /** @@ -668,8 +702,10 @@ static void ICACHE_FLASH_ATTR do_devices_bmp180_read(COMMAND_RESULT *cb, const c char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) bmp180_set_address(parse_pins.address); } @@ -679,9 +715,11 @@ static void ICACHE_FLASH_ATTR do_devices_bmp180_read(COMMAND_RESULT *cb, const c float temperature; int pressure; char *res = i2c_status_tochar(bmp180_read(BMP180_NO_PIN, BMP180_NO_PIN, &pressure, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); + } } /** @@ -695,8 +733,10 @@ static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const c char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) bmp280_set_address(parse_pins.address); } @@ -706,9 +746,11 @@ static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const c float temperature; float pressure; char *res = i2c_status_tochar(bmp280_read(BMP280_NO_PIN, BMP280_NO_PIN, &pressure, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); + } } @@ -723,8 +765,10 @@ static void ICACHE_FLASH_ATTR do_devices_bh1750_read(COMMAND_RESULT *cb, const c char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) bh1750_set_address(parse_pins.address); } @@ -733,9 +777,11 @@ static void ICACHE_FLASH_ATTR do_devices_bh1750_read(COMMAND_RESULT *cb, const c return; float illuminance; char *res = i2c_status_tochar(bh1750_read(BH1750_NO_PIN, BH1750_NO_PIN, &illuminance)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); + if(res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); + } } /** @@ -749,8 +795,10 @@ static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) mpu6050_set_address(parse_pins.address); } @@ -761,11 +809,13 @@ static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const MPU6050_XYZ gyro; float temperature; char *res = i2c_status_tochar(mpu6050_read(MPU6050_NO_PIN, MPU6050_NO_PIN, &acc, &gyro, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", - temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); + if(res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", + temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); + } } /** @@ -779,8 +829,10 @@ static void ICACHE_FLASH_ATTR do_devices_hmc5883l_read(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) hmc5883l_set_address(parse_pins.address); } @@ -789,8 +841,10 @@ static void ICACHE_FLASH_ATTR do_devices_hmc5883l_read(COMMAND_RESULT *cb, const return; HMC5883L_XYZ compass; char *res = i2c_status_tochar(hmc5883l_read(HMC5883L_NO_PIN, HMC5883L_NO_PIN, &compass)); - if(responce_error(cb, res)) + if(res != 0) { + dh_command_fail(cb, res); return; + } char floatbufx[10] = "NaN"; char floatbufy[10] = "NaN"; char floatbufz[10] = "NaN"; @@ -816,8 +870,10 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_read(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_PULLUP, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) pcf8574_set_address(parse_pins.address); } @@ -826,14 +882,18 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_read(COMMAND_RESULT *cb, const return; if(fields & AF_PULLUP) { char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_pullup, 0)); - if(responce_error(cb, res)) + if (res != 0) { + dh_command_fail(cb, res); return; + } } unsigned int pins; char *res = i2c_status_tochar(pcf8574_read(PCF8574_NO_PIN, PCF8574_NO_PIN, &pins)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, pins, system_get_time(), PCF8574_SUITABLE_PINS); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, pins, system_get_time(), PCF8574_SUITABLE_PINS); + } } /** @@ -846,14 +906,15 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_write(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_SET | AF_CLEAR, &fields); - if(responce_error(cb, parse_res)) { + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; } else if( (fields & (AF_SET | AF_CLEAR)) == 0) { - responce_error(cb, "Dummy request"); + dh_command_fail(cb, "Dummy request"); return; } else if( (parse_pins.pins_to_set | parse_pins.pins_to_clear | PCF8574_SUITABLE_PINS) != PCF8574_SUITABLE_PINS ) { - responce_error(cb, "Unsuitable pin"); + dh_command_fail(cb, "Unsuitable pin"); return; } if(fields & AF_ADDRESS) @@ -863,9 +924,11 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_write(COMMAND_RESULT *cb, const return; char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_set, parse_pins.pins_to_clear)); - if(responce_error(cb, res)) - return; - responce_ok(cb); + if(res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } /** @@ -878,10 +941,12 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCF8574_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_DATA | AF_TEXT_DATA, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { - responce_error(cb, "Text not specified"); + dh_command_fail(cb, "Text not specified"); return; } if(fields & AF_ADDRESS) @@ -891,9 +956,11 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c return; char *res = i2c_status_tochar(pcf8574_hd44780_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.data, parse_pins.data_len)); - if(responce_error(cb, res)) - return; - responce_ok(cb); + if (res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } /** @@ -902,14 +969,16 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c static void ICACHE_FLASH_ATTR do_devices_mhz19_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) { if(paramslen) { - responce_error(cb, "Command does not have parameters"); + dh_command_fail(cb, "Command does not have parameters"); return; } int co2; char *res = mhz19_read(&co2); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"co2\":%d}", co2); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"co2\":%d}", co2); + } } @@ -924,8 +993,10 @@ static void ICACHE_FLASH_ATTR do_devices_lm75_read(COMMAND_RESULT *cb, const cha char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) lm75_set_address(parse_pins.address); } @@ -934,9 +1005,11 @@ static void ICACHE_FLASH_ATTR do_devices_lm75_read(COMMAND_RESULT *cb, const cha return; float temperature; char *res = i2c_status_tochar(lm75_read(LM75_NO_PIN, LM75_NO_PIN, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + } } @@ -949,8 +1022,10 @@ static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const c ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) si7021_set_address(parse_pins.address); } @@ -960,9 +1035,11 @@ static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const c float temperature; float humidity; char *res = i2c_status_tochar(si7021_read(SI7021_NO_PIN, SI7021_NO_PIN, &humidity, &temperature)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); + } } /** @@ -974,8 +1051,10 @@ static void ICACHE_FLASH_ATTR do_devices_ads1115_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) ads1115_set_address(parse_pins.address); } @@ -984,10 +1063,12 @@ static void ICACHE_FLASH_ATTR do_devices_ads1115_read(COMMAND_RESULT *cb, const return; float values[4]; char *res = i2c_status_tochar(ads1115_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", - values[0], values[1], values[2], values[3]); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", + values[0], values[1], values[2], values[3]); + } } /** @@ -1001,14 +1082,18 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) pcf8591_set_address(parse_pins.address); if(fields & AF_REF) { char *res = i2c_status_tochar(pcf8591_set_vref(parse_pins.ref)); - if(responce_error(cb, res)) + if (res != 0) { + dh_command_fail(cb, res); return; + } } } fields |= AF_ADDRESS; @@ -1016,10 +1101,12 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const return; float values[4]; char *res = i2c_status_tochar(pcf8591_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", - values[0], values[1], values[2], values[3]); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", + values[0], values[1], values[2], values[3]); + } } @@ -1033,26 +1120,32 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(parse_pins.pin_value_readed != 1) { - responce_error(cb, "Unsuitable pin"); + dh_command_fail(cb, "Unsuitable pin"); return; } if(fields & AF_ADDRESS) pcf8591_set_address(parse_pins.address); if(fields & AF_REF) { char *res = i2c_status_tochar(pcf8591_set_vref(parse_pins.ref)); - if(responce_error(cb, res)) + if (res != 0) { + dh_command_fail(cb, res); return; + } } fields |= AF_ADDRESS; if(i2c_init(cb, fields, &parse_pins)) return; char *res = i2c_status_tochar(pcf8591_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); - if(responce_error(cb, res)) - return; - responce_ok(cb); + if (res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } /** @@ -1065,26 +1158,32 @@ static void ICACHE_FLASH_ATTR do_devices_mcp4725_write(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(parse_pins.pin_value_readed != 1) { - responce_error(cb, "Unsuitable pin"); + dh_command_fail(cb, "Unsuitable pin"); return; } if(fields & AF_ADDRESS) mcp4725_set_address(parse_pins.address); if(fields & AF_REF) { char *res = i2c_status_tochar(mcp4725_set_vref(parse_pins.ref)); - if(responce_error(cb, res)) + if (res != 0) { + dh_command_fail(cb, res); return; + } } fields |= AF_ADDRESS; if(i2c_init(cb, fields, &parse_pins)) return; char *res = i2c_status_tochar(mcp4725_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); - if(responce_error(cb, res)) - return; - responce_ok(cb); + if (res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } /** @@ -1098,14 +1197,18 @@ static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const c char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) ina219_set_address(parse_pins.address); if(fields & AF_REF) { char *res = i2c_status_tochar(ina219_set_shunt(parse_pins.ref)); - if(responce_error(cb, res)) + if (res != 0) { + dh_command_fail(cb, res); return; + } } } fields |= AF_ADDRESS; @@ -1115,11 +1218,13 @@ static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const c float current; float power; char *res = i2c_status_tochar(ina219_read(ADS1115_NO_PIN, ADS1115_NO_PIN, &voltage, ¤t, &power)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"voltage\":%f, \"current\":%f, \"power\":%f}", - voltage, current, power); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"voltage\":%f, \"current\":%f, \"power\":%f}", + voltage, current, power); + } } /** @@ -1132,11 +1237,13 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_CS) { if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { - responce_error(cb, "Unsuitable pin"); + dh_command_fail(cb, "Unsuitable pin"); return; } } @@ -1163,7 +1270,7 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_read(COMMAND_RESULT *cb, const } MFRC522_PICC_HaltA(); MFRC522_PCD_AntennaOff(); - responce_error(cb, MFRC522_GetStatusCodeName(result)); + dh_command_fail(cb, MFRC522_GetStatusCodeName(result)); } /** @@ -1177,16 +1284,18 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS | AF_ADDRESS | AF_KEY | (check ? AF_DATA : 0), &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_CS) { if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { - responce_error(cb, "Unsuitable pin"); + dh_command_fail(cb, "Unsuitable pin"); return; } } if((fields & AF_ADDRESS) == 0) { - responce_error(cb, "Block address not specified"); + dh_command_fail(cb, "Block address not specified"); return; } if((fields & AF_KEY) == 0) { @@ -1194,15 +1303,15 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL os_memset(parse_pins.storage.key.key_data, 0xFF, MF_KEY_SIZE); parse_pins.storage.key.key_len = MF_KEY_SIZE; } else if(parse_pins.storage.key.key_len != MF_KEY_SIZE) { - responce_error(cb, "Wrong key length"); + dh_command_fail(cb, "Wrong key length"); return; } if(check) { if((fields & AF_DATA) == 0) { - responce_error(cb, "Data not specified"); + dh_command_fail(cb, "Data not specified"); return; } else if(parse_pins.data_len != 16) { - responce_error(cb, "Data length should be 16 bytes"); + dh_command_fail(cb, "Data length should be 16 bytes"); return; } } @@ -1226,7 +1335,7 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL if(result == MFRC522_STATUS_OK) { parse_pins.count = len; if(check) - responce_ok(cb); + dh_command_done(cb, ""); else cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); MFRC522_PICC_HaltA(); @@ -1240,7 +1349,7 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL MFRC522_PICC_HaltA(); MFRC522_PCD_StopCrypto1(); MFRC522_PCD_AntennaOff(); - responce_error(cb, MFRC522_GetStatusCodeName(result)); + dh_command_fail(cb, MFRC522_GetStatusCodeName(result)); } /** @@ -1253,8 +1362,10 @@ static void ICACHE_FLASH_ATTR do_devices_pca9685_control(COMMAND_RESULT *cb, con char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, PCA9685_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_FLOATVALUES | AF_PERIOD, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) pca9685_set_address(parse_pins.address); fields |= AF_ADDRESS; @@ -1263,9 +1374,11 @@ static void ICACHE_FLASH_ATTR do_devices_pca9685_control(COMMAND_RESULT *cb, con char *res = i2c_status_tochar(pca9685_control(PCA9685_NO_PIN, PCA9685_NO_PIN, parse_pins.storage.float_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : PCA9685_NO_PERIOD)); - if(responce_error(cb, res)) - return; - responce_ok(cb); + if (res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } /** @@ -1279,8 +1392,10 @@ static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if(fields & AF_ADDRESS) mlx90614_set_address(parse_pins.address); } @@ -1290,9 +1405,11 @@ static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const float ambient; float object; char *res = i2c_status_tochar(mlx90614_read(MLX90614_NO_PIN, MLX90614_NO_PIN, &ambient, &object)); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"ambient\":%f, \"object\":%f}", ambient, object); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"ambient\":%f, \"object\":%f}", ambient, object); + } } /** @@ -1304,14 +1421,18 @@ static void ICACHE_FLASH_ATTR do_devices_max6675_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } } float temperature; char *res = max6675_read((fields & AF_CS) ? parse_pins.CS : MAX6675_NO_PIN, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + } } /** @@ -1324,14 +1445,18 @@ static void ICACHE_FLASH_ATTR do_devices_max31855_read(COMMAND_RESULT *cb, const if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } } float temperature; char *res = max31855_read((fields & AF_CS) ? parse_pins.CS : MAX31855_NO_PIN, &temperature); - if(responce_error(cb, res)) - return; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + if (res != 0) { + dh_command_fail(cb, res); + } else { + cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + } } /** @@ -1344,10 +1469,12 @@ static void ICACHE_FLASH_ATTR do_devices_tm1637_write(COMMAND_RESULT *cb, const char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); - if(responce_error(cb, parse_res)) + if (parse_res != 0) { + dh_command_fail(cb, parse_res); return; + } if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { - responce_error(cb, "Text not specified"); + dh_command_fail(cb, "Text not specified"); return; } fields |= AF_ADDRESS; @@ -1355,9 +1482,11 @@ static void ICACHE_FLASH_ATTR do_devices_tm1637_write(COMMAND_RESULT *cb, const return; char *res = i2c_status_tochar(tm1636_write(TM1636_NO_PIN, TM1636_NO_PIN, parse_pins.data, parse_pins.data_len)); - if(responce_error(cb, res)) - return; - responce_ok(cb); + if (res != 0) { + dh_command_fail(cb, res); + } else { + dh_command_done(cb, ""); + } } #endif // devices commands @@ -1441,5 +1570,5 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co } } - responce_error(cb, "Unknown command"); + dh_command_fail(cb, "Unknown command"); } diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index d9a9ccb..a6e0081 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -145,3 +145,23 @@ int ICACHE_FLASH_ATTR dhsender_data_to_json(char *buf, unsigned int buf_len, } return -1; } + + +/* + * dh_command_done() implementation. + */ +void ICACHE_FLASH_ATTR dh_command_done(COMMAND_RESULT *cmd_res, const char *str) +{ + cmd_res->callback(cmd_res->data, DHSTATUS_OK, + RDT_CONST_STRING, str); +} + + +/* + * dh_command_fail() implementation. + */ +void ICACHE_FLASH_ATTR dh_command_fail(COMMAND_RESULT *cmd_res, const char *str) +{ + cmd_res->callback(cmd_res->data, DHSTATUS_ERROR, + RDT_CONST_STRING, str); +} diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index 37b2c00..f53fa63 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -12,6 +12,7 @@ #include "user_config.h" #include "dhsettings.h" #include "dhutils.h" +#include "irom.h" #include @@ -41,7 +42,7 @@ typedef enum { RNT_NOTIFICATION_ONEWIRE ///< Notification will be marked as onewire. } REQUEST_NOTIFICATION_TYPE; -/** Responce status*/ +/** Response status*/ typedef enum { DHSTATUS_ERROR = 0, ///< Send Error string DHSTATUS_OK ///< Send OK string @@ -114,4 +115,43 @@ int dhsender_data_to_json(char *buf, unsigned int buf_len, int is_notification, REQUEST_DATA_TYPE data_type, SENDERDATA *data, unsigned int data_len, unsigned int pin); + +/** + * @brief Report command success. + * @param[in] cmd_res Command result. + * @param[in] str String message to report. + */ +void dh_command_done(COMMAND_RESULT *cmd_res, const char *str); + +/* + * @brief Report command success (ROM). + * + * The same as dh_command_done() but uses ROM to store string message. + */ +/*#define dh_command_DONE(cmd_res, str) \ +do { \ + static const char static_str[] DH_RO_ATTR = str; \ + dh_command_done(cmd_res, static_str); \ +} while(0)*/ + + +/** + * @brief Report command failure. + * @param[in] cmd_res Command result. + * @param[in] str String error to report. + */ +void dh_command_fail(COMMAND_RESULT *cmd_res, const char *str); + +/* + * @brief Report command failure (ROM). + * + * The same as dh_command_fail() but uses ROM to store string message. + */ +/*#define dh_command_FAIL(cmd_res, str) \ +do { \ + static const char static_str[] DH_RO_ATTR = str; \ + dh_command_fail(cmd_res, static_str); \ +} while(0) */ + + #endif /* _DHSENDER_DATA_H_ */ From 0810a785ad29cdf2969ea1d1d8ff41fa2f64d176 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 19 Apr 2017 19:30:03 +0300 Subject: [PATCH 26/83] review the DH/adc module command handlers now are in the module inself firmware size is 398948 --- firmware-src/sources/DH/adc.c | 124 ++++++++++++++++++++++++ firmware-src/sources/DH/adc.h | 56 +++++++++++ firmware-src/sources/DH/cmd_gpio.c | 110 ---------------------- firmware-src/sources/DH/cmd_gpio.h | 34 ------- firmware-src/sources/DH/gpio.c | 106 +++++++++++++++++++++ firmware-src/sources/DH/gpio.h | 26 ++++++ firmware-src/sources/dhadc.c | 33 ------- firmware-src/sources/dhadc.h | 33 ------- firmware-src/sources/dhcommands.c | 130 ++++++++------------------ firmware-src/sources/dhnotification.c | 4 +- 10 files changed, 351 insertions(+), 305 deletions(-) create mode 100644 firmware-src/sources/DH/adc.c create mode 100644 firmware-src/sources/DH/adc.h delete mode 100644 firmware-src/sources/DH/cmd_gpio.c delete mode 100644 firmware-src/sources/DH/cmd_gpio.h delete mode 100644 firmware-src/sources/dhadc.c delete mode 100644 firmware-src/sources/dhadc.h diff --git a/firmware-src/sources/DH/adc.c b/firmware-src/sources/DH/adc.c new file mode 100644 index 0000000..272fa69 --- /dev/null +++ b/firmware-src/sources/DH/adc.c @@ -0,0 +1,124 @@ +/** + * @file + * @brief ADC hardware access layer for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/adc.h" + +#include +#include +#include +#include +#include + +// module variables +static os_timer_t mTimer; + +/* + * dh_adc_get_value() implementation. + */ +float ICACHE_FLASH_ATTR dh_adc_get_value(void) +{ + return system_adc_read() / 1024.0f; +} + + +/** + * @brief Timeout callback. + */ +static void ICACHE_FLASH_ATTR timeout_cb(void *arg) +{ + // call external handler + dh_adc_loop_value_cb(dh_adc_get_value()); +} + + +/* + * dh_adc_loop() implementation. + */ +void ICACHE_FLASH_ATTR dh_adc_loop(unsigned int period_ms) +{ + os_timer_disarm(&mTimer); + if (period_ms) { + os_timer_setfn(&mTimer, timeout_cb, NULL); + os_timer_arm(&mTimer, period_ms, 1); + } +} + + +#if 1 // command handlers +#include "dhcommand_parser.h" +#include + +/** + * Minimum notification timeout, milliseconds. + */ +#define MIN_TIMEOUT_MS 250 + + +/** + * Maximum notification timeout, milliseconds. + */ +#define MAX_TIMEOUT_MS 0x7fffff + + +/* + * dh_handle_adc_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_READ, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + + if (info.pins_to_read != DH_ADC_SUITABLE_PINS) { + dh_command_fail(cmd_res, "Unknown ADC channel"); + return; // FAILED + } + } + + // OK, report ADC value + cmd_res->callback(cmd_res->data, DHSTATUS_OK, + RDT_FLOAT, dh_adc_get_value()); +} + + +/* + * dh_handle_adc_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_VALUES, &fields); + // TODO: use AF_TIMEOUT here? + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } else if (info.pin_value_readed != DH_ADC_SUITABLE_PINS) { + dh_command_fail(cmd_res, "Unknown ADC channel"); + return; // FAILED + } + + const unsigned int timeout = info.storage.uint_values[0]; + if ((timeout != 0 && timeout < MIN_TIMEOUT_MS) || timeout > MAX_TIMEOUT_MS) { + dh_command_fail(cmd_res, "Wrong period"); + } else { + dh_adc_loop(timeout); + dh_command_done(cmd_res, ""); + } +} + +#endif // command handlers diff --git a/firmware-src/sources/DH/adc.h b/firmware-src/sources/DH/adc.h new file mode 100644 index 0000000..d6c5edd --- /dev/null +++ b/firmware-src/sources/DH/adc.h @@ -0,0 +1,56 @@ +/** + * @file + * @brief ADC hardware access layer for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DH_ADC_H_ +#define _DH_ADC_H_ + +/** + * @brief ADC suitable channels. + */ +#define DH_ADC_SUITABLE_PINS 0x01 // ADC0 + + +/** + * @brief Get ADC value. + * @return ADC voltage in volts. + */ +float dh_adc_get_value(void); + + +/** + * @brief Start ADC loop measurement. + * @param[in] period_ms Measurement interval in milliseconds. + */ +void dh_adc_loop(unsigned int period_ms); + + +/** + * @brief Callback function for loop measurement. + * @param[in] value ADC voltage in volts. + */ +// TODO: consider to use callback function pointer +extern void dh_adc_loop_value_cb(float value); + + +#if 1 // command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "adc/read" command. + */ +void dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "adc/int" command. + */ +void dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif // command handlers + +#endif /* _DH_ADC_H_ */ diff --git a/firmware-src/sources/DH/cmd_gpio.c b/firmware-src/sources/DH/cmd_gpio.c deleted file mode 100644 index c197da3..0000000 --- a/firmware-src/sources/DH/cmd_gpio.c +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file - * @brief Handle GPIO commands. - * @copyright 2017 [DeviceHive](http://devicehive.com) - * @author Nikolay Khabarov - */ -#include "DH/cmd_gpio.h" -#include "DH/gpio.h" - -#include "dhcommand_parser.h" -#include - -/** - * Minimum notification timeout, milliseconds. - */ -#define MIN_TIMEOUT_MS 50 - - -/** - * Maximum notification timeout, milliseconds. - */ -#define MAX_TIMEOUT_MS 0x7fffff - - -/* - * dh_handle_gpio_write() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, - 0, AF_SET | AF_CLEAR, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else if (!(fields & (AF_SET | AF_CLEAR))) { - dh_command_fail(cmd_res, "Dummy request"); - } else if (!!dh_gpio_write(info.pins_to_set, info.pins_to_clear)) { - dh_command_fail(cmd_res, "Unsuitable pin"); - } else { - dh_command_done(cmd_res, ""); - } -} - - -/* - * dh_handle_gpio_read() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - if (params_len) { - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, 0, - AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - - // initialize GPIO as input - if (!!dh_gpio_input(info.pins_to_init, - info.pins_to_pullup, - info.pins_to_nopull)) { - dh_command_fail(cmd_res, "Wrong initialization parameters"); - return; // FAILED - } - } - - // OK, read GPIO input - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_GPIO, - 0, dh_gpio_read(), system_get_time(), - DH_GPIO_SUITABLE_PINS); -} - - -/* - * dh_handle_gpio_int() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), - AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else if (fields == 0) { - dh_command_fail(cmd_res, "Wrong action"); - } else if (info.timeout < MIN_TIMEOUT_MS || info.timeout > MAX_TIMEOUT_MS) { - dh_command_fail(cmd_res, "Timeout out of range"); - } else if (!!dh_gpio_subscribe_int(info.pins_to_disable, - info.pins_to_rising, - info.pins_to_falling, - info.pins_to_both, - info.timeout)) { - dh_command_fail(cmd_res, "Unsuitable pin"); - } else { - dh_command_done(cmd_res, ""); - } -} diff --git a/firmware-src/sources/DH/cmd_gpio.h b/firmware-src/sources/DH/cmd_gpio.h deleted file mode 100644 index 8ecaa12..0000000 --- a/firmware-src/sources/DH/cmd_gpio.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file - * @brief Handle GPIO commands. - * @copyright 2017 [DeviceHive](http://devicehive.com) - * @author Nikolay Khabarov - */ -#ifndef _DH_CMD_GPIO_H_ -#define _DH_CMD_GPIO_H_ - -#include "dhsender_data.h" - - -/** - * @brief Handle "gpio/write" command. - */ -void dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "gpio/read" command. - */ -void dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "gpio/int" command. - */ -void dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -#endif /* _DH_CMD_GPIO_H_ */ diff --git a/firmware-src/sources/DH/gpio.c b/firmware-src/sources/DH/gpio.c index 60d05f9..670ffa2 100644 --- a/firmware-src/sources/DH/gpio.c +++ b/firmware-src/sources/DH/gpio.c @@ -339,3 +339,109 @@ int ICACHE_FLASH_ATTR dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, return r; } + + +#if 1 // command handlers +#include "dhcommand_parser.h" +#include + +/** + * Minimum notification timeout, milliseconds. + */ +#define MIN_TIMEOUT_MS 50 + + +/** + * Maximum notification timeout, milliseconds. + */ +#define MAX_TIMEOUT_MS 0x7fffff + + +/* + * dh_handle_gpio_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, + 0, AF_SET | AF_CLEAR, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (!(fields & (AF_SET | AF_CLEAR))) { + dh_command_fail(cmd_res, "Dummy request"); + } else if (!!dh_gpio_write(info.pins_to_set, info.pins_to_clear)) { + dh_command_fail(cmd_res, "Unsuitable pin"); + } else { + dh_command_done(cmd_res, ""); + } +} + + +/* + * dh_handle_gpio_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, 0, + AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + + // initialize GPIO as input + if (!!dh_gpio_input(info.pins_to_init, + info.pins_to_pullup, + info.pins_to_nopull)) { + dh_command_fail(cmd_res, "Wrong initialization parameters"); + return; // FAILED + } + } + + // OK, read GPIO input + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_GPIO, + 0, dh_gpio_read(), system_get_time(), + DH_GPIO_SUITABLE_PINS); +} + + +/* + * dh_handle_gpio_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), + AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (fields == 0) { + dh_command_fail(cmd_res, "Wrong action"); + } else if (info.timeout < MIN_TIMEOUT_MS || info.timeout > MAX_TIMEOUT_MS) { + dh_command_fail(cmd_res, "Timeout out of range"); + } else if (!!dh_gpio_subscribe_int(info.pins_to_disable, + info.pins_to_rising, + info.pins_to_falling, + info.pins_to_both, + info.timeout)) { + dh_command_fail(cmd_res, "Unsuitable pin"); + } else { + dh_command_done(cmd_res, ""); + } +} + +#endif // command handlers diff --git a/firmware-src/sources/DH/gpio.h b/firmware-src/sources/DH/gpio.h index fd56e6a..79ebb65 100644 --- a/firmware-src/sources/DH/gpio.h +++ b/firmware-src/sources/DH/gpio.h @@ -162,4 +162,30 @@ int dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, // TODO: consider to use callback function pointer extern void dh_gpio_extra_int_cb(DHGpioPinMask caused_pins); + +#if 1 // command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "gpio/write" command. + */ +void dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "gpio/read" command. + */ +void dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "gpio/int" command. + */ +void dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif // command handlers + #endif /* _DH_GPIO_H_ */ diff --git a/firmware-src/sources/dhadc.c b/firmware-src/sources/dhadc.c deleted file mode 100644 index 8d298bc..0000000 --- a/firmware-src/sources/dhadc.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * dhadc.h - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - */ -#include "dhadc.h" - -#include -#include -#include -#include -#include - -LOCAL os_timer_t mADCTimer; - -float ICACHE_FLASH_ATTR dhadc_get_value(void){ - return system_adc_read()/1024.0f; -} - -LOCAL void ICACHE_FLASH_ATTR send_adc_data(void *arg) { - dhadc_loop_value(dhadc_get_value()); -} - -void ICACHE_FLASH_ATTR dhadc_loop(unsigned int period) { - os_timer_disarm(&mADCTimer); - if(period) { - os_timer_setfn(&mADCTimer, (os_timer_func_t *)send_adc_data, NULL); - os_timer_arm(&mADCTimer, period, 1); - } -} diff --git a/firmware-src/sources/dhadc.h b/firmware-src/sources/dhadc.h deleted file mode 100644 index 102a0d1..0000000 --- a/firmware-src/sources/dhadc.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * \file dhadc.h - * \brief ADC hardware access layer for DeviceHive firmware. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - */ - -#ifndef _DHADC_H_ -#define _DHADC_H_ - -/** ADC suitable channels. */ -#define DHADC_SUITABLE_PINS 0b01 // ADC0 - -/** - * \brief Get ADC value. - * \return Voltage in volts. - */ -float dhadc_get_value(void); - -/** - * \brief Start loop measurement with some interval. - * \param[in] period Period in milliseconds. - */ -void dhadc_loop(unsigned int period); - -/** - * \brief Callback for loop measurement. - * \param[in] value Voltage in volts. - */ -extern void dhadc_loop_value(float value); - -#endif /* _DHADC_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 0483370..3e1a3ea 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -11,7 +11,7 @@ #include "dhcommands.h" #include "dhsender_queue.h" #include "DH/gpio.h" -#include "dhadc.h" +#include "DH/adc.h" #include "dhnotification.h" #include "snprintf.h" #include "dhcommand_parser.h" @@ -46,16 +46,12 @@ #include "devices/max31855.h" #include "devices/tm1636.h" -#include "DH/cmd_gpio.h" - #include #include #include #include #include -#define ADCNOTIFICATION_MIN_TIMEOUT_MS 250 - LOCAL int ICACHE_FLASH_ATTR onewire_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { if(fields & AF_PIN) { if(dhonewire_set_pin(parse_pins->pin) == 0) { @@ -135,58 +131,6 @@ LOCAL int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, #if 1 // ADC and PWM commands -/** - * @brief Do "adc/read" command. - */ -static void ICACHE_FLASH_ATTR do_adc_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, AF_READ, &fields); - if(parse_res) { - dh_command_fail(cb, parse_res); - return; - } else if(parse_pins.pins_to_read != DHADC_SUITABLE_PINS) { - dh_command_fail(cb, "Unknown ADC channel"); - return; - } - } - - cb->callback(cb->data, DHSTATUS_OK, RDT_FLOAT, dhadc_get_value()); -} - - -/** - * @brief Do "adc/int" command. - */ -static void ICACHE_FLASH_ATTR do_adc_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, - AF_VALUES, &fields); - if(parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } else if(parse_pins.pin_value_readed != 0x1) { - dh_command_fail(cb, "Wrong adc channel"); - return; - } else if((parse_pins.storage.uint_values[0] < ADCNOTIFICATION_MIN_TIMEOUT_MS && parse_pins.storage.uint_values[0] != 0) || parse_pins.storage.uint_values[0] > 0x7fffff) { - dh_command_fail(cb, "Wrong period"); - return; - } else { - dhadc_loop(parse_pins.storage.uint_values[0]); - dh_command_done(cb, ""); - return; - } - } - dh_command_fail(cb, "Wrong parameters"); -} - /** * @brief Do "pwm/control" command. @@ -196,7 +140,7 @@ static void ICACHE_FLASH_ATTR do_pwm_control(COMMAND_RESULT *cb, const char *com gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_VALUES | AF_PERIOD | AF_COUNT, &fields); if(parse_res != 0) { dh_command_fail(cb, parse_res); @@ -220,7 +164,7 @@ static void ICACHE_FLASH_ATTR do_uart_write(COMMAND_RESULT *cb, const char *comm gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_UARTMODE | AF_DATA, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -243,7 +187,7 @@ static void ICACHE_FLASH_ATTR do_uart_read(COMMAND_RESULT *cb, const char *comma ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -287,7 +231,7 @@ static void ICACHE_FLASH_ATTR do_uart_int(COMMAND_RESULT *cb, const char *comman gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, dhuart_get_callback_timeout(), + &parse_pins, DH_ADC_SUITABLE_PINS, dhuart_get_callback_timeout(), AF_UARTMODE | AF_TIMEOUT, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -333,7 +277,7 @@ static void ICACHE_FLASH_ATTR do_i2c_master_read(COMMAND_RESULT *cb, const char gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -372,7 +316,7 @@ static void ICACHE_FLASH_ATTR do_i2c_master_write(COMMAND_RESULT *cb, const char gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); if(parse_res) { dh_command_fail(cb, parse_res); @@ -404,7 +348,7 @@ static void ICACHE_FLASH_ATTR do_spi_master_read(COMMAND_RESULT *cb, const char gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); if(parse_res != 0) { dh_command_fail(cb, parse_res); @@ -433,7 +377,7 @@ static void ICACHE_FLASH_ATTR do_spi_master_write(COMMAND_RESULT *cb, const char gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS | AF_SPIMODE | AF_DATA, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -461,7 +405,7 @@ static void ICACHE_FLASH_ATTR do_onewire_master_read(COMMAND_RESULT *cb, const c gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA | AF_COUNT, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -494,7 +438,7 @@ static void ICACHE_FLASH_ATTR do_onewire_master_write(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char * parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -518,7 +462,7 @@ static void ICACHE_FLASH_ATTR do_onewire_master_search(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -564,7 +508,7 @@ static void ICACHE_FLASH_ATTR do_onewire_dht_read(COMMAND_RESULT *cb, const char gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -588,7 +532,7 @@ static void ICACHE_FLASH_ATTR do_onewire_ws2812b_write(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -616,7 +560,7 @@ static void ICACHE_FLASH_ATTR do_devices_ds18b20_read(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char * parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -643,7 +587,7 @@ static void ICACHE_FLASH_ATTR do_devices_dht11_read(COMMAND_RESULT *cb, const ch gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -672,7 +616,7 @@ static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const ch gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, AF_PIN, &fields); + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -700,7 +644,7 @@ static void ICACHE_FLASH_ATTR do_devices_bmp180_read(COMMAND_RESULT *cb, const c ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -731,7 +675,7 @@ static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const c ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -763,7 +707,7 @@ static void ICACHE_FLASH_ATTR do_devices_bh1750_read(COMMAND_RESULT *cb, const c ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -793,7 +737,7 @@ static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -827,7 +771,7 @@ static void ICACHE_FLASH_ATTR do_devices_hmc5883l_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -991,7 +935,7 @@ static void ICACHE_FLASH_ATTR do_devices_lm75_read(COMMAND_RESULT *cb, const cha ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1021,7 +965,7 @@ static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const c gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -1050,7 +994,7 @@ static void ICACHE_FLASH_ATTR do_devices_ads1115_read(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -1080,7 +1024,7 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1118,7 +1062,7 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1156,7 +1100,7 @@ static void ICACHE_FLASH_ATTR do_devices_mcp4725_write(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1195,7 +1139,7 @@ static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const c ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1236,7 +1180,7 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_read(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -1282,7 +1226,7 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL ALLOWED_FIELDS fields = 0; const int check = os_strcmp(command, "devices/mfrc522/mifare/read"); char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS | AF_ADDRESS | AF_KEY | (check ? AF_DATA : 0), &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1390,7 +1334,7 @@ static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1420,7 +1364,7 @@ static void ICACHE_FLASH_ATTR do_devices_max6675_read(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -1444,7 +1388,7 @@ static void ICACHE_FLASH_ATTR do_devices_max31855_read(COMMAND_RESULT *cb, const ALLOWED_FIELDS fields = 0; if(paramslen) { char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, AF_CS, &fields); + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); return; @@ -1467,7 +1411,7 @@ static void ICACHE_FLASH_ATTR do_devices_tm1637_write(COMMAND_RESULT *cb, const gpio_command_params parse_pins; ALLOWED_FIELDS fields = 0; char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DHADC_SUITABLE_PINS, 0, + &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); if (parse_res != 0) { dh_command_fail(cb, parse_res); @@ -1500,8 +1444,8 @@ RO_DATA struct { {"gpio/read", dh_handle_gpio_read}, {"gpio/int", dh_handle_gpio_int}, - {"adc/read", do_adc_read}, - {"adc/int", do_adc_int}, + {"adc/read", dh_handle_adc_read}, + {"adc/int", dh_handle_adc_int}, {"pwm/control", do_pwm_control}, {"uart/write", do_uart_write}, diff --git a/firmware-src/sources/dhnotification.c b/firmware-src/sources/dhnotification.c index dd13e2f..0e9f292 100644 --- a/firmware-src/sources/dhnotification.c +++ b/firmware-src/sources/dhnotification.c @@ -11,7 +11,7 @@ #include "dhnotification.h" #include "dhsender.h" #include "DH/gpio.h" -#include "dhadc.h" +#include "DH/adc.h" #include "user_config.h" #include "snprintf.h" #include "dhdata.h" @@ -32,7 +32,7 @@ void ICACHE_FLASH_ATTR dh_gpio_int_cb(DHGpioPinMask caused_pins) { dhsender_notification(RNT_NOTIFICATION_GPIO, RDT_GPIO, caused_pins, dh_gpio_read(), system_get_time(), DH_GPIO_SUITABLE_PINS); } -void ICACHE_FLASH_ATTR dhadc_loop_value(float value){ +void ICACHE_FLASH_ATTR dh_adc_loop_value_cb(float value){ if(dhmem_isblock()) { dhstat_got_notification_dropped(); return; From 1a1e9d4b2a223d1bbcc67d900eb3ccd64d09a7a4 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 20 Apr 2017 14:16:03 +0300 Subject: [PATCH 27/83] introduce feature macro to enable/disable commands --- firmware-src/sources/DH/adc.c | 4 ++-- firmware-src/sources/DH/adc.h | 7 ++++--- firmware-src/sources/DH/gpio.c | 4 ++-- firmware-src/sources/DH/gpio.h | 6 +++--- firmware-src/sources/dhcommands.c | 5 +++++ firmware-src/sources/user_config.h | 8 ++++++++ 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/firmware-src/sources/DH/adc.c b/firmware-src/sources/DH/adc.c index 272fa69..f28541b 100644 --- a/firmware-src/sources/DH/adc.c +++ b/firmware-src/sources/DH/adc.c @@ -47,7 +47,7 @@ void ICACHE_FLASH_ATTR dh_adc_loop(unsigned int period_ms) } -#if 1 // command handlers +#ifdef DH_COMMANDS_ADC // ADC command handlers #include "dhcommand_parser.h" #include @@ -121,4 +121,4 @@ void ICACHE_FLASH_ATTR dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *co } } -#endif // command handlers +#endif /* DH_COMMANDS_ADC */ diff --git a/firmware-src/sources/DH/adc.h b/firmware-src/sources/DH/adc.h index d6c5edd..bfdb2c0 100644 --- a/firmware-src/sources/DH/adc.h +++ b/firmware-src/sources/DH/adc.h @@ -7,6 +7,8 @@ #ifndef _DH_ADC_H_ #define _DH_ADC_H_ +#include "user_config.h" + /** * @brief ADC suitable channels. */ @@ -35,7 +37,7 @@ void dh_adc_loop(unsigned int period_ms); extern void dh_adc_loop_value_cb(float value); -#if 1 // command handlers +#ifdef DH_COMMANDS_ADC // ADC command handlers #include "dhsender_data.h" /** @@ -51,6 +53,5 @@ void dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, void dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); -#endif // command handlers - +#endif /* DH_COMMANDS_ADC */ #endif /* _DH_ADC_H_ */ diff --git a/firmware-src/sources/DH/gpio.c b/firmware-src/sources/DH/gpio.c index 670ffa2..bf893db 100644 --- a/firmware-src/sources/DH/gpio.c +++ b/firmware-src/sources/DH/gpio.c @@ -341,7 +341,7 @@ int ICACHE_FLASH_ATTR dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, } -#if 1 // command handlers +#ifdef DH_COMMANDS_GPIO // GPIO command handlers #include "dhcommand_parser.h" #include @@ -444,4 +444,4 @@ void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *c } } -#endif // command handlers +#endif /* DH_COMMANDS_GPIO */ diff --git a/firmware-src/sources/DH/gpio.h b/firmware-src/sources/DH/gpio.h index 79ebb65..5ab4633 100644 --- a/firmware-src/sources/DH/gpio.h +++ b/firmware-src/sources/DH/gpio.h @@ -8,6 +8,7 @@ #define _DH_GPIO_H_ #include +#include "user_config.h" /** * @brief Pin mask type. @@ -163,7 +164,7 @@ int dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, extern void dh_gpio_extra_int_cb(DHGpioPinMask caused_pins); -#if 1 // command handlers +#ifdef DH_COMMANDS_GPIO // GPIO command handlers #include "dhsender_data.h" /** @@ -186,6 +187,5 @@ void dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, void dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); -#endif // command handlers - +#endif /* DH_COMMANDS_GPIO */ #endif /* _DH_GPIO_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 3e1a3ea..33c7d72 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -1440,12 +1440,17 @@ RO_DATA struct { void (*func)(COMMAND_RESULT*, const char*, const char*, unsigned int); } g_command_table[] = { +#ifdef DH_COMMANDS_GPIO {"gpio/write", dh_handle_gpio_write}, {"gpio/read", dh_handle_gpio_read}, {"gpio/int", dh_handle_gpio_int}, +#endif /* DH_COMMANDS_GPIO */ +#ifdef DH_COMMANDS_ADC {"adc/read", dh_handle_adc_read}, {"adc/int", dh_handle_adc_int}, +#endif /* DH_COMMANDS_ADC */ + {"pwm/control", do_pwm_control}, {"uart/write", do_uart_write}, diff --git a/firmware-src/sources/user_config.h b/firmware-src/sources/user_config.h index 723b393..3449002 100644 --- a/firmware-src/sources/user_config.h +++ b/firmware-src/sources/user_config.h @@ -36,4 +36,12 @@ /** HTTP webserver and RESTful service port. */ #define HTTPD_PORT 80 +// customize command set +#define DH_COMMANDS_GPIO // enable GPIO commands +#define DH_COMMANDS_ADC // enable ADC commands +#define DH_COMMANDS_PWM // enable PWM commands +#define DH_COMMANDS_UART // enable UART commands +#define DH_COMMANDS_I2C // enable I2C commands +#define DH_COMMANDS_SPI // enable SPI commands + #endif /* _USER_CONFIG_H_ */ From ec14e966213cfdadce0197ddf4e7e8581d71ba56 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 20 Apr 2017 15:10:50 +0300 Subject: [PATCH 28/83] review PWM module - hw_pwm_start() returns zero on success! --- firmware-src/sources/DH/gpio.c | 6 +- firmware-src/sources/DH/pwm.c | 213 ++++++++++++++++++++++++++++++ firmware-src/sources/DH/pwm.h | 69 ++++++++++ firmware-src/sources/dhcommands.c | 31 +---- firmware-src/sources/dhpwm.c | 133 ------------------- firmware-src/sources/dhpwm.h | 41 ------ 6 files changed, 288 insertions(+), 205 deletions(-) create mode 100644 firmware-src/sources/DH/pwm.c create mode 100644 firmware-src/sources/DH/pwm.h delete mode 100644 firmware-src/sources/dhpwm.c delete mode 100644 firmware-src/sources/dhpwm.h diff --git a/firmware-src/sources/DH/gpio.c b/firmware-src/sources/DH/gpio.c index bf893db..93bdd7f 100644 --- a/firmware-src/sources/DH/gpio.c +++ b/firmware-src/sources/DH/gpio.c @@ -5,9 +5,7 @@ * @author Nikolay Khabarov */ #include "DH/gpio.h" - -#include "user_config.h" -#include "dhpwm.h" +#include "DH/pwm.h" #include "dhmem.h" #include @@ -44,7 +42,7 @@ void ICACHE_FLASH_ATTR dh_gpio_init(void) void ICACHE_FLASH_ATTR dh_gpio_prepare_pins(DHGpioPinMask pins, bool disable_pwm) { if (disable_pwm) - dhpwm_disable_pins(pins); + dh_pwm_disable(pins); // only suitable pins are checked: GPIO0..GPIO5 if (pins & DH_GPIO_PIN(0)) diff --git a/firmware-src/sources/DH/pwm.c b/firmware-src/sources/DH/pwm.c new file mode 100644 index 0000000..d568d5f --- /dev/null +++ b/firmware-src/sources/DH/pwm.c @@ -0,0 +1,213 @@ +/** + * @file + * @brief Software PWM implementation for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/pwm.h" +#include "DH/adc.h" +#include "dhdebug.h" + +#include +#include +#include +#include +#include + +#define FRC1_ENABLE_TIMER BIT7 +#define FRC1_AUTO_LOAD BIT6 + +#define MIN_PERIOD_US 500 +#define MAX_PERIOD_US 2000004000 + + +typedef enum { + DIVDED_BY_1 = 0, + DIVDED_BY_16 = 4, + DIVDED_BY_256 = 8 +} TIMER_DIV_MODE; + +typedef enum { + TM_LEVEL_INT = 1, + TM_EDGE_INT = 0 +} TIMER_INT_MODE; + +// module variables +static DHGpioPinMask mDisablePinOn[DH_PWM_DEPTH + 1] = {0}; +static unsigned int mPeriodUs = DH_PWM_DEFAULT_PERIOD_US; +static unsigned char mCounter = 0; +static unsigned char mPwmInUse = 0; +static unsigned int mTotalCount = 0; +static DHGpioPinMask mUsedPins = 0; + + +/** + * @brief Disable PWM timer. + */ +static void ICACHE_FLASH_ATTR disarm_timer(void) +{ + TM1_EDGE_INT_DISABLE(); + ETS_FRC1_INTR_DISABLE(); +} + +/** + * @brief Timer callback function. + */ +static void timer_cb(void) +{ + if (mCounter == 0) { + if (mTotalCount) { + mTotalCount--; + if (mTotalCount == 0) { + disarm_timer(); + gpio_output_set(0, mDisablePinOn[DH_PWM_DEPTH], + mDisablePinOn[DH_PWM_DEPTH], 0); + dh_pwm_disable(mUsedPins | mDisablePinOn[0]); + return; + } + } else { + if (mPwmInUse == 0) + disarm_timer(); + } + gpio_output_set(mUsedPins, 0, mUsedPins, 0); + mPwmInUse = 0; + } else { + const DHGpioPinMask pins = mDisablePinOn[mCounter]; + if (pins) { + gpio_output_set(0, pins, pins, 0); + mPwmInUse = 1; + } + } + mCounter++; + if (mCounter >= DH_PWM_DEPTH) + mCounter = 0; +} + + +/** + * @brief Enable PWM timer. + */ +static void ICACHE_FLASH_ATTR arm_timer(void) +{ + // use mFrequency + mPwmInUse = 1; + mCounter = 1; + unsigned int tacts; + TIMER_DIV_MODE timer_div; + if (mPeriodUs < 10000000) { + timer_div = DIVDED_BY_1; + tacts = mPeriodUs * (80 >> timer_div) / DH_PWM_DEPTH; + } else { + timer_div = DIVDED_BY_256; + tacts = mPeriodUs / DH_PWM_DEPTH * 80 / (1 << timer_div); + } + + RTC_REG_WRITE(FRC1_CTRL_ADDRESS, FRC1_AUTO_LOAD | timer_div | FRC1_ENABLE_TIMER | TM_EDGE_INT); + ETS_FRC_TIMER1_INTR_ATTACH(timer_cb, NULL); + TM1_EDGE_INT_ENABLE(); + ETS_FRC1_INTR_ENABLE(); + RTC_REG_WRITE(FRC1_LOAD_ADDRESS, tacts); + + dhdebug("PWM enable with period %u us, timer: %u/%u tacts", + mPeriodUs, tacts, 1 << timer_div); +} + + +/* + * dh_pwm_start() implementation. + */ +int ICACHE_FLASH_ATTR dh_pwm_start(uint32_t duty[DH_GPIO_PIN_COUNT], + DHGpioPinMask pins, + unsigned int period_us, + unsigned int count) +{ + if (pins & ~DH_GPIO_SUITABLE_PINS) + return -1; // unsuitable pins + if (period_us < MIN_PERIOD_US || period_us >= MAX_PERIOD_US) + return -2; // period is out of range + int i; + for (i = 0; i < DH_GPIO_PIN_COUNT; i++) { + if (duty[i] > DH_PWM_DEPTH) + return -3; // bad duty value + } + + disarm_timer(); + mPeriodUs = period_us; + mTotalCount = count; + dh_pwm_disable(pins); + for (i = 0; i < DH_GPIO_PIN_COUNT; i++) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); + if ((pins & pin)) { + dhdebug("PWM for %d pin, duty: %d", i, duty[i]); + if (duty[i]) { + mUsedPins |= pin; + mDisablePinOn[duty[i]] |= pin; + } else { + mDisablePinOn[0] |= pin; + } + } + } + + dh_gpio_prepare_pins(mUsedPins | mDisablePinOn[0], 0); + gpio_output_set(mUsedPins, mDisablePinOn[0], + mUsedPins | mDisablePinOn[0], 0); + if (mUsedPins) + arm_timer(); + + return 0; // OK +} + + +/* + * dh_pwm_get_period_us() implementation. + */ +unsigned int ICACHE_FLASH_ATTR dh_pwm_get_period_us(void) +{ + return mPeriodUs; +} + + +/* + * dh_pwm_disable() implementation. + */ +void ICACHE_FLASH_ATTR dh_pwm_disable(DHGpioPinMask pins) +{ + int i, n = sizeof(mDisablePinOn)/sizeof(mDisablePinOn[0]); + for (i = 0; i < n; i++) { + mDisablePinOn[i] &= ~pins; + } + mUsedPins &= ~pins; +} + + +#ifdef DH_COMMANDS_PWM // PWMcommand handlers +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_pwm_control() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_pwm_control(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_VALUES | AF_PERIOD | AF_COUNT, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (!!dh_pwm_start(info.storage.uint_values, + info.pin_value_readed, + (fields & AF_PERIOD) ? info.periodus + : dh_pwm_get_period_us(), + info.count)) { + dh_command_fail(cmd_res, "Wrong parameters"); + } else { + dh_command_done(cmd_res, ""); // OK + } +} + +#endif /* DH_COMMANDS_PWM */ diff --git a/firmware-src/sources/DH/pwm.h b/firmware-src/sources/DH/pwm.h new file mode 100644 index 0000000..da5ec06 --- /dev/null +++ b/firmware-src/sources/DH/pwm.h @@ -0,0 +1,69 @@ +/** + * @file + * @brief Software PWM implementation for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + * + * This module uses ESP8266 hardware timer, so any other module + * with hardware timer requirement will be incompatible. + */ +#ifndef _DH_PWM_H_ +#define _DH_PWM_H_ + +#include "DH/gpio.h" +#include "user_config.h" + +/** + * @brief Default PWM frequency in microseconds. + */ +#define DH_PWM_DEFAULT_PERIOD_US 1000 + +/** + * @brief PWM depth, high value may cause very high CPU load. + */ +#define DH_PWM_DEPTH 100 + + +/** + * @brief Start PWM for specified pins. + * @param[in] duty Array with pins duty cycles for each pin. + * @param[in] pins Bitwise pin mask with pins that should be enabled, + * these pins must have correct values in `duty` array. + * @param[in] period_us PWM period, microseconds. + * @param[in] count Number of tacts for PWM. If zero PWM will not stop automatically. + * @return Zero on success. + */ +int dh_pwm_start(uint32_t duty[DH_GPIO_PIN_COUNT], + DHGpioPinMask pins, + unsigned int period_us, + unsigned int count); + + +/** + * @brief Get current PWM period. + * @return PWM period in microseconds. + */ +unsigned int dh_pwm_get_period_us(void); + + +/** + * @brief Stops PWM for specified pins. + * + * PWM timer will stop automatically if no pins left. + * + * @param[in] pins Bitwise pins mask. + */ +void dh_pwm_disable(DHGpioPinMask pins); + + +#ifdef DH_COMMANDS_PWM // PWM command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "pwm/control" command. + */ +void dh_handle_pwm_control(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_PWM */ +#endif /* _DH_PWM_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 33c7d72..a62d287 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -21,7 +21,7 @@ #include "dhspi.h" #include "dhonewire.h" #include "dhdebug.h" -#include "dhpwm.h" +#include "DH/pwm.h" #include "dhutils.h" #include "devices/ds18b20.h" #include "devices/dht.h" @@ -129,31 +129,6 @@ LOCAL int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, return 0; } -#if 1 // ADC and PWM commands - - -/** - * @brief Do "pwm/control" command. - */ -static void ICACHE_FLASH_ATTR do_pwm_control(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_VALUES | AF_PERIOD | AF_COUNT, &fields); - if(parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(dhpwm_set_pwm(&parse_pins.storage.uint_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : dhpwm_get_period_us(), parse_pins.count)) - dh_command_done(cb, ""); - else - dh_command_fail(cb, "Wrong parameters"); -} - -#endif // ADC and PWM commands - #if 1 // UART commands /** @@ -1451,7 +1426,9 @@ RO_DATA struct { {"adc/int", dh_handle_adc_int}, #endif /* DH_COMMANDS_ADC */ - {"pwm/control", do_pwm_control}, +#ifdef DH_COMMANDS_PWM + {"pwm/control", dh_handle_pwm_control}, +#endif /* DH_COMMANDS_PWM */ {"uart/write", do_uart_write}, {"uart/read", do_uart_read}, diff --git a/firmware-src/sources/dhpwm.c b/firmware-src/sources/dhpwm.c deleted file mode 100644 index c1c5c22..0000000 --- a/firmware-src/sources/dhpwm.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * dhpwm.h - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - */ -#include "dhpwm.h" -#include "DH/gpio.h" -#include "dhdebug.h" -#include "user_config.h" - -#include -#include -#include -#include -#include - -#define FRC1_ENABLE_TIMER BIT7 -#define FRC1_AUTO_LOAD BIT6 -typedef enum { - DIVDED_BY_1 = 0, - DIVDED_BY_16 = 4, - DIVDED_BY_256 = 8 -} TIMER_DIV_MODE; -typedef enum { - TM_LEVEL_INT = 1, - TM_EDGE_INT = 0, -} TIMER_INT_MODE; - -LOCAL uint32 mDisablePinOn[DHPWM_DEPTH + 1] = {0}; -LOCAL unsigned int mPeriodUs = DHPWM_DEFAULT_PERIOD_US; -LOCAL unsigned char mCounter = 0; -LOCAL unsigned char mPwmInUse = 0; -LOCAL unsigned int mTotalCount = 0; -LOCAL uint32 mUsedPins = 0; - -void ICACHE_FLASH_ATTR disarm_pwm_timer(void) { - TM1_EDGE_INT_DISABLE(); - ETS_FRC1_INTR_DISABLE(); -} - -void on_timer(void) { - if(mCounter == 0) { - if(mTotalCount) { - mTotalCount--; - if(mTotalCount == 0) { - disarm_pwm_timer(); - gpio_output_set(0, mDisablePinOn[DHPWM_DEPTH], mDisablePinOn[DHPWM_DEPTH], 0); - dhpwm_disable_pins(mUsedPins | mDisablePinOn[0]); - return; - } - } else { - if(mPwmInUse == 0) - disarm_pwm_timer(); - } - gpio_output_set(mUsedPins, 0, mUsedPins, 0); - mPwmInUse = 0; - } else { - const uint32 pins = mDisablePinOn[mCounter]; - if(pins) { - gpio_output_set(0, pins, pins, 0); - mPwmInUse = 1; - } - } - mCounter++; - if(mCounter >= DHPWM_DEPTH) - mCounter = 0; -} - -void ICACHE_FLASH_ATTR arm_pwm_timer(void) { - // use mFrequency - mPwmInUse = 1; - mCounter = 1; - unsigned int tacts; - TIMER_DIV_MODE timer_div; - if(mPeriodUs < 10000000) { - timer_div = DIVDED_BY_1; - tacts = mPeriodUs * (80 >> timer_div) / DHPWM_DEPTH; - } else { - timer_div = DIVDED_BY_256; - tacts = mPeriodUs / DHPWM_DEPTH * 80 / (1 << timer_div); - } - RTC_REG_WRITE(FRC1_CTRL_ADDRESS, FRC1_AUTO_LOAD | timer_div | FRC1_ENABLE_TIMER | TM_EDGE_INT); - ETS_FRC_TIMER1_INTR_ATTACH(on_timer, NULL); - TM1_EDGE_INT_ENABLE(); - ETS_FRC1_INTR_ENABLE(); - RTC_REG_WRITE(FRC1_LOAD_ADDRESS, tacts); - dhdebug("PWM enable with period %u us, timer %u/%u tacts", mPeriodUs, tacts, 1 << timer_div); -} - -int ICACHE_FLASH_ATTR dhpwm_set_pwm(uint32_t *pinsduty, unsigned int pinsmask, unsigned int periodus, unsigned int count) { - int i; - if((pinsmask | DH_GPIO_SUITABLE_PINS) != DH_GPIO_SUITABLE_PINS || periodus < 500 || periodus >= 2000004000) - return 0; - for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { - if(pinsduty[i] > DHPWM_DEPTH) - return 0; - } - disarm_pwm_timer(); - mPeriodUs = periodus; - mTotalCount = count; - dhpwm_disable_pins(pinsmask); - for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { - if((pinsmask & DH_GPIO_PIN(i))) { - dhdebug("PWM for %d pin, duty: %d", i, pinsduty[i]); - if(pinsduty[i]) { - mUsedPins |= (1 << i); - mDisablePinOn[pinsduty[i]] |= (1 << i); - } else { - mDisablePinOn[0] |= (1 << i); - } - } - } - dh_gpio_prepare_pins(mUsedPins | mDisablePinOn[0], 0); - gpio_output_set(mUsedPins, mDisablePinOn[0], mUsedPins | mDisablePinOn[0], 0); - if(mUsedPins) - arm_pwm_timer(); - return 1; -} - -unsigned int ICACHE_FLASH_ATTR dhpwm_get_period_us(void) { - return mPeriodUs; -} - -void ICACHE_FLASH_ATTR dhpwm_disable_pins(unsigned int pinsmask) { - int i; - for(i = 0; i < sizeof(mDisablePinOn)/sizeof(uint32); i++) { - mDisablePinOn[i] &= ~pinsmask; - } - mUsedPins &= ~pinsmask; -} diff --git a/firmware-src/sources/dhpwm.h b/firmware-src/sources/dhpwm.h deleted file mode 100644 index ccdad94..0000000 --- a/firmware-src/sources/dhpwm.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * \file dhpwm.h - * \brief Software PWM implementation for ESP8266. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - * \details This module uses ESP8266 hardware timer, so any other module with hardware timer requirement will be incompatible. - */ - -#ifndef _DHPWM_H_ -#define _DHPWM_H_ - -/** Default frequency in microseconds. */ -#define DHPWM_DEFAULT_PERIOD_US 1000 -/** PWM depth, high value may cause very high CPU load. */ -#define DHPWM_DEPTH 100 - -/** - * \brief Start PWM for specified pins. - * \param[in] pinsduty Array with pins duty cycles for each pin. - * \param[in] pinsmask Bitwise pins mask with pins that should be enabled, this pins have to have correct value in pinsduty array. - * \param[in] periodus PWM period. - * \param[in] count Number of tacts for PWM. If zero PWM will not stop automatically. - * \return Non zero value on success or zero on failure. - */ -int dhpwm_set_pwm(unsigned int *pinsduty, unsigned int pinsmask, unsigned int periodus, unsigned int count); - -/** - * \brief Get current PWM period. - * \return PWM period in microseconds. - */ -unsigned int dhpwm_get_period_us(void); - -/** - * \brief Stops PWM for specified pins. - * \details PWM timer will stop automatically if no pins left. - * \param[in] pinsmask Bitwise pins mask. - */ -void dhpwm_disable_pins(unsigned int pinsmask); - -#endif /* _DHPWM_H_ */ From 78b625a5e6b9c2f973458dc3eae98c1418ee46a9 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 20 Apr 2017 16:39:50 +0300 Subject: [PATCH 29/83] review UART module - dh_uart_init() returns zero on success --- firmware-src/sources/DH/pwm.c | 2 +- firmware-src/sources/DH/uart.c | 459 ++++++++++++++++++ firmware-src/sources/DH/uart.h | 188 +++++++ firmware-src/sources/devices/mhz19.c | 12 +- firmware-src/sources/dhap.c | 1 - firmware-src/sources/dhcommands.c | 139 +----- firmware-src/sources/dhdebug.c | 1 - firmware-src/sources/dhnotification.c | 3 +- firmware-src/sources/dhterminal.c | 48 +- firmware-src/sources/dhterminal_commandline.c | 14 +- firmware-src/sources/dhterminal_commands.c | 225 ++++----- firmware-src/sources/dhterminal_configure.c | 30 +- firmware-src/sources/dhuart.c | 211 -------- firmware-src/sources/dhuart.h | 122 ----- firmware-src/sources/dhzc_web.c | 1 - firmware-src/sources/main.c | 4 +- firmware-src/sources/user_config.h | 2 +- 17 files changed, 825 insertions(+), 637 deletions(-) create mode 100644 firmware-src/sources/DH/uart.c create mode 100644 firmware-src/sources/DH/uart.h delete mode 100644 firmware-src/sources/dhuart.c delete mode 100644 firmware-src/sources/dhuart.h diff --git a/firmware-src/sources/DH/pwm.c b/firmware-src/sources/DH/pwm.c index d568d5f..8c888a4 100644 --- a/firmware-src/sources/DH/pwm.c +++ b/firmware-src/sources/DH/pwm.c @@ -180,7 +180,7 @@ void ICACHE_FLASH_ATTR dh_pwm_disable(DHGpioPinMask pins) } -#ifdef DH_COMMANDS_PWM // PWMcommand handlers +#ifdef DH_COMMANDS_PWM // PWM command handlers #include "dhcommand_parser.h" #include diff --git a/firmware-src/sources/DH/uart.c b/firmware-src/sources/DH/uart.c new file mode 100644 index 0000000..bb02bab --- /dev/null +++ b/firmware-src/sources/DH/uart.c @@ -0,0 +1,459 @@ +/** + * @file + * @brief UART HAL for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/uart.h" +#include "DH/adc.h" +#include "dhdebug.h" + +#include +#include +#include +#include +#include +#include + +#define UART_BASE 0x60000000 +#define UART_INTERUPTION_STATE_REGISTER (UART_BASE + 0x08) +#define UART_INTERUPTION_ENABLE_REGISTER (UART_BASE + 0x0C) +#define UART_INTERUPTION_REGISTER (UART_BASE + 0x10) +#define UART_STATUS_REGISTER (UART_BASE + 0x1C) +#define UART_DIV_REGISTER (UART_BASE + 0x14) +#define UART_CONFIGURATION_REGISTER0 (UART_BASE + 0x20) +#define UART_CONFIGURATION_REGISTER1 (UART_BASE + 0x24) + +#define BUFFER_OVERFLOW_RESERVE INTERFACES_BUF_SIZE + +// module variables +static DHUartDataMode mDataMode = DH_UART_MODE_IGNORE; +static uint8_t mUartBuf[INTERFACES_BUF_SIZE + BUFFER_OVERFLOW_RESERVE] = {0}; +static size_t mUartBufPos = 0; +static os_timer_t mUartTimer; +static unsigned int mTimeoutMs = 250; +static int mBufInterrupt = false; +static os_timer_t mRecoverLEDTimer; +static int mKeepLED = false; + +static void arm_buf_timer(void); + + +/** + * @brief Buffer timer callback. + */ +static void ICACHE_FLASH_ATTR buf_timeout_cb(void *arg) +{ + size_t sz = mUartBufPos; + if (sz > INTERFACES_BUF_SIZE) + sz = INTERFACES_BUF_SIZE; + dh_uart_buf_rcv_cb(mUartBuf, sz); + + ETS_UART_INTR_DISABLE(); + if (sz != mUartBufPos) { + os_memmove(mUartBuf, &mUartBuf[sz], + mUartBufPos - sz); + mUartBufPos -= sz; + } else { + mUartBufPos = 0; + } + ETS_UART_INTR_ENABLE(); + if (mUartBufPos) + arm_buf_timer(); +} + + +/** + * Start buffer timer. + */ +static void ICACHE_FLASH_ATTR arm_buf_timer(void) +{ + os_timer_disarm(&mUartTimer); + os_timer_setfn(&mUartTimer, buf_timeout_cb, NULL); + os_timer_arm(&mUartTimer, (mTimeoutMs == 0 || mUartBufPos >= INTERFACES_BUF_SIZE) ? 1 : mTimeoutMs, 0); +} + + +/** + * @brief UART RX interruption handler. + */ +static void int_cb(void *arg) +{ + if (READ_PERI_REG(UART_INTERUPTION_STATE_REGISTER) & BIT(0)) { + const int rcvChar = READ_PERI_REG(UART_BASE) & 0xFF; + WRITE_PERI_REG(UART_INTERUPTION_REGISTER, BIT(0)); + + switch(mDataMode) { + case DH_UART_MODE_PER_BYTE: + dh_uart_char_rcv_cb(rcvChar); + break; + + case DH_UART_MODE_PER_BUF: + if (mUartBufPos >= sizeof(mUartBuf)) { + return; // buffer overflow + } + mUartBuf[mUartBufPos++] = rcvChar; + if (mBufInterrupt) { + if (mUartBufPos <= INTERFACES_BUF_SIZE) { + arm_buf_timer(); + } + } + break; + + case DH_UART_MODE_IGNORE: + break; + } + } else { + WRITE_PERI_REG(UART_INTERUPTION_REGISTER, 0xffff); + } +} + + +/* + * dh_uart_init() implementation. + */ +int ICACHE_FLASH_ATTR dh_uart_init(int speed, int databits, char parity, int stopbits) +{ + if (speed < 300 || speed > 230400) + return -1; // bad speed + if (databits < 5 || databits > 8) + return -1; // bad databits + if (parity != 'N' && parity != 'O' && parity != 'E') + return -1; // bad parity + if (stopbits < 1 || stopbits > 2) + return -1; // bad stopbits + + ETS_UART_INTR_DISABLE(); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + gpio_output_set(0, 0, 0, BIT(1) | BIT(3)); + PIN_PULLUP_EN(PERIPHS_IO_MUX_U0RXD_U); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + + WRITE_PERI_REG(UART_DIV_REGISTER, UART_CLK_FREQ / speed); + WRITE_PERI_REG(UART_CONFIGURATION_REGISTER0, 0); + SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, ((parity == 'E') ? 0 : 1) << 0); + SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, ((parity == 'N') ? 0 : 1) << 1); + SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, (databits - 5) << 2); + SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, ((stopbits == 2) ? 3 : 1) << 4); + SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, BIT(17) | BIT(18)); + CLEAR_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, BIT(17) | BIT(18)); + WRITE_PERI_REG(UART_CONFIGURATION_REGISTER1, BIT(0) | BIT(16) | BIT(23)); + ETS_UART_INTR_ATTACH(int_cb, 0); + WRITE_PERI_REG(UART_INTERUPTION_REGISTER, 0xffff); + SET_PERI_REG_MASK(UART_INTERUPTION_ENABLE_REGISTER, BIT(0)); + ETS_UART_INTR_ENABLE(); + + return 0; // OK +} + + +/** + * @brief Recover the LED state. + */ +static void ICACHE_FLASH_ATTR led_recover(void *arg) +{ + ETS_INTR_LOCK(); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); + gpio_output_set(0, 0b0110, 0b0110, 0); + ETS_INTR_UNLOCK(); +} + + +/** + * @brief Turn the LED off. + */ +static void ICACHE_FLASH_ATTR led_off(void) +{ + gpio_output_set(0, 0, 0, 0b0110); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + os_delay_us(10000); +} + + +/* + * dh_uart_leds() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_leds(DHUartLedsMode mode) +{ + if (mode == DH_UART_LEDS_ON) { + mKeepLED = true; + led_recover(0); + } else { + mKeepLED = false; + led_off(); + } +} + + +/** + * @brief Send one char to the UART. + */ +static void ICACHE_FLASH_ATTR send_char(int ch) +{ + while ((READ_PERI_REG(UART_STATUS_REGISTER) >> 16) & 0xFF); + WRITE_PERI_REG(UART_BASE, ch); +} + + +/* + * dh_uart_send_str() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_send_str(const char *str) +{ + if (mDataMode != DH_UART_MODE_PER_BYTE) + return; + + if (mKeepLED) { + os_timer_disarm(&mRecoverLEDTimer); + led_off(); + } + + while (*str) + send_char(*str++); + + if (mKeepLED) { + os_timer_setfn(&mRecoverLEDTimer, led_recover, NULL); + os_timer_arm(&mRecoverLEDTimer, 20, 0); + } +} + + +/* + * dh_uart_send_line() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_send_line(const char *str) +{ + dh_uart_send_str(str); + dh_uart_send_str("\r\n"); +} + + +/* + * dh_uart_send_buf() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_send_buf(const void *buf_, size_t len) +{ + if (mDataMode != DH_UART_MODE_PER_BUF) + return; + + if (mKeepLED) { + os_timer_disarm(&mRecoverLEDTimer); + led_off(); + } + + const char *buf = (const char*)buf_; + while (len--) { + system_soft_wdt_feed(); + send_char(*buf++); + } + + if (mKeepLED) { + os_timer_setfn(&mRecoverLEDTimer, led_recover, NULL); + os_timer_arm(&mRecoverLEDTimer, 20, 0); + } +} + + +/* + * dh_uart_set_mode() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_set_mode(DHUartDataMode mode) +{ + mDataMode = mode; + if (mode == DH_UART_MODE_PER_BUF) { + mUartBufPos = 0; + } else if(mode == DH_UART_MODE_PER_BYTE) { + mBufInterrupt = false; + } +} + + +/* + * dh_uart_set_callback_timeout() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_set_callback_timeout(unsigned int timeout_ms) +{ + mTimeoutMs = timeout_ms; +} + + +/* + * dh_uart_get_callback_timeout() implementation. + */ +unsigned int ICACHE_FLASH_ATTR dh_uart_get_callback_timeout(void) +{ + return mTimeoutMs; +} + + +/* + * dh_uart_get_buf() implementation. + */ +size_t ICACHE_FLASH_ATTR dh_uart_get_buf(void **buf) +{ + *buf = mUartBuf; + return mUartBufPos; +} + + +/* + * dh_uart_reset_buf() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_reset_buf(void) +{ + mUartBufPos = 0; +} + + +/* + * dh_uart_enable_buf_interrupt() implementation. + */ +void ICACHE_FLASH_ATTR dh_uart_enable_buf_interrupt(int enable) +{ + mBufInterrupt = enable; +} + + +#ifdef DH_COMMANDS_UART // UART command handlers +#include "dhcommand_parser.h" +#include "dhterminal.h" +#include + +/** + * @brief UART initialization helper. + * @return Non-zero if UART was initialized. Zero otherwise. + */ +static int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params, int is_int) +{ + if (fields & AF_UARTMODE) { + if (params->uart_speed == 0 && is_int) { + dh_uart_enable_buf_interrupt(false); + dh_command_done(cmd_res, ""); + return 1; + } else if(!!dh_uart_init(params->uart_speed, params->uart_bits, + params->uart_partity, params->uart_stopbits)) { + dh_command_fail(cmd_res, "Wrong UART mode"); + return 1; + } + } + + return 0; +} + +/* + * dh_handle_uart_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_UARTMODE | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (!uart_init(cmd_res, fields, &info, false)) { + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + dh_uart_send_buf(info.data, info.data_len); + dh_command_done(cmd_res, ""); + } +} + + +/** + * dh_handle_uart_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + if (uart_init(cmd_res, fields, &info, false)) + return; + if (fields & AF_TIMEOUT) { + if (info.timeout > 1000) { // TODO: MAX timeout constant + dh_command_fail(cmd_res, "Timeout out of range"); + return; + } + if (!(fields & AF_DATA)) { + dh_command_fail(cmd_res, "Timeout can be specified only with data"); + return; + } + } + } + + if (fields & AF_DATA) { + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + dh_uart_send_buf(info.data, info.data_len); + system_soft_wdt_feed(); + delay_ms((fields & AF_TIMEOUT) ? info.timeout : 250); + system_soft_wdt_feed(); + } + + char *buf = 0; + size_t len = dh_uart_get_buf((void**)&buf); + if (len > INTERFACES_BUF_SIZE) + len = INTERFACES_BUF_SIZE; + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, buf, len); + dh_uart_set_mode(DH_UART_MODE_PER_BUF); +} + + +/** + * dh_handle_uart_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, dh_uart_get_callback_timeout(), + AF_UARTMODE | AF_TIMEOUT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + if ((fields & AF_TIMEOUT) && info.timeout > 5000) { // TODO: MAX timeout constant + dh_command_fail(cmd_res, "Timeout out of range"); + return; + } + if (uart_init(cmd_res, fields, &info, true)) + return; + if (fields & AF_TIMEOUT) + dh_uart_set_callback_timeout(info.timeout); + } + + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + dh_uart_enable_buf_interrupt(true); + dh_command_done(cmd_res, ""); +} + + +/** + * dh_handle_uart_terminal() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_terminal(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + dh_command_fail(cmd_res, "No parameters expected"); + return; + } + + dhterminal_init(); + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_UART */ diff --git a/firmware-src/sources/DH/uart.h b/firmware-src/sources/DH/uart.h new file mode 100644 index 0000000..69b003d --- /dev/null +++ b/firmware-src/sources/DH/uart.h @@ -0,0 +1,188 @@ +/** + * @file + * @brief UART HAL for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + * + * UART Hardware access layer for ESP8266. Can operate in two modes: DH_UART_MODE_PER_BYTE or DH_UART_MODE_PER_BUF. + * + * In DH_UART_MODE_PER_BYTE all writing operations with strings are allowed, but data operations are disabled. + * Each received byte cause dh_uart_char_rcv callback. + * + * In DH_UART_MODE_PER_BUF all writing operations with data are allowed, but char operations are disabled. + * Callback dh_uart_buf_rcv will be called after number of byte in buffer is greater or equal + * INTERFACES_BUF_SIZE or last byte was received later than specified timeout. + */ +#ifndef _DH_UART_H_ +#define _DH_UART_H_ + +#include +#include "user_config.h" + +/** + * @brief UART mode. + */ +typedef enum { + DH_UART_MODE_IGNORE, ///< @brief Ignore input data, can print everything. + DH_UART_MODE_PER_BYTE, ///< @brief Receive data byte by byte. @details Dedicated callback on each byte, some send data function is disabled. + DH_UART_MODE_PER_BUF ///< @brief Receive data per buffer. @details Dedicated callback with buffer with some timeout which disabled by default, some send data function is disabled. +} DHUartDataMode; + + +/** + * @brief UART LED mode. + */ +typedef enum { + DH_UART_LEDS_ON, + DH_UART_LEDS_OFF +} DHUartLedsMode; + + +/** + * @brief Initialize UART module. + * @param[in] speed Bitrate. For example: 115200 or 19200. + * @param[in] databits Number of bits in byte for UART. From 5 to 8. + * @param[in] parity Use parity bit or not. Char value: 'N'(not), 'E'(even) or 'O'(odd). + * @param[in] stopbits Number of stop bits: 1 or 2. + * @return Zero on success. + */ +int dh_uart_init(int speed, int databits, char parity, int stopbits); + + +/** + * @brief Keep TX LEDs always on. + * + * Some modules has LEDs which are connected to TX pins. + * This method allows to keep this LEDs on. + * + * @param[in] on LEDs mode. + */ +void dh_uart_leds(DHUartLedsMode mode); + + +/** + * @brief Write string to UART. + * @warning Doesn't work in DH_UART_MODE_PER_BUF mode. + * @param[in] str String, i.e. byte array that should be written. + * Will transmit buffer until first null char. + */ +void dh_uart_send_str(const char *str); + + +/** + * @brief Write string to UART and add "\r\n" to the end. + * @warning Doesn't work in DH_UART_MODE_PER_BUF mode. + * @param[in] str String, i.e. byte array that should be written. + * Will transmit buffer until first null char. + */ +void dh_uart_send_line(const char *str); + + +/** + * @brief Write byte array with specified size. + * @warning Doesn't work in DH_UART_MODE_PER_BYTE mode. + * @param[in] buf Byte array. + * @param[in] len Number of bytes in buffer. + */ +void dh_uart_send_buf(const void *buf, size_t len); + + +/** + * @brief Set current operating mode. + * @details Buffer is cleaned up on setting DH_UART_MODE_PER_BUF mode. + * @param[in] mode New operating mode. + */ +void dh_uart_set_mode(DHUartDataMode mode); + + +/** + * @brief Set timeout for callback. + * + * This timeout means how many ms without receiving bytes + * should pass before calling callback. + * Make sense only when mode is DH_UART_MODE_PER_BUF and callback is enabled. + * + * @param[in] timeout_ms Timeout in milliseconds. + */ +void dh_uart_set_callback_timeout(unsigned int timeout_ms); + + +/** + * @brief Get current callback timeout. + * @return Timeout in milliseconds. + */ +unsigned int dh_uart_get_callback_timeout(void); + + +/** + * @brief Get receiving buffer. + * @param[out] buf Pointer where pointer to buffer is stored. + * @return Number of bytes in buffer. + */ +size_t dh_uart_get_buf(void **buf); + + +/** + * @brief Clear receiving buffer. + */ +void dh_uart_reset_buf(void); + + +/** + * @brief Enable/disable DH_UART_MODE_PER_BUF callbacks. + * + * Callbacks are disabled by default. + * + * @param[in] enable Non zero value for enabling, zero for disabling. + */ +void dh_uart_enable_buf_interrupt(int enable); + + +/** + * @brief Callback declaration for DH_UART_MODE_PER_BYTE mode. + * @param[in] ch Received character. + */ +extern void dh_uart_char_rcv_cb(int ch); + + +/** + * @brief Callback declaration for DH_UART_MODE_PER_BUF mode. + * @param[in] buf Data that was received. + * @param[in] len Size of data in bytes. + */ +extern void dh_uart_buf_rcv_cb(const void *buf, size_t len); + + +#ifdef DH_COMMANDS_UART // UART command handlers +#include "dhsender_data.h" + + +/** + * @brief Handle "uart/write" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "uart/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "uart/int" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "uart/terminal" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_terminal(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_UART */ +#endif /* _DH_UART_H_ */ diff --git a/firmware-src/sources/devices/mhz19.c b/firmware-src/sources/devices/mhz19.c index 99bf78c..55e5262 100644 --- a/firmware-src/sources/devices/mhz19.c +++ b/firmware-src/sources/devices/mhz19.c @@ -7,7 +7,7 @@ * */ #include "mhz19.h" -#include "dhuart.h" +#include "DH/uart.h" #include "dhdebug.h" #include "dhutils.h" @@ -20,12 +20,12 @@ char * ICACHE_FLASH_ATTR mhz19_read(int *co2) { char *result; int i; char cs = 0; - dhuart_set_mode(DUM_PER_BUF); - if(dhuart_init(9600, 8, 'N', 1) == 0) - return "Uart init failed"; - dhuart_send_buf(request, sizeof(request)); + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + if(dh_uart_init(9600, 8, 'N', 1) != 0) + return "failed to init UART"; + dh_uart_send_buf(request, sizeof(request)); delay_ms(20); - int len = dhuart_get_buf(&result); + size_t len = dh_uart_get_buf((void**)&result); if(len != 9){ if(len) return "Response length mismatch"; diff --git a/firmware-src/sources/dhap.c b/firmware-src/sources/dhap.c index 83bdcbe..ac50072 100644 --- a/firmware-src/sources/dhap.c +++ b/firmware-src/sources/dhap.c @@ -10,7 +10,6 @@ #include "snprintf.h" #include "user_config.h" #include "dhdebug.h" -#include "dhuart.h" #include #include diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index a62d287..7dc3192 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -12,11 +12,11 @@ #include "dhsender_queue.h" #include "DH/gpio.h" #include "DH/adc.h" +#include "DH/uart.h" #include "dhnotification.h" #include "snprintf.h" #include "dhcommand_parser.h" #include "dhterminal.h" -#include "dhuart.h" #include "dhi2c.h" #include "dhspi.h" #include "dhonewire.h" @@ -115,133 +115,6 @@ LOCAL int ICACHE_FLASH_ATTR i2c_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, return 0; } -LOCAL int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins, unsigned int isint) { - if(fields & AF_UARTMODE) { - if(parse_pins->uart_speed == 0 && isint) { - dhuart_enable_buf_interrupt(0); - dh_command_done(cb, ""); - return 1; - } else if(!dhuart_init(parse_pins->uart_speed, parse_pins->uart_bits, parse_pins->uart_partity, parse_pins->uart_stopbits)) { - dh_command_fail(cb, "Wrong UART mode"); - return 1; - } - } - return 0; -} - -#if 1 // UART commands - -/** - * @brief Do "uart/write" command. - */ -static void ICACHE_FLASH_ATTR do_uart_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_UARTMODE | AF_DATA, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(uart_init(cb, fields, &parse_pins, 0)) - return; - dhuart_set_mode(DUM_PER_BUF); - dhuart_send_buf(parse_pins.data, parse_pins.data_len); - dh_command_done(cb, ""); -} - - -/** - * @brief Do "uart/read" command. - */ -static void ICACHE_FLASH_ATTR do_uart_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(uart_init(cb, fields, &parse_pins, 0)) - return; - if(fields & AF_TIMEOUT) { - if(parse_pins.timeout > 1000) { - dh_command_fail(cb, "Timeout is too long"); - return; - } - if((fields & AF_DATA) == 0) { - dh_command_fail(cb, "Timeout can be specified only with data"); - return; - } - } - } - if(fields & AF_DATA) { - dhuart_set_mode(DUM_PER_BUF); - dhuart_send_buf(parse_pins.data, parse_pins.data_len); - system_soft_wdt_feed(); - delay_ms((fields & AF_TIMEOUT) ? parse_pins.timeout : 250); - system_soft_wdt_feed(); - } - char *buf; - int len = dhuart_get_buf(&buf); - if(len > INTERFACES_BUF_SIZE) - len = INTERFACES_BUF_SIZE; - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, buf, len); - dhuart_set_mode(DUM_PER_BUF); -} - - -/** - * @brief Do "uart/int" command. - */ -static void ICACHE_FLASH_ATTR do_uart_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, dhuart_get_callback_timeout(), - AF_UARTMODE | AF_TIMEOUT, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & AF_TIMEOUT) && parse_pins.timeout > 5000) { - dh_command_fail(cb, "Timeout is too long"); - return; - } - if(uart_init(cb, fields, &parse_pins, 1)) - return; - if(fields & AF_TIMEOUT) - dhuart_set_callback_timeout(parse_pins.timeout); - } - dhuart_set_mode(DUM_PER_BUF); - dhuart_enable_buf_interrupt(1); - dh_command_done(cb, ""); -} - - -/** - * @brief Do "uart/terminal" command. - */ -static void ICACHE_FLASH_ATTR do_uart_terminal(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - dh_command_fail(cb, "Command does not have parameters"); - return; - } - dhterminal_init(); - dh_command_done(cb, ""); -} - -#endif // UART commands - #if 1 // I2C commands /** @@ -1430,10 +1303,12 @@ RO_DATA struct { {"pwm/control", dh_handle_pwm_control}, #endif /* DH_COMMANDS_PWM */ - {"uart/write", do_uart_write}, - {"uart/read", do_uart_read}, - {"uart/int", do_uart_int}, - {"uart/terminal", do_uart_terminal}, +#ifdef DH_COMMANDS_UART + {"uart/write", dh_handle_uart_write}, + {"uart/read", dh_handle_uart_read}, + {"uart/int", dh_handle_uart_int}, + {"uart/terminal", dh_handle_uart_terminal}, +#endif /* DH_COMMANDS_UART */ { "i2c/master/read", do_i2c_master_read}, { "i2c/master/write", do_i2c_master_write}, diff --git a/firmware-src/sources/dhdebug.c b/firmware-src/sources/dhdebug.c index 77389a3..5babb17 100644 --- a/firmware-src/sources/dhdebug.c +++ b/firmware-src/sources/dhdebug.c @@ -15,7 +15,6 @@ #include #include #include "dhdebug.h" -#include "dhuart.h" #include "dhterminal.h" #include "user_config.h" #include "dhutils.h" diff --git a/firmware-src/sources/dhnotification.c b/firmware-src/sources/dhnotification.c index 0e9f292..8e51ed2 100644 --- a/firmware-src/sources/dhnotification.c +++ b/firmware-src/sources/dhnotification.c @@ -40,11 +40,12 @@ void ICACHE_FLASH_ATTR dh_adc_loop_value_cb(float value){ dhsender_notification(RNT_NOTIFICATION_ADC, RDT_FLOAT, value); } -void ICACHE_FLASH_ATTR dhuart_buf_rcv(const char *buf, unsigned int len) { +void ICACHE_FLASH_ATTR dh_uart_buf_rcv_cb(const void *buf, size_t len) { if(dhmem_isblock()) { dhstat_got_notification_dropped(); return; } + dhsender_notification(RNT_NOTIFICATION_UART, RDT_DATA_WITH_LEN, buf, len); } diff --git a/firmware-src/sources/dhterminal.c b/firmware-src/sources/dhterminal.c index 626618f..0e792e8 100644 --- a/firmware-src/sources/dhterminal.c +++ b/firmware-src/sources/dhterminal.c @@ -9,7 +9,7 @@ * */ #include "dhterminal.h" -#include "dhuart.h" +#include "DH/uart.h" #include "user_config.h" #include "snprintf.h" #include "dhterminal_commandline.h" @@ -48,19 +48,19 @@ LOCAL int isInUse = 0; LOCAL void ICACHE_FLASH_ATTR printWelcome(void) { if(mMode == SM_NORMAL_MODE) { - dhuart_send_str("$ "); + dh_uart_send_str("$ "); } else if(mMode == SM_INPUT_MODE || mMode == SM_HIDDEN_INPUT_MODE) { - dhuart_send_str("> "); + dh_uart_send_str("> "); } mRcvBuffPos = 0; os_memset(mRcvBuff, 0, sizeof(mRcvBuff)); } void ICACHE_FLASH_ATTR dhterminal_set_input(const char *line) { - dhuart_send_str("\r\x1B[K"); + dh_uart_send_str("\r\x1B[K"); printWelcome(); mRcvBuffPos = snprintf(mRcvBuff, sizeof(mRcvBuff), "%s", line); - dhuart_send_str(mRcvBuff); + dh_uart_send_str(mRcvBuff); } const char * ICACHE_FLASH_ATTR dhterminal_get_history(void) { @@ -151,7 +151,7 @@ LOCAL void ICACHE_FLASH_ATTR do_command(void *arg) { if(mInputCallBack) mInputCallBack(mRcvBuff); else - dhuart_send_line("\r\nNo callback specified."); + dh_uart_send_line("\r\nNo callback specified."); if(mode == SM_NORMAL_MODE && mMode == SM_NORMAL_MODE) { printWelcome(); } @@ -175,7 +175,7 @@ LOCAL void ICACHE_FLASH_ATTR usage_timer(void *arg) { isInUse = 0; } -void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { +void ICACHE_FLASH_ATTR dh_uart_char_rcv_cb(int c) { isInUse = 1; os_timer_disarm(&mUsageTimer); os_timer_setfn(&mUsageTimer, (os_timer_func_t *)usage_timer, NULL); @@ -192,10 +192,10 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { if(mMode == SM_DEBUG_MODE || mMode == SM_OUTPUT_MODE || mMode == SM_AWATING_MODE) { if(c == 'Q' || c == 'q' || c == 0x3 /*Ctrl+C*/) { if(c == 0x3) - dhuart_send_str("^C\r\n"); + dh_uart_send_str("^C\r\n"); dhterminal_reset(); } else if(c == '\n' && mMode == SM_DEBUG_MODE) { - dhuart_send_str("\r\n"); + dh_uart_send_str("\r\n"); } return; } @@ -241,18 +241,18 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { } else if(os_strcmp(mEscSequence, "[C") == 0) { // Right if(mRcvBuff[mRcvBuffPos]) { mRcvBuffPos++; - dhuart_send_str("\x1B"); - dhuart_send_str(mEscSequence); + dh_uart_send_str("\x1B"); + dh_uart_send_str(mEscSequence); } } else if(os_strcmp(mEscSequence, "[D") == 0) { // Left if(mRcvBuffPos) { mRcvBuffPos--; - dhuart_send_str("\x1B"); - dhuart_send_str(mEscSequence); + dh_uart_send_str("\x1B"); + dh_uart_send_str(mEscSequence); } } else if(os_strcmp(mEscSequence, "[3~") == 0) { // Delete if(mRcvBuff[mRcvBuffPos]) - dhuart_send_str("\x1B[1P"); + dh_uart_send_str("\x1B[1P"); for(i = mRcvBuffPos + 1; i < sizeof(mRcvBuff); i++) { if(mRcvBuff[i - 1] == 0) break; @@ -264,7 +264,7 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { } if(c == '\n') { - dhuart_send_str("\r\n"); + dh_uart_send_str("\r\n"); do_command(0); } else { if(c == 0x09) { // Tab @@ -277,7 +277,7 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { dhterminal_set_input(a); } } else if(c == 0x03) { // Ctrl+C - dhuart_send_str("^C\r\n"); + dh_uart_send_str("^C\r\n"); dhterminal_reset(); } else if(c == 0x1B) { // ESC character mEscRecieving = 1; @@ -290,19 +290,19 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { break; } mRcvBuffPos--; - dhuart_send_str("\x1B[D\x1B[1P"); + dh_uart_send_str("\x1B[D\x1B[1P"); } else if(mRcvBuff[mInputLimiter - 2] == 0) { // if we have space if(c > 0x1F) { if(mFilterCallback) if(mFilterCallback(c) == 0) return; if(mRcvBuff[mRcvBuffPos] !=0) - dhuart_send_str("\x1B[@"); + dh_uart_send_str("\x1B[@"); if(mMode == SM_HIDDEN_INPUT_MODE) { - dhuart_send_str("*"); + dh_uart_send_str("*"); } else { char b[] = {c,0}; - dhuart_send_str(b); + dh_uart_send_str(b); } char next = c; for(i = mRcvBuffPos; i < sizeof(mRcvBuff); i++) { @@ -321,7 +321,7 @@ void ICACHE_FLASH_ATTR dhuart_char_rcv(char c) { void dhterminal_debug(const char *pFormat, va_list ap) { int len = vsnprintf(&mDebugBuff[mDebugBuffPos], sizeof(mDebugBuff) - mDebugBuffPos - 2, pFormat, ap); if(mMode == SM_DEBUG_MODE) { - dhuart_send_line(&mDebugBuff[mDebugBuffPos]); + dh_uart_send_line(&mDebugBuff[mDebugBuffPos]); } else { mDebugBuffPos += len; mDebugBuff[mDebugBuffPos++] = '\r'; @@ -338,9 +338,9 @@ void dhterminal_debug(const char *pFormat, va_list ap) { } void ICACHE_FLASH_ATTR dhterminal_init(void) { - dhuart_init(UART_BAUND_RATE, 8, 'N', 1); - dhuart_set_mode(DUM_PER_BYTE); - dhuart_send_str("\r\n**********************************\r\nUart terminal ready.\r\n"); + dh_uart_init(UART_BAUND_RATE, 8, 'N', 1); + dh_uart_set_mode(DH_UART_MODE_PER_BYTE); + dh_uart_send_str("\r\n**********************************\r\nUart terminal ready.\r\n"); dhterminal_reset(); } diff --git a/firmware-src/sources/dhterminal_commandline.c b/firmware-src/sources/dhterminal_commandline.c index 4856e31..c1cfefa 100644 --- a/firmware-src/sources/dhterminal_commandline.c +++ b/firmware-src/sources/dhterminal_commandline.c @@ -11,7 +11,7 @@ #include "dhterminal_commandline.h" #include "dhterminal_commands.h" #include "snprintf.h" -#include "dhuart.h" +#include "DH/uart.h" #include #include @@ -42,12 +42,12 @@ static const DHCOMMAND mCommands[] = { }; void ICACHE_FLASH_ATTR command_help(void) { - dhuart_send_line("Welcome to the DeviceHive firmware. List of accepted command:\r\n"); + dh_uart_send_line("Welcome to the DeviceHive firmware. List of accepted command:\r\n"); int i; for(i = 0; i < sizeof(mCommands)/sizeof(DHCOMMAND); i++ ) { - dhuart_send_str(mCommands[i].name); - dhuart_send_str(" - "); - dhuart_send_line(mCommands[i].help); + dh_uart_send_str(mCommands[i].name); + dh_uart_send_str(" - "); + dh_uart_send_line(mCommands[i].help); } } @@ -78,8 +78,8 @@ void ICACHE_FLASH_ATTR dhterminal_commandline_do(const char *command) { return; } } - dhuart_send_str(command); - dhuart_send_line(": Unknown command. Type 'help' for help."); + dh_uart_send_str(command); + dh_uart_send_line(": Unknown command. Type 'help' for help."); } char * ICACHE_FLASH_ATTR dhterminal_commandline_autocompleter(const char *pattern) { diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index ac146ae..d0561c9 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -10,7 +10,7 @@ */ #include "dhterminal_commands.h" #include "dhterminal.h" -#include "dhuart.h" +#include "DH/uart.h" #include "snprintf.h" #include "dhconnector.h" #include "dhsettings.h" @@ -63,32 +63,32 @@ LOCAL void ICACHE_FLASH_ATTR sprintMac(char *buff, const uint8 *mac) { void ICACHE_FLASH_ATTR dhterminal_commands_uname(const char *args) { char digitBuff[32]; - dhuart_send_line("DeviceHive ESP8266 firmware v"FIRMWARE_VERSION" [Built: "__TIME__" "__DATE__"]"); - dhuart_send_line("Git revision: "FIRMWARE_GIT_REVISION); - dhuart_send_line("Created by Nikolay Khabarov."); - dhuart_send_str("ChipID: 0x"); + dh_uart_send_line("DeviceHive ESP8266 firmware v"FIRMWARE_VERSION" [Built: "__TIME__" "__DATE__"]"); + dh_uart_send_line("Git revision: "FIRMWARE_GIT_REVISION); + dh_uart_send_line("Created by Nikolay Khabarov."); + dh_uart_send_str("ChipID: 0x"); snprintf(digitBuff, sizeof(digitBuff), "%X", system_get_chip_id()); - dhuart_send_str(digitBuff); - dhuart_send_str(", SDK version: "); - dhuart_send_str(system_get_sdk_version()); - dhuart_send_line(""); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", SDK version: "); + dh_uart_send_str(system_get_sdk_version()); + dh_uart_send_line(""); } LOCAL void ICACHE_FLASH_ATTR printIpInfo(uint8 if_index) { struct ip_info info; char digitBuff[32]; if(!wifi_get_ip_info(if_index, &info)) { - dhuart_send_line("Failed to get ip info"); + dh_uart_send_line("Failed to get ip info"); } else { - dhuart_send_str("IP: "); + dh_uart_send_str("IP: "); sprintIp(digitBuff, &info.ip); - dhuart_send_str(digitBuff); - dhuart_send_str(", netmask: "); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", netmask: "); sprintIp(digitBuff, &info.netmask); - dhuart_send_str(digitBuff); - dhuart_send_str(", gateway: "); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", gateway: "); sprintIp(digitBuff, &info.gw); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); } } @@ -98,19 +98,19 @@ void ICACHE_FLASH_ATTR dhterminal_commands_status(const char *args) { const struct DHStat *stat = dhstat_get(); - dhuart_send_str("Network adapter "); + dh_uart_send_str("Network adapter "); if(!wifi_get_macaddr(STATION_IF, mac)) { - dhuart_send_str("[Failed to get mac address]"); + dh_uart_send_str("[Failed to get mac address]"); } else { sprintMac(digitBuff, mac); - dhuart_send_str(digitBuff); + dh_uart_send_str(digitBuff); } if(wifi_get_opmode() == SOFTAP_MODE) { struct softap_config softapConfig; - dhuart_send_str(" is in AP mode, SSID "); + dh_uart_send_str(" is in AP mode, SSID "); wifi_softap_get_config(&softapConfig); - dhuart_send_line(softapConfig.ssid); + dh_uart_send_line((const char*)softapConfig.ssid); printIpInfo(SOFTAP_IF); } else { struct station_config stationConfig; @@ -118,101 +118,102 @@ void ICACHE_FLASH_ATTR dhterminal_commands_status(const char *args) { os_memset(&stationConfig, 0, sizeof(stationConfig)); os_strcpy(stationConfig.ssid, "[Can not get SSID]"); } + const char *ssid = (const char*)stationConfig.ssid; switch(wifi_station_get_connect_status()) { case STATION_IDLE: - dhuart_send_line(" is in idle"); + dh_uart_send_line(" is in idle"); break; case STATION_CONNECTING: - dhuart_send_str(" is connecting to "); - dhuart_send_line(stationConfig.ssid); + dh_uart_send_str(" is connecting to "); + dh_uart_send_line(ssid); break; case STATION_WRONG_PASSWORD: - dhuart_send_str(" has wrong password for "); - dhuart_send_line(stationConfig.ssid); + dh_uart_send_str(" has wrong password for "); + dh_uart_send_line(ssid); break; case STATION_NO_AP_FOUND: - dhuart_send_str(" can not find AP with SSID "); - dhuart_send_line(stationConfig.ssid); + dh_uart_send_str(" can not find AP with SSID "); + dh_uart_send_line(ssid); break; case STATION_CONNECT_FAIL: - dhuart_send_str(" has fail while connecting to "); - dhuart_send_line(stationConfig.ssid); + dh_uart_send_str(" has fail while connecting to "); + dh_uart_send_line(ssid); break; case STATION_GOT_IP: { - dhuart_send_str(" is connected to "); - dhuart_send_line(stationConfig.ssid); + dh_uart_send_str(" is connected to "); + dh_uart_send_line(ssid); printIpInfo(STATION_IF); break; } default: - dhuart_send_line(" is in unknown state"); + dh_uart_send_line(" is in unknown state"); break; } - dhuart_send_str("Wi-Fi disconnect count: "); + dh_uart_send_str("Wi-Fi disconnect count: "); snprintf(digitBuff, sizeof(digitBuff), "%u", stat->wifiLosts); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); } - dhuart_send_str("Bytes received: "); + dh_uart_send_str("Bytes received: "); printBytes(digitBuff, stat->bytesReceived); - dhuart_send_str(digitBuff); - dhuart_send_str(", sent: "); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", sent: "); printBytes(digitBuff, stat->bytesSent); - dhuart_send_str(digitBuff); - dhuart_send_str(", errors: "); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", errors: "); snprintf(digitBuff, sizeof(digitBuff), "%u", stat->networkErrors); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); - dhuart_send_str("Httpd requests received: "); + dh_uart_send_str("Httpd requests received: "); snprintf(digitBuff, sizeof(digitBuff), "%u", stat->httpdRequestsCount); - dhuart_send_str(digitBuff); - dhuart_send_str(", errors: "); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", errors: "); snprintf(digitBuff, sizeof(digitBuff), "%u", stat->httpdErrorsCount); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); - dhuart_send_str("DeviceHive: "); + dh_uart_send_str("DeviceHive: "); switch(dhconnector_get_state()) { case CS_DISCONNECT: - dhuart_send_str("connection is not established"); + dh_uart_send_str("connection is not established"); break; case CS_GETINFO: - dhuart_send_str("getting info from server"); + dh_uart_send_str("getting info from server"); break; case CS_RESOLVEWEBSOCKET: case CS_WEBSOCKET: - dhuart_send_str("connecting to web socket"); + dh_uart_send_str("connecting to web socket"); break; case CS_OPERATE: - dhuart_send_str("successfully connected to server"); + dh_uart_send_str("successfully connected to server"); break; default: - dhuart_send_str("unknown state"); + dh_uart_send_str("unknown state"); break; } - dhuart_send_str(", errors count: "); + dh_uart_send_str(", errors count: "); snprintf(digitBuff, sizeof(digitBuff), "%u", stat->serverErrors); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); - dhuart_send_str("Responses created/dropped: "); + dh_uart_send_str("Responses created/dropped: "); snprintf(digitBuff, sizeof(digitBuff), "%u/%u", stat->responcesTotal, stat->responcesDroppedCount); - dhuart_send_str(digitBuff); - dhuart_send_str(", notification created/dropped: "); + dh_uart_send_str(digitBuff); + dh_uart_send_str(", notification created/dropped: "); snprintf(digitBuff, sizeof(digitBuff), "%u/%u", stat->notificationsTotal, stat->notificationsDroppedCount); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); - dhuart_send_str("Local REST requests/errors: "); + dh_uart_send_str("Local REST requests/errors: "); snprintf(digitBuff, sizeof(digitBuff), "%u/%u", stat->localRestRequestsCount, stat->localRestResponcesErrors); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); - dhuart_send_str("Free heap size: "); + dh_uart_send_str("Free heap size: "); snprintf(digitBuff, sizeof(digitBuff), "%d", system_get_free_heap_size()); - dhuart_send_str(digitBuff); - dhuart_send_str(" bytes"); + dh_uart_send_str(digitBuff); + dh_uart_send_str(" bytes"); - dhuart_send_str(", request queue size: "); + dh_uart_send_str(", request queue size: "); snprintf(digitBuff, sizeof(digitBuff), "%d", dhsender_queue_length()); - dhuart_send_line(digitBuff); + dh_uart_send_line(digitBuff); } @@ -221,15 +222,15 @@ LOCAL void ICACHE_FLASH_ATTR scan_done_cb (void *arg, STATUS status) { int i; if(dhterminal_get_mode() == SM_OUTPUT_MODE) { if(status != OK) { - dhuart_send_line("scan failed"); + dh_uart_send_line("scan failed"); return; } struct bss_info *link = (struct bss_info *)arg; link = link->next.stqe_next; //ignore first according to the sdk manual if(link) - dhuart_send_line("SSID Rssi Channel Auth BSSID"); + dh_uart_send_line("SSID Rssi Channel Auth BSSID"); else - dhuart_send_line("No wireless networks found."); + dh_uart_send_line("No wireless networks found."); while(link) { char * auth = 0; switch(link->authmode) { @@ -263,7 +264,7 @@ LOCAL void ICACHE_FLASH_ATTR scan_done_cb (void *arg, STATUS status) { if(buff[i] == 0) buff[i] = ' '; } - dhuart_send_line(buff); + dh_uart_send_line(buff); link = link->next.stqe_next; } dhterminal_set_mode(SM_NORMAL_MODE, 0, 0, 0, 0); @@ -274,59 +275,59 @@ LOCAL void ICACHE_FLASH_ATTR scan_done_cb (void *arg, STATUS status) { void ICACHE_FLASH_ATTR dhterminal_commands_scan(const char *args) { static struct scan_config config = {0, 0, 0, 1}; if(wifi_station_scan(&config, scan_done_cb)) { - dhuart_send_line("Scanning..."); + dh_uart_send_line("Scanning..."); mIsCommandWorking = 1; dhterminal_set_mode(SM_OUTPUT_MODE, 0, 0, 0, 0); } else { - dhuart_send_line("Failed to start scan."); + dh_uart_send_line("Failed to start scan."); } } void ICACHE_FLASH_ATTR dhterminal_commands_debug(const char *args) { - dhuart_send_line("Debug output enabled. Press 'q' for exit."); + dh_uart_send_line("Debug output enabled. Press 'q' for exit."); dhterminal_set_mode(SM_DEBUG_MODE, 0, 0, 0, 0); - dhuart_send_str(dhterminal_get_debug_ouput()); + dh_uart_send_str(dhterminal_get_debug_ouput()); } void ICACHE_FLASH_ATTR dhterminal_commands_history(const char *args) { const char *tmp = dhterminal_get_history(); while(*tmp) { - dhuart_send_line(tmp); + dh_uart_send_line(tmp); while(*tmp++); } } void ICACHE_FLASH_ATTR dhterminal_commands_reboot(const char *args) { - dhuart_send_line("Rebooting..."); + dh_uart_send_line("Rebooting..."); system_restart(); } void ICACHE_FLASH_ATTR dhterminal_commands_config(const char *args) { - dhuart_send_str("Wi-Fi Mode: "); + dh_uart_send_str("Wi-Fi Mode: "); switch(dhsettings_get_wifi_mode()) { case WIFI_MODE_CLIENT: - dhuart_send_line("Client"); + dh_uart_send_line("Client"); break; case WIFI_MODE_AP: - dhuart_send_line("Access Point"); + dh_uart_send_line("Access Point"); break; } - dhuart_send_str("Wi-Fi SSID: "); - dhuart_send_line(dhsettings_get_wifi_ssid()); - dhuart_send_str("DeviceHive Server: "); - dhuart_send_line(dhsettings_get_devicehive_server()); - dhuart_send_str("DeviceHive DeviceId: "); - dhuart_send_line(dhsettings_get_devicehive_deviceid()); + dh_uart_send_str("Wi-Fi SSID: "); + dh_uart_send_line(dhsettings_get_wifi_ssid()); + dh_uart_send_str("DeviceHive Server: "); + dh_uart_send_line(dhsettings_get_devicehive_server()); + dh_uart_send_str("DeviceHive DeviceId: "); + dh_uart_send_line(dhsettings_get_devicehive_deviceid()); } void ICACHE_FLASH_ATTR dhterminal_commands_configure(const char *args) { int force = (os_strcmp(args, "--force-clear") == 0) ? 1 : 0; if(force || os_strcmp(args, "--clear") == 0) { if(dhsettings_clear(force)) { - dhuart_send_line("Settings was cleared, rebooting..."); + dh_uart_send_line("Settings was cleared, rebooting..."); system_restart(); } else { - dhuart_send_line("Error while cleaning settings."); + dh_uart_send_line("Error while cleaning settings."); } } else { dhterminal_configure_start(); @@ -334,19 +335,19 @@ void ICACHE_FLASH_ATTR dhterminal_commands_configure(const char *args) { } void ICACHE_FLASH_ATTR dhterminal_commands_echo(const char *args) { - dhuart_send_line(args); + dh_uart_send_line(args); } LOCAL void ICACHE_FLASH_ATTR nslookup_res(const char *name, ip_addr_t *ip, void *arg) { char ipstr[16]; if(ip == NULL) { - dhuart_send_line("FAILED"); + dh_uart_send_line("FAILED"); } else { sprintIp(ipstr, ip); - dhuart_send_str("Host "); - dhuart_send_str(name); - dhuart_send_str(" IP is "); - dhuart_send_line(ipstr); + dh_uart_send_str("Host "); + dh_uart_send_str(name); + dh_uart_send_str(" IP is "); + dh_uart_send_line(ipstr); } } @@ -362,11 +363,11 @@ LOCAL void ICACHE_FLASH_ATTR startResolve(const char *domain, dns_found_callback static ip_addr_t ip; static struct espconn connector = {0}; err_t r = espconn_gethostbyname(&connector, domain, &ip, output_mode_cb); - dhuart_send_line("Resolving..."); + dh_uart_send_line("Resolving..."); if(r == ESPCONN_OK) { res_cb(domain, &ip, &connector); } else if(r != ESPCONN_INPROGRESS) { - dhuart_send_line("ERROR: illegal request"); + dh_uart_send_line("ERROR: illegal request"); } else { mIsCommandWorking = 1; dhterminal_set_mode(SM_OUTPUT_MODE, 0, 0, 0, 0); @@ -391,21 +392,21 @@ LOCAL void ICACHE_FLASH_ATTR ping_cb(void* arg, void *pdata) { mRecieved++; mTotalDelay += pingresp->resp_time; snprintf(digitbuf, sizeof(digitbuf), "%d", pingresp->bytes); - dhuart_send_str(digitbuf); - dhuart_send_str(" bytes received from "); + dh_uart_send_str(digitbuf); + dh_uart_send_str(" bytes received from "); sprintIp(digitbuf, (const struct ip_addr *)&pingopt->ip); - dhuart_send_str(digitbuf); - dhuart_send_str(" in "); + dh_uart_send_str(digitbuf); + dh_uart_send_str(" in "); snprintf(digitbuf, sizeof(digitbuf), "%d", pingresp->resp_time); - dhuart_send_str(digitbuf); - dhuart_send_str(" ms, icmp_seq = "); + dh_uart_send_str(digitbuf); + dh_uart_send_str(" ms, icmp_seq = "); snprintf(digitbuf, sizeof(digitbuf), "%d", mSent); - dhuart_send_line(digitbuf); + dh_uart_send_line(digitbuf); } else { mLost++; - dhuart_send_str("Request timed out, icmp_seq = "); + dh_uart_send_str("Request timed out, icmp_seq = "); snprintf(digitbuf, sizeof(digitbuf), "%d", mSent); - dhuart_send_line(digitbuf); + dh_uart_send_line(digitbuf); } } } @@ -413,22 +414,22 @@ LOCAL void ICACHE_FLASH_ATTR ping_cb(void* arg, void *pdata) { LOCAL void ICACHE_FLASH_ATTR ping_done_cb(void* arg, void *pdata) { char digitbuf[16]; if(dhterminal_get_mode() == SM_OUTPUT_MODE) { - dhuart_send_str("Total sent: "); + dh_uart_send_str("Total sent: "); snprintf(digitbuf, sizeof(digitbuf), "%d", mSent); - dhuart_send_str(digitbuf); - dhuart_send_str(", received: "); + dh_uart_send_str(digitbuf); + dh_uart_send_str(", received: "); snprintf(digitbuf, sizeof(digitbuf), "%d", mRecieved); - dhuart_send_str(digitbuf); - dhuart_send_str(", lost: "); + dh_uart_send_str(digitbuf); + dh_uart_send_str(", lost: "); snprintf(digitbuf, sizeof(digitbuf), "%d", mLost); - dhuart_send_str(digitbuf); + dh_uart_send_str(digitbuf); if(mRecieved) { - dhuart_send_str(", average time: "); + dh_uart_send_str(", average time: "); snprintf(digitbuf, sizeof(digitbuf), "%d", mTotalDelay/mRecieved); - dhuart_send_str(digitbuf); - dhuart_send_line(" ms"); + dh_uart_send_str(digitbuf); + dh_uart_send_line(" ms"); } else { - dhuart_send_line(""); + dh_uart_send_line(""); } dhterminal_set_mode(SM_NORMAL_MODE, 0, 0, 0, 0); } diff --git a/firmware-src/sources/dhterminal_configure.c b/firmware-src/sources/dhterminal_configure.c index a99c55b..a7c225e 100644 --- a/firmware-src/sources/dhterminal_configure.c +++ b/firmware-src/sources/dhterminal_configure.c @@ -9,7 +9,7 @@ * */ #include "dhterminal_configure.h" -#include "dhuart.h" +#include "DH/uart.h" #include "dhterminal.h" #include "dhsettings.h" #include "rand.h" @@ -26,21 +26,21 @@ LOCAL char mComleaterBuff[48]; LOCAL void ICACHE_FLASH_ATTR get_accesskey_cb(const char *key) { if(*key) dhsettings_set_devicehive_accesskey(key); - dhuart_send_str("Configuring complete, store settings..."); + dh_uart_send_str("Configuring complete, store settings..."); if(dhsettings_commit()) { - dhuart_send_line("OK"); - dhuart_send_line("Rebooting..."); + dh_uart_send_line("OK"); + dh_uart_send_line("Rebooting..."); system_restart(); } else { - dhuart_send_line("ERROR. Not saved. Check debug output."); + dh_uart_send_line("ERROR. Not saved. Check debug output."); } dhterminal_set_mode(SM_NORMAL_MODE, 0, 0, 0, 0); } LOCAL void ICACHE_FLASH_ATTR get_deviceid_cb(const char *id) { dhsettings_set_devicehive_deviceid(id); - dhuart_send_line("Enter DeviceHive AccessKey. Leave empty to keep current."); - dhuart_send_line("Allowed chars are A-Za-z0-9/+="); + dh_uart_send_line("Enter DeviceHive AccessKey. Leave empty to keep current."); + dh_uart_send_line("Allowed chars are A-Za-z0-9/+="); dhterminal_set_mode(SM_HIDDEN_INPUT_MODE, get_accesskey_cb, 0, dhsettings_accesskey_filter, DHSETTINGS_ACCESSKEY_MAX_LENGTH); } @@ -59,8 +59,8 @@ LOCAL void ICACHE_FLASH_ATTR get_server_cb(const char *server) { buf[pos + 1] = 0; dhsettings_set_devicehive_server(buf); - dhuart_send_line("Enter DeviceHive DeviceId. Press Tab button to generate random."); - dhuart_send_line("Allowed chars are A-Za-z0-9-"); + dh_uart_send_line("Enter DeviceHive DeviceId. Press Tab button to generate random."); + dh_uart_send_line("Allowed chars are A-Za-z0-9-"); dhterminal_set_mode(SM_INPUT_MODE, get_deviceid_cb, generate_deviceid, dhsettings_deviceid_filter, DHSETTINGS_DEVICEID_MAX_LENGTH); if(dhsettings_get_devicehive_deviceid()[0] == 0) dhterminal_set_input(generate_deviceid("")); @@ -71,15 +71,15 @@ LOCAL void ICACHE_FLASH_ATTR get_server_cb(const char *server) { LOCAL void ICACHE_FLASH_ATTR get_password_cb(const char *password) { if(*password) dhsettings_set_wifi_password(password); - dhuart_send_line("Enter DeviceHive API URL."); - dhuart_send_line("Example: "DEFAULT_SERVER); + dh_uart_send_line("Enter DeviceHive API URL."); + dh_uart_send_line("Example: "DEFAULT_SERVER); dhterminal_set_mode(SM_INPUT_MODE, get_server_cb, 0, dhsettings_server_filter, DHSETTINGS_SERVER_MAX_LENGTH); dhterminal_set_input(dhsettings_get_devicehive_server()); } LOCAL void ICACHE_FLASH_ATTR get_ssid_cb(const char *ssid) { dhsettings_set_wifi_ssid(ssid); - dhuart_send_line("Enter Wi-Fi network password. Leave empty to keep current."); + dh_uart_send_line("Enter Wi-Fi network password. Leave empty to keep current."); dhterminal_set_mode(SM_HIDDEN_INPUT_MODE, get_password_cb, 0, 0, DHSETTINGS_PASSWORD_MAX_LENGTH); } @@ -89,7 +89,7 @@ void ICACHE_FLASH_ATTR get_mode_cb(const char *mode) { } else { dhsettings_set_wifi_mode(WIFI_MODE_AP); } - dhuart_send_line("Enter Wi-Fi network SSID."); + dh_uart_send_line("Enter Wi-Fi network SSID."); dhterminal_set_mode(SM_INPUT_MODE, get_ssid_cb, 0, 0, DHSETTINGS_SSID_MAX_LENGTH); dhterminal_set_input(dhsettings_get_wifi_ssid()); } @@ -101,8 +101,8 @@ LOCAL int ICACHE_FLASH_ATTR configure_mode_filter(char c) { } void ICACHE_FLASH_ATTR dhterminal_configure_start(void) { - dhuart_send_line("Welcome to the DeviceHive setup utility. Use Ctrl+C to interrupt."); - dhuart_send_line("Choose Wi-Fi mode: '0' - WiFi client, '1' - WiFi Access Point."); + dh_uart_send_line("Welcome to the DeviceHive setup utility. Use Ctrl+C to interrupt."); + dh_uart_send_line("Choose Wi-Fi mode: '0' - WiFi client, '1' - WiFi Access Point."); dhterminal_set_mode(SM_INPUT_MODE, get_mode_cb, 0, configure_mode_filter, 1); dhterminal_set_input((dhsettings_get_wifi_mode() == WIFI_MODE_CLIENT) ? "0" : "1"); } diff --git a/firmware-src/sources/dhuart.c b/firmware-src/sources/dhuart.c deleted file mode 100644 index 9987e57..0000000 --- a/firmware-src/sources/dhuart.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * dhuart.c - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: uart hal for esp8266 - * - */ -#include "dhuart.h" -#include "user_config.h" -#include "dhdebug.h" - -#include -#include -#include -#include -#include -#include - -#define UART_BASE 0x60000000 -#define UART_INTERUPTION_STATE_REGISTER (UART_BASE + 0x08) -#define UART_INTERUPTION_ENABLE_REGISTER (UART_BASE + 0x0C) -#define UART_INTERUPTION_REGISTER (UART_BASE + 0x10) -#define UART_STATUS_REGISTER (UART_BASE + 0x1C) -#define UART_DIV_REGISTER (UART_BASE + 0x14) -#define UART_CONFIGURATION_REGISTER0 (UART_BASE + 0x20) -#define UART_CONFIGURATION_REGISTER1 (UART_BASE + 0x24) - -#define DHUART_BUFFER_OVERFLOW_RESERVE INTERFACES_BUF_SIZE -LOCAL DHUART_DATA_MODE mDataMode = DUM_IGNORE; -LOCAL char mUartBuf[INTERFACES_BUF_SIZE + DHUART_BUFFER_OVERFLOW_RESERVE]; -LOCAL unsigned int mUartBufPos = 0; -LOCAL os_timer_t mUartTimer; -LOCAL unsigned int mUartTimerTimeout = 250; -LOCAL unsigned char mBufInterrupt = 0; -LOCAL os_timer_t mRecoverLEDTimer; -LOCAL char mKeepLED = 0; - -LOCAL ICACHE_FLASH_ATTR void arm_buf_timer(void); - -LOCAL void ICACHE_FLASH_ATTR buf_timeout(void *arg) { - unsigned int sz = mUartBufPos; - if(sz > INTERFACES_BUF_SIZE) - sz = INTERFACES_BUF_SIZE; - dhuart_buf_rcv(mUartBuf, sz); - ETS_UART_INTR_DISABLE(); - if(sz != mUartBufPos) { - os_memmove(mUartBuf, &mUartBuf[sz], mUartBufPos - sz); - mUartBufPos -= sz; - } else { - mUartBufPos = 0; - } - ETS_UART_INTR_ENABLE(); - if(mUartBufPos) - arm_buf_timer(); -} - -LOCAL ICACHE_FLASH_ATTR void arm_buf_timer(void) { - os_timer_disarm(&mUartTimer); - os_timer_setfn(&mUartTimer, (os_timer_func_t *)buf_timeout, NULL); - os_timer_arm(&mUartTimer, (mUartTimerTimeout == 0 || mUartBufPos >= INTERFACES_BUF_SIZE) ? 1 :mUartTimerTimeout, 0); -} - -LOCAL void dhuart_intr_handler(void *arg) { - if(READ_PERI_REG(UART_INTERUPTION_STATE_REGISTER) & BIT(0)) { - const char rcvChar = READ_PERI_REG(UART_BASE) & 0xFF; - WRITE_PERI_REG(UART_INTERUPTION_REGISTER, BIT(0)); - switch(mDataMode) { - case DUM_PER_BYTE: - dhuart_char_rcv(rcvChar); - break; - case DUM_PER_BUF: - if(mUartBufPos >= sizeof(mUartBuf)) { - return; - } - mUartBuf[mUartBufPos++] = rcvChar; - if(mBufInterrupt) { - if(mUartBufPos <= INTERFACES_BUF_SIZE) { - arm_buf_timer(); - } - } - break; - case DUM_IGNORE: - break; - } - } else { - WRITE_PERI_REG(UART_INTERUPTION_REGISTER, 0xffff); - } -} - -int ICACHE_FLASH_ATTR dhuart_init(unsigned int speed, unsigned int databits, char parity, unsigned int stopbits) { - if(speed < 300 || speed > 230400 || databits < 5 || databits > 8 || !(parity == 'N' || parity == 'O' || parity == 'E') || stopbits > 2 || stopbits < 1) - return 0; - ETS_UART_INTR_DISABLE(); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); - gpio_output_set(0, 0, 0, BIT(1) | BIT(3)); - PIN_PULLUP_EN(PERIPHS_IO_MUX_U0RXD_U); - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); - - WRITE_PERI_REG(UART_DIV_REGISTER, UART_CLK_FREQ / speed); - WRITE_PERI_REG(UART_CONFIGURATION_REGISTER0, 0); - SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, ((parity == 'E') ? 0 : 1) << 0); - SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, ((parity == 'N') ? 0 : 1) << 1); - SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, (databits - 5) << 2); - SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, ((stopbits == 2) ? 3 : 1) << 4); - SET_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, BIT(17) | BIT(18)); - CLEAR_PERI_REG_MASK(UART_CONFIGURATION_REGISTER0, BIT(17) | BIT(18)); - WRITE_PERI_REG(UART_CONFIGURATION_REGISTER1, BIT(0) | BIT(16) | BIT(23)); - ETS_UART_INTR_ATTACH(dhuart_intr_handler, 0); - WRITE_PERI_REG(UART_INTERUPTION_REGISTER, 0xffff); - SET_PERI_REG_MASK(UART_INTERUPTION_ENABLE_REGISTER, BIT(0)); - ETS_UART_INTR_ENABLE(); - return 1; -} - -LOCAL void ICACHE_FLASH_ATTR led_recover(void *arg) { - ETS_INTR_LOCK(); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); - gpio_output_set(0, 0b0110, 0b0110, 0); - ETS_INTR_UNLOCK(); -} - -LOCAL void ICACHE_FLASH_ATTR led_off(void) { - gpio_output_set(0, 0, 0, 0b0110); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); - os_delay_us(10000); -} - -void ICACHE_FLASH_ATTR dhuart_leds(DHUART_LEDS_MODE mode) { - if(mode == DHUART_LEDS_ON) { - mKeepLED = 1; - led_recover(NULL); - } else { - mKeepLED = 0; - led_off(); - } -} - -LOCAL void ICACHE_FLASH_ATTR dhuart_send_char(char c) { - while((READ_PERI_REG(UART_STATUS_REGISTER) >> 16) & 0xFF); - WRITE_PERI_REG(UART_BASE, c); -} - -void ICACHE_FLASH_ATTR dhuart_send_str(const char *str) { - if(mDataMode == DUM_PER_BUF) - return; - if(mKeepLED) { - os_timer_disarm(&mRecoverLEDTimer); - led_off(); - } - while(*str) - dhuart_send_char(*str++); - if(mKeepLED) { - os_timer_setfn(&mRecoverLEDTimer, (os_timer_func_t *)led_recover, NULL); - os_timer_arm(&mRecoverLEDTimer, 20, 0); - } -} - -void ICACHE_FLASH_ATTR dhuart_send_line(const char *str) { - dhuart_send_str(str); - dhuart_send_str("\r\n"); -} - -void ICACHE_FLASH_ATTR dhuart_send_buf(const char *buf, unsigned int len) { - if(mDataMode == DUM_PER_BYTE) - return; - if(mKeepLED) { - os_timer_disarm(&mRecoverLEDTimer); - led_off(); - } - while(len--) { - system_soft_wdt_feed(); - dhuart_send_char(*buf++); - } - if(mKeepLED) { - os_timer_setfn(&mRecoverLEDTimer, (os_timer_func_t *)led_recover, NULL); - os_timer_arm(&mRecoverLEDTimer, 20, 0); - } -} - -void ICACHE_FLASH_ATTR dhuart_set_mode(DHUART_DATA_MODE mode) { - mDataMode = mode; - if(mode == DUM_PER_BUF) { - mUartBufPos = 0; - } else if(mode == DUM_PER_BYTE) { - mBufInterrupt = 0; - } -} - -unsigned int ICACHE_FLASH_ATTR dhuart_get_callback_timeout(void) { - return mUartTimerTimeout; -} - -void ICACHE_FLASH_ATTR dhuart_set_callback_timeout(unsigned int timeout) { - mUartTimerTimeout = timeout; -} - -unsigned int ICACHE_FLASH_ATTR dhuart_get_buf(char ** buf) { - *buf = mUartBuf; - return mUartBufPos; -} - -void ICACHE_FLASH_ATTR dhuart_reset_buf(void) { - mUartBufPos = 0; -} - -void ICACHE_FLASH_ATTR dhuart_enable_buf_interrupt(int enable) { - mBufInterrupt = enable ? 1 : 0; -} diff --git a/firmware-src/sources/dhuart.h b/firmware-src/sources/dhuart.h deleted file mode 100644 index 914e526..0000000 --- a/firmware-src/sources/dhuart.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * \file dhuart.h - * \brief UART HAL for ESP8266. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - * \details UART Hardware access layer for ESP8266. Can operate in two modes: DUM_PER_BYTE or DUM_PER_BUF. - * In DUM_PER_BYTE all writing operations with strings are allowed, but data operations are disabled. - * Each received byte cause dhuart_char_rcv callback. In DUM_PER_BUF all writing operations with data - * are allowed, but char operations are disabled. Callback dhuart_buf_rcv will be called after number - * of byte in buffer is greate or eqaul INTERFACES_BUF_SIZE or last byte was received later than - * specified timeout. - */ - -#ifndef _DHUART_H_ -#define _DHUART_H_ - -/** UART mode. */ -typedef enum { - DUM_IGNORE, ///< Ignore input data, can print everything. - DUM_PER_BYTE, ///< Receive data byte by byte, dedicated callback on each byte, some send data function is disabled. - DUM_PER_BUF ///< Receive data per buffer, dedicated callback with buffer with some timeout which disabled by default, some send data function is disabled. -} DHUART_DATA_MODE; - -typedef enum { - DHUART_LEDS_ON, - DHUART_LEDS_OFF -} DHUART_LEDS_MODE; - -/** - * \brief Initializes UART. - * \param[in] speed Bitrate. 115200 or 19200 for example. - * \param[in] databits Number of bits in byte for UART. From 5 to 8. - * \param[in] parity Use parity bit or not. Char value: N(not), E(even) or O(odd). - * \param[in] stopbits Number of stop bits: 1 or 2. - * \return Non zero value on success. Zero on error. - */ -int dhuart_init(unsigned int speed, unsigned int databits, char parity, unsigned int stopbits); - -/** - * \brief Keep TX LEDs always on. - * \details Some modules has LEDs which are connected to TX pins. This method allows to keep this LEDs on. - * \param[in] on LEDs mode. - */ -void dhuart_leds(DHUART_LEDS_MODE mode); - -/** - * \brief Write string to UART. - * \details Doesn't works only in DUM_PER_BUF mode. - * \param[in] str String, ie bytes array that should be written. Will transmit buffer until first null char. - */ -void dhuart_send_str(const char *str); - -/** - * \brief Write string to UART and add "\r\n" to the end of string. - * \details Doesn't work in DUM_PER_BUF mode. - * \param[in] str String, ie bytes array that should be written. Will transmit buffer until first null char. - */ -void dhuart_send_line(const char *str); - -/** - * \brief Write char array with specified size to UART. - * \details Doesn't works only in DUM_PER_BYTE mode. - * \param[in] buf Chars array. - * \param[in] len Number of chars in buf. - */ -void dhuart_send_buf(const char *buf, unsigned int len); - -/** - * \brief Set current operating mode. - * \details Buffer is cleaned up on setting DUM_PER_BUF mode. - * \param[in] mode New operating mode. - */ -void dhuart_set_mode(DHUART_DATA_MODE mode); - -/** - * \brief Set timeout for callback. - * \details This timeout means how many ms without receiving bytes should pass before calling callback. - * Make sense only when mode is DUM_PER_BUF and callback is enabled. - * \param[in] timeout Timeout in ms. - */ -void dhuart_set_callback_timeout(unsigned int timeout); - -/** - * \brief Get receiving buffer. - * \param[out] buf Pointer where pointer to buffer should be stored. - * \return Number of bytes in buffer. - */ -unsigned int dhuart_get_buf(char ** buf); - -/** - * \brief Clean up buffer. - */ -void dhuart_reset_buf(void); - -/** - * \brief Enable or disable DUM_PER_BUF callbacks. - * \details Disabled by default. - * \param[in] enable Non zero value for enabling, zero for disabling. - */ -void dhuart_enable_buf_interrupt(int enable); - -/** - * \brief Get current timeout value. - * \return Timeout value in milliseconds. - */ -unsigned int dhuart_get_callback_timeout(void); - -/** - * \brief Callback declaration for DUM_PER_BYTE mode. - * \param[in] c Char that was received. - */ -extern void dhuart_char_rcv(char c); - -/** - * \brief Callback declaration for DUM_PER_BUF mode. - * \param[in] buf Data that was received. - * \param[in] len Size of data. - */ -extern void dhuart_buf_rcv(const char *buf, unsigned int len); - -#endif /* _DHUART_H_ */ diff --git a/firmware-src/sources/dhzc_web.c b/firmware-src/sources/dhzc_web.c index 4060ffe..7a15b0d 100644 --- a/firmware-src/sources/dhzc_web.c +++ b/firmware-src/sources/dhzc_web.c @@ -9,7 +9,6 @@ #include "dhzc_web.h" #include "httpd.h" #include "dhdebug.h" -#include "dhuart.h" #include "dhesperrors.h" #include "dhsettings.h" #include "dhzc_pages.h" diff --git a/firmware-src/sources/main.c b/firmware-src/sources/main.c index c50c4cd..96d3955 100644 --- a/firmware-src/sources/main.c +++ b/firmware-src/sources/main.c @@ -9,7 +9,7 @@ * */ #include "dhdebug.h" -#include "dhuart.h" +#include "DH/uart.h" #include "dhsender_queue.h" #include "dhterminal.h" #include "dhsettings.h" @@ -126,7 +126,7 @@ void user_init(void) { } dhdebug("*****************************"); if(mSpecialMode) { // if special mode was called by user or if there is no settings - dhuart_leds(DHUART_LEDS_ON); + dh_uart_leds(DH_UART_LEDS_ON); dhdebug("Wi-Fi Zero Configuration Mode"); dhap_init(WIFI_CONFIGURATION_SSID, NULL); dhzc_dnsd_init(); diff --git a/firmware-src/sources/user_config.h b/firmware-src/sources/user_config.h index 3449002..98f2284 100644 --- a/firmware-src/sources/user_config.h +++ b/firmware-src/sources/user_config.h @@ -21,7 +21,7 @@ #ifndef FIRMWARE_GIT_REVISION #define FIRMWARE_GIT_REVISION "unknown" #endif -/** Buffer size for data that uses for commands which require data transmition via interfaces like UART, I2C etc. */ +/** Buffer size for data that uses for commands which require data transmission via interfaces like UART, I2C etc. */ #define INTERFACES_BUF_SIZE 264 /** Encode type for data field in commands. Can be DATAENCODEBASE64 or DATAENCODEHEX.*/ #define DATAENCODEBASE64 From 73b71cd96f52d4df6cd935e71b1037a965fe0619 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 20 Apr 2017 17:58:59 +0300 Subject: [PATCH 30/83] fix some warnings "pointer targets in passing argument differ in signedness" --- firmware-src/sources/devices/dht.c | 8 ++++---- firmware-src/sources/dhap.c | 4 ++-- firmware-src/sources/dhcommand_parser.c | 12 ++++++------ firmware-src/sources/dhcommands.c | 4 ++-- firmware-src/sources/dhconnector.c | 6 +++--- firmware-src/sources/dhi2c.c | 2 +- firmware-src/sources/dhterminal_commands.c | 2 +- firmware-src/sources/dhzc_dnsd.c | 4 ++-- firmware-src/sources/dhzc_post.c | 2 +- firmware-src/sources/dns.c | 2 +- firmware-src/sources/httpd.c | 4 ++-- firmware-src/sources/mdnsd.c | 2 +- 12 files changed, 26 insertions(+), 26 deletions(-) diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 3769872..998de69 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -33,18 +33,18 @@ LOCAL char * ICACHE_FLASH_ATTR dht_read(int pin, char *buf) { } char * ICACHE_FLASH_ATTR dht11_read(int pin, int *humidity, int *temperature) { - unsigned char buf[DHT_PACKET_SIZE]; + char buf[DHT_PACKET_SIZE]; char *r = dht_read(pin, buf); if(r) return r; - *humidity = buf[0]; + *humidity = (uint8_t)buf[0]; if(temperature) - *temperature = buf[2]; + *temperature = (uint8_t)buf[2]; return NULL; } char * ICACHE_FLASH_ATTR dht22_read(int pin, float *humidity, float *temperature) { - unsigned char buf[DHT_PACKET_SIZE]; + char buf[DHT_PACKET_SIZE]; char *r = dht_read(pin, buf); if(r) return r; diff --git a/firmware-src/sources/dhap.c b/firmware-src/sources/dhap.c index ac50072..9c1c6ee 100644 --- a/firmware-src/sources/dhap.c +++ b/firmware-src/sources/dhap.c @@ -33,12 +33,12 @@ void ICACHE_FLASH_ATTR dhap_init(const char *ssid, const char *password) { apconfig = (struct softap_config *)os_zalloc(sizeof(struct softap_config));; if(!wifi_softap_dhcps_stop()) dhdebug("Failed to wifi_softap_dhcps_stop()"); - apconfig->ssid_len = snprintf(apconfig->ssid, sizeof(apconfig->ssid), "%s", ssid); + apconfig->ssid_len = snprintf((char*)apconfig->ssid, sizeof(apconfig->ssid), "%s", ssid); apconfig->authmode = AUTH_OPEN; if(password) { if(os_strlen(password) >= 8) { apconfig->authmode = AUTH_WPA_WPA2_PSK; - snprintf(apconfig->password, sizeof(apconfig->password), "%s", password); + snprintf((char*)apconfig->password, sizeof(apconfig->password), "%s", password); } else { dhdebug("AP password is too short, use open network"); } diff --git a/firmware-src/sources/dhcommand_parser.c b/firmware-src/sources/dhcommand_parser.c index 6ef93e8..e47a549 100644 --- a/firmware-src/sources/dhcommand_parser.c +++ b/firmware-src/sources/dhcommand_parser.c @@ -59,7 +59,7 @@ LOCAL char * ICACHE_FLASH_ATTR readUIntField(struct jsonparse_state *jparser, AL *readedfields |= field; return 0; } - const int res = strToUInt(&jparser->json[jparser->vstart], &value); + const int res = strToUInt(&jparser->json[jparser->vstart], (unsigned int*)&value); if(!res) return NONINTEGER; *out = value; @@ -109,7 +109,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int out->uart_speed = 0; continue; } - int res = strToUInt(&jparser.json[jparser.vstart], &val); + int res = strToUInt(&jparser.json[jparser.vstart], (unsigned int*)&val); if(!res) return "Wrong mode integer value"; if(fields & AF_UARTMODE) { @@ -175,7 +175,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int p = 2; else p = 0; - const int res = hexToByte(&jparser.json[jparser.vstart + p], &c); + const int res = hexToByte(&jparser.json[jparser.vstart + p], (uint8_t*)&c); if(res != (jparser.vlen - p)) return "Address is wrong"; out->address = c; @@ -223,7 +223,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int return UNEXPECTED; jsonparse_next(&jparser); if(jsonparse_next(&jparser) != JSON_TYPE_ERROR) { - out->storage.key.key_len = dhdata_decode(&jparser.json[jparser.vstart], jparser.vlen, out->storage.key.key_data, sizeof(out->storage.key.key_data)); + out->storage.key.key_len = dhdata_decode(&jparser.json[jparser.vstart], jparser.vlen, (char*)out->storage.key.key_data, sizeof(out->storage.key.key_data)); if(out->storage.key.key_len == 0) return "Key is broken"; *readedfields |= AF_KEY; @@ -249,7 +249,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int pinmask = all; pinnum = -1; } else { - const int res = strToUInt(&jparser.json[jparser.vstart], &pinnum); + const int res = strToUInt(&jparser.json[jparser.vstart], (unsigned int*)&pinnum); if(!res || pinnum < 0 || pinnum >= DH_GPIO_PIN_COUNT || (pins_found & DH_GPIO_PIN(pinnum))) return "Wrong argument"; pins_found |= (1 << pinnum); @@ -338,7 +338,7 @@ char * ICACHE_FLASH_ATTR parse_params_pins_set(const char *params, unsigned int *readedfields |= AF_FLOATVALUES; } else if((fields & AF_VALUES)) { // BE CAREFULL, all digits values have to be under this if int value, i; - if(!strToUInt(&jparser.json[jparser.vstart], &value)) + if(!strToUInt(&jparser.json[jparser.vstart], (unsigned int*)&value)) return NONINTEGER; if(pinnum > 0 ) out->storage.uint_values[pinnum] = value; diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 7dc3192..b1321ff 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -1121,9 +1121,9 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL if(result == MFRC522_STATUS_OK) { uint8_t len = (sizeof(parse_pins.data) > 0xFF) ? 0xFF : sizeof(parse_pins.data); if(check) - result = MFRC522_MIFARE_Write(parse_pins.address, parse_pins.data, parse_pins.data_len); + result = MFRC522_MIFARE_Write(parse_pins.address, (uint8_t*)parse_pins.data, parse_pins.data_len); else - result = MFRC522_MIFARE_Read(parse_pins.address, parse_pins.data, &len); + result = MFRC522_MIFARE_Read(parse_pins.address, (uint8_t*)parse_pins.data, &len); if(result == MFRC522_STATUS_OK) { parse_pins.count = len; if(check) diff --git a/firmware-src/sources/dhconnector.c b/firmware-src/sources/dhconnector.c index df0f099..735e850 100644 --- a/firmware-src/sources/dhconnector.c +++ b/firmware-src/sources/dhconnector.c @@ -179,7 +179,7 @@ LOCAL void network_connect_cb(void *arg) { dhdebug("ASSERT: networkConnectCb wrong state %d", mConnectionState); } int res; - if( (res = espconn_send(&mDHConnector, request->data, request->len)) != ESPCONN_OK) { + if( (res = espconn_send(&mDHConnector, (uint8_t*)request->data, request->len)) != ESPCONN_OK) { mConnectionState = CS_DISCONNECT; dhesperrors_espconn_result("network_connect_cb failed:", res); espconn_disconnect(&mDHConnector); @@ -347,8 +347,8 @@ void ICACHE_FLASH_ATTR dhconnector_init(void) { wifi_set_phy_mode(PHY_MODE_11N); os_memset(stationConfig.ssid, 0, sizeof(stationConfig.ssid)); os_memset(stationConfig.password, 0, sizeof(stationConfig.password)); - snprintf(stationConfig.ssid, sizeof(stationConfig.ssid), "%s", dhsettings_get_wifi_ssid()); - snprintf(stationConfig.password, sizeof(stationConfig.password), "%s", dhsettings_get_wifi_password()); + snprintf((char*)stationConfig.ssid, sizeof(stationConfig.ssid), "%s", dhsettings_get_wifi_ssid()); + snprintf((char*)stationConfig.password, sizeof(stationConfig.password), "%s", dhsettings_get_wifi_password()); if(dhsettings_get_devicehive_deviceid()[0]) { char hostname[33]; // limit length to 32 chars due to the sdk limit diff --git a/firmware-src/sources/dhi2c.c b/firmware-src/sources/dhi2c.c index f6e3249..0b1c830 100644 --- a/firmware-src/sources/dhi2c.c +++ b/firmware-src/sources/dhi2c.c @@ -175,7 +175,7 @@ LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_act(unsigned int address, char *buf, for(i = 0; i < len; i++) { system_soft_wdt_feed(); if(is_read) { - res = dhi2c_readbyte(&buf[i], (i + 1) == len); + res = dhi2c_readbyte((unsigned char*)&buf[i], (i + 1) == len); } else { res = dhi2c_writebyte(buf[i]); } diff --git a/firmware-src/sources/dhterminal_commands.c b/firmware-src/sources/dhterminal_commands.c index d0561c9..f778917 100644 --- a/firmware-src/sources/dhterminal_commands.c +++ b/firmware-src/sources/dhterminal_commands.c @@ -116,7 +116,7 @@ void ICACHE_FLASH_ATTR dhterminal_commands_status(const char *args) { struct station_config stationConfig; if(!wifi_station_get_config(&stationConfig)) { os_memset(&stationConfig, 0, sizeof(stationConfig)); - os_strcpy(stationConfig.ssid, "[Can not get SSID]"); + os_strcpy((char*)stationConfig.ssid, "[Can not get SSID]"); } const char *ssid = (const char*)stationConfig.ssid; switch(wifi_station_get_connect_status()) { diff --git a/firmware-src/sources/dhzc_dnsd.c b/firmware-src/sources/dhzc_dnsd.c index 35f9aba..acfe0e4 100644 --- a/firmware-src/sources/dhzc_dnsd.c +++ b/firmware-src/sources/dhzc_dnsd.c @@ -40,7 +40,7 @@ LOCAL int ICACHE_FLASH_ATTR dnsd_answer(char *data, unsigned int len) { struct ip_info info; if(wifi_get_ip_info(SOFTAP_IF, &info) == 0) info.ip.addr = 0; - return len + dns_add_answer(&data[len], NULL, NULL, DNS_TYPE_A, 60, + return len + dns_add_answer((uint8_t*)&data[len], NULL, NULL, DNS_TYPE_A, 60, sizeof(info.ip.addr), (uint8_t *)&info.ip.addr, NULL, NULL); } @@ -87,7 +87,7 @@ LOCAL void ICACHE_FLASH_ATTR dhzc_dnsd_recv_cb(void *arg, char *data, unsigned s sizeof(premot->remote_ip)); } - if(espconn_send(conn, mDNSAnswerBuffer, rlen)) { + if(espconn_send(conn, (uint8_t*)mDNSAnswerBuffer, rlen)) { dhdebug("Failed to send response"); mSendingInProgress = 0; if(conn->type & ESPCONN_TCP) diff --git a/firmware-src/sources/dhzc_post.c b/firmware-src/sources/dhzc_post.c index 462e94f..aaac4d2 100644 --- a/firmware-src/sources/dhzc_post.c +++ b/firmware-src/sources/dhzc_post.c @@ -37,7 +37,7 @@ LOCAL int ICACHE_FLASH_ATTR read_value(const char *data, unsigned int len, char b[0] = data[pos + 1]; if(pos + 2 < len) b[1] = data[pos + 2]; - set = hexToByte(b, &c); + set = hexToByte(b, (uint8_t*)&c); pos += set; } else { c = data[pos]; diff --git a/firmware-src/sources/dns.c b/firmware-src/sources/dns.c index fdc41d2..4a634f8 100644 --- a/firmware-src/sources/dns.c +++ b/firmware-src/sources/dns.c @@ -14,7 +14,7 @@ const uint8_t LOCAL_DOMAIN[] = "local"; LOCAL uint32_t to_fqdn(uint8_t *buf, const uint8_t *d) { uint32_t pos; pos = 1; - char *sp = buf; + uint8_t *sp = buf; uint32_t len = 0; while(*d) { if(*d == '.') { diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index 2ee143f..4ce1527 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -62,9 +62,9 @@ LOCAL void ICACHE_FLASH_ATTR send_res(struct espconn *conn, const char *data, in if (is_irom(data)) { char buf[len]; irom_read(buf, len, data); - res = espconn_send(conn, buf, len); + res = espconn_send(conn, (uint8_t*)buf, len); } else { - res = espconn_send(conn, (char *)data, len); + res = espconn_send(conn, (uint8_t*)data, len); } if(res) { dhstat_got_network_error(); diff --git a/firmware-src/sources/mdnsd.c b/firmware-src/sources/mdnsd.c index 0a4de4c..96e19f0 100644 --- a/firmware-src/sources/mdnsd.c +++ b/firmware-src/sources/mdnsd.c @@ -157,7 +157,7 @@ int ICACHE_FLASH_ATTR mdnsd_start(const char *name, unsigned long addr) { if(mMDNSdConn.proto.udp) mdnsd_stop(); - mName = name; + mName = (const uint8_t*)name; mAddr = addr; mMDNSAddr.addr = addr; From 49dad9373cd72b7433cb75afa99c18d753a7b870 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 21 Apr 2017 15:11:31 +0300 Subject: [PATCH 31/83] review SPI module Return zero on success! --- firmware-src/sources/DH/pwm.c | 1 - firmware-src/sources/DH/spi.c | 298 ++++++++++++++++++++++++ firmware-src/sources/DH/spi.h | 91 ++++++++ firmware-src/sources/devices/max31855.c | 14 +- firmware-src/sources/devices/max6675.c | 12 +- firmware-src/sources/devices/mfrc522.c | 50 ++-- firmware-src/sources/dhcommands.c | 81 +------ firmware-src/sources/dhspi.c | 157 ------------- firmware-src/sources/dhspi.h | 54 ----- 9 files changed, 432 insertions(+), 326 deletions(-) create mode 100644 firmware-src/sources/DH/spi.c create mode 100644 firmware-src/sources/DH/spi.h delete mode 100644 firmware-src/sources/dhspi.c delete mode 100644 firmware-src/sources/dhspi.h diff --git a/firmware-src/sources/DH/pwm.c b/firmware-src/sources/DH/pwm.c index 8c888a4..457af04 100644 --- a/firmware-src/sources/DH/pwm.c +++ b/firmware-src/sources/DH/pwm.c @@ -184,7 +184,6 @@ void ICACHE_FLASH_ATTR dh_pwm_disable(DHGpioPinMask pins) #include "dhcommand_parser.h" #include - /* * dh_handle_pwm_control() implementation. */ diff --git a/firmware-src/sources/DH/spi.c b/firmware-src/sources/DH/spi.c new file mode 100644 index 0000000..5702276 --- /dev/null +++ b/firmware-src/sources/DH/spi.c @@ -0,0 +1,298 @@ +/** + * @file + * @brief SPI bus implementation for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/spi.h" +#include "DH/gpio.h" +#include "DH/adc.h" + +#include +#include +#include +#include + +#define FUNC_HSPI 2 +#define SPI_BASE 0x60000100 // HSPI +#define SPI_CTRL2 0x60000114 +#define SPI_CLOCK 0x60000118 +#define SPI_USER 0x6000011C +#define SPI_USER1 0x60000120 +#define SPI_W0 0x60000140 +#define SPI_USR_MISO BIT(28) +#define SPI_USR_MOSI BIT(27) +#define SPI_CLKDIV_PRE 0x00001FFF +#define SPI_CLKDIV_PRE_S 18 +#define SPI_CLKCNT_N 0x0000003F +#define SPI_CLKCNT_N_S 12 +#define SPI_CLKCNT_H 0x0000003F +#define SPI_CLKCNT_H_S 6 +#define SPI_CLKCNT_L 0x0000003F +#define SPI_CLKCNT_L_S 0 +#define SPI_CK_OUT_HIGH_MODE 0x0000000F +#define SPI_CK_OUT_HIGH_MODE_S 12 +#define SPI_CK_OUT_LOW_MODE 0x0000000F +#define SPI_CK_OUT_LOW_MODE_S 8 +#define SPI_CK_OUT_EDGE BIT(7) +#define SPI_CK_I_EDGE BIT(6) +#define SPI_USR_MOSI_BITLEN 0x000001FF +#define SPI_USR_MOSI_BITLEN_S 17 +#define SPI_USR_MISO_BITLEN 0x000001FF +#define SPI_USR_MISO_BITLEN_S 8 +#define SPI_USR BIT(18) +#define SPI_CS_DELAY_US 2 + +// module variables +static unsigned int mSPICSPin = DH_SPI_NO_CS; +static DHSpiMode mSPIMode = DH_SPI_CPOL0CPHA0; + + +/** + * @brief Enable CS. + */ +static void ICACHE_FLASH_ATTR spi_enable_cs(void) +{ + if (mSPICSPin == DH_SPI_NO_CS) + return; // do nothing + + dh_gpio_write(0, DH_GPIO_PIN(mSPICSPin)); + os_delay_us(SPI_CS_DELAY_US); +} + + +/** + * @brief Disable CS. + */ +static void ICACHE_FLASH_ATTR spi_disable_cs(void) +{ + if (mSPICSPin == DH_SPI_NO_CS) + return; // do nothing + + dh_gpio_write(DH_GPIO_PIN(mSPICSPin), 0); + os_delay_us(SPI_CS_DELAY_US); +} + + +/** + * @brief Re-initialize SPI module. + */ +static void ICACHE_FLASH_ATTR spi_reinit(void) +{ + const DHGpioPinMask pins = DH_GPIO_PIN(12) | DH_GPIO_PIN(13) | DH_GPIO_PIN(14); + dh_gpio_open_drain(0, pins); + dh_gpio_pull_up(0, pins); + gpio_output_set(0, 0, 0, pins); + + WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPI); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPI); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI); + WRITE_PERI_REG(SPI_USER, 0); + WRITE_PERI_REG(SPI_CLOCK, // 1 MHz + ((15 & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) + | ((4 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) + | ((1 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) + | ((3 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); + if (mSPIMode & 0x1) { // CPHA + SET_PERI_REG_MASK(SPI_USER, SPI_CK_OUT_EDGE); + CLEAR_PERI_REG_MASK(SPI_USER, SPI_CK_I_EDGE); + } else { + SET_PERI_REG_MASK(SPI_USER, SPI_CK_I_EDGE); + CLEAR_PERI_REG_MASK(SPI_USER, SPI_CK_OUT_EDGE); + } + if (mSPIMode & 0x2) { // CPOL + SET_PERI_REG_MASK(SPI_CTRL2, SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_HIGH_MODE_S); + CLEAR_PERI_REG_MASK(SPI_CTRL2, SPI_CK_OUT_LOW_MODE << SPI_CK_OUT_LOW_MODE_S); + } else { + SET_PERI_REG_MASK(SPI_CTRL2, SPI_CK_OUT_LOW_MODE << SPI_CK_OUT_LOW_MODE_S); + CLEAR_PERI_REG_MASK(SPI_CTRL2, SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_LOW_MODE_S); + } + + WRITE_PERI_REG(SPI_USER1, + ((7 & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S) + | ((7 & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S)); + + spi_enable_cs(); +} + + +/* + * dh_spi_set_mode() implementation. + */ +int ICACHE_FLASH_ATTR dh_spi_set_mode(DHSpiMode mode) +{ + switch (mode) { + case DH_SPI_CPOL0CPHA0: + case DH_SPI_CPOL0CPHA1: + case DH_SPI_CPOL1CPHA0: + case DH_SPI_CPOL1CPHA1: + break; // OK + + default: + return -1; // bad mode + } + + mSPIMode = mode; + return 0; // OK +} + + +/* + * dh_spi_set_cs_pin() implementation. + */ +int ICACHE_FLASH_ATTR dh_spi_set_cs_pin(unsigned int pin) +{ + if (pin != DH_SPI_NO_CS) { + if (pin >= DH_GPIO_PIN_COUNT) + return -1; // bad pin number + if (!(DH_GPIO_PIN(pin) & DH_GPIO_SUITABLE_PINS)) + return -1; // unsuitable pin + if (pin == 12 || pin == 13 || pin == 14) + return -1; // protected pins + } + + mSPICSPin = pin; + return 0; // OK +} + + +/* + * dh_spi_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_spi_write(const void *buf_, size_t len, int disable_cs) +{ + spi_reinit(); + + CLEAR_PERI_REG_MASK(SPI_USER, SPI_USR_MISO); + SET_PERI_REG_MASK(SPI_USER, SPI_USR_MOSI); + + const uint8_t *buf = (const uint8_t*)buf_; + while (len--) { + while (READ_PERI_REG(SPI_BASE) & SPI_USR) + ; + WRITE_PERI_REG(SPI_W0, *buf++); + SET_PERI_REG_MASK(SPI_BASE, SPI_USR); + } + + if (disable_cs) + spi_disable_cs(); +} + + +/* + * dh_spi_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_spi_read(void *buf_, size_t len) +{ + spi_reinit(); + + CLEAR_PERI_REG_MASK(SPI_USER, SPI_USR_MOSI); + SET_PERI_REG_MASK(SPI_USER, SPI_USR_MISO); + while (READ_PERI_REG(SPI_BASE) & SPI_USR) + ; + + uint8_t *buf = (uint8_t*)buf_; + while (len--) { + SET_PERI_REG_MASK(SPI_BASE, SPI_USR); + while (READ_PERI_REG(SPI_BASE) & SPI_USR) + ; + *buf++ = READ_PERI_REG(SPI_W0) & 0xff; + } + + spi_disable_cs(); +} + + + +#ifdef DH_COMMANDS_SPI // SPI command handlers +#include "dhcommand_parser.h" +#include + +/** + * @brief SPI initialization helper. + * @return Non-zero if SPI was initialized. Zero otherwise. + */ +static int ICACHE_FLASH_ATTR spi_init(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, const gpio_command_params *params) +{ + if (fields & AF_CS) { + if (!!dh_spi_set_cs_pin(params->CS)) { + dh_command_fail(cmd_res, "Wrong CS pin"); + return 1; // FAILED + } + } + + if(fields & AF_SPIMODE) { + if (!!dh_spi_set_mode((DHSpiMode)params->spi_mode)) { + dh_command_fail(cmd_res, "Wrong SPI mode"); + return 1; // FAILED + } + } + + return 0; // continue +} + + +/* + * do_spi_master_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if (!(fields & AF_COUNT)) + info.count = 2; + if (info.count == 0 || info.count > INTERFACES_BUF_SIZE) { + dh_command_fail(cmd_res, "Wrong read size"); + return; + } + + if (spi_init(cmd_res, fields, &info)) + return; + + if (fields & AF_DATA) + dh_spi_write(info.data, info.data_len, 0); + dh_spi_read(info.data, info.count); + + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, info.data, info.count); +} + + +/* + * do_spi_master_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_spi_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_CS | AF_SPIMODE | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if (spi_init(cmd_res, fields, &info)) + return; + + if (!(fields & AF_DATA)) { + dh_command_fail(cmd_res, "Data not specified"); + return; + } + + dh_spi_write(info.data, info.data_len, 1); + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_SPI */ diff --git a/firmware-src/sources/DH/spi.h b/firmware-src/sources/DH/spi.h new file mode 100644 index 0000000..206554d --- /dev/null +++ b/firmware-src/sources/DH/spi.h @@ -0,0 +1,91 @@ +/** + * @file + * @brief SPI bus implementation for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DH_SPI_H_ +#define _DH_SPI_H_ + +#include "user_config.h" + +#include + +/** + * @brief SPI operation mode. + */ +typedef enum { + DH_SPI_CPOL0CPHA0 = 0, ///< @brief Low clock polarity, front edge. + DH_SPI_CPOL0CPHA1 = 1, ///< @brief Low clock polarity, rear edge. + DH_SPI_CPOL1CPHA0 = 2, ///< @brief High clock polarity, front edge. + DH_SPI_CPOL1CPHA1 = 3, ///< @brief High clock polarity, rear edge. +} DHSpiMode; + + +/** + * @brief Virtual pin for CS. + * + * It means that module will not set up CS line automatically. + */ +#define DH_SPI_NO_CS (~0U) + + +/** + * @brief Set SPI mode. + * @param[in] mode SPI mode. + * @return Zero on success. + */ +int dh_spi_set_mode(DHSpiMode mode); + + +/** + * @brief Set CS pin + * @param[in] pin Pin number. Can be DH_SPI_NO_CS. + * @return Zero on success. + */ +int dh_spi_set_cs_pin(unsigned int pin); + + +/** + * @brief Write data to SPI bus. + * + * Pins will be initialized automatically. + * + * @param[in] buf Buffer to write. + * @param[in] len Buffer length in bytes. + * @param[in] disable_cs Non zero value means that CS should be disabled after operation, zero value means not. + */ +void dh_spi_write(const void *buf, size_t len, int disable_cs); + + +/** + * @brief Read data from SPI bus. + * + * Pins will be initialized automatically. + * + * CS will be disabled after operation. + * + * @param[out] buf Buffer to read data to. + * @param[in] len Buffer length in bytes. + */ +void dh_spi_read(void *buf, size_t len); + + +#ifdef DH_COMMANDS_SPI // SPI command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "spi/master/read" command. + */ +void dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "spi/master/write" command. + */ +void dh_handle_spi_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_SPI */ +#endif /* _DH_SPI_H_ */ diff --git a/firmware-src/sources/devices/max31855.c b/firmware-src/sources/devices/max31855.c index 0891113..db5f766 100644 --- a/firmware-src/sources/devices/max31855.c +++ b/firmware-src/sources/devices/max31855.c @@ -7,9 +7,9 @@ * */ #include "max31855.h" -#include "dhspi.h" -#include "dhutils.h" #include "DH/gpio.h" +#include "DH/spi.h" +#include "dhutils.h" #include #include @@ -19,22 +19,22 @@ static int mCSPin = 15; char * ICACHE_FLASH_ATTR max31855_read(int pin, float *temperature) { char buf[4]; if(pin == MAX31855_NO_PIN) { - dhspi_set_cs_pin(mCSPin); + dh_spi_set_cs_pin(mCSPin); } else { - int ok = (pin != DHSPI_NOCS); + int ok = (pin != DH_SPI_NO_CS); if(ok) - ok = dhspi_set_cs_pin(pin); + ok = (0 == dh_spi_set_cs_pin(pin)); if(!ok) return "Wrong CS pin"; mCSPin = pin; } - dhspi_set_mode(SPI_CPOL0CPHA0); + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); //start converting dh_gpio_write(DH_GPIO_PIN(mCSPin), 0); delay_ms(100); - dhspi_read((char *)&buf, sizeof(buf)); + dh_spi_read((char *)&buf, sizeof(buf)); if(buf[3] & 0x01) return "Open circuit"; diff --git a/firmware-src/sources/devices/max6675.c b/firmware-src/sources/devices/max6675.c index 39d14ae..87bb293 100644 --- a/firmware-src/sources/devices/max6675.c +++ b/firmware-src/sources/devices/max6675.c @@ -7,8 +7,8 @@ * */ #include "max6675.h" -#include "dhspi.h" #include "DH/gpio.h" +#include "DH/spi.h" #include "dhutils.h" #include @@ -19,22 +19,22 @@ static int mCSPin = 15; char * ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) { char buf[2]; if(pin == MAX6675_NO_PIN) { - dhspi_set_cs_pin(mCSPin); + dh_spi_set_cs_pin(mCSPin); } else { - int ok = (pin != DHSPI_NOCS); + int ok = (pin != DH_SPI_NO_CS); if(ok) - ok = dhspi_set_cs_pin(pin); + ok = (0 == dh_spi_set_cs_pin(pin)); if(!ok) return "Wrong CS pin"; mCSPin = pin; } - dhspi_set_mode(SPI_CPOL0CPHA0); + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); //start converting dh_gpio_write(DH_GPIO_PIN(mCSPin), 0); delay_ms(250); - dhspi_read((char *)&buf, sizeof(buf)); + dh_spi_read((char *)&buf, sizeof(buf)); if((buf[0] & 0x80) || (buf[1] & 0x02)) return "Protocol error"; diff --git a/firmware-src/sources/devices/mfrc522.c b/firmware-src/sources/devices/mfrc522.c index ec8faea..98ffe75 100644 --- a/firmware-src/sources/devices/mfrc522.c +++ b/firmware-src/sources/devices/mfrc522.c @@ -5,7 +5,7 @@ */ #include "mfrc522.h" -#include "dhspi.h" +#include "DH/spi.h" #include "dhdebug.h" #include "snprintf.h" @@ -21,7 +21,7 @@ MFRC522_StatusCode MFRC522_MIFARE_TwoStepHelper(uint8_t command, uint8_t blockAd // Functions for setting up ESP8266 ///////////////////////////////////////////////////////////////////////////////////// MFRC522_StatusCode ICACHE_FLASH_ATTR MFRC522_Set_CS(int pin) { - if(dhspi_set_cs_pin(pin)) { + if(0 == dh_spi_set_cs_pin(pin)) { _chipSelectPin = pin; return MFRC522_STATUS_OK; } @@ -44,11 +44,11 @@ void ICACHE_FLASH_ATTR MFRC522_PCD_WriteRegister( uint8_t reg, ///< The registe uint8_t value ///< The value to write. ) { uint8_t buf; - dhspi_set_cs_pin(_chipSelectPin); - dhspi_set_mode(0); + dh_spi_set_cs_pin(_chipSelectPin); + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); buf = reg & 0x7E; // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3. - dhspi_write(&buf, 1, 0); - dhspi_write(&value, 1, 1); + dh_spi_write(&buf, 1, 0); + dh_spi_write(&value, 1, 1); } // End MFRC522_PCD_WriteRegister() /** @@ -60,12 +60,12 @@ void ICACHE_FLASH_ATTR MFRC522_PCD_WriteRegister_n( uint8_t reg, ///< The regis uint8_t *values ///< The values to write. Byte array. ) { uint8_t buf; - dhspi_set_cs_pin(_chipSelectPin); - dhspi_set_mode(0); + dh_spi_set_cs_pin(_chipSelectPin); + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); buf = reg & 0x7E; // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3. - dhspi_write(&buf, 1, 0); - dhspi_write(values, count - 1, 0); - dhspi_write(&values[count - 1], 1, 1); + dh_spi_write(&buf, 1, 0); + dh_spi_write(values, count - 1, 0); + dh_spi_write(&values[count - 1], 1, 1); } // End MFRC522_PCD_WriteRegister() /** @@ -75,11 +75,11 @@ void ICACHE_FLASH_ATTR MFRC522_PCD_WriteRegister_n( uint8_t reg, ///< The regis uint8_t ICACHE_FLASH_ATTR MFRC522_PCD_ReadRegister( uint8_t reg ///< The register to read from. One of the PCD_Register enums. ) { uint8_t buf; - dhspi_set_cs_pin(_chipSelectPin); - dhspi_set_mode(0); + dh_spi_set_cs_pin(_chipSelectPin); + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); buf = 0x80 | (reg & 0x7E); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3. - dhspi_write(&buf, 1, 0); - dhspi_read(&buf, 1); + dh_spi_write(&buf, 1, 0); + dh_spi_read(&buf, 1); return buf; } // End MFRC522_PCD_ReadRegister() @@ -98,11 +98,11 @@ void ICACHE_FLASH_ATTR MFRC522_PCD_ReadRegister_n( uint8_t reg, ///< The regist //Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" uint8_ts from register.")); uint8_t address = 0x80 | (reg & 0x7E); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3. uint8_t index = 0; // Index in values array. - dhspi_set_mode(0); // Set the settings to work with SPI bus - dhspi_set_cs_pin(_chipSelectPin); // Select slave + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); // Set the settings to work with SPI bus + dh_spi_set_cs_pin(_chipSelectPin); // Select slave count--; // One read is performed outside of the loop - dhspi_write(&address, 1, 0); // Tell MFRC522 which address we want to read + dh_spi_write(&address, 1, 0); // Tell MFRC522 which address we want to read while (index < count) { if (index == 0 && rxAlign) { // Only update bit positions rxAlign..7 in values[0] // Create bit mask for bit positions rxAlign..7 @@ -113,18 +113,18 @@ void ICACHE_FLASH_ATTR MFRC522_PCD_ReadRegister_n( uint8_t reg, ///< The regist } // Read value and tell that we want to read the same address again. uint8_t value; - dhspi_read(&value, 1); - dhspi_write(&address, 1, 0); + dh_spi_read(&value, 1); + dh_spi_write(&address, 1, 0); // Apply mask to both current value of values[0] and the new data in value. values[0] = (values[index] & ~mask) | (value & mask); } else { // Normal case - dhspi_read(&values[index], 1); - dhspi_write(&address, 1, 0); + dh_spi_read(&values[index], 1); + dh_spi_write(&address, 1, 0); } index++; } - dhspi_read(&values[index], 1); // Read the final uint8_t. + dh_spi_read(&values[index], 1); // Read the final uint8_t. } // End MFRC522_PCD_ReadRegister() /** @@ -196,8 +196,8 @@ MFRC522_StatusCode ICACHE_FLASH_ATTR MFRC522_PCD_CalculateCRC( uint8_t *data, / */ void ICACHE_FLASH_ATTR MFRC522_PCD_Init() { // Set the chipSelectPin as digital output, do not select the slave yet - dhspi_set_cs_pin(_chipSelectPin); - dhspi_set_mode(0); + dh_spi_set_cs_pin(_chipSelectPin); + dh_spi_set_mode(DH_SPI_CPOL0CPHA0); // When communicating with a PICC we need a timeout if something goes wrong. // f_timer = 13.56 MHz / (2*TPreScaler+1) where TPreScaler = [TPrescaler_Hi:TPrescaler_Lo]. diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index b1321ff..8d32b05 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -13,12 +13,12 @@ #include "DH/gpio.h" #include "DH/adc.h" #include "DH/uart.h" +#include "DH/spi.h" #include "dhnotification.h" #include "snprintf.h" #include "dhcommand_parser.h" #include "dhterminal.h" #include "dhi2c.h" -#include "dhspi.h" #include "dhonewire.h" #include "dhdebug.h" #include "DH/pwm.h" @@ -62,22 +62,6 @@ LOCAL int ICACHE_FLASH_ATTR onewire_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fiel return 0; } -LOCAL int ICACHE_FLASH_ATTR spi_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { - if(fields & AF_CS) { - if(dhspi_set_cs_pin(parse_pins->CS) == 0) { - dh_command_fail(cb, "Wrong CS pin"); - return 1; - } - } - if(fields & AF_SPIMODE) { - if(dhspi_set_mode(parse_pins->spi_mode) == 0) { - dh_command_fail(cb, "Wrong SPI mode"); - return 1; - } - } - return 0; -} - LOCAL char *ICACHE_FLASH_ATTR i2c_status_tochar(DHI2C_STATUS status) { switch(status) { case DHI2C_NOACK: @@ -186,63 +170,6 @@ static void ICACHE_FLASH_ATTR do_i2c_master_write(COMMAND_RESULT *cb, const char #endif // I2C commands -#if 1 // SPI commands - -/** - * @brief Do "spi/master/read" command. - */ -static void ICACHE_FLASH_ATTR do_spi_master_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); - if(parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & AF_COUNT) == 0) - parse_pins.count = 2; - if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - dh_command_fail(cb, "Wrong read size"); - return; - } - if(spi_init(cb, fields, &parse_pins)) - return; - if(fields & AF_DATA) - dhspi_write(parse_pins.data, parse_pins.data_len, 0); - dhspi_read(parse_pins.data, parse_pins.count); - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); -} - - -/** - * @brief Do "spi/master/write" command. - */ -static void ICACHE_FLASH_ATTR do_spi_master_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_CS | AF_SPIMODE | AF_DATA, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(spi_init(cb, fields, &parse_pins)) - return; - if((fields & AF_DATA) == 0) { - dh_command_fail(cb, "Data not specified"); - return; - } - dhspi_write(parse_pins.data, parse_pins.data_len, 1); - dh_command_done(cb, ""); -} - -#endif // SPI commands - #if 1 // onewire commands /** @@ -1313,8 +1240,10 @@ RO_DATA struct { { "i2c/master/read", do_i2c_master_read}, { "i2c/master/write", do_i2c_master_write}, - { "spi/master/read", do_spi_master_read}, - { "spi/master/write", do_spi_master_write}, +#ifdef DH_COMMANDS_SPI + { "spi/master/read", dh_handle_spi_master_read}, + { "spi/master/write", dh_handle_spi_master_write}, +#endif /* DH_COMMANDS_SPI */ { "onewire/master/read", do_onewire_master_read}, { "onewire/master/write", do_onewire_master_write}, diff --git a/firmware-src/sources/dhspi.c b/firmware-src/sources/dhspi.c deleted file mode 100644 index 2130554..0000000 --- a/firmware-src/sources/dhspi.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * dhspi.c - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: SPI implementation - * - */ -#include "dhspi.h" -#include "DH/gpio.h" - -#include -#include -#include -#include -#include - -#define FUNC_HSPI 2 -#define SPI_BASE 0x60000100 // HSPI -#define SPI_CTRL2 0x60000114 -#define SPI_CLOCK 0x60000118 -#define SPI_USER 0x6000011C -#define SPI_USER1 0x60000120 -#define SPI_W0 0x60000140 -#define SPI_USR_MISO (1 << 28) -#define SPI_USR_MOSI (1 << 27) -#define SPI_CLKDIV_PRE 0x00001FFF -#define SPI_CLKDIV_PRE_S 18 -#define SPI_CLKCNT_N 0x0000003F -#define SPI_CLKCNT_N_S 12 -#define SPI_CLKCNT_H 0x0000003F -#define SPI_CLKCNT_H_S 6 -#define SPI_CLKCNT_L 0x0000003F -#define SPI_CLKCNT_L_S 0 -#define SPI_CK_OUT_HIGH_MODE 0x0000000F -#define SPI_CK_OUT_HIGH_MODE_S 12 -#define SPI_CK_OUT_LOW_MODE 0x0000000F -#define SPI_CK_OUT_LOW_MODE_S 8 -#define SPI_CK_OUT_EDGE (1 << 7) -#define SPI_CK_I_EDGE (1 << 6) -#define SPI_USR_MOSI_BITLEN 0x000001FF -#define SPI_USR_MOSI_BITLEN_S 17 -#define SPI_USR_MISO_BITLEN 0x000001FF -#define SPI_USR_MISO_BITLEN_S 8 -#define SPI_USR (1 << 18) - -#define DHSPI_CS_DELAY_US 2 - -LOCAL unsigned int mSPICSPin = DHSPI_NOCS; -LOCAL unsigned char mSPIMode = 0; - -LOCAL void ICACHE_FLASH_ATTR dhspi_cs_enable() { - if(mSPICSPin == DHSPI_NOCS) - return; - dh_gpio_write(0, DH_GPIO_PIN(mSPICSPin)); - os_delay_us(DHSPI_CS_DELAY_US); -} - -LOCAL void ICACHE_FLASH_ATTR dhspi_cs_disable() { - if(mSPICSPin == DHSPI_NOCS) - return; - dh_gpio_write(DH_GPIO_PIN(mSPICSPin), 0); - os_delay_us(DHSPI_CS_DELAY_US); -} - -LOCAL void ICACHE_FLASH_ATTR dhspi_reinit() { - const DHGpioPinMask spipins = DH_GPIO_PIN(12) | DH_GPIO_PIN(13) | DH_GPIO_PIN(14); - dh_gpio_open_drain(0, spipins); - dh_gpio_pull_up(0, spipins); - gpio_output_set(0, 0, 0, spipins); - - WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_HSPI); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_HSPI); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_HSPI); - WRITE_PERI_REG(SPI_USER, 0); - WRITE_PERI_REG( - SPI_CLOCK, // 1 MHz - ((15 & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) | ((4 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) | ((1 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) | ((3 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); - if(mSPIMode & 0x1) { // CPHA - SET_PERI_REG_MASK(SPI_USER, SPI_CK_OUT_EDGE); - CLEAR_PERI_REG_MASK(SPI_USER, SPI_CK_I_EDGE); - } else { - SET_PERI_REG_MASK(SPI_USER, SPI_CK_I_EDGE); - CLEAR_PERI_REG_MASK(SPI_USER, SPI_CK_OUT_EDGE); - } - if(mSPIMode & 0x2) { // CPOL - SET_PERI_REG_MASK(SPI_CTRL2, - SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_HIGH_MODE_S); - CLEAR_PERI_REG_MASK(SPI_CTRL2, - SPI_CK_OUT_LOW_MODE << SPI_CK_OUT_LOW_MODE_S); - } else { - SET_PERI_REG_MASK(SPI_CTRL2, - SPI_CK_OUT_LOW_MODE << SPI_CK_OUT_LOW_MODE_S); - CLEAR_PERI_REG_MASK(SPI_CTRL2, - SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_LOW_MODE_S); - } - - WRITE_PERI_REG(SPI_USER1, - ((7 & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S) | ((7 & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S)); - - dhspi_cs_enable(); -} - -int ICACHE_FLASH_ATTR dhspi_set_mode(unsigned int mode) { - if(mode > 3) - return 0; - mSPIMode = mode; - return 1; -} - -int ICACHE_FLASH_ATTR dhspi_set_cs_pin(unsigned int cs_pin) { - if(cs_pin != DHSPI_NOCS - && (cs_pin == 12 || cs_pin == 13 || cs_pin == 14 - || cs_pin >= DH_GPIO_PIN_COUNT - || (DH_GPIO_PIN(cs_pin) & DH_GPIO_SUITABLE_PINS) == 0)) - return 0; - mSPICSPin = cs_pin; - return 1; -} - -void ICACHE_FLASH_ATTR dhspi_write(const char *buf, unsigned int len, - int disable_cs) { - dhspi_reinit(); - - CLEAR_PERI_REG_MASK(SPI_USER, SPI_USR_MISO); - SET_PERI_REG_MASK(SPI_USER, SPI_USR_MOSI); - while (len--) { - while (READ_PERI_REG(SPI_BASE) & SPI_USR) - ; - WRITE_PERI_REG(SPI_W0, *buf++); - SET_PERI_REG_MASK(SPI_BASE, SPI_USR); - } - - if(disable_cs) - dhspi_cs_disable(); -} - -void ICACHE_FLASH_ATTR dhspi_read(char *buf, unsigned int len) { - dhspi_reinit(); - - CLEAR_PERI_REG_MASK(SPI_USER, SPI_USR_MOSI); - SET_PERI_REG_MASK(SPI_USER, SPI_USR_MISO); - while (READ_PERI_REG(SPI_BASE) & SPI_USR) - ; - while (len--) { - SET_PERI_REG_MASK(SPI_BASE, SPI_USR); - while (READ_PERI_REG(SPI_BASE) & SPI_USR) - ; - *buf++ = READ_PERI_REG(SPI_W0) & 0xff; - - } - - dhspi_cs_disable(); -} diff --git a/firmware-src/sources/dhspi.h b/firmware-src/sources/dhspi.h deleted file mode 100644 index c8eae5e..0000000 --- a/firmware-src/sources/dhspi.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \file dhspi.h - * \brief Implementation of SPI bus for ESP8266. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - */ - -#ifndef _DHSPI_H_ -#define _DHSPI_H_ - -/** SPI operation mode */ -typedef enum { - SPI_CPOL0CPHA0 = 0, ///< Low clock polarity, front edge - SPI_CPOL0CPHA1 = 1, ///< Low clock polarity, rear edge - SPI_CPOL1CPHA0 = 2, ///< High clock polarity, front edge - SPI_CPOL1CPHA1 = 3, ///< High clock polarity, rear edge -} DHSPI_MODE; - -/** Virtual pin for CS. It means that module will not set up CS line automatically. */ -#define DHSPI_NOCS (~(uint32_t)0U) - -/** - * \brief Set SPI mode - * \param[in] mode SPI mode, can be use DHSPI_MODE enum. - * \return Non zero value on success, zero on error. - */ -int dhspi_set_mode(unsigned int mode); - -/** - * \brief Set CS pim - * \param[in] cs_pin Pin number. Can be DHSPI_NOCS. - * \return Non zero value on success, zero on error. - */ -int dhspi_set_cs_pin(unsigned int cs_pin); - -/** - * \brief Write data to SPI bus. - * \details Pins will be initialized automatically. - * \param[in] buf Buffer with data. - * \param[in] len Data length in bytes. - * \param[in] disable_cs Non zero value means that CS should be disabled after operation, zero value means not. - */ -void dhspi_write(const char *buf, unsigned int len, int disable_cs); - -/** - * \brief Read data from I2C bus. - * \details Pins will be initialized automatically. - * \param[out] buf Buffer with data. - * \param[in] len Data length in bytes. - */ -void dhspi_read(char *buf, unsigned int len); - -#endif /* _DHSPI_H_ */ From 1ae7dddce3c2ffbe7bef3c625082d75bcdb7437f Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 21 Apr 2017 16:52:42 +0300 Subject: [PATCH 32/83] review I2C module --- firmware-src/sources/DH/gpio.c | 2 +- firmware-src/sources/DH/gpio.h | 2 +- firmware-src/sources/DH/i2c.c | 404 ++++++++++++++++++ firmware-src/sources/DH/i2c.h | 98 +++++ firmware-src/sources/DH/spi.c | 3 +- firmware-src/sources/DH/uart.c | 6 +- firmware-src/sources/devices/ads1115.c | 19 +- firmware-src/sources/devices/ads1115.h | 6 +- firmware-src/sources/devices/bh1750.c | 13 +- firmware-src/sources/devices/bh1750.h | 6 +- firmware-src/sources/devices/bmp180.c | 26 +- firmware-src/sources/devices/bmp180.h | 6 +- firmware-src/sources/devices/bmp280.c | 29 +- firmware-src/sources/devices/bmp280.h | 6 +- firmware-src/sources/devices/hmc5883l.c | 15 +- firmware-src/sources/devices/hmc5883l.h | 4 +- firmware-src/sources/devices/ina219.c | 21 +- firmware-src/sources/devices/ina219.h | 10 +- firmware-src/sources/devices/lm75.c | 13 +- firmware-src/sources/devices/lm75.h | 6 +- firmware-src/sources/devices/mcp4725.c | 19 +- firmware-src/sources/devices/mcp4725.h | 10 +- firmware-src/sources/devices/mlx90614.c | 17 +- firmware-src/sources/devices/mlx90614.h | 6 +- firmware-src/sources/devices/mpu6050.c | 21 +- firmware-src/sources/devices/mpu6050.h | 4 +- firmware-src/sources/devices/pca9685.c | 25 +- firmware-src/sources/devices/pca9685.h | 6 +- firmware-src/sources/devices/pcf8574.c | 33 +- firmware-src/sources/devices/pcf8574.h | 14 +- .../sources/devices/pcf8574_hd44780.c | 52 +-- .../sources/devices/pcf8574_hd44780.h | 4 +- firmware-src/sources/devices/pcf8591.c | 33 +- firmware-src/sources/devices/pcf8591.h | 14 +- firmware-src/sources/devices/si7021.c | 17 +- firmware-src/sources/devices/si7021.h | 6 +- firmware-src/sources/devices/tm1636.h | 4 +- firmware-src/sources/devices/tm1637.c | 24 +- firmware-src/sources/dhcommands.c | 204 +++------ firmware-src/sources/dhi2c.c | 201 --------- firmware-src/sources/dhi2c.h | 53 --- firmware-src/sources/dhsender_data.c | 10 + firmware-src/sources/dhsender_data.h | 9 + 43 files changed, 814 insertions(+), 667 deletions(-) create mode 100644 firmware-src/sources/DH/i2c.c create mode 100644 firmware-src/sources/DH/i2c.h delete mode 100644 firmware-src/sources/dhi2c.c delete mode 100644 firmware-src/sources/dhi2c.h diff --git a/firmware-src/sources/DH/gpio.c b/firmware-src/sources/DH/gpio.c index 93bdd7f..14689c4 100644 --- a/firmware-src/sources/DH/gpio.c +++ b/firmware-src/sources/DH/gpio.c @@ -39,7 +39,7 @@ void ICACHE_FLASH_ATTR dh_gpio_init(void) /* * dh_gpio_prepare_pins() implementation. */ -void ICACHE_FLASH_ATTR dh_gpio_prepare_pins(DHGpioPinMask pins, bool disable_pwm) +void ICACHE_FLASH_ATTR dh_gpio_prepare_pins(DHGpioPinMask pins, int disable_pwm) { if (disable_pwm) dh_pwm_disable(pins); diff --git a/firmware-src/sources/DH/gpio.h b/firmware-src/sources/DH/gpio.h index 5ab4633..d3480d1 100644 --- a/firmware-src/sources/DH/gpio.h +++ b/firmware-src/sources/DH/gpio.h @@ -54,7 +54,7 @@ void dh_gpio_init(void); * @param[in] pin_mask Bitwise pin mask to use as GPIO pins. * @param[in] disable_pwm Flag to disable PWM if it was enabled before. */ -void dh_gpio_prepare_pins(DHGpioPinMask pins, bool disable_pwm); +void dh_gpio_prepare_pins(DHGpioPinMask pins, int disable_pwm); /** diff --git a/firmware-src/sources/DH/i2c.c b/firmware-src/sources/DH/i2c.c new file mode 100644 index 0000000..9a030f0 --- /dev/null +++ b/firmware-src/sources/DH/i2c.c @@ -0,0 +1,404 @@ +/** + * @file + * @brief Software I2C implementation for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/i2c.h" +#include "DH/gpio.h" +#include "DH/adc.h" + +#include +#include +#include +#include +#include + +#define I2C_DELAY_US 5 +#define I2C_ERROR_TIMEOUT_US 50000 + +// module variables +static DHGpioPinMask mSDAPin = DH_GPIO_PIN(0); +static DHGpioPinMask mSCLPin = DH_GPIO_PIN(2); + + +/* + * dh_i2c_error_string() implementation. + */ +const char* ICACHE_FLASH_ATTR dh_i2c_error_string(int status) +{ + switch(status) { + case DH_I2C_OK: + return 0; + case DH_I2C_NOACK: + return "no ACK response"; + case DH_I2C_WRONG_PARAMETERS: + return "Wrong parameters"; + case DH_I2C_BUS_BUSY: + return "Bus is busy"; + case DH_I2C_DEVICE_ERROR: + return "Device error"; + } + + return 0; +} + + +/* + * dh_i2c_init() implementation. + */ +int ICACHE_FLASH_ATTR dh_i2c_init(unsigned int sda_pin, unsigned int scl_pin) +{ + const DHGpioPinMask SDA = DH_GPIO_PIN(sda_pin); + const DHGpioPinMask SCL = DH_GPIO_PIN(scl_pin); + if (!(SDA&DH_GPIO_SUITABLE_PINS) || !(SCL&DH_GPIO_SUITABLE_PINS) || SDA == SCL) + return DH_I2C_WRONG_PARAMETERS; + + mSDAPin = SDA; + mSCLPin = SCL; + dh_i2c_reinit(); + return DH_I2C_OK; +} + + +/* + * dh_i2c_reinit() implementation. + */ +void ICACHE_FLASH_ATTR dh_i2c_reinit(void) +{ + dh_gpio_open_drain(mSDAPin | mSCLPin, 0); + dh_gpio_prepare_pins(mSDAPin | mSCLPin, true/*disable_pwm*/); + dh_gpio_pull_up(mSDAPin | mSCLPin, 0); + gpio_output_set(mSDAPin | mSCLPin, 0, mSDAPin | mSCLPin, 0); +} + + +/** + * @brief Set pin value. + */ +static int ICACHE_FLASH_ATTR i2c_set_pin(DHGpioPinMask pin_mask, int val) +{ + if (val) { + gpio_output_set(pin_mask, 0, pin_mask, 0); + } else { + gpio_output_set(0, pin_mask, pin_mask, 0); + } + os_delay_us(I2C_DELAY_US); + + int i; // busy-wait loop + for(i = 0; i < I2C_ERROR_TIMEOUT_US; i++) { + const int vv = (gpio_input_get()&pin_mask) != 0; + if (vv ^ val) { + // values are still different + os_delay_us(1); // wait a bit + } else { + return DH_I2C_OK; + } + } + + return DH_I2C_BUS_BUSY; +} + + +/** + * @brief Start I2C communication. + */ +static int ICACHE_FLASH_ATTR i2c_start(void) +{ + int res; + + res = i2c_set_pin(mSDAPin, 1); + if (res != DH_I2C_OK) + return res; + res = i2c_set_pin(mSCLPin, 1); + if (res != DH_I2C_OK) + return res; + + res = i2c_set_pin(mSDAPin, 0); + if (res != DH_I2C_OK) + return res; + res = i2c_set_pin(mSCLPin, 0); + if (res != DH_I2C_OK) + return res; + + return DH_I2C_OK; +} + + +/** + * @brief Stop I2C communication. + */ +static int ICACHE_FLASH_ATTR i2c_stop(void) +{ + int res; + + res = i2c_set_pin(mSDAPin, 0); + if (res != DH_I2C_OK) + return res; + res = i2c_set_pin(mSCLPin, 1); + if (res != DH_I2C_OK) + return res; + res = i2c_set_pin(mSDAPin, 1); + if (res != DH_I2C_OK) + return res; + + return DH_I2C_OK; +} + + +/** + * @brief Write one byte to I2C bus. + */ +static int ICACHE_FLASH_ATTR i2c_writebyte(int ch) +{ + int res, i; + + // msb-first + for (i = 7; i >= 0; i--) { + res = i2c_set_pin(mSDAPin, (ch>>i)&1); + if (res != DH_I2C_OK) + return res; + res = i2c_set_pin(mSCLPin, 1); + if (res != DH_I2C_OK) + return res; + os_delay_us(I2C_DELAY_US); + res = i2c_set_pin(mSCLPin, 0); + if (res != DH_I2C_OK) + return res; + } + + // check ACK + gpio_output_set(mSDAPin, 0, mSDAPin, 0); + os_delay_us(I2C_DELAY_US); + res = i2c_set_pin(mSCLPin, 1); + if (res != DH_I2C_OK) + return res; + os_delay_us(I2C_DELAY_US); + const int nack = (gpio_input_get() & mSDAPin) != 0; + res = i2c_set_pin(mSCLPin, 0); + if (res != DH_I2C_OK) + return res; + if (nack) + return DH_I2C_NOACK; + + return DH_I2C_OK; +} + + +/** + * @brief Read one byte from I2C bus. + */ +static int ICACHE_FLASH_ATTR i2c_readbyte(int *byte, int ack_bit) +{ + int res, i; + + gpio_output_set(mSDAPin, 0, mSDAPin, 0); + os_delay_us(I2C_DELAY_US); + + // msb-first + for (i = 7; i >= 0; i--) { + res = i2c_set_pin(mSCLPin, 1); + if (res != DH_I2C_OK) + return res; + os_delay_us(I2C_DELAY_US); + const int bit = (gpio_input_get() & mSDAPin) != 0; + *byte |= bit << i; + res = i2c_set_pin(mSCLPin, 0); + if (res != DH_I2C_OK) + return res; + } + + // send ACK + res = i2c_set_pin(mSDAPin, ack_bit); + if (res != DH_I2C_OK) + return res; + res = i2c_set_pin(mSCLPin, 1); + if (res != DH_I2C_OK) + return res; + os_delay_us(I2C_DELAY_US); + res = i2c_set_pin(mSCLPin, 0); + if (res != DH_I2C_OK) + return res; + + return DH_I2C_OK; +} + + +/** + * @brief Do I2C bus communication. + */ +static int ICACHE_FLASH_ATTR i2c_act(unsigned int address, uint8_t *buf, size_t len, int send_stop, int is_read) +{ + if (len > INTERFACES_BUF_SIZE || address > 0xFF) + return DH_I2C_WRONG_PARAMETERS; + + // start + int res = i2c_start(); + if (res != DH_I2C_OK) + return res; + + // write address + res = i2c_writebyte(is_read ? (address | 0x01) + : (address & ~0x01)); + if (res != DH_I2C_OK) { + i2c_stop(); + return res; + } + + while (len--) { + system_soft_wdt_feed(); + if (is_read) { + int byte = 0; + res = i2c_readbyte(&byte, 0 == len); + *buf++ = byte; + } else { + res = i2c_writebyte(*buf++); + } + if (res != DH_I2C_OK) { + i2c_stop(); + return res; + } + } + + if (send_stop) { + return i2c_stop(); + } else { + return DH_I2C_OK; + } +} + + +/* + * dh_i2c_write() implementation. + */ +int ICACHE_FLASH_ATTR dh_i2c_write(unsigned int address, const void *buf, size_t len, int send_stop) +{ + return i2c_act(address, (uint8_t*)buf, len, send_stop, 0); +} + + +/* + * dh_i2c_read() implementation. + */ +int ICACHE_FLASH_ATTR dh_i2c_read(unsigned int address, void *buf, size_t len) +{ + return i2c_act(address, (uint8_t*)buf, len, 1/*send_stop*/, 1); +} + + + +#ifdef DH_COMMANDS_I2C // I2C command handlers +#include "dhcommand_parser.h" +#include + + +/* + * dh_i2c_init_helper() implementation. + */ +int ICACHE_FLASH_ATTR dh_i2c_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, const gpio_command_params *params) +{ + if ((fields & AF_ADDRESS) == 0) { + dh_command_fail(cmd_res, "Address not specified"); + return 1; // FAILED + } + + int init = ((fields & AF_SDA) != 0) + ((fields & AF_SCL) != 0); + if (init == 2) { + const int res = dh_i2c_init(params->SDA, params->SCL); + const char *err = dh_i2c_error_string(res); + if (err != 0) { + dh_command_fail(cmd_res, err); + return 1; // FAILED + } + } else if(init == 1) { + dh_command_fail(cmd_res, "Only one pin specified"); + return 1; // FAILED + } else { + dh_i2c_reinit(); + } + + return 0; // continue +} + + +/* + * dh_handle_i2c_master_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_i2c_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if (!(fields & AF_COUNT)) + info.count = 2; + if (info.count == 0 || info.count > INTERFACES_BUF_SIZE) { + dh_command_fail(cmd_res, "Wrong read size"); + return; + } + + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; + + // write + if (fields & AF_DATA) { + int res = dh_i2c_write(info.address, info.data, info.data_len, 0); + err_msg = dh_i2c_error_string(res); + if (err_msg) { + dh_command_fail(cmd_res, err_msg); + return; + } + } + + // read + int res = dh_i2c_read(info.address, info.data, info.count); + err_msg = dh_i2c_error_string(res); + if (err_msg) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done_buf(cmd_res, info.data, info.count); + } +} + + +/* + * dh_handle_i2c_master_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_i2c_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if((fields & AF_DATA) == 0) { + dh_command_fail(cmd_res, "Data not specified"); + return; + } + + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; + + const int res = dh_i2c_write(info.address, info.data, info.data_len, 1); + err_msg = dh_i2c_error_string(res); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} + +#endif /* DH_COMMANDS_I2C */ diff --git a/firmware-src/sources/DH/i2c.h b/firmware-src/sources/DH/i2c.h new file mode 100644 index 0000000..cfa63f9 --- /dev/null +++ b/firmware-src/sources/DH/i2c.h @@ -0,0 +1,98 @@ +/** + * @file + * @brief Software I2C implementation for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DH_I2C_H_ +#define _DH_I2C_H_ + +#include "user_config.h" +#include + +/** + * @brief I2C functions return status. + */ +typedef enum { + DH_I2C_OK, ///< @brief Success. + DH_I2C_NOACK, ///< @brief ACK response was not received on bus. + DH_I2C_WRONG_PARAMETERS, ///< @brief Wrong parameters. + DH_I2C_BUS_BUSY, ///< @brief Module wasn't able to set desired level on bus during specified timeout. + DH_I2C_DEVICE_ERROR ///< @brief Error in device. +} DH_I2C_Status; + + +/** + * @brief Get error message based on status. + * @return NULL if status is OK, error message otherwise. + */ +const char* dh_i2c_error_string(int status); + + +/** + * @brief Prepare pins for usage with I2C. + * @param[in] sda_pin Pin number for SDA line. + * @param[in] scl_pin Pin number for SCL line. + * @return Status value, one of DH_I2C_Status value. + */ +int dh_i2c_init(unsigned int sda_pin, + unsigned int scl_pin); + + +/** + * @brief Prepare last successfully prepared pins for usage with I2C. + */ +void dh_i2c_reinit(void); + + +/** + * @brief Write data to I2C bus. + * @param[in] address Device address. + * @param[in] buf Buffer to write. + * @param[in] len Buffer length in bytes. + * @param[in] send_stop Send STOP after writing if this parameter has non zero value, do not send if parameter is zero. + * @return Status value, one of DH_I2C_Status value. + */ +int dh_i2c_write(unsigned int address, + const void *buf, size_t len, + int send_stop); + + +/** + * @brief Read data from I2C bus. + * @param[in] address Device address. + * @param[out] buf Buffer to read data to. + * @param[in] len Buffer length in bytes. + * @return Status value, one of DH_I2C_Status value. + */ +int dh_i2c_read(unsigned int address, + void *buf, size_t len); + + +#ifdef DH_COMMANDS_I2C // I2C command handlers +#include "dhcommand_parser.h" +#include "dhsender_data.h" + +/** + * @brief Helper function to initialize I2C bus. + * @return Non-zero if I2C was initialized. Zero otherwise. + */ +int dh_i2c_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params); + + +/** + * @brief Handle "i2c/master/read" command. + */ +void dh_handle_i2c_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "i2c/master/write" command. + */ +void dh_handle_i2c_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_I2C */ +#endif /* _DH_I2C_H_ */ diff --git a/firmware-src/sources/DH/spi.c b/firmware-src/sources/DH/spi.c index 5702276..285bab8 100644 --- a/firmware-src/sources/DH/spi.c +++ b/firmware-src/sources/DH/spi.c @@ -204,7 +204,6 @@ void ICACHE_FLASH_ATTR dh_spi_read(void *buf_, size_t len) } - #ifdef DH_COMMANDS_SPI // SPI command handlers #include "dhcommand_parser.h" #include @@ -263,7 +262,7 @@ void ICACHE_FLASH_ATTR dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const dh_spi_write(info.data, info.data_len, 0); dh_spi_read(info.data, info.count); - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, info.data, info.count); + dh_command_done_buf(cmd_res, info.data, info.count); } diff --git a/firmware-src/sources/DH/uart.c b/firmware-src/sources/DH/uart.c index bb02bab..91a0c76 100644 --- a/firmware-src/sources/DH/uart.c +++ b/firmware-src/sources/DH/uart.c @@ -400,11 +400,11 @@ void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char * system_soft_wdt_feed(); } - char *buf = 0; - size_t len = dh_uart_get_buf((void**)&buf); + void *buf = 0; + size_t len = dh_uart_get_buf(&buf); if (len > INTERFACES_BUF_SIZE) len = INTERFACES_BUF_SIZE; - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, buf, len); + dh_command_done_buf(cmd_res, buf, len); dh_uart_set_mode(DH_UART_MODE_PER_BUF); } diff --git a/firmware-src/sources/devices/ads1115.c b/firmware-src/sources/devices/ads1115.c index 3485342..484651e 100644 --- a/firmware-src/sources/devices/ads1115.c +++ b/firmware-src/sources/devices/ads1115.c @@ -7,7 +7,6 @@ * */ #include "ads1115.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,12 +15,12 @@ static int mAddress = ADS1115_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float *values) { +DH_I2C_Status ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float *values) { char buf[3]; - DHI2C_STATUS status; + DH_I2C_Status status; int channel; if(sda != ADS1115_NO_PIN && scl != ADS1115_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("ads1115: failed to set up pins"); return status; } @@ -31,27 +30,27 @@ DHI2C_STATUS ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float *values) { buf[0] = 0x01; // Config register buf[1] = ((0b100 | channel) << 4) | 0x83; // single shot mode, +-4.096V, measure between input and gnd. buf[2] = 0x80; // 128 samples per second, comparator is disabled. - if((status = dhi2c_write(mAddress, buf, 3, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { dhdebug("ads1115: failed to write config"); return status; } do { - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("ads1115: failed to write get config"); return status; } - if((status = dhi2c_read(mAddress, &buf[1], 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, &buf[1], 2)) != DH_I2C_OK) { dhdebug("ads1115: failed to read config"); return status; } } while((buf[1] & 0x80) == 0); // while conversion is in progress buf[0] = 0x00; // get conversation register - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("ads1115: failed to write get conversation register"); return status; } - if((status = dhi2c_read(mAddress, &buf[1], 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, &buf[1], 2)) != DH_I2C_OK) { dhdebug("ads1115: failed to read coefficients"); return status; } @@ -59,7 +58,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float *values) { values++; } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR ads1115_set_address(int address) { diff --git a/firmware-src/sources/devices/ads1115.h b/firmware-src/sources/devices/ads1115.h index 16eef12..f1f3f9f 100644 --- a/firmware-src/sources/devices/ads1115.h +++ b/firmware-src/sources/devices/ads1115.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_ADS1115_H_ #define SOURCES_DEVICES_ADS1115_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define ADS1115_DEFAULT_ADDRESS 0x90 @@ -21,9 +21,9 @@ * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[out] values Pointer to four float values to store result in Volts. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS ads1115_read(int sda, int scl, float *values); +DH_I2C_Status ads1115_read(int sda, int scl, float *values); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/bh1750.c b/firmware-src/sources/devices/bh1750.c index df5f832..15ce521 100644 --- a/firmware-src/sources/devices/bh1750.c +++ b/firmware-src/sources/devices/bh1750.c @@ -7,7 +7,6 @@ * */ #include "bh1750.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,29 +15,29 @@ static int mAddress = BH1750_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR bh1750_read(int sda, int scl, float *illuminance) { +DH_I2C_Status ICACHE_FLASH_ATTR bh1750_read(int sda, int scl, float *illuminance) { char buf[2]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != BH1750_NO_PIN && scl != BH1750_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("bh1750: failed to set up pins"); return status; } } buf[0] = 0x21; // One Time High Resolution (0.5 lx) - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bh1750: failed to measure"); return status; } delay_ms(180); - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("bh1750: failed to read"); return status; } *illuminance = (float)unsignedInt16be(buf, 0) / 1.2f / 2.0f; - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR bh1750_set_address(int address) { diff --git a/firmware-src/sources/devices/bh1750.h b/firmware-src/sources/devices/bh1750.h index e39642d..dc07dbc 100644 --- a/firmware-src/sources/devices/bh1750.h +++ b/firmware-src/sources/devices/bh1750.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_BH1750_H_ #define SOURCES_DEVICES_BH1750_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define BH1750_DEFAULT_ADDRESS 0x46 @@ -21,9 +21,9 @@ * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[in] illuminance Illuminance in lux. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS bh1750_read(int sda, int scl, float *illuminance); +DH_I2C_Status bh1750_read(int sda, int scl, float *illuminance); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/bmp180.c b/firmware-src/sources/devices/bmp180.c index 230297f..b06d981 100644 --- a/firmware-src/sources/devices/bmp180.c +++ b/firmware-src/sources/devices/bmp180.c @@ -7,7 +7,7 @@ * */ #include "bmp180.h" -#include "dhi2c.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,23 +16,23 @@ static int mAddress = BMP180_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, float *temperature) { +DH_I2C_Status ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, float *temperature) { char buf[22]; unsigned int raw_temperature; unsigned int raw_pressure; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != BMP180_NO_PIN && scl != BMP180_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("bmp180: failed to set up pins"); return status; } } buf[0] = 0xAA; // get factory parameters - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp180: failed to write get coefficients command"); return status; } - if((status = dhi2c_read(mAddress, buf, sizeof(buf))) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, sizeof(buf))) != DH_I2C_OK) { dhdebug("bmp180: failed to read coefficients"); return status; } @@ -52,17 +52,17 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, floa buf[0] = 0xF4; // measure temperature buf[1] = 0x2E; - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp180: failed to stare measure temperature"); return status; } delay_ms(50); buf[0] = 0xF6; // get result - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp180: failed to write get temperature command"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("bmp180: failed to read temperature"); return status; } @@ -70,17 +70,17 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, floa buf[0] = 0xF4; // measure pressure buf[1] = 0x34; - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp180: failed to stare measure pressure"); return status; } delay_ms(50); buf[0] = 0xF6; // get result - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp180: failed to write get pressure command"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("bmp180: failed to read pressure"); return status; } @@ -112,7 +112,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, floa p = p + ((x1 + x2 + 3791) >> 4); *pressure = p; - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR bmp180_set_address(int address) { diff --git a/firmware-src/sources/devices/bmp180.h b/firmware-src/sources/devices/bmp180.h index 50d7332..4dd862f 100644 --- a/firmware-src/sources/devices/bmp180.h +++ b/firmware-src/sources/devices/bmp180.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_BMP180_H_ #define SOURCES_DEVICES_BMP180_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define BMP180_DEFAULT_ADDRESS 0xEE @@ -22,9 +22,9 @@ * \param[in] scl Pin for I2C's SCL. * \param[out] pressure Pointer for storing pressure result measure in Pascals. * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS bmp180_read(int sda, int scl, int *pressure, float *temperature); +DH_I2C_Status bmp180_read(int sda, int scl, int *pressure, float *temperature); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/bmp280.c b/firmware-src/sources/devices/bmp280.c index b9baf8e..e60cd00 100644 --- a/firmware-src/sources/devices/bmp280.c +++ b/firmware-src/sources/devices/bmp280.c @@ -8,7 +8,6 @@ */ #include "bmp280.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -17,21 +16,21 @@ static int mAddress = BMP280_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, float *temperature) { +DH_I2C_Status ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, float *temperature) { char buf[24]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != BMP280_NO_PIN && scl != BMP280_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("bmp280: failed to set up pins"); return status; } } buf[0] = 0x88; // get factory parameters - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp280: failed to write get coefficients command"); return status; } - if((status = dhi2c_read(mAddress, buf, sizeof(buf))) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, sizeof(buf))) != DH_I2C_OK) { dhdebug("bmp280: failed to read coefficients"); return status; } @@ -51,35 +50,35 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, fl // configure buf[0] = 0xF5; // config buf[1] = 0x0C; // filter coefficient 8, spi off, duration 0 - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to configure"); return status; } buf[0] = 0xF4; // control buf[1] = 0xB7; // both oversampling to x16, normal mode - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to configure"); return status; } do { // wait until data is ready buf[0] = 0xF3; // status - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp280: failed to get status"); return status; } - if((status = dhi2c_read(mAddress, buf, 1)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to read status"); return status; } } while(buf[0] & (1<<3)); buf[0] = 0xF7; // read press and temp result - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp280: failed to start reading"); return status; } - if((status = dhi2c_read(mAddress, buf, 6)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 6)) != DH_I2C_OK) { dhdebug("bmp280: failed to read"); return status; } @@ -104,7 +103,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, fl v1 = (P3 * v1 * v1 / 524288.0 + P2 * v1) / 524288.0; v1 = (1.0 + v1 / 32768.0) * P1; if(v1 == 0.0) { - return DHI2C_DEVICE_ERROR; + return DH_I2C_DEVICE_ERROR; } double p = 1048576.0 - raw_pressure; p = (p - v2 / 4096.0) * 6250.0 / v1; @@ -115,11 +114,11 @@ DHI2C_STATUS ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, fl buf[0] = 0xF4; // control buf[1] = 0x0; // sleep mode - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to shutdown"); return status; } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR bmp280_set_address(int address) { diff --git a/firmware-src/sources/devices/bmp280.h b/firmware-src/sources/devices/bmp280.h index c8b11be..71a67fe 100644 --- a/firmware-src/sources/devices/bmp280.h +++ b/firmware-src/sources/devices/bmp280.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_BMP280_H_ #define SOURCES_DEVICES_BMP280_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define BMP280_DEFAULT_ADDRESS 0xEC @@ -22,9 +22,9 @@ * \param[in] scl Pin for I2C's SCL. * \param[out] pressure Pointer for storing pressure result measure in Pascals. * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS bmp280_read(int sda, int scl, float *pressure, float *temperature); +DH_I2C_Status bmp280_read(int sda, int scl, float *pressure, float *temperature); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/hmc5883l.c b/firmware-src/sources/devices/hmc5883l.c index 7a44d47..846fc32 100644 --- a/firmware-src/sources/devices/hmc5883l.c +++ b/firmware-src/sources/devices/hmc5883l.c @@ -7,7 +7,6 @@ * */ #include "hmc5883l.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -18,12 +17,12 @@ static int mAddress = HMC5883L_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, +DH_I2C_Status ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass) { char buf[7]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != HMC5883L_NO_PIN && scl != HMC5883L_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to set up pins"); return status; } @@ -31,7 +30,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, buf[0] = 0x02; // mode register buf[1] = 1 << 0; // single run mode - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to power up"); return status; } @@ -39,11 +38,11 @@ DHI2C_STATUS ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, delay_ms(80); buf[0] = 0x03; // get data - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to set read register"); return status; } - if((status = dhi2c_read(mAddress, buf, 7)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 7)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to read"); return status; } @@ -55,7 +54,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, compass->X = (x == HMC5883l_OVERFLOWED_RAW) ? HMC5883l_OVERFLOWED : (x * 1.3f / 2048.0f); compass->Y = (y == HMC5883l_OVERFLOWED_RAW) ? HMC5883l_OVERFLOWED : (y * 1.3f / 2048.0f); compass->Z = (z == HMC5883l_OVERFLOWED_RAW) ? HMC5883l_OVERFLOWED : (z * 1.3f / 2048.0f); - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR hmc5883l_set_address(int address) { diff --git a/firmware-src/sources/devices/hmc5883l.h b/firmware-src/sources/devices/hmc5883l.h index 8fe1f4f..10659fe 100644 --- a/firmware-src/sources/devices/hmc5883l.h +++ b/firmware-src/sources/devices/hmc5883l.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_HMC5883L_H_ #define SOURCES_DEVICES_HMC5883L_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define HMC5883L_DEFAULT_ADDRESS 0x3C @@ -32,7 +32,7 @@ typedef struct { * \param[out] compass Compass data in normalized vector. If axis is overflowed during measure, HMC5883l_OVERFLOWED is a value. * \return NULL on success, text description on error. */ -DHI2C_STATUS hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass); +DH_I2C_Status hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/ina219.c b/firmware-src/sources/devices/ina219.c index 9c7a7bd..d10c956 100644 --- a/firmware-src/sources/devices/ina219.c +++ b/firmware-src/sources/devices/ina219.c @@ -7,7 +7,6 @@ * */ #include "ina219.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -18,11 +17,11 @@ static int mAddress = INA219_DEFAULT_ADDRESS; static float mResistance = 0.1f; -DHI2C_STATUS ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, float *current, float *power) { +DH_I2C_Status ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, float *current, float *power) { char buf[12]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != INA219_NO_PIN && scl != INA219_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("ina219: failed to set up pins"); return status; } @@ -32,7 +31,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, flo buf[0] = 0x05; buf[1] = ((cal >> 8) & 0xFF); buf[2] = (cal & 0xFF); - if((status = dhi2c_write(mAddress, buf, 3, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { dhdebug("ina219: failed to write calibration data"); return status; } @@ -41,11 +40,11 @@ DHI2C_STATUS ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, flo char i; for(i = 1; i < 5; i++) { - if((status = dhi2c_write(mAddress, &i, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, &i, 1, 0)) != DH_I2C_OK) { dhdebug("ina219: failed to write address"); return status; } - if((status = dhi2c_read(mAddress, &buf[i * 2], 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, &buf[i * 2], 2)) != DH_I2C_OK) { dhdebug("ina219: failed to read data"); return status; } @@ -55,16 +54,16 @@ DHI2C_STATUS ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, flo *current = ((float)signedInt16be(buf, 8)) / 100000.0f; *power = ((float)unsignedInt16be(buf, 6)) / 100000.0f * 20.0f; - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR ina219_set_address(int address) { mAddress = address; } -DHI2C_STATUS ICACHE_FLASH_ATTR ina219_set_shunt(float resistance) { +DH_I2C_Status ICACHE_FLASH_ATTR ina219_set_shunt(float resistance) { if(mResistance <= 0.0f) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; mResistance = resistance; - return DHI2C_OK; + return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/ina219.h b/firmware-src/sources/devices/ina219.h index 2dbb264..c210a83 100644 --- a/firmware-src/sources/devices/ina219.h +++ b/firmware-src/sources/devices/ina219.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_INA219_H_ #define SOURCES_DEVICES_INA219_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define INA219_DEFAULT_ADDRESS 0x80 @@ -23,9 +23,9 @@ * \param[out] voltage Input voltage in Volts. * \param[out] current Current in Amperes. * \param[out] power Total power since first call. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS ina219_read(int sda, int scl, float *voltage, float *current, float *power); +DH_I2C_Status ina219_read(int sda, int scl, float *voltage, float *current, float *power); /** * \brief Set sensor address which should be used while reading. @@ -37,8 +37,8 @@ void ina219_set_address(int address); * \brief Set reference shunt resistance. * \note Default is 0.1 Ohm. * \param[in] resistance Resistance in Ohms. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS ina219_set_shunt(float resistance); +DH_I2C_Status ina219_set_shunt(float resistance); #endif /* SOURCES_DEVICES_INA219_H_ */ diff --git a/firmware-src/sources/devices/lm75.c b/firmware-src/sources/devices/lm75.c index acdba22..3b25371 100644 --- a/firmware-src/sources/devices/lm75.c +++ b/firmware-src/sources/devices/lm75.c @@ -7,7 +7,6 @@ * */ #include "lm75.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,30 +15,30 @@ static int mAddress = LM75_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR lm75_read(int sda, int scl, float *temperature) { +DH_I2C_Status ICACHE_FLASH_ATTR lm75_read(int sda, int scl, float *temperature) { char buf[2]; int raw_temperature; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != LM75_NO_PIN && scl != LM75_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("lm75: failed to set up pins"); return status; } } buf[0] = 0x0; // get temperature - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("lm75: failed to write get temperature command"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("lm75: failed to read temperature"); return status; } raw_temperature = signedInt16be(buf, 0); *temperature = (float)raw_temperature / 256.0f; - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR lm75_set_address(int address) { diff --git a/firmware-src/sources/devices/lm75.h b/firmware-src/sources/devices/lm75.h index f1e83ff..fcd217b 100644 --- a/firmware-src/sources/devices/lm75.h +++ b/firmware-src/sources/devices/lm75.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_LM75_H_ #define SOURCES_DEVICES_LM75_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define LM75_DEFAULT_ADDRESS 0x90 @@ -21,9 +21,9 @@ * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[out] temperature Pointer for storing temperature result measure in Celsius. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS lm75_read(int sda, int scl, float *temperature); +DH_I2C_Status lm75_read(int sda, int scl, float *temperature); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/mcp4725.c b/firmware-src/sources/devices/mcp4725.c index ac3c00f..9215b21 100644 --- a/firmware-src/sources/devices/mcp4725.c +++ b/firmware-src/sources/devices/mcp4725.c @@ -7,7 +7,6 @@ * */ #include "mcp4725.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -17,13 +16,13 @@ static int mAddress = MCP4725_DEFAULT_ADDRESS; static float mVoltage = 3.3f; -DHI2C_STATUS ICACHE_FLASH_ATTR mcp4725_write(int sda, int scl, float value) { +DH_I2C_Status ICACHE_FLASH_ATTR mcp4725_write(int sda, int scl, float value) { char buf[3]; - DHI2C_STATUS status; + DH_I2C_Status status; if(value < 0.0f || value > mVoltage) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; if(sda != MCP4725_NO_PIN && scl != MCP4725_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("mcp4725: failed to set up pins"); return status; } @@ -34,20 +33,20 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mcp4725_write(int sda, int scl, float value) { buf[0] = 0x40; // Config(write DAC register) buf[1] = ((v >> 4) & 0xFF); buf[2] = ((v & 0xF) << 4); // LSB bits - if((status = dhi2c_write(mAddress, buf, 3, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { dhdebug("mcp4725: failed to write"); return status; } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR mcp4725_set_address(int address) { mAddress = address; } -DHI2C_STATUS ICACHE_FLASH_ATTR mcp4725_set_vref(float voltage) { +DH_I2C_Status ICACHE_FLASH_ATTR mcp4725_set_vref(float voltage) { if(mVoltage <= 0.0f) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; mVoltage = voltage; - return DHI2C_OK; + return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/mcp4725.h b/firmware-src/sources/devices/mcp4725.h index ed6e1d9..ffd9139 100644 --- a/firmware-src/sources/devices/mcp4725.h +++ b/firmware-src/sources/devices/mcp4725.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_MCP4725_H_ #define SOURCES_DEVICES_MCP4725_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define MCP4725_DEFAULT_ADDRESS 0xC0 @@ -21,9 +21,9 @@ * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[out] value Voltage in Volts. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS mcp4725_write(int sda, int scl, float value); +DH_I2C_Status mcp4725_write(int sda, int scl, float value); /** * \brief Set sensor address which should be used while reading. @@ -35,8 +35,8 @@ void mcp4725_set_address(int address); * \brief Set reference voltage in volts. * \note Default is 3.3V. * \param[in] voltage Voltage in Volts. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS mcp4725_set_vref(float voltage); +DH_I2C_Status mcp4725_set_vref(float voltage); #endif /* SOURCES_DEVICES_MCP4725_H_ */ diff --git a/firmware-src/sources/devices/mlx90614.c b/firmware-src/sources/devices/mlx90614.c index 05184df..a0fc451 100644 --- a/firmware-src/sources/devices/mlx90614.c +++ b/firmware-src/sources/devices/mlx90614.c @@ -7,7 +7,6 @@ * */ #include "mlx90614.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,23 +15,23 @@ static int mAddress = MLX90614_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, float *object) { +DH_I2C_Status ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, float *object) { char buf[2]; - DHI2C_STATUS status; + DH_I2C_Status status; int raw_temperature; if(sda != MLX90614_NO_PIN && scl != MLX90614_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("mlx90614: failed to set up pins"); return status; } } buf[0] = 0x06; // Ta register - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("mlx90614: failed to get Ta register"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("mlx90614: failed to read Ta"); return status; } @@ -40,17 +39,17 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, f *ambient = raw_temperature * 0.02f - 273.15f; buf[0] = 0x07; // Tobj1 register - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("mlx90614: failed to get Tobj1 register"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("mlx90614: failed to read Tobj1"); return status; } raw_temperature = signedInt16le(buf, 0); *object = raw_temperature * 0.02f - 273.15f; - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR mlx90614_set_address(int address) { diff --git a/firmware-src/sources/devices/mlx90614.h b/firmware-src/sources/devices/mlx90614.h index b2c62e5..f637443 100644 --- a/firmware-src/sources/devices/mlx90614.h +++ b/firmware-src/sources/devices/mlx90614.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_MLX90614_H_ #define SOURCES_DEVICES_MLX90614_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define MLX90614_DEFAULT_ADDRESS 0xB4 @@ -22,9 +22,9 @@ * \param[in] scl Pin for I2C's SCL. * \param[out] ambient Pointer for storing ambient temperature result measure in Celsius. * \param[out] object Pointer for storing object temperature result measure in Celsius. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS mlx90614_read(int sda, int scl, float *ambient, float *object); +DH_I2C_Status mlx90614_read(int sda, int scl, float *ambient, float *object); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/mpu6050.c b/firmware-src/sources/devices/mpu6050.c index 00ada01..43a7e48 100644 --- a/firmware-src/sources/devices/mpu6050.c +++ b/firmware-src/sources/devices/mpu6050.c @@ -7,7 +7,6 @@ * */ #include "mpu6050.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -17,13 +16,13 @@ static int mAddress = MPU6050_DEFAULT_ADDRESS; #define EARTH_GRAVITY_ACCELERATION 9.80665f -DHI2C_STATUS ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, +DH_I2C_Status ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature) { char buf[16]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != MPU6050_NO_PIN && scl != MPU6050_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("mpu6050: failed to set up pins"); return status; } @@ -31,21 +30,21 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, buf[0] = 0x6B; // power up buf[1] = 0; // no sleep bit - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to power up"); return status; } buf[0] = 0x1C; // accelerometer configuration buf[1] = (1 << 4); // AFS_SEL = 2, range +-8 g - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to configure accelerometer"); return status; } buf[0] = 0x1B; // gyroscope configuration buf[1] = (1 << 4); // FS_SEL = 2, range +-1000 dps - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to configure gyroscope"); return status; } @@ -53,18 +52,18 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, delay_ms(50); buf[0] = 0x3B; // get data - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("mpu6050: failed to set read register"); return status; } - if((status = dhi2c_read(mAddress, buf, 14)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 14)) != DH_I2C_OK) { dhdebug("mpu6050: failed to read"); return status; } buf[14] = 0x6B; // power down buf[15] = 1 << 6; // sleep bit - if((status = dhi2c_write(mAddress, &buf[14], 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, &buf[14], 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to power up"); return status; } @@ -83,7 +82,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, if(temparature) *temparature = signedInt16be(buf, 6) / 340.0f + 36.53f; - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR mpu6050_set_address(int address) { diff --git a/firmware-src/sources/devices/mpu6050.h b/firmware-src/sources/devices/mpu6050.h index 2e0d8fa..511f1fd 100644 --- a/firmware-src/sources/devices/mpu6050.h +++ b/firmware-src/sources/devices/mpu6050.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_MPU6050_H_ #define SOURCES_DEVICES_MPU6050_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define MPU6050_DEFAULT_ADDRESS 0xD0 @@ -32,7 +32,7 @@ typedef struct { * \param[out] temparature Gyroscope data in degree per second. Can be NULL. * \return NULL on success, text description on error. */ -DHI2C_STATUS mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature); +DH_I2C_Status mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/pca9685.c b/firmware-src/sources/devices/pca9685.c index 08d51e6..67a8d17 100644 --- a/firmware-src/sources/devices/pca9685.c +++ b/firmware-src/sources/devices/pca9685.c @@ -7,7 +7,6 @@ * */ #include "pca9685.h" -#include "dhi2c.h" #include "DH/gpio.h" #include "dhdebug.h" #include "dhutils.h" @@ -17,22 +16,22 @@ static int mAddress = PCA9685_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus) { +DH_I2C_Status ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus) { char buf[5]; - DHI2C_STATUS status; + DH_I2C_Status status; unsigned int i; for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { if(pinsmask & DH_GPIO_PIN(i)) { if(pinsduty[i] > 100.0f || pinsduty[i] < 0.0f) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; } } if(periodus != PCA9685_NO_PERIOD && (periodus > 41667 || periodus < 655)) // hardware limits - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; if(sda != PCA9685_NO_PIN && scl != PCA9685_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pca9685: failed to set up pins"); return status; } @@ -43,22 +42,22 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty pb[0] = 0xFE; // Prescaler pb[1] = ((25 * periodus) / 4096.0f) - 0.5f; // value buf[0] = 0xFE; // Prescaler - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("pca9685: failed to choose prescaler"); return status; } - if((status = dhi2c_read(mAddress, buf, 1)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed read prescaler"); return status; } if(pb[1] != buf[0]) { buf[0] = 0x00; // MODE1 buf[1] = 0x31; // turn off oscillator, prescaler can be changed only then - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to shutdown"); return status; } - if((status = dhi2c_write(mAddress, pb, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, pb, 2, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to set up frequency"); return status; } @@ -67,7 +66,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty buf[0] = 0x00; // MODE1 buf[1] = 0x21; // allow auto increment, turn on oscillator - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to init"); return status; } @@ -79,14 +78,14 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty if(pinsmask & DH_GPIO_PIN(i)) { *v = pinsduty[i] * 40.95f; buf[0] = 0x06 + 4 * i; - if((status = dhi2c_write(mAddress, buf, 5, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 5, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to write"); return status; } } } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR pca9685_set_address(int address) { diff --git a/firmware-src/sources/devices/pca9685.h b/firmware-src/sources/devices/pca9685.h index 5621ef6..6b3d7e2 100644 --- a/firmware-src/sources/devices/pca9685.h +++ b/firmware-src/sources/devices/pca9685.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_PCA9685_H_ #define SOURCES_DEVICES_PCA9685_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default i2c address*/ #define PCA9685_DEFAULT_ADDRESS 0x80 @@ -27,9 +27,9 @@ * \param[in] pinsduty Array with pins duty cycles for each pin. * \param[in] pinsmask Bitwise pins mask with pins that should be enabled, this pins have to have correct value in pinsduty array. * \param[in] periodus PWM period. Can be PCA9685_NO_PERIOD to use current. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus); +DH_I2C_Status pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/pcf8574.c b/firmware-src/sources/devices/pcf8574.c index 0c4e34d..a265538 100644 --- a/firmware-src/sources/devices/pcf8574.c +++ b/firmware-src/sources/devices/pcf8574.c @@ -7,7 +7,6 @@ * */ #include "pcf8574.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,56 +15,56 @@ static int mAddress = PCF8574_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_read(int sda, int scl, unsigned int *pins) { +DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_read(int sda, int scl, unsigned int *pins) { char buf; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != PCF8574_NO_PIN && scl != PCF8574_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8574: failed to set up pins"); return status; } } - if((status = dhi2c_read(mAddress, &buf, 1)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, &buf, 1)) != DH_I2C_OK) { dhdebug("pcf8574: failed to read"); return status; } *pins = (unsigned char)buf; - return DHI2C_OK; + return DH_I2C_OK; } -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear) { +DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear) { char buf; - DHI2C_STATUS status; + DH_I2C_Status status; unsigned int current_state; if(pins_to_set & pins_to_clear) - return DHI2C_WRONG_PARAMETERS; - if((status = pcf8574_read(sda, scl, ¤t_state)) != DHI2C_OK) { + return DH_I2C_WRONG_PARAMETERS; + if((status = pcf8574_read(sda, scl, ¤t_state)) != DH_I2C_OK) { return status; } buf = (char)((current_state | pins_to_set) & (~pins_to_clear) & PCF8574_SUITABLE_PINS); - if((status = dhi2c_write(mAddress, &buf, 1, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, &buf, 1, 1)) != DH_I2C_OK) { dhdebug("pcf8574: failed to write"); return status; } - return DHI2C_OK; + return DH_I2C_OK; } -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_set(int sda, int scl, unsigned int pins) { +DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_set(int sda, int scl, unsigned int pins) { char buf; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != PCF8574_NO_PIN && scl != PCF8574_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8574: failed to set up pins"); return status; } } buf = pins & PCF8574_SUITABLE_PINS; - if((status = dhi2c_write(mAddress, &buf, 1, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, &buf, 1, 1)) != DH_I2C_OK) { dhdebug("pcf8574: failed to write"); return status; } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR pcf8574_set_address(int address) { diff --git a/firmware-src/sources/devices/pcf8574.h b/firmware-src/sources/devices/pcf8574.h index c945b5d..98b6a05 100644 --- a/firmware-src/sources/devices/pcf8574.h +++ b/firmware-src/sources/devices/pcf8574.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_PCF8574_H_ #define SOURCES_DEVICES_PCF8574_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define PCF8574_DEFAULT_ADDRESS 0x4E @@ -23,9 +23,9 @@ * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[out] pins Pointer where pin mask will be stored. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pcf8574_read(int sda, int scl, unsigned int *pins); +DH_I2C_Status pcf8574_read(int sda, int scl, unsigned int *pins); /** * \brief Write data on extender pins. @@ -33,18 +33,18 @@ DHI2C_STATUS pcf8574_read(int sda, int scl, unsigned int *pins); * \param[in] scl Pin for I2C's SCL. * \param[in] pins_to_set Pin mask to set up high level. * \param[in] pins_to_clear Pin mask to set up low level. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear); +DH_I2C_Status pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear); /** * \brief Set all pins. * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[in] pins Pin mask of pins state. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pcf8574_set(int sda, int scl, unsigned int pins); +DH_I2C_Status pcf8574_set(int sda, int scl, unsigned int pins); /** * \brief Set extender address which should be used while reading. diff --git a/firmware-src/sources/devices/pcf8574_hd44780.c b/firmware-src/sources/devices/pcf8574_hd44780.c index 3a4c0ff..88a0842 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.c +++ b/firmware-src/sources/devices/pcf8574_hd44780.c @@ -22,64 +22,64 @@ #define PIN_D6 (1 << 6) #define PIN_D7 (1 << 7) -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_write_half(int sda, +LOCAL DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write_half(int sda, int scl, char half, int is_command) { - DHI2C_STATUS status; + DH_I2C_Status status; char pins = ((half & (1 << 3)) ? PIN_D7 : 0) | ((half & (1 << 2)) ? PIN_D6 : 0) | ((half & (1 << 1)) ? PIN_D5 : 0) | ((half & (1 << 0)) ? PIN_D4 : 0); pins |= PIN_BACKLIGHT | (is_command ? 0 : PIN_RS); // set enable HIGH - if((status = pcf8574_set(sda, scl, pins | PIN_E)) != DHI2C_OK) + if((status = pcf8574_set(sda, scl, pins | PIN_E)) != DH_I2C_OK) return status; os_delay_us(1); // set enable to LOW - if((status = pcf8574_set(sda, scl, pins)) != DHI2C_OK) + if((status = pcf8574_set(sda, scl, pins)) != DH_I2C_OK) return status; - return DHI2C_OK; + return DH_I2C_OK; } -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_write_byte(int sda, +LOCAL DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write_byte(int sda, int scl, char byte, int is_command) { - DHI2C_STATUS status; - if((status = pcf8574_hd44780_write_half(sda, scl, (byte >> 4) & 0x0F, is_command)) != DHI2C_OK) + DH_I2C_Status status; + if((status = pcf8574_hd44780_write_half(sda, scl, (byte >> 4) & 0x0F, is_command)) != DH_I2C_OK) return status; - if((status = pcf8574_hd44780_write_half(sda, scl, byte & 0x0F, is_command)) != DHI2C_OK) + if((status = pcf8574_hd44780_write_half(sda, scl, byte & 0x0F, is_command)) != DH_I2C_OK) return status; - return DHI2C_OK; + return DH_I2C_OK; } -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_set_line(int sda, +LOCAL DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_set_line(int sda, int scl, unsigned int line) { - DHI2C_STATUS status; + DH_I2C_Status status; switch (line) { case 0: if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x14, 1)) - != DHI2C_OK) + != DH_I2C_OK) return status; break; case 1: if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x40, 1)) - != DHI2C_OK) + != DH_I2C_OK) return status; break; case 2: if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x14, 1)) - != DHI2C_OK) + != DH_I2C_OK) return status; break; case 3: if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x54, 1)) - != DHI2C_OK) + != DH_I2C_OK) return status; break; default: break; } - return DHI2C_OK; + return DH_I2C_OK; } -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const char *text, unsigned int len) { - DHI2C_STATUS status; +DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const char *text, unsigned int len) { + DH_I2C_Status status; int i; const static char init_data[] = { 0b00101100, // function set @@ -89,22 +89,22 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const cha }; // clear enable - if((status = pcf8574_set(sda, scl, ~((char)(PIN_E | PIN_RW)))) != DHI2C_OK) + if((status = pcf8574_set(sda, scl, ~((char)(PIN_E | PIN_RW)))) != DH_I2C_OK) return status; // initialization for(i = 0; i < 3; i++) { - if((status = pcf8574_hd44780_write_half(sda, scl, 0b0011, 1)) != DHI2C_OK) + if((status = pcf8574_hd44780_write_half(sda, scl, 0b0011, 1)) != DH_I2C_OK) return status; os_delay_us(5000); } - if((status = pcf8574_hd44780_write_half(sda, scl, 0b0010, 1)) != DHI2C_OK) + if((status = pcf8574_hd44780_write_half(sda, scl, 0b0010, 1)) != DH_I2C_OK) return status; os_delay_us(100); // configure for(i = 0; i < sizeof(init_data); i++) { - if((status = pcf8574_hd44780_write_byte(sda, scl, init_data[i], 1)) != DHI2C_OK) + if((status = pcf8574_hd44780_write_byte(sda, scl, init_data[i], 1)) != DH_I2C_OK) return status; os_delay_us(2000); } @@ -121,7 +121,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const cha line++; if(line > 3) break; - if((status = pcf8574_hd44780_set_line(sda, scl, line)) != DHI2C_OK) + if((status = pcf8574_hd44780_set_line(sda, scl, line)) != DH_I2C_OK) return status; ch = 0; if(nlc) @@ -129,10 +129,10 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const cha if(nla || nlc) continue; } - if((status = pcf8574_hd44780_write_byte(sda, scl, text[i], 0)) != DHI2C_OK) + if((status = pcf8574_hd44780_write_byte(sda, scl, text[i], 0)) != DH_I2C_OK) return status; ch++; } - return DHI2C_OK; + return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/pcf8574_hd44780.h b/firmware-src/sources/devices/pcf8574_hd44780.h index 2dd2322..a29f8cd 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.h +++ b/firmware-src/sources/devices/pcf8574_hd44780.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_PCF8574_HD44780_H_ #define SOURCES_DEVICES_PCF8574_HD44780_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** * \brief Set text on screen. @@ -20,6 +20,6 @@ * \param[in] len Number of chars to write. Data more then 80 bytes is ignored. * \return NULL on success, text description on error. */ -DHI2C_STATUS pcf8574_hd44780_write(int sda, int scl, const char *text, unsigned int len); +DH_I2C_Status pcf8574_hd44780_write(int sda, int scl, const char *text, unsigned int len); #endif /* SOURCES_DEVICES_PCF8574_HD44780_H_ */ diff --git a/firmware-src/sources/devices/pcf8591.c b/firmware-src/sources/devices/pcf8591.c index 596bcd3..41a0325 100644 --- a/firmware-src/sources/devices/pcf8591.c +++ b/firmware-src/sources/devices/pcf8591.c @@ -7,7 +7,6 @@ * */ #include "pcf8591.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -18,29 +17,29 @@ static int mAddress = PCF8591_DEFAULT_ADDRESS; static float mVoltage = 3.3f; -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8591_read(int sda, int scl, float *values) { +DH_I2C_Status ICACHE_FLASH_ATTR pcf8591_read(int sda, int scl, float *values) { char buf[4]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != PCF8591_NO_PIN && scl != PCF8591_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8591: failed to set up pins"); return status; } } buf[0] = 0x45; // Config - if((status = dhi2c_write(mAddress, buf, 1, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 1)) != DH_I2C_OK) { dhdebug("pcf8591: failed to write"); return status; } //dummy read to make sure all values was updated - if((status = dhi2c_read(mAddress, buf, 4)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 4)) != DH_I2C_OK) { dhdebug("pcf8591: failed to write"); return status; } os_delay_us(250); - if((status = dhi2c_read(mAddress, buf, 4)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 4)) != DH_I2C_OK) { dhdebug("pcf8591: failed to write"); return status; } @@ -48,16 +47,16 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pcf8591_read(int sda, int scl, float *values) { for(i = 0; i < sizeof(buf); i++) { values[i] = mVoltage * ((float)buf[i]) / 255.0f; } - return DHI2C_OK; + return DH_I2C_OK; } -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8591_write(int sda, int scl, float value) { +DH_I2C_Status ICACHE_FLASH_ATTR pcf8591_write(int sda, int scl, float value) { char buf[3]; - DHI2C_STATUS status; + DH_I2C_Status status; if(value < 0.0f || value > mVoltage) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; if(sda != PCF8591_NO_PIN && scl != PCF8591_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8591: failed to set up pins"); return status; } @@ -67,20 +66,20 @@ DHI2C_STATUS ICACHE_FLASH_ATTR pcf8591_write(int sda, int scl, float value) { buf[0] = 0x44; // Config buf[1] = v; - if((status = dhi2c_write(mAddress, buf, 2, 1)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("pcf8591: failed to write"); return status; } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR pcf8591_set_address(int address) { mAddress = address; } -DHI2C_STATUS ICACHE_FLASH_ATTR pcf8591_set_vref(float voltage) { +DH_I2C_Status ICACHE_FLASH_ATTR pcf8591_set_vref(float voltage) { if(mVoltage <= 0.0f) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; mVoltage = voltage; - return DHI2C_OK; + return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/pcf8591.h b/firmware-src/sources/devices/pcf8591.h index 752235b..51be4b9 100644 --- a/firmware-src/sources/devices/pcf8591.h +++ b/firmware-src/sources/devices/pcf8591.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_PCF8591_H_ #define SOURCES_DEVICES_PCF8591_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define PCF8591_DEFAULT_ADDRESS 0x90 @@ -21,18 +21,18 @@ * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[out] values Pointer to four float values to store result in Volts. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pcf8591_read(int sda, int scl, float *values); +DH_I2C_Status pcf8591_read(int sda, int scl, float *values); /** * \brief Set DAC voltages. * \param[in] sda Pin for I2C's SDA. * \param[in] scl Pin for I2C's SCL. * \param[out] value Voltage in Volts. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pcf8591_write(int sda, int scl, float value); +DH_I2C_Status pcf8591_write(int sda, int scl, float value); /** * \brief Set sensor address which should be used while reading. @@ -44,8 +44,8 @@ void pcf8591_set_address(int address); * \brief Set reference voltage in volts. * \note Default is 3.3V. * \param[in] voltage Voltage in Volts. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS pcf8591_set_vref(float voltage); +DH_I2C_Status pcf8591_set_vref(float voltage); #endif /* SOURCES_DEVICES_PCF8591_H_ */ diff --git a/firmware-src/sources/devices/si7021.c b/firmware-src/sources/devices/si7021.c index 7ce0830..821046e 100644 --- a/firmware-src/sources/devices/si7021.c +++ b/firmware-src/sources/devices/si7021.c @@ -7,7 +7,6 @@ * */ #include "si7021.h" -#include "dhi2c.h" #include "dhdebug.h" #include "dhutils.h" @@ -16,22 +15,22 @@ static int mAddress = SI7021_DEFAULT_ADDRESS; -DHI2C_STATUS ICACHE_FLASH_ATTR si7021_read(int sda, int scl, float *humidity, float *temperature) { +DH_I2C_Status ICACHE_FLASH_ATTR si7021_read(int sda, int scl, float *humidity, float *temperature) { char buf[2]; - DHI2C_STATUS status; + DH_I2C_Status status; if(sda != SI7021_NO_PIN && scl != SI7021_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("si7021: failed to set up pins"); return status; } } buf[0] = 0xE5; // read humidity, hold master - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("si7021: failed to write get humidity"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("si7021: failed to read humidity"); return status; } @@ -39,18 +38,18 @@ DHI2C_STATUS ICACHE_FLASH_ATTR si7021_read(int sda, int scl, float *humidity, fl if(temperature) { buf[0] = 0xE0; // read temperature from humidity measurement - if((status = dhi2c_write(mAddress, buf, 1, 0)) != DHI2C_OK) { + if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("si7021: failed to write get temperature"); return status; } - if((status = dhi2c_read(mAddress, buf, 2)) != DHI2C_OK) { + if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("si7021: failed to read temperature"); return status; } *temperature = ((float)unsignedInt16be(buf, 0)) * 175.72f / 65536.0f - 46.85f; } - return DHI2C_OK; + return DH_I2C_OK; } void ICACHE_FLASH_ATTR si7021_set_address(int address) { diff --git a/firmware-src/sources/devices/si7021.h b/firmware-src/sources/devices/si7021.h index b9c50af..1c0a7fc 100644 --- a/firmware-src/sources/devices/si7021.h +++ b/firmware-src/sources/devices/si7021.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_SI7021_H_ #define SOURCES_DEVICES_SI7021_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Default sensor i2c address*/ #define SI7021_DEFAULT_ADDRESS 0x80 @@ -22,9 +22,9 @@ * \param[in] scl Pin for I2C's SCL. * \param[out] humidity Pointer for storing relative humidity result measure in percents. * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return Status value, one of DHI2C_STATUS enum. + * \return Status value, one of DH_I2C_Status enum. */ -DHI2C_STATUS si7021_read(int sda, int scl, float *humidity, float *temperature); +DH_I2C_Status si7021_read(int sda, int scl, float *humidity, float *temperature); /** * \brief Set sensor address which should be used while reading. diff --git a/firmware-src/sources/devices/tm1636.h b/firmware-src/sources/devices/tm1636.h index c380de0..608e4c9 100644 --- a/firmware-src/sources/devices/tm1636.h +++ b/firmware-src/sources/devices/tm1636.h @@ -9,7 +9,7 @@ #ifndef SOURCES_DEVICES_TM1636_H_ #define SOURCES_DEVICES_TM1636_H_ -#include "dhi2c.h" +#include "DH/i2c.h" /** Do not initialize pin */ #define TM1636_NO_PIN -1 @@ -23,6 +23,6 @@ * \param[in] len Number of chars to write. * \return NULL on success, text description on error. */ -DHI2C_STATUS tm1636_write(int sda, int scl, const char *text, unsigned int len); +DH_I2C_Status tm1636_write(int sda, int scl, const char *text, unsigned int len); #endif /* SOURCES_DEVICES_TM1636_H_ */ diff --git a/firmware-src/sources/devices/tm1637.c b/firmware-src/sources/devices/tm1637.c index 2ecb67c..ac49fbc 100644 --- a/firmware-src/sources/devices/tm1637.c +++ b/firmware-src/sources/devices/tm1637.c @@ -28,9 +28,9 @@ RO_DATA const unsigned char segments_table[] = { 0b11110110 // 9 }; -DHI2C_STATUS ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, unsigned int len) { +DH_I2C_Status ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, unsigned int len) { int i, j; - DHI2C_STATUS status; + DH_I2C_Status status; char v; char buf[6]; @@ -38,7 +38,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, os_memset(buf, 0, sizeof(buf)); for(i = 0, j = 0; i < len; i++) { if(j >= sizeof(buf)) - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; if(text[i] >= 0x30 && text[i] <= 0x39) { v = irom_char(&segments_table[text[i] - 0x30]); } else if(text[i] == ' ') { @@ -46,7 +46,7 @@ DHI2C_STATUS ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, } else if(text[i] == '-') { v = 0b00000010; } else { - return DHI2C_WRONG_PARAMETERS; + return DH_I2C_WRONG_PARAMETERS; } if((i + 1) < len) { if((text[i + 1] == ':' || text[i + 1] == '.')) { @@ -60,32 +60,32 @@ DHI2C_STATUS ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, // init pins if(sda != TM1636_NO_PIN && scl != TM1636_NO_PIN) { - if((status = dhi2c_init(sda, scl)) != DHI2C_OK) { + if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("tm1636: failed to set up pins"); return status; } } // write data to display register command - status = dhi2c_write(bitwise_reverse_byte(0x40), NULL, 0 , 1); - if(status != DHI2C_OK) { + status = dh_i2c_write(bitwise_reverse_byte(0x40), NULL, 0 , 1); + if(status != DH_I2C_OK) { dhdebug("tm1636: failed to init"); return status; } // write segments - status = dhi2c_write(bitwise_reverse_byte(0xC0), buf, sizeof(buf), 1); - if(status != DHI2C_OK) { + status = dh_i2c_write(bitwise_reverse_byte(0xC0), buf, sizeof(buf), 1); + if(status != DH_I2C_OK) { dhdebug("tm1636: failed to write segments"); return status; } // control display, max brightness - status = dhi2c_read(bitwise_reverse_byte(0x8F), NULL, 0); - if(status != DHI2C_OK) { + status = dh_i2c_read(bitwise_reverse_byte(0x8F), NULL, 0); + if(status != DH_I2C_OK) { dhdebug("tm1636: failed to control"); return status; } - return DHI2C_OK; + return DH_I2C_OK; } diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 8d32b05..e841fd8 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -14,11 +14,11 @@ #include "DH/adc.h" #include "DH/uart.h" #include "DH/spi.h" +#include "DH/i2c.h" #include "dhnotification.h" #include "snprintf.h" #include "dhcommand_parser.h" #include "dhterminal.h" -#include "dhi2c.h" #include "dhonewire.h" #include "dhdebug.h" #include "DH/pwm.h" @@ -62,114 +62,6 @@ LOCAL int ICACHE_FLASH_ATTR onewire_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fiel return 0; } -LOCAL char *ICACHE_FLASH_ATTR i2c_status_tochar(DHI2C_STATUS status) { - switch(status) { - case DHI2C_NOACK: - return "ACK response not detected"; - case DHI2C_WRONG_PARAMETERS: - return "Wrong parameters"; - case DHI2C_BUS_BUSY: - return "Bus is busy"; - case DHI2C_DEVICE_ERROR: - return "Device error"; - case DHI2C_OK: - break; - } - return 0; -} - -LOCAL int ICACHE_FLASH_ATTR i2c_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { - if((fields & AF_ADDRESS) == 0) { - dh_command_fail(cb, "Address not specified"); - return 1; - } - int init = ((fields & AF_SDA) ? 1 : 0) + ((fields & AF_SCL) ? 1 : 0); - if(init == 2) { - char *res = i2c_status_tochar(dhi2c_init(parse_pins->SDA, parse_pins->SCL)); - if (res != 0) { - dh_command_fail(cb, res); - return 1; - } - } else if(init == 1) { - dh_command_fail(cb, "Only one pin specified"); - return 1; - } else { - dhi2c_reinit(); - } - return 0; -} - -#if 1 // I2C commands - -/** - * @brief Do "i2c/master/read" command. - */ -static void ICACHE_FLASH_ATTR do_i2c_master_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & AF_COUNT) == 0) - parse_pins.count = 2; - if(parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - dh_command_fail(cb, "Wrong read size"); - return; - } - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res; - if(fields & AF_DATA) { - res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 0)); - if(res) { - dh_command_fail(cb, res); - return; - } - } - res = i2c_status_tochar(dhi2c_read(parse_pins.address, parse_pins.data, parse_pins.count)); - if(res) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); - } -} - - -/** - * @brief Do "i2c/master/write" command. - */ -static void ICACHE_FLASH_ATTR do_i2c_master_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); - if(parse_res) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & AF_DATA) == 0) { - dh_command_fail(cb, "Data not specified"); - return; - } - if(i2c_init(cb, fields, &parse_pins)) - return; - char *res = i2c_status_tochar(dhi2c_write(parse_pins.address, parse_pins.data, parse_pins.data_len, 1)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - -#endif // I2C commands - #if 1 // onewire commands /** @@ -201,7 +93,7 @@ static void ICACHE_FLASH_ATTR do_onewire_master_read(COMMAND_RESULT *cb, const c return; } dhonewire_read(parse_pins.data, parse_pins.count); - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); + dh_command_done_buf(cb, parse_pins.data, parse_pins.count); } @@ -293,7 +185,7 @@ static void ICACHE_FLASH_ATTR do_onewire_dht_read(COMMAND_RESULT *cb, const char } parse_pins.count = dhonewire_dht_read(parse_pins.data, sizeof(parse_pins.data)); if(parse_pins.count) - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); + dh_command_done_buf(cb, parse_pins.data, parse_pins.count); else dh_command_fail(cb, "No response"); } @@ -429,11 +321,11 @@ static void ICACHE_FLASH_ATTR do_devices_bmp180_read(COMMAND_RESULT *cb, const c bmp180_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float temperature; int pressure; - char *res = i2c_status_tochar(bmp180_read(BMP180_NO_PIN, BMP180_NO_PIN, &pressure, &temperature)); + const char *res = dh_i2c_error_string(bmp180_read(BMP180_NO_PIN, BMP180_NO_PIN, &pressure, &temperature)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -460,11 +352,11 @@ static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const c bmp280_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float temperature; float pressure; - char *res = i2c_status_tochar(bmp280_read(BMP280_NO_PIN, BMP280_NO_PIN, &pressure, &temperature)); + const char *res = dh_i2c_error_string(bmp280_read(BMP280_NO_PIN, BMP280_NO_PIN, &pressure, &temperature)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -492,10 +384,10 @@ static void ICACHE_FLASH_ATTR do_devices_bh1750_read(COMMAND_RESULT *cb, const c bh1750_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float illuminance; - char *res = i2c_status_tochar(bh1750_read(BH1750_NO_PIN, BH1750_NO_PIN, &illuminance)); + const char *res = dh_i2c_error_string(bh1750_read(BH1750_NO_PIN, BH1750_NO_PIN, &illuminance)); if(res != 0) { dh_command_fail(cb, res); } else { @@ -522,12 +414,12 @@ static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const mpu6050_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; MPU6050_XYZ acc; MPU6050_XYZ gyro; float temperature; - char *res = i2c_status_tochar(mpu6050_read(MPU6050_NO_PIN, MPU6050_NO_PIN, &acc, &gyro, &temperature)); + const char *res = dh_i2c_error_string(mpu6050_read(MPU6050_NO_PIN, MPU6050_NO_PIN, &acc, &gyro, &temperature)); if(res != 0) { dh_command_fail(cb, res); } else { @@ -556,10 +448,10 @@ static void ICACHE_FLASH_ATTR do_devices_hmc5883l_read(COMMAND_RESULT *cb, const hmc5883l_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; HMC5883L_XYZ compass; - char *res = i2c_status_tochar(hmc5883l_read(HMC5883L_NO_PIN, HMC5883L_NO_PIN, &compass)); + const char *res = dh_i2c_error_string(hmc5883l_read(HMC5883L_NO_PIN, HMC5883L_NO_PIN, &compass)); if(res != 0) { dh_command_fail(cb, res); return; @@ -597,17 +489,17 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_read(COMMAND_RESULT *cb, const pcf8574_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; if(fields & AF_PULLUP) { - char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_pullup, 0)); + const char *res = dh_i2c_error_string(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_pullup, 0)); if (res != 0) { dh_command_fail(cb, res); return; } } unsigned int pins; - char *res = i2c_status_tochar(pcf8574_read(PCF8574_NO_PIN, PCF8574_NO_PIN, &pins)); + const char *res = dh_i2c_error_string(pcf8574_read(PCF8574_NO_PIN, PCF8574_NO_PIN, &pins)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -639,9 +531,9 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_write(COMMAND_RESULT *cb, const if(fields & AF_ADDRESS) pcf8574_set_address(parse_pins.address); fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - char *res = i2c_status_tochar(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, + const char *res = dh_i2c_error_string(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_set, parse_pins.pins_to_clear)); if(res != 0) { dh_command_fail(cb, res); @@ -671,9 +563,9 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c if(fields & AF_ADDRESS) pcf8574_set_address(parse_pins.address); fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - char *res = i2c_status_tochar(pcf8574_hd44780_write(PCF8574_NO_PIN, PCF8574_NO_PIN, + const char *res = dh_i2c_error_string(pcf8574_hd44780_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.data, parse_pins.data_len)); if (res != 0) { dh_command_fail(cb, res); @@ -720,10 +612,10 @@ static void ICACHE_FLASH_ATTR do_devices_lm75_read(COMMAND_RESULT *cb, const cha lm75_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float temperature; - char *res = i2c_status_tochar(lm75_read(LM75_NO_PIN, LM75_NO_PIN, &temperature)); + const char *res = dh_i2c_error_string(lm75_read(LM75_NO_PIN, LM75_NO_PIN, &temperature)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -749,11 +641,11 @@ static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const c si7021_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float temperature; float humidity; - char *res = i2c_status_tochar(si7021_read(SI7021_NO_PIN, SI7021_NO_PIN, &humidity, &temperature)); + const char *res = dh_i2c_error_string(si7021_read(SI7021_NO_PIN, SI7021_NO_PIN, &humidity, &temperature)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -778,10 +670,10 @@ static void ICACHE_FLASH_ATTR do_devices_ads1115_read(COMMAND_RESULT *cb, const ads1115_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float values[4]; - char *res = i2c_status_tochar(ads1115_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); + const char *res = dh_i2c_error_string(ads1115_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -808,7 +700,7 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const if(fields & AF_ADDRESS) pcf8591_set_address(parse_pins.address); if(fields & AF_REF) { - char *res = i2c_status_tochar(pcf8591_set_vref(parse_pins.ref)); + const char *res = dh_i2c_error_string(pcf8591_set_vref(parse_pins.ref)); if (res != 0) { dh_command_fail(cb, res); return; @@ -816,10 +708,10 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const } } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float values[4]; - char *res = i2c_status_tochar(pcf8591_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); + const char *res = dh_i2c_error_string(pcf8591_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -850,16 +742,16 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const if(fields & AF_ADDRESS) pcf8591_set_address(parse_pins.address); if(fields & AF_REF) { - char *res = i2c_status_tochar(pcf8591_set_vref(parse_pins.ref)); + const char *res = dh_i2c_error_string(pcf8591_set_vref(parse_pins.ref)); if (res != 0) { dh_command_fail(cb, res); return; } } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - char *res = i2c_status_tochar(pcf8591_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); + const char *res = dh_i2c_error_string(pcf8591_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); if (res != 0) { dh_command_fail(cb, res); } else { @@ -888,16 +780,16 @@ static void ICACHE_FLASH_ATTR do_devices_mcp4725_write(COMMAND_RESULT *cb, const if(fields & AF_ADDRESS) mcp4725_set_address(parse_pins.address); if(fields & AF_REF) { - char *res = i2c_status_tochar(mcp4725_set_vref(parse_pins.ref)); + const char *res = dh_i2c_error_string(mcp4725_set_vref(parse_pins.ref)); if (res != 0) { dh_command_fail(cb, res); return; } } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - char *res = i2c_status_tochar(mcp4725_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); + const char *res = dh_i2c_error_string(mcp4725_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); if (res != 0) { dh_command_fail(cb, res); } else { @@ -923,7 +815,7 @@ static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const c if(fields & AF_ADDRESS) ina219_set_address(parse_pins.address); if(fields & AF_REF) { - char *res = i2c_status_tochar(ina219_set_shunt(parse_pins.ref)); + const char *res = dh_i2c_error_string(ina219_set_shunt(parse_pins.ref)); if (res != 0) { dh_command_fail(cb, res); return; @@ -931,12 +823,12 @@ static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const c } } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float voltage; float current; float power; - char *res = i2c_status_tochar(ina219_read(ADS1115_NO_PIN, ADS1115_NO_PIN, &voltage, ¤t, &power)); + const char *res = dh_i2c_error_string(ina219_read(ADS1115_NO_PIN, ADS1115_NO_PIN, &voltage, ¤t, &power)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -1056,7 +948,7 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL if(check) dh_command_done(cb, ""); else - cb->callback(cb->data, DHSTATUS_OK, RDT_DATA_WITH_LEN, parse_pins.data, parse_pins.count); + dh_command_done_buf(cb, parse_pins.data, parse_pins.count); MFRC522_PICC_HaltA(); MFRC522_PCD_StopCrypto1(); MFRC522_PCD_AntennaOff(); @@ -1088,9 +980,9 @@ static void ICACHE_FLASH_ATTR do_devices_pca9685_control(COMMAND_RESULT *cb, con if(fields & AF_ADDRESS) pca9685_set_address(parse_pins.address); fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - char *res = i2c_status_tochar(pca9685_control(PCA9685_NO_PIN, PCA9685_NO_PIN, + const char *res = dh_i2c_error_string(pca9685_control(PCA9685_NO_PIN, PCA9685_NO_PIN, parse_pins.storage.float_values, parse_pins.pin_value_readed, (fields & AF_PERIOD) ? parse_pins.periodus : PCA9685_NO_PERIOD)); if (res != 0) { @@ -1119,11 +1011,11 @@ static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const mlx90614_set_address(parse_pins.address); } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float ambient; float object; - char *res = i2c_status_tochar(mlx90614_read(MLX90614_NO_PIN, MLX90614_NO_PIN, &ambient, &object)); + const char *res = dh_i2c_error_string(mlx90614_read(MLX90614_NO_PIN, MLX90614_NO_PIN, &ambient, &object)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -1197,9 +1089,9 @@ static void ICACHE_FLASH_ATTR do_devices_tm1637_write(COMMAND_RESULT *cb, const return; } fields |= AF_ADDRESS; - if(i2c_init(cb, fields, &parse_pins)) + if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - char *res = i2c_status_tochar(tm1636_write(TM1636_NO_PIN, TM1636_NO_PIN, + const char *res = dh_i2c_error_string(tm1636_write(TM1636_NO_PIN, TM1636_NO_PIN, parse_pins.data, parse_pins.data_len)); if (res != 0) { dh_command_fail(cb, res); @@ -1237,8 +1129,10 @@ RO_DATA struct { {"uart/terminal", dh_handle_uart_terminal}, #endif /* DH_COMMANDS_UART */ - { "i2c/master/read", do_i2c_master_read}, - { "i2c/master/write", do_i2c_master_write}, +#ifdef DH_COMMANDS_I2C + { "i2c/master/read", dh_handle_i2c_master_read}, + { "i2c/master/write", dh_handle_i2c_master_write}, +#endif /* DH_COMMANDS_I2C */ #ifdef DH_COMMANDS_SPI { "spi/master/read", dh_handle_spi_master_read}, diff --git a/firmware-src/sources/dhi2c.c b/firmware-src/sources/dhi2c.c deleted file mode 100644 index 0b1c830..0000000 --- a/firmware-src/sources/dhi2c.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * dhi2c.c - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: I2C module - * - */ -#include "dhi2c.h" -#include "DH/gpio.h" -#include "user_config.h" - -#include -#include -#include -#include -#include - -#define I2C_DELAY_US 5 -#define I2C_ERROR_TIMEOUT_US 50000 - -LOCAL unsigned int mSDAPin = (1 << 0); -LOCAL unsigned int mSCLPin = (1 << 2); - -DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_init(unsigned int sda_pin, unsigned int scl_pin) { - const unsigned int SDA = (1 << sda_pin); - const unsigned int SCL = (1 << scl_pin); - if((SDA & DH_GPIO_SUITABLE_PINS) == 0 || (SCL & DH_GPIO_SUITABLE_PINS) == 0 || SDA == SCL) - return DHI2C_WRONG_PARAMETERS; - - mSDAPin = SDA; - mSCLPin = SCL; - dhi2c_reinit(); - return DHI2C_OK; -} - -void ICACHE_FLASH_ATTR dhi2c_reinit(void) { - dh_gpio_open_drain(mSDAPin | mSCLPin, 0); - dh_gpio_prepare_pins(mSDAPin | mSCLPin, 1); - dh_gpio_pull_up(mSDAPin | mSCLPin, 0); - gpio_output_set(mSDAPin | mSCLPin, 0, mSDAPin | mSCLPin, 0); -} - -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_set_pin(unsigned int pin_mask, int val) { - if(val) { - gpio_output_set(pin_mask, 0, pin_mask, 0); - val = pin_mask; - } else { - gpio_output_set(0, pin_mask, pin_mask, 0); - } - os_delay_us(I2C_DELAY_US); - int i; - for(i = 0; i < I2C_ERROR_TIMEOUT_US; i++) { - const unsigned int c = gpio_input_get(); - if( (c & pin_mask) == val) - return DHI2C_OK; - os_delay_us(1); - } - return DHI2C_BUS_BUSY; -} - -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_start(void) { - DHI2C_STATUS res; - res = dhi2c_set_pin(mSDAPin, 1); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSCLPin, 1); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSDAPin, 0); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSCLPin, 0); - if(res != DHI2C_OK) - return res; - return DHI2C_OK; -} - -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_stop(void) { - DHI2C_STATUS res; - res = dhi2c_set_pin(mSDAPin, 0); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSCLPin, 1); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSDAPin, 1); - if(res != DHI2C_OK) - return res; - return DHI2C_OK; -} - -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_writebyte(unsigned char byte) { - DHI2C_STATUS res; - int i; - for (i = 7; i >= 0; i--) { - const unsigned int bit = ((1 << i) & byte); - res = dhi2c_set_pin(mSDAPin, bit); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSCLPin, 1); - if(res != DHI2C_OK) - return res; - os_delay_us(I2C_DELAY_US); - res = dhi2c_set_pin(mSCLPin, 0); - if(res != DHI2C_OK) - return res; - } - // check ACK - gpio_output_set(mSDAPin, 0, mSDAPin, 0); - os_delay_us(I2C_DELAY_US); - res = dhi2c_set_pin(mSCLPin, 1); - if(res != DHI2C_OK) - return res; - os_delay_us(I2C_DELAY_US); - const unsigned int ackbit = (gpio_input_get() & mSDAPin) ? 1 : 0; - res = dhi2c_set_pin(mSCLPin, 0); - if(res != DHI2C_OK) - return res; - if(ackbit) - return DHI2C_NOACK; - return DHI2C_OK; -} - -DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_readbyte(unsigned char *byte, int ackbit) { - DHI2C_STATUS res; - gpio_output_set(mSDAPin, 0, mSDAPin, 0); - os_delay_us(I2C_DELAY_US); - int i; - unsigned char rb = 0; - for (i = 7; i >= 0; i--) { - res = dhi2c_set_pin(mSCLPin, 1); - if(res != DHI2C_OK) - return res; - os_delay_us(I2C_DELAY_US); - const unsigned int bit = (gpio_input_get() & mSDAPin) ? 1 :0; - rb |= bit << i; - res = dhi2c_set_pin(mSCLPin, 0); - if(res != DHI2C_OK) - return res; - } - // send ACK - res = dhi2c_set_pin(mSDAPin, ackbit); - if(res != DHI2C_OK) - return res; - res = dhi2c_set_pin(mSCLPin, 1); - if(res != DHI2C_OK) - return res; - os_delay_us(I2C_DELAY_US); - res = dhi2c_set_pin(mSCLPin, 0); - if(res != DHI2C_OK) - return res; - *byte = rb; - return DHI2C_OK; -} - -LOCAL DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_act(unsigned int address, char *buf, unsigned int len, int sendstop, int is_read) { - if(len > INTERFACES_BUF_SIZE || address > 0xFF) - return DHI2C_WRONG_PARAMETERS; - DHI2C_STATUS res; - res = dhi2c_start(); - if(res != DHI2C_OK) - return res; - if(is_read) - res = dhi2c_writebyte(address | 0x1); - else - res = dhi2c_writebyte(address & 0xFE); - if(res != DHI2C_OK) { - dhi2c_stop(); - return res; - } - int i; - for(i = 0; i < len; i++) { - system_soft_wdt_feed(); - if(is_read) { - res = dhi2c_readbyte((unsigned char*)&buf[i], (i + 1) == len); - } else { - res = dhi2c_writebyte(buf[i]); - } - if(res != DHI2C_OK) { - dhi2c_stop(); - return res; - } - } - if(sendstop) { - res = dhi2c_stop(); - if(res != DHI2C_OK) - return res; - } - return DHI2C_OK; -} - -DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_write(unsigned int address, const char *buf, unsigned int len, int sendstop) { - return dhi2c_act(address, (char *)buf, len, sendstop, 0); -} - -DHI2C_STATUS ICACHE_FLASH_ATTR dhi2c_read(unsigned int address, char *buf, unsigned int len) { - return dhi2c_act(address, buf, len, 1, 1); -} diff --git a/firmware-src/sources/dhi2c.h b/firmware-src/sources/dhi2c.h deleted file mode 100644 index 0902742..0000000 --- a/firmware-src/sources/dhi2c.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * \file dhi2c.h - * \brief Software implementation of I2C bus for ESP8266. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - */ - -#ifndef _DHI2C_H_ -#define _DHI2C_H_ - -/** I2C functions return status */ -typedef enum { - DHI2C_OK, ///< Success. - DHI2C_NOACK, ///< ACK response did not receive on bus. - DHI2C_WRONG_PARAMETERS, ///< Wrong parameters. - DHI2C_BUS_BUSY, ///< Module wasn't able to set desired level on bus during timeout time. - DHI2C_DEVICE_ERROR ///< Error in device. -} DHI2C_STATUS; - -/** - * \brief Prepare pins for usage with I2C. - * \param[in] sda_pin Pin number for SDA line. - * \param[in] scl_pin Pin number for SCL line. - * \return Status value, one of DHI2C_STATUS enum. - */ -DHI2C_STATUS dhi2c_init(unsigned int sda_pin, unsigned int scl_pin); - -/** - * \brief Prepare last successfully prepared pins for usage with I2C. - */ -void dhi2c_reinit(void); - -/** - * \brief Write data to I2C bus. - * \param[in] address Device address. - * \param[in] buf Buffer with data. - * \param[in] len Data length in bytes. - * \param[in] sendstop Send STOP after writing if this parameter has non zero value, do not send if parameter is zero. - * \return Status value, one of DHI2C_STATUS enum. - */ -DHI2C_STATUS dhi2c_write(unsigned int address, const char *buf, unsigned int len, int sendstop); - -/** - * \brief Read data from I2C bus. - * \param[in] address Device address. - * \param[out] buf Buffer with data. - * \param[in] len Data length in bytes. - * \return Status value, one of DHI2C_STATUS enum. - */ -DHI2C_STATUS dhi2c_read(unsigned int address, char *buf, unsigned int len); - -#endif /* _DHI2C_H_ */ diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index a6e0081..24c6478 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -157,6 +157,16 @@ void ICACHE_FLASH_ATTR dh_command_done(COMMAND_RESULT *cmd_res, const char *str) } +/* + * dh_command_done_buf() implementation. + */ +void ICACHE_FLASH_ATTR dh_command_done_buf(COMMAND_RESULT *cmd_res, const void *buf, size_t len) +{ + cmd_res->callback(cmd_res->data, DHSTATUS_OK, + RDT_DATA_WITH_LEN, buf, len); +} + + /* * dh_command_fail() implementation. */ diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index f53fa63..2a58483 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -135,6 +135,15 @@ do { \ } while(0)*/ +/** + * @brief Report command success with data buffer. + * @param[in] cmd_res Command result. + * @param[in] buf Buffer to report. + * @param[in] len Buffer length in bytes. + */ +void dh_command_done_buf(COMMAND_RESULT *cmd_res, const void *buf, size_t len); + + /** * @brief Report command failure. * @param[in] cmd_res Command result. From c73882563806a2a4f84e9b91a423fba7098ac3b8 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 21 Apr 2017 17:58:39 +0300 Subject: [PATCH 33/83] fix rest of warnings --- firmware-src/sources/dhsettings.c | 2 +- firmware-src/sources/httpd.c | 2 +- firmware-src/sources/mdnsd.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/firmware-src/sources/dhsettings.c b/firmware-src/sources/dhsettings.c index 35f0b12..2d14500 100644 --- a/firmware-src/sources/dhsettings.c +++ b/firmware-src/sources/dhsettings.c @@ -41,7 +41,7 @@ typedef struct { }; } DH_SETTINGS; -static DH_SETTINGS_DATA mSettingsData = {0}; +static DH_SETTINGS_DATA mSettingsData = {{0}}; LOCAL uint32_t ICACHE_FLASH_ATTR getStorageCrc(DH_SETTINGS *storage) { return crc32(storage->storage, sizeof(storage->storage)); diff --git a/firmware-src/sources/httpd.c b/firmware-src/sources/httpd.c index 4ce1527..f7d428e 100644 --- a/firmware-src/sources/httpd.c +++ b/firmware-src/sources/httpd.c @@ -47,7 +47,7 @@ LOCAL char *mPostBuf = 0; LOCAL unsigned int mPostBufPos = 0; LOCAL HttpRequestCb mGetHttpRequestCb = 0; LOCAL HttpRequestCb mPostHttpRequestCb = 0; -LOCAL CONTENT_ITEM mContentQueue[MAX_CONNECTIONS] = {0}; +LOCAL CONTENT_ITEM mContentQueue[MAX_CONNECTIONS] = {{{0}}}; LOCAL int ICACHE_FLASH_ATTR is_remote_equal(const esp_tcp *tcp, CONTENT_ITEM *item) { if(os_memcmp(tcp->remote_ip, item->remote_ip, sizeof(tcp->remote_ip)) == 0 diff --git a/firmware-src/sources/mdnsd.c b/firmware-src/sources/mdnsd.c index 96e19f0..10cf643 100644 --- a/firmware-src/sources/mdnsd.c +++ b/firmware-src/sources/mdnsd.c @@ -38,9 +38,10 @@ LOCAL struct ip_addr mMulticastIP = { MDNS_IP }; LOCAL void ICACHE_FLASH_ATTR announce(const uint8_t *data, uint32_t len) { mSendingInProgress = 1; - *(unsigned long *)mMDNSdConn.proto.udp->remote_ip = MDNS_IP; + const struct ip_addr mdns_ip = { MDNS_IP }; + os_memcpy(mMDNSdConn.proto.udp->remote_ip, &mdns_ip, sizeof(mdns_ip)); mMDNSdConn.proto.udp->remote_port = MDNS_PORT; - *(unsigned long *)mMDNSdConn.proto.udp->local_ip = mMulticastIP.addr; + os_memcpy(mMDNSdConn.proto.udp->local_ip, &mMulticastIP, sizeof(mMulticastIP)); mMDNSdConn.proto.udp->local_port = MDNS_PORT; espconn_send(&mMDNSdConn, (uint8_t *)data, len); } From 46055297f540d4907ff31407cf4f8870b693bdec Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 25 Apr 2017 21:55:35 +0300 Subject: [PATCH 34/83] Review onewire module --- firmware-src/sources/DH/onewire.c | 590 +++++++++++++++++++++++++ firmware-src/sources/DH/onewire.h | 145 ++++++ firmware-src/sources/devices/dht.c | 85 +++- firmware-src/sources/devices/dht.h | 13 + firmware-src/sources/devices/ds18b20.c | 10 +- firmware-src/sources/dhcommands.c | 190 +------- firmware-src/sources/dhnotification.c | 13 +- firmware-src/sources/dhonewire.c | 369 ---------------- firmware-src/sources/dhonewire.h | 91 ---- firmware-src/sources/user_config.h | 1 + 10 files changed, 858 insertions(+), 649 deletions(-) create mode 100644 firmware-src/sources/DH/onewire.c create mode 100644 firmware-src/sources/DH/onewire.h delete mode 100644 firmware-src/sources/dhonewire.c delete mode 100644 firmware-src/sources/dhonewire.h diff --git a/firmware-src/sources/DH/onewire.c b/firmware-src/sources/DH/onewire.c new file mode 100644 index 0000000..fe98448 --- /dev/null +++ b/firmware-src/sources/DH/onewire.c @@ -0,0 +1,590 @@ +/** + * @file + * @brief Software implementation of onewire interface for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "DH/onewire.h" +#include "DH/adc.h" +#include "dhdebug.h" + +#include +#include +#include +#include +#include +#include +#include + +// module variables +static unsigned int mOneWirePin = 0; +static DHGpioPinMask mIntPins = 0; +static unsigned int mIntErrorCount = 0; +static unsigned int mWaitSearchPins = 0; +static os_timer_t mIntTimer; + +#define ONEWIRE_MAX_INT_SEARCH_ATTEMPS 5 +#define ONEWIRE_MAX_INT_DELAY_MS 20 +#define ONEWIRE_RESET_LENGHT_US 640 + + +/** + * @brief Lock interruptions. + */ +static void ICACHE_FLASH_ATTR lock_int(void) +{ + if (mIntPins) + dh_gpio_subscribe_extra_int(mIntPins, 0, 0, 0); +} + + +/** + * @brief Unlock interruptions. + */ +static void ICACHE_FLASH_ATTR unlock_int(void) +{ + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, mIntPins); + dh_gpio_subscribe_extra_int(0, 0, mIntPins, 0); +} + + +/* + * dh_onewire_set_pin() implementation. + */ +int ICACHE_FLASH_ATTR dh_onewire_set_pin(unsigned int pin) +{ + if (!(DH_GPIO_PIN(pin) & DH_GPIO_SUITABLE_PINS)) + return -1; // unsuitable pin + + mOneWirePin = pin; + return 0; // OK +} + + +/* + * dh_onewire_get_pin() implementation. + */ +unsigned int ICACHE_FLASH_ATTR dh_onewire_get_pin(void) +{ + return mOneWirePin; +} + + +/** + * @brief Reset onewire bus. + * @return Non-zero if device is presented. Zero otherwise. + */ +int ICACHE_FLASH_ATTR dh_onewire_reset(DHGpioPinMask pin_mask, int exit_on_presence) +{ + system_soft_wdt_feed(); + const int pinstate = (gpio_input_get() & pin_mask) !=0; + dh_gpio_open_drain(pin_mask, 0); + dh_gpio_pull_up(pin_mask, 0); + dh_gpio_prepare_pins(pin_mask, 1); + if (!pinstate) { + gpio_output_set(pin_mask, 0, pin_mask, 0); + os_delay_us(500); + } + if (!(gpio_input_get() & pin_mask)) + return 0; + + // send RESET + gpio_output_set(0, pin_mask, pin_mask, 0); + os_delay_us(ONEWIRE_RESET_LENGHT_US); + gpio_output_set(pin_mask, 0, pin_mask, 0); + + // check RESPONSE + int i, presence = 0; + for (i = 0; i < 480; i++) { // wait at least 480 usec + if (!presence && i < 240) { + if (i > 15) { + if (!(gpio_input_get() & pin_mask)) + presence = 1; + } + } else if(exit_on_presence) { + if (presence) { + if (gpio_input_get() & pin_mask) + return 1; + } else { + return 0; + } + } + os_delay_us(1); + } + + return presence; +} + + +/** + * @brief Do 1 bit communication. + */ +static int ICACHE_FLASH_ATTR onewire_act_bit(int bit, DHGpioPinMask pin_mask) +{ + // time slot start + char res = 0; + ETS_INTR_LOCK(); + gpio_output_set(0, pin_mask, pin_mask, 0); + os_delay_us(5); + + if (bit) { + gpio_output_set(pin_mask, 0, pin_mask, 0); + os_delay_us(5); + if (gpio_input_get() & pin_mask) + res = bit; + ETS_INTR_UNLOCK(); + os_delay_us(80); + } else { + os_delay_us(85); + gpio_output_set(pin_mask, 0, pin_mask, 0); + ETS_INTR_UNLOCK(); + } + + os_delay_us(5); // pause between time slots + return res; +} + + +/** + * @brief Do 1 byte communication. + */ +static int ICACHE_FLASH_ATTR onewire_act_byte(int byte, DHGpioPinMask pin_mask) +{ + system_soft_wdt_feed(); + + int i, res = 0; + for (i = 0; i < 8; i++) // lsb-first + res |= onewire_act_bit(byte & BIT(i), pin_mask); + + return res; +} + + +/* + * dh_onewire_write() implementation. + */ +int ICACHE_FLASH_ATTR dh_onewire_write(const void *buf_, size_t len) +{ + lock_int(); + + const DHGpioPinMask pin_mask = DH_GPIO_PIN(mOneWirePin); + int present = dh_onewire_reset(pin_mask, 0); + if (!present) { + unlock_int(); + return -1; // failed + } + + const uint8_t *buf = (const uint8_t*)buf_; + while (len--) + onewire_act_byte(*buf++, pin_mask); + + unlock_int(); + return 0; // OK +} + + +/* + * dh_onewire_read() implementation. + */ +int ICACHE_FLASH_ATTR dh_onewire_read(void *buf_, size_t len) { + lock_int(); + + const DHGpioPinMask pin_mask = DH_GPIO_PIN(mOneWirePin); + uint8_t *buf = (uint8_t*)buf_; + while (len--) + *buf++ = onewire_act_byte(0xFF, pin_mask); + + unlock_int(); + return 0; // OK +} + + +/** + * @brief Check onewire CRC. + * @return Zero on success. + */ +static int ICACHE_FLASH_ATTR dh_onewire_check_crc(const uint8_t data[8]) +{ + int seed = 0; + + int i, j; + for (i = 0; i < 8; i++) { + int b = data[i]; + for (j = 0; j < 8; j++) { + if((seed ^ b) & 0x01) + seed = (seed >> 1) ^ 0x8C; + else + seed >>= 1; + b >>= 1; + } + } + + return seed; +} + + +/* + * dh_onewire_search() implementation. + */ +int ICACHE_FLASH_ATTR dh_onewire_search(void *buf_, size_t *len, int command, unsigned int pin) +{ + uint8_t address[8] = {0}; + if (*len < sizeof(address)) + return -1; // too few space in buffer + + const DHGpioPinMask pin_mask = DH_GPIO_PIN(pin); + int lastAmbiguity = 8*sizeof(address); + char *buf = (char*)buf_; + size_t copyied = 0; + + lock_int(); + + do { + if (!dh_onewire_reset(pin_mask, 0)) { + unlock_int(); + if (lastAmbiguity == 8*sizeof(address)) { + *len = 0; // devices are not connected + return 0; + } + return -1; // something wrong + } + + onewire_act_byte(command, pin_mask); + int i, ambiguity = -1; + for (i = 0; i < 8*sizeof(address); i++) { + if (!(gpio_input_get() & pin_mask)) { + unlock_int(); + return -1; // lost + } + + const int byte = i/8; + const int bit = BIT(i%8); + + const int bit1 = onewire_act_bit(0x1, pin_mask); + const int bit2 = onewire_act_bit(0x1, pin_mask); + if (bit1 && bit2) { + unlock_int(); + if (i == 0 && lastAmbiguity == 8*sizeof(address)) { + *len = 0; // first interaction, no devices found + return 0; // OK, no devices + } + // dhdebug("Onewire error while search at %u bit", i); + return -1; // something wrong + } else if(bit1 && !bit2) { + address[byte] |= bit; + onewire_act_bit(0x1, pin_mask); + } else if(!bit1 && bit2) { + address[byte] &= ~bit; + onewire_act_bit(0x0, pin_mask); + } else { + if (i < lastAmbiguity) { + address[byte] &= ~bit; + onewire_act_bit(0x0, pin_mask); + ambiguity = i; + } else { + address[byte] |= bit; + onewire_act_bit(0x1, pin_mask); + } + } + } + lastAmbiguity = ambiguity; + + if (0 == dh_onewire_check_crc(address)) { + os_memcpy(buf, address, sizeof(address)); + buf += sizeof(address); + copyied += sizeof(address); + if (copyied + sizeof(address) > *len) + break; // no more space + } else { + unlock_int(); + return -1; // bad CRC + } + } while (lastAmbiguity >= 0); + + *len = copyied; + unlock_int(); + return 0; // OK +} + + +/** + * @brief Timer callback. + */ +static void ICACHE_FLASH_ATTR onewire_int_search(void *arg) +{ + int i; + for (i = 0; i < DH_GPIO_PIN_COUNT; i++) { + const DHGpioPinMask pin = DH_GPIO_PIN(i); + if (pin & mWaitSearchPins) { + uint8_t buf[INTERFACES_BUF_SIZE]; + size_t len = sizeof(buf); + int res = dh_onewire_search(buf, &len, 0xF0, i); + if (len == 0) + res = 1; // not found + if (0 == res) + dh_onewire_search_result(i, buf, len); + else + mIntErrorCount++; + if (0 == res || mIntErrorCount > ONEWIRE_MAX_INT_SEARCH_ATTEMPS) { + mIntErrorCount = 0; + mWaitSearchPins &= ~pin; + } + + // re-arm timer to avoid long operating in timer interruption. + if (mWaitSearchPins) { + os_timer_disarm(&mIntTimer); + os_timer_setfn(&mIntTimer, onewire_int_search, NULL); + os_timer_arm(&mIntTimer, ONEWIRE_MAX_INT_DELAY_MS, 0); + } + break; + } + } +} + + +/* + * dh_gpio_extra_int_cb() implementation. + */ +void ICACHE_FLASH_ATTR dh_gpio_extra_int_cb(DHGpioPinMask caused_pins) +{ + os_timer_disarm(&mIntTimer); + mWaitSearchPins |= caused_pins; + os_timer_setfn(&mIntTimer, onewire_int_search, NULL); + os_timer_arm(&mIntTimer, ONEWIRE_MAX_INT_DELAY_MS, 0); +} + + +/* + * dh_onewire_int() implementation. + */ +int ICACHE_FLASH_ATTR dh_onewire_int(DHGpioPinMask search_pins, DHGpioPinMask disable_pins) +{ + int res = dh_gpio_subscribe_extra_int(disable_pins, 0, search_pins, 0); + if (!!res) + return res; // failed to subscribe + + mIntPins |= search_pins; + mIntPins &= ~disable_pins; + return 0; // OK +} + + +#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers +#include "dhcommand_parser.h" +#include + + +/** + * @brief Initialization helper. + * @return Non-zero if onewire was initialized. Zero otherwise. + */ +int ICACHE_FLASH_ATTR dh_onewire_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params) +{ + if (fields & AF_PIN) { + if (!!dh_onewire_set_pin(params->pin)) { + dh_command_fail(cmd_res, "Wrong onewire pin"); + return 1; // FAILED + } + } + + return 0; // continue +} + + +/** + * @brief Handle "onewire/master/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_PIN | AF_DATA | AF_COUNT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if ((fields & AF_COUNT) == 0 || info.count == 0 || info.count > INTERFACES_BUF_SIZE) { + dh_command_fail(cmd_res, "Wrong read size"); + return; // FAILED + } + if ((fields & AF_DATA) == 0) { + dh_command_fail(cmd_res, "Command for reading is not specified"); + return; + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + if (!!dh_onewire_write(info.data, info.data_len)) { + dh_command_fail(cmd_res, "No response"); + return; // FAILED + } + dh_onewire_read(info.data, info.count); + dh_command_done_buf(cmd_res, info.data, info.count); +} + + +/** + * @brief Handle "onewire/master/write" commands. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_PIN | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + if (!!dh_onewire_write(info.data, info.data_len)) { + dh_command_fail(cmd_res, "No response"); + return; // FAILED + } + + dh_command_done(cmd_res, ""); +} + + +/** + * Handle "onewire/master/search" or "onewire/master/alarm" commands. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_search(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if(dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + } + + int check = os_strcmp(command, "onewire/master/search"); + size_t data_len = sizeof(info.data); + if (!!dh_onewire_search(info.data, &data_len, (check == 0) ? 0xF0 : 0xEC, dh_onewire_get_pin())) + dh_command_fail(cmd_res, "Error during search"); + else + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_SEARCH64, dh_onewire_get_pin(), info.data, data_len); +} + + +/** + * @brief Handle "onewire/master/int" command. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), + AF_DISABLE | AF_PRESENCE, &fields); + if (err_msg != 0) + dh_command_fail(cmd_res, err_msg); + else if (fields == 0) + dh_command_fail(cmd_res, "Wrong action"); + else if (!!dh_onewire_int(info.pins_to_presence, info.pins_to_disable)) + dh_command_fail(cmd_res, "Unsuitable pin"); + else + dh_command_done(cmd_res, ""); +} + + +/** + * Write data to WS2812b device. + */ +/*static*/ void ws2812b_write(const void *buf_, size_t len, DHGpioPinMask pin_mask, + unsigned int T, unsigned int S, unsigned int L) +{ + // due to the strict timings, this method should be in IRAM, + // don't mark it with ICACHE_FLASH_ATTR + + // send each byte in real time + unsigned int ss, se, r; + const uint8_t *buf = (const uint8_t*)buf_; + while (len--) { + int j, v = *buf++; + for (j = 0x80; j > 0; j >>= 1) { + GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pin_mask); + asm volatile("rsr %0, ccount" : "=r"(r)); + ss = r + ((v & j) ? L : S); + se = r + T; + do { + asm volatile("rsr %0, ccount" : "=r"(r)); + } while(r < ss); + GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pin_mask); + do { + asm volatile("rsr %0, ccount" : "=r"(r)); + } while(r < se); + } + } +} + + +/** + * @brief Write data to WS2812b like device + * @param[in] pin 1-wire pin for communication. + * @param[in] buf Pointer to buffer with data. + * @param[in] len Buffer length in bytes. + */ +static void ICACHE_FLASH_ATTR onewire_ws2812b_write(const void *buf, size_t len) +{ + // init number of CPU tacts for delay + // delays are lower that spec on 50ns due to GPIO latency, anyway spec allows 150ns jitter. + const int freq = system_get_cpu_freq(); // MHz + const unsigned S = 350 * freq / 1000; + const unsigned L = 750 * freq / 1000; + + ETS_INTR_LOCK(); + + // send reset, low more then 50 ms + const DHGpioPinMask pin = DH_GPIO_PIN(mOneWirePin); + gpio_output_set(0, pin, pin, 0); // low and initialize + os_delay_us(50); + ws2812b_write(buf, len, pin, S + L, S, L); + + ETS_INTR_UNLOCK(); +} + + +/** + * @brief Handle "onewire/ws2812b/write" command. + */ +// TODO: move this code to dedicated device file! +void ICACHE_FLASH_ATTR dh_handle_onewire_ws2812b_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + + const char *err_msg = parse_params_pins_set(params, params_len, &info, + DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (!(fields & AF_DATA)) { + dh_command_fail(cmd_res, "Data not specified"); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + + onewire_ws2812b_write(info.data, info.data_len); + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_ONEWIRE */ diff --git a/firmware-src/sources/DH/onewire.h b/firmware-src/sources/DH/onewire.h new file mode 100644 index 0000000..e94a471 --- /dev/null +++ b/firmware-src/sources/DH/onewire.h @@ -0,0 +1,145 @@ +/** + * @file + * @brief Software implementation of onewire interface for ESP8266 firmware. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DH_ONEWIRE_H_ +#define _DH_ONEWIRE_H_ + +#include "user_config.h" +#include "DH/gpio.h" + +#include + + +/** + * @brief Set pin for onewire, but not initialize it. + * @param[in] pin Pin number. + * @return Zero on success. + */ +int dh_onewire_set_pin(unsigned int pin); + + +/** + * @brief Get pin that configured for onewire. + * @return Pin number. + */ +unsigned int dh_onewire_get_pin(void); + + +/** + * @brief Reset onewire bus. + * @param[in] pin_mask Pin mask to reset. + * @param[in] exit_on_presence Flag to exit immediately if device found. + * @return Non-zero if device is presented. Zero otherwise. + */ +int dh_onewire_reset(DHGpioPinMask pin_mask, int exit_on_presence); + + +/** + * @brief Write data to onewire bus. + * + * Pin will be initialized automatically. + * @param[in] buf Buffer with data to write. + * @param[in] len Buffer length in bytes. + * return Zero on success. + */ +int dh_onewire_write(const void *buf, size_t len); + + +/** + * @brief Read data from onewire bus. + * + * Pin will NOT be initialized automatically, will use previous pin. + * + * @param[out] buf Buffer to read data to. + * @param[in] len Number of bytes to read, buffer should be at least the same size. + * @return Zero on success. + */ +int dh_onewire_read(void *buf, size_t len); + + +// command 0xF0 // SEARCH ROM + +/** + * @brief Search for onewire devices. + * @param[out] buf Buffer to store 64 bits addresses. + * @param[in,out] len Receives number of bytes allowed in buffer, returns number of copied bytes. Can return 0, that means no devices were found. + * @param[in] command Bus command for search, 0xF0 - SEARCH ROM, 0xEC - ALARM SEARCH. + * @param[in] pin Pin number for using during search. + * @return Zero on success. + */ +int dh_onewire_search(void *buf, size_t *len, + int command, unsigned int pin); + + +/** + * @brief Enable interruption. + * @param[in] search_pins Pins that will awaiting for PRESENSE and then runs SEARCH command. + * @param[in] disable_pins Pin mask for disabling. + * @return Zero on success. + */ +int dh_onewire_int(DHGpioPinMask search_pins, DHGpioPinMask disable_pins); + + +/** + * @brief Callback for search result. + * @param[in] pin Pin number where found. + * @param[in] buf Buffer with 64 bits addresses. + * @param[in] len Buffer length in bytes. + */ +// TODO: consider to use callback function pointer +extern void dh_onewire_search_result(unsigned int pin, const void* buf, size_t len); + + +#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers +#include "dhsender_data.h" +#include "dhcommand_parser.h" + +/** + * @brief Initialization helper. + * @return Non-zero if onewire was initialized. Zero otherwise. + */ +int dh_onewire_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params); + + +/** + * @brief Handle "onewire/master/read" command. + */ +void dh_handle_onewire_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "onewire/master/write" commands. + */ +void dh_handle_onewire_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * Handle "onewire/master/search" or "onewire/master/alarm" commands. + */ +void dh_handle_onewire_master_search(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "onewire/master/int" command. + */ +void dh_handle_onewire_master_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "onewire/ws2812b/write" command. + */ +// TODO: move this code to dedicated device file! +void dh_handle_onewire_ws2812b_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_ONEWIRE */ + +#endif /* _DH_ONEWIRE_H_ */ diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 998de69..e2e01ab 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -7,18 +7,24 @@ * */ #include "dht.h" -#include "dhonewire.h" +#include "DH/onewire.h" +#include "DH/adc.h" #include "dhdebug.h" #include "dhutils.h" +#include #include -#include +#include +#include +#include -#define DHT_PACKET_SIZE 5 +#define DHT_PACKET_SIZE 5 +#define DHT_RESET_LENGTH_US 25000 +#define DHT_TIMEOUT_US 200 LOCAL char * ICACHE_FLASH_ATTR dht_read(int pin, char *buf) { if(pin != DHT_NO_PIN) { - if(!dhonewire_set_pin(pin)) { + if (!!dh_onewire_set_pin(pin)) { return "Failed to set up onewire pin"; } } @@ -54,3 +60,74 @@ char * ICACHE_FLASH_ATTR dht22_read(int pin, float *humidity, float *temperature *temperature = signedInt16be_sm(buf, 2) / 10.0f; return NULL; } + + +LOCAL unsigned int ICACHE_FLASH_ATTR donewire_dht_measure_high(unsigned int pin) { + unsigned int counter = 0; + while((gpio_input_get() & pin) == 0) { + if(counter > DHT_TIMEOUT_US) + return 0; + os_delay_us(1); + counter++; + } + counter = 0; + while((gpio_input_get() & pin)) { + if(counter > DHT_TIMEOUT_US) + return DHT_TIMEOUT_US; + os_delay_us(1); + counter++; + } + return counter; +} + +int ICACHE_FLASH_ATTR dhonewire_dht_read(char *buf, unsigned int len) { + const unsigned int pin = DH_GPIO_PIN(dh_onewire_get_pin()); + if (dh_onewire_reset(pin, 1) == 0) + return 0; + ETS_INTR_LOCK(); + unsigned int i; + if(donewire_dht_measure_high(pin) >= DHT_TIMEOUT_US) { // wait till response finish + ETS_INTR_UNLOCK(); + return 0; + } + for(i = 0; i / 8 < len; i++) { + unsigned int time = donewire_dht_measure_high(pin); + if(time >= DHT_TIMEOUT_US || time <= 10) { + break; + } else { + const char bit = 1 << (7 - i % 8); + if(time > 25) + buf[i / 8] |= bit; + else + buf[i / 8] &= ~bit; + } + system_soft_wdt_feed(); + } + ETS_INTR_UNLOCK(); + return i / 8; +} + + +/** + * @brief Do "onewire/dht/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_dht_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) +{ + gpio_command_params parse_pins; + ALLOWED_FIELDS fields = 0; + if(paramslen) { + char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (parse_res != 0) { + dh_command_fail(cb, parse_res); + return; + } + if(dh_onewire_init_helper(cb, fields, &parse_pins)) + return; + } + parse_pins.count = dhonewire_dht_read(parse_pins.data, sizeof(parse_pins.data)); + if(parse_pins.count) + dh_command_done_buf(cb, parse_pins.data, parse_pins.count); + else + dh_command_fail(cb, "No response"); +} + diff --git a/firmware-src/sources/devices/dht.h b/firmware-src/sources/devices/dht.h index 8ed2734..2a13d74 100644 --- a/firmware-src/sources/devices/dht.h +++ b/firmware-src/sources/devices/dht.h @@ -30,4 +30,17 @@ char *dht11_read(int pin, int *humidity, int *temperature); */ char *dht22_read(int pin, float *humidity, float *temperature); + +/** + * \brief Read data from DHT like devices. + * \details Checksum will not be checked. + * \param[out] buf Buffer for data. + * \param[in] len Buffer length in bytes. + * \return Number of read bytes on success, zero on error. + */ +int dhonewire_dht_read(char *buf, unsigned int len); + +#include "dhsender_data.h" +void dh_handle_onewire_dht_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen); + #endif /* SOURCES_DEVICES_DHT_H_ */ diff --git a/firmware-src/sources/devices/ds18b20.c b/firmware-src/sources/devices/ds18b20.c index 8f83ef4..8eef037 100644 --- a/firmware-src/sources/devices/ds18b20.c +++ b/firmware-src/sources/devices/ds18b20.c @@ -7,7 +7,7 @@ * */ #include "ds18b20.h" -#include "dhonewire.h" +#include "DH/onewire.h" #include "dhutils.h" #include @@ -19,22 +19,22 @@ char * ICACHE_FLASH_ATTR ds18b20_read(int pin, float *temperature) { int16_t *res = (int16_t *)&in_buf[0]; out_buf[0] = 0xCC; if(pin != DS18B20_NO_PIN) { - if(!dhonewire_set_pin(pin)) { + if(!!dh_onewire_set_pin(pin)) { return "Failed to set up onewire pin"; } } out_buf[1] = 0x44; // start measure, use defaults - if(!dhonewire_write(out_buf, sizeof(out_buf))) { + if (!!dh_onewire_write(out_buf, sizeof(out_buf))) { return "No response"; } delay_ms(750); // maximum possible time for measure out_buf[1] = 0xBE; // read memory - if(!dhonewire_write(out_buf, sizeof(out_buf))) { + if (!!dh_onewire_write(out_buf, sizeof(out_buf))) { return "Failed to read"; } - if(!dhonewire_read(in_buf, sizeof(in_buf))) { + if (!!dh_onewire_read(in_buf, sizeof(in_buf))) { return "Failed to read data"; } *temperature = (*res / 16.0f); // default precision diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index e841fd8..8722a65 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -15,13 +15,13 @@ #include "DH/uart.h" #include "DH/spi.h" #include "DH/i2c.h" +#include "DH/pwm.h" +#include "DH/onewire.h" #include "dhnotification.h" #include "snprintf.h" #include "dhcommand_parser.h" #include "dhterminal.h" -#include "dhonewire.h" #include "dhdebug.h" -#include "DH/pwm.h" #include "dhutils.h" #include "devices/ds18b20.h" #include "devices/dht.h" @@ -52,170 +52,6 @@ #include #include -LOCAL int ICACHE_FLASH_ATTR onewire_init(COMMAND_RESULT *cb, ALLOWED_FIELDS fields, gpio_command_params *parse_pins) { - if(fields & AF_PIN) { - if(dhonewire_set_pin(parse_pins->pin) == 0) { - dh_command_fail(cb, "Wrong onewire pin"); - return 1; - } - } - return 0; -} - -#if 1 // onewire commands - -/** - * @brief Do "onewire/master/read" command. - */ -static void ICACHE_FLASH_ATTR do_onewire_master_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_PIN | AF_DATA | AF_COUNT, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & AF_COUNT) == 0 || parse_pins.count == 0 || parse_pins.count > INTERFACES_BUF_SIZE) { - dh_command_fail(cb, "Wrong read size"); - return; - } - if((fields & AF_DATA) == 0) { - dh_command_fail(cb, "Command for reading is not specified"); - return; - } - if(onewire_init(cb, fields, &parse_pins)) - return; - if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { - dh_command_fail(cb, "No response"); - return; - } - dhonewire_read(parse_pins.data, parse_pins.count); - dh_command_done_buf(cb, parse_pins.data, parse_pins.count); -} - - -/** - * @brief Do "onewire/master/write" commands. - */ -static void ICACHE_FLASH_ATTR do_onewire_master_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char * parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_PIN | AF_DATA, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(onewire_init(cb, fields, &parse_pins)) - return; - if(dhonewire_write(parse_pins.data, parse_pins.data_len) == 0) { - dh_command_fail(cb, "No response"); - return; - } - dh_command_done(cb, ""); -} - -/** - * Do "onewire/master/search" or "onewire/master/alarm" commands. - */ -static void ICACHE_FLASH_ATTR do_onewire_master_search(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(onewire_init(cb, fields, &parse_pins)) - return; - } - parse_pins.data_len = sizeof(parse_pins.data) ; - - int check = os_strcmp(command, "onewire/master/search"); - if(dhonewire_search(parse_pins.data, (unsigned long *)&parse_pins.data_len, (check == 0) ? 0xF0 : 0xEC, dhonewire_get_pin())) - cb->callback(cb->data, DHSTATUS_OK, RDT_SEARCH64, dhonewire_get_pin(), parse_pins.data, parse_pins.data_len); - else - dh_command_fail(cb, "Error during search"); -} - - -/** - * @brief Do "onewire/master/int" command. - */ -static void ICACHE_FLASH_ATTR do_onewire_master_int(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), AF_DISABLE | AF_PRESENCE, &fields); - if(parse_res) - dh_command_fail(cb, parse_res); - else if(fields == 0) - dh_command_fail(cb, "Wrong action"); - else if(dhonewire_int(parse_pins.pins_to_presence, parse_pins.pins_to_disable)) - dh_command_done(cb, ""); - else - dh_command_fail(cb, "Unsuitable pin"); -} - - -/** - * @brief Do "onewire/dht/read" command. - */ -static void ICACHE_FLASH_ATTR do_onewire_dht_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(onewire_init(cb, fields, &parse_pins)) - return; - } - parse_pins.count = dhonewire_dht_read(parse_pins.data, sizeof(parse_pins.data)); - if(parse_pins.count) - dh_command_done_buf(cb, parse_pins.data, parse_pins.count); - else - dh_command_fail(cb, "No response"); -} - - -/** - * @brief Do "onewire/ws2812b/write" command. - */ -static void ICACHE_FLASH_ATTR do_onewire_ws2812b_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & AF_DATA) == 0) { - dh_command_fail(cb, "Data not specified"); - return; - } - if(onewire_init(cb, fields, &parse_pins)) - return; - dhonewire_ws2812b_write(parse_pins.data, parse_pins.data_len); - dh_command_done(cb, ""); -} - -#endif // onewire commands - #if 1 // devices commands /** @@ -232,7 +68,7 @@ static void ICACHE_FLASH_ATTR do_devices_ds18b20_read(COMMAND_RESULT *cb, const dh_command_fail(cb, parse_res); return; } - if(onewire_init(cb, fields, &parse_pins)) + if(dh_onewire_init_helper(cb, fields, &parse_pins)) return; } float temperature; @@ -259,7 +95,7 @@ static void ICACHE_FLASH_ATTR do_devices_dht11_read(COMMAND_RESULT *cb, const ch dh_command_fail(cb, parse_res); return; } - if(onewire_init(cb, fields, &parse_pins)) + if(dh_onewire_init_helper(cb, fields, &parse_pins)) return; } @@ -288,7 +124,7 @@ static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const ch dh_command_fail(cb, parse_res); return; } - if(onewire_init(cb, fields, &parse_pins)) + if(dh_onewire_init_helper(cb, fields, &parse_pins)) return; } @@ -1139,13 +975,15 @@ RO_DATA struct { { "spi/master/write", dh_handle_spi_master_write}, #endif /* DH_COMMANDS_SPI */ - { "onewire/master/read", do_onewire_master_read}, - { "onewire/master/write", do_onewire_master_write}, - { "onewire/master/search", do_onewire_master_search}, - { "onewire/master/alarm", do_onewire_master_search}, - { "onewire/master/int", do_onewire_master_int}, - { "onewire/dht/read", do_onewire_dht_read}, - { "onewire/ws2812b/write", do_onewire_ws2812b_write}, +#ifdef DH_COMMANDS_ONEWIRE + { "onewire/master/read", dh_handle_onewire_master_read}, + { "onewire/master/write", dh_handle_onewire_master_write}, + { "onewire/master/search", dh_handle_onewire_master_search}, + { "onewire/master/alarm", dh_handle_onewire_master_search}, + { "onewire/master/int", dh_handle_onewire_master_int}, + { "onewire/dht/read", dh_handle_onewire_dht_read}, + { "onewire/ws2812b/write", dh_handle_onewire_ws2812b_write}, +#endif /* DH_COMMANDS_ONEWIRE */ { "devices/ds18b20/read", do_devices_ds18b20_read}, { "devices/dht11/read", do_devices_dht11_read}, diff --git a/firmware-src/sources/dhnotification.c b/firmware-src/sources/dhnotification.c index 8e51ed2..d2033fc 100644 --- a/firmware-src/sources/dhnotification.c +++ b/firmware-src/sources/dhnotification.c @@ -49,10 +49,15 @@ void ICACHE_FLASH_ATTR dh_uart_buf_rcv_cb(const void *buf, size_t len) { dhsender_notification(RNT_NOTIFICATION_UART, RDT_DATA_WITH_LEN, buf, len); } - void ICACHE_FLASH_ATTR dhonewire_search_result(unsigned int pin_number, char *buf, unsigned long len) { - if(dhmem_isblock()) { + +/* + * dh_onewire_search_result() implementation. + */ +void ICACHE_FLASH_ATTR dh_onewire_search_result(unsigned int pin, const void *buf, size_t len) +{ + if (dhmem_isblock()) { dhstat_got_notification_dropped(); return; } - dhsender_notification(RNT_NOTIFICATION_ONEWIRE, RDT_SEARCH64, pin_number, buf, len); - } + dhsender_notification(RNT_NOTIFICATION_ONEWIRE, RDT_SEARCH64, pin, buf, len); +} diff --git a/firmware-src/sources/dhonewire.c b/firmware-src/sources/dhonewire.c deleted file mode 100644 index 552e332..0000000 --- a/firmware-src/sources/dhonewire.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * dhonewire.c - * - * Copyright 2015 DeviceHive - * - * Author: Nikolay Khabarov - * - * Description: Software onewire implementation - * - */ -#include "dhonewire.h" -#include "DH/gpio.h" -#include "user_config.h" -#include "dhdebug.h" - -#include -#include -#include -#include -#include -#include -#include - -LOCAL unsigned int mOneWirePin = 0; -LOCAL unsigned int mIntPins = 0; -LOCAL unsigned int mIntErrorCount = 0; -LOCAL unsigned int mWaitSearchPins = 0; -LOCAL os_timer_t mOWIntTimer; - -#define ONEWIRE_MAX_INT_SEARCH_ATTEMPS 5 -#define ONEWIRE_MAX_INT_DELAY_MS 20 -#define ONEWIRE_RESET_LENGHT_US 640 -#define ONEWIRE_DHT_RESET_LENGTH_US 25000 -#define ONEWIRE_DHT_TIMEOUT_US 200 - -LOCAL void ICACHE_FLASH_ATTR lock_int(void) { - if(mIntPins) - dh_gpio_subscribe_extra_int(mIntPins, 0, 0, 0); -} - -LOCAL void ICACHE_FLASH_ATTR unlock_int(void) { - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, mIntPins); - dh_gpio_subscribe_extra_int(0, 0, mIntPins, 0); -} - -int ICACHE_FLASH_ATTR dhonewire_set_pin(unsigned int pin) { - if((DH_GPIO_PIN(pin) & DH_GPIO_SUITABLE_PINS) == 0) - return 0; - mOneWirePin = pin; - return 1; -} - -int ICACHE_FLASH_ATTR dhonewire_get_pin(void) { - return mOneWirePin; -} - -LOCAL int ICACHE_FLASH_ATTR dhonewire_reset(unsigned int pin, unsigned int reset_length, int exit_on_presence) { - system_soft_wdt_feed(); - const unsigned int pinstate = gpio_input_get() & pin; - unsigned int i; - unsigned int presence = 0; - dh_gpio_open_drain(pin, 0); - dh_gpio_pull_up(pin, 0); - dh_gpio_prepare_pins(pin, 1); - if(pinstate == 0) { - gpio_output_set(pin, 0, pin, 0); - os_delay_us(500); - } - if((gpio_input_get() & pin) == 0) - return 0; - // send RESET - gpio_output_set(0, pin, pin, 0); - os_delay_us(reset_length); - gpio_output_set(pin, 0, pin, 0); - // check RESPONCE - for (i = 0; i < 480; i++) { // wait at least 480 msec - if(presence == 0 && i < 240) { - if(i > 15) { - if((gpio_input_get() & pin) == 0) - presence = 1; - } - } else if(exit_on_presence) { - if(presence) { - if(gpio_input_get() & pin) - return 1; - } else { - return 0; - } - } - os_delay_us(1); - } - return presence; -} - -LOCAL char ICACHE_FLASH_ATTR dhonewire_act_bit(char bit, unsigned int pin) { - // time slot start - char res = 0; - ETS_INTR_LOCK(); - gpio_output_set(0, pin, pin, 0); - os_delay_us(5); - if(bit) { - gpio_output_set(pin, 0, pin, 0); - os_delay_us(5); - if(gpio_input_get() & pin) - res |= bit; - ETS_INTR_UNLOCK(); - os_delay_us(80); - } else { - os_delay_us(85); - gpio_output_set(pin, 0, pin, 0); - ETS_INTR_UNLOCK(); - } - os_delay_us(5); // pause between time slots - return res; -} - -LOCAL char ICACHE_FLASH_ATTR dhonewire_act_byte(char byte, unsigned int pin) { - system_soft_wdt_feed(); - unsigned int i = 0; - char res = 0; - for(i = 0; i < 8; i++) - res |= dhonewire_act_bit(byte & (1 << i), pin); - return res; -} - -int ICACHE_FLASH_ATTR dhonewire_write(const char *buf, unsigned int len) { - const unsigned int pin = (1 << mOneWirePin); - lock_int(); - if(dhonewire_reset(pin, ONEWIRE_RESET_LENGHT_US, 0) == 0) { - unlock_int(); - return 0; - } - while(len--) - dhonewire_act_byte(*buf++, pin); - unlock_int(); - return 1; -} - -int ICACHE_FLASH_ATTR dhonewire_read(char *buf, unsigned int len) { - const unsigned int pin = (1 << mOneWirePin); - lock_int(); - while(len--) - *buf++ = dhonewire_act_byte(0xFF, pin); - unlock_int(); - return 1; -} - -LOCAL unsigned int ICACHE_FLASH_ATTR dhonewire_check_crc(char *data) { - unsigned int seed = 0; - int i, j; - for (i = 0; i < 8; i++) { - char b = data[i]; - for (j = 0; j < 8; j++) { - if((seed ^ b) & 0x01) - seed = (seed >> 1) ^ 0x8C; - else - seed >>= 1; - b >>= 1; - } - } - return seed; -} - -int ICACHE_FLASH_ATTR dhonewire_search(char *buf, unsigned long *len, char command, unsigned int pin_number) { - const unsigned int pin = (1 << pin_number); - int i; - char address[8] = {0}; - const unsigned int bitCount = sizeof(address) * 8; - int lastAmbiguity = bitCount; - int ambiguity; - unsigned int copyied = 0; - if(*len < 8) - return 0; - lock_int(); - do { - int res = dhonewire_reset(pin, ONEWIRE_RESET_LENGHT_US, 0); - if(res == 0) { - unlock_int(); - if(lastAmbiguity == bitCount) { - *len = 0; // devices are not connected - return 1; - } - return 0; - } - dhonewire_act_byte(command, pin); - ambiguity = -1; - for(i = 0; i < bitCount; i++) { - const int byte = i / 8; - if((gpio_input_get() & pin) == 0) { - unlock_int(); - return 0; - } - const char bit = 1 << (i % 8); - const char bit1 = dhonewire_act_bit(0x1, pin); - const char bit2 = dhonewire_act_bit(0x1, pin); - if(bit1 && bit2) { - unlock_int(); - if(i == 0 && lastAmbiguity == bitCount) { - *len = 0; // first interaction, no devices found - return 1; - } - dhdebug("Onewire error while search at %u bit", i); - return 0; - } else if(bit1 && bit2 == 0) { - address[byte] |= bit; - dhonewire_act_bit(0x1, pin); - } else if(bit1 == 0 && bit2) { - address[byte] &= ~bit; - dhonewire_act_bit(0x0, pin); - } else { - if(i < lastAmbiguity) { - address[byte] &= ~bit; - dhonewire_act_bit(0x0, pin); - ambiguity = i; - } else { - address[byte] |= bit; - dhonewire_act_bit(0x1, pin); - } - } - } - lastAmbiguity = ambiguity; - if(dhonewire_check_crc(address) == 0) { - os_memcpy(buf, address, sizeof(address)); - buf += sizeof(address); - copyied += sizeof(address); - if(copyied + sizeof(address) > *len) - break; - } else { - unlock_int(); - return 0; - } - } while (lastAmbiguity >= 0); - *len = copyied; - unlock_int(); - return 1; -} - -LOCAL void ICACHE_FLASH_ATTR dhonewire_int_search(void *arg) { - int i; - for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { - const DHGpioPinMask pin = DH_GPIO_PIN(i); - if(pin & mWaitSearchPins) { - char buf[INTERFACES_BUF_SIZE]; - unsigned long len = sizeof(buf); - unsigned int res = dhonewire_search(buf, &len, 0xF0, i); - if(len == 0) - res = 0; - if(res) - dhonewire_search_result(i, buf, len); - else - mIntErrorCount++; - if(res || mIntErrorCount > ONEWIRE_MAX_INT_SEARCH_ATTEMPS) { - mIntErrorCount = 0; - mWaitSearchPins &= ~pin; - } - - // rearm timer to avoid long operating in timer interruption. - if(mWaitSearchPins) { - os_timer_disarm(&mOWIntTimer); - os_timer_setfn(&mOWIntTimer, (os_timer_func_t *)dhonewire_int_search, NULL); - os_timer_arm(&mOWIntTimer, ONEWIRE_MAX_INT_DELAY_MS, 0); - } - break; - } - } -} - -void ICACHE_FLASH_ATTR dh_gpio_extra_int_cb(DHGpioPinMask caused_pins) { - os_timer_disarm(&mOWIntTimer); - mWaitSearchPins |= caused_pins; - os_timer_setfn(&mOWIntTimer, (os_timer_func_t *)dhonewire_int_search, NULL); - os_timer_arm(&mOWIntTimer, ONEWIRE_MAX_INT_DELAY_MS, 0); -} - -int ICACHE_FLASH_ATTR dhonewire_int(unsigned int search_pins, unsigned int disable_pins) { - if(!!dh_gpio_subscribe_extra_int(disable_pins, 0, search_pins, 0)) - return 0; - mIntPins |= search_pins; - mIntPins &= ~disable_pins; - return 1; -} - -LOCAL unsigned int ICACHE_FLASH_ATTR donewire_dht_measure_high(unsigned int pin) { - unsigned int counter = 0; - while((gpio_input_get() & pin) == 0) { - if(counter > ONEWIRE_DHT_TIMEOUT_US) - return 0; - os_delay_us(1); - counter++; - } - counter = 0; - while((gpio_input_get() & pin)) { - if(counter > ONEWIRE_DHT_TIMEOUT_US) - return ONEWIRE_DHT_TIMEOUT_US; - os_delay_us(1); - counter++; - } - return counter; -} - -int ICACHE_FLASH_ATTR dhonewire_dht_read(char *buf, unsigned int len) { - const unsigned int pin = (1 << mOneWirePin); - if(dhonewire_reset(pin, ONEWIRE_DHT_RESET_LENGTH_US, 1) == 0) - return 0; - ETS_INTR_LOCK(); - unsigned int i; - if(donewire_dht_measure_high(pin) >= ONEWIRE_DHT_TIMEOUT_US) { // wait till response finish - ETS_INTR_UNLOCK(); - return 0; - } - for(i = 0; i / 8 < len; i++) { - unsigned int time = donewire_dht_measure_high(pin); - if(time >= ONEWIRE_DHT_TIMEOUT_US || time <= 10) { - break; - } else { - const char bit = 1 << (7 - i % 8); - if(time > 25) - buf[i / 8] |= bit; - else - buf[i / 8] &= ~bit; - } - system_soft_wdt_feed(); - } - ETS_INTR_UNLOCK(); - return i / 8; -} - -/*LOCAL*/ void ws2812b_write(const char *buf, const char *ebuf, unsigned int pin, - unsigned T, unsigned S, unsigned L) { - // due to the strict timings, this method should be in IRAM, - // don't mark it with ICACHE_FLASH_ATTR or even LOCAL - - // send each byte in real time - int j; - unsigned ss, se, r; - for( ; buf < ebuf; buf++) { - for(j = 0x80; j >= 0x01; j >>= 1) { - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pin); - asm volatile("rsr %0, ccount" : "=r"(r)); - ss = r + ((*buf & j) ? L : S); - se = r + T; - do { - asm volatile("rsr %0, ccount" : "=r"(r)); - } while(r < ss); - GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pin); - do { - asm volatile("rsr %0, ccount" : "=r"(r)); - } while(r < se); - } - } -} - -void ICACHE_FLASH_ATTR dhonewire_ws2812b_write(const char *buf, unsigned int len) { - // init number of CPU tacts for delay - // delays are lower that spec on 50ns due to GPIO latency, anyway spec allows 150ns jitter. - const int freq = system_get_cpu_freq(); // MHz - const unsigned S = 350 * freq / 1000; - const unsigned L = 750 * freq / 1000; - const char *ebuf = buf + len; - const unsigned int pin = (1 << mOneWirePin); - ETS_INTR_LOCK(); - - // send reset, low more then 50 ms - gpio_output_set(0, pin, pin, 0); // low and initialize - os_delay_us(50); - ws2812b_write(buf, ebuf, pin, S + L, S, L); - - ETS_INTR_UNLOCK(); -} diff --git a/firmware-src/sources/dhonewire.h b/firmware-src/sources/dhonewire.h deleted file mode 100644 index 9f1c406..0000000 --- a/firmware-src/sources/dhonewire.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * \file dhonewire.h - * \brief Software implementation of onewire interface for ESP8266. - * \author Nikolay Khabarov - * \date 2015 - * \copyright DeviceHive MIT - */ - -#ifndef _DHONEWIRE_H_ -#define _DHONEWIRE_H_ - - -/** - * \brief Set pin for onewire, but not initialize it. - * \param[in] cs_pin Pin number. - * \return Non zero value on success, zero on error. - */ -int dhonewire_set_pin(unsigned int pin); - -/** - * \brief Get pin that configured for onewire. - * \return Pin number. - */ -int dhonewire_get_pin(void); - -/** - * \brief Write data to onewire bus. - * \details Pin will be initialized automatically. - * \param[in] buf Buffer with data. - * \param[in] len Data length in bytes. - * \return Non zero value on success, zero on error. - */ -int dhonewire_write(const char *buf, unsigned int len); - -/** - * \brief Read data from onewire bus. - * \details Pin will NOT be initialized automatically, will use previous pin. - * \param[out] buf Buffer for data. - * \param[in] len Number of bytes to read, buffer have to be at least the same size. - * \return Non zero value on success, zero on error. - */ -int dhonewire_read(char *buf, unsigned int len); - -// command 0xF0 // SEARCH ROM - -/** - * \brief Search for onewire devices. - * \param[out] buf Buffer to store 64 bits addresses. - * \param[in,out] len Receives number of bytes allowed in buffer, returns number of copied bytes. Can return 0, that means no devices were found. - * \param[in] command Bus command for search, 0xF0 - SEARCH ROM, 0xEC - ALARM SEARCH. - * \param[in] pin Pin number for using during search. - * \return Non zero value on success, zero on error. - */ -int dhonewire_search(char *buf, unsigned long *len, char command, unsigned int pin_number); - -/** - * \brief Enable interruption. - * \param[in] search_pins Pins that will awaiting for PRESENSE and then runs SEARCH command. - * \param[in] disable_pins Pin mask for disabling. - * \return Non zero value on success, zero on error. - */ -int dhonewire_int(unsigned int search_pins, unsigned int disable_pins); - -/** - * \brief Callback for search result. - * \param[in] is_ok Non zero value on success, zero on error. - * \param[in] pin_number Pin number where found. - * \param[in] buf Buffer with 64 bits addresses. - * \param[in] len Buffer length in bytes. - * \return Non zero value on success, zero on error. - */ -extern void dhonewire_search_result(unsigned int pin_number, char *buf, unsigned long len); - -/** - * \brief Read data from DHT like devices. - * \details Checksum will not be checked. - * \param[out] buf Buffer for data. - * \param[in] len Buffer length in bytes. - * \return Number of read bytes on success, zero on error. - */ -int dhonewire_dht_read(char *buf, unsigned int len); - -/** - * \brief Write data to WS2812b like device - * \param[in] pin 1-wire pin for communication. - * \param[in] buf Pointer to buffer with data. - * \param[in] len Buffer length. - */ -void dhonewire_ws2812b_write(const char *buf, unsigned int len); - -#endif /* _DHONEWIRE_H_ */ diff --git a/firmware-src/sources/user_config.h b/firmware-src/sources/user_config.h index 98f2284..c2c5c21 100644 --- a/firmware-src/sources/user_config.h +++ b/firmware-src/sources/user_config.h @@ -43,5 +43,6 @@ #define DH_COMMANDS_UART // enable UART commands #define DH_COMMANDS_I2C // enable I2C commands #define DH_COMMANDS_SPI // enable SPI commands +#define DH_COMMANDS_ONEWIRE // enable onewire commands #endif /* _USER_CONFIG_H_ */ From 4f370e5f0245c8da19356eeae89ef6aabdd165c8 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 26 Apr 2017 04:07:23 +0300 Subject: [PATCH 35/83] move all command handlers to dedicated files under sources/commands/ subdirectory --- firmware-src/Makefile | 2 +- firmware-src/sources/DH/adc.c | 77 ------- firmware-src/sources/DH/adc.h | 20 -- firmware-src/sources/DH/gpio.c | 106 ---------- firmware-src/sources/DH/gpio.h | 26 --- firmware-src/sources/DH/i2c.c | 119 +---------- firmware-src/sources/DH/i2c.h | 28 --- firmware-src/sources/DH/onewire.c | 222 +------------------- firmware-src/sources/DH/onewire.h | 51 ----- firmware-src/sources/DH/pwm.c | 32 --- firmware-src/sources/DH/pwm.h | 12 -- firmware-src/sources/DH/spi.c | 93 -------- firmware-src/sources/DH/spi.h | 20 -- firmware-src/sources/DH/uart.c | 146 +------------ firmware-src/sources/DH/uart.h | 34 --- firmware-src/sources/commands/adc_cmd.c | 84 ++++++++ firmware-src/sources/commands/adc_cmd.h | 29 +++ firmware-src/sources/commands/dht_cmd.c | 40 ++++ firmware-src/sources/commands/dht_cmd.h | 18 ++ firmware-src/sources/commands/gpio_cmd.c | 113 ++++++++++ firmware-src/sources/commands/gpio_cmd.h | 36 ++++ firmware-src/sources/commands/i2c_cmd.c | 125 +++++++++++ firmware-src/sources/commands/i2c_cmd.h | 38 ++++ firmware-src/sources/commands/onewire_cmd.c | 146 +++++++++++++ firmware-src/sources/commands/onewire_cmd.h | 52 +++++ firmware-src/sources/commands/pwm_cmd.c | 40 ++++ firmware-src/sources/commands/pwm_cmd.h | 22 ++ firmware-src/sources/commands/spi_cmd.c | 101 +++++++++ firmware-src/sources/commands/spi_cmd.h | 29 +++ firmware-src/sources/commands/uart_cmd.c | 153 ++++++++++++++ firmware-src/sources/commands/uart_cmd.h | 43 ++++ firmware-src/sources/commands/ws2812b_cmd.c | 103 +++++++++ firmware-src/sources/commands/ws2812b_cmd.h | 23 ++ firmware-src/sources/devices/dht.c | 24 --- firmware-src/sources/devices/dht.h | 3 - firmware-src/sources/dhcommands.c | 15 +- 36 files changed, 1208 insertions(+), 1017 deletions(-) create mode 100644 firmware-src/sources/commands/adc_cmd.c create mode 100644 firmware-src/sources/commands/adc_cmd.h create mode 100644 firmware-src/sources/commands/dht_cmd.c create mode 100644 firmware-src/sources/commands/dht_cmd.h create mode 100644 firmware-src/sources/commands/gpio_cmd.c create mode 100644 firmware-src/sources/commands/gpio_cmd.h create mode 100644 firmware-src/sources/commands/i2c_cmd.c create mode 100644 firmware-src/sources/commands/i2c_cmd.h create mode 100644 firmware-src/sources/commands/onewire_cmd.c create mode 100644 firmware-src/sources/commands/onewire_cmd.h create mode 100644 firmware-src/sources/commands/pwm_cmd.c create mode 100644 firmware-src/sources/commands/pwm_cmd.h create mode 100644 firmware-src/sources/commands/spi_cmd.c create mode 100644 firmware-src/sources/commands/spi_cmd.h create mode 100644 firmware-src/sources/commands/uart_cmd.c create mode 100644 firmware-src/sources/commands/uart_cmd.h create mode 100644 firmware-src/sources/commands/ws2812b_cmd.c create mode 100644 firmware-src/sources/commands/ws2812b_cmd.h diff --git a/firmware-src/Makefile b/firmware-src/Makefile index ba6ca8a..a91bb57 100644 --- a/firmware-src/Makefile +++ b/firmware-src/Makefile @@ -14,7 +14,7 @@ TARGETELF = $(OBJDIR)/devicehive.elf INCLUDEDIRS = $(addprefix -I,$(SDKPATH)/include $(CURDIR)/sources) LIBDIR = $(addprefix -L,$(SDKPATH)/lib) LIBS = $(addprefix -l,c gcc phy pp net80211 lwip wpa main json crypto) -SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) $(wildcard sources/DH/*.c) +SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) $(wildcard sources/DH/*.c) $(wildcard sources/commands/*.c) OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:%.c=%.o)) GITVER = $(shell git rev-parse HEAD 2> /dev/null || echo \"not a git repo\") CFLAGS = -O2 -Wall -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -nostdlib -std=gnu89 -DFIRMWARE_GIT_REVISION=\"$(GITVER)\" diff --git a/firmware-src/sources/DH/adc.c b/firmware-src/sources/DH/adc.c index f28541b..de0f970 100644 --- a/firmware-src/sources/DH/adc.c +++ b/firmware-src/sources/DH/adc.c @@ -45,80 +45,3 @@ void ICACHE_FLASH_ATTR dh_adc_loop(unsigned int period_ms) os_timer_arm(&mTimer, period_ms, 1); } } - - -#ifdef DH_COMMANDS_ADC // ADC command handlers -#include "dhcommand_parser.h" -#include - -/** - * Minimum notification timeout, milliseconds. - */ -#define MIN_TIMEOUT_MS 250 - - -/** - * Maximum notification timeout, milliseconds. - */ -#define MAX_TIMEOUT_MS 0x7fffff - - -/* - * dh_handle_adc_read() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - if (params_len) { - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, AF_READ, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - - if (info.pins_to_read != DH_ADC_SUITABLE_PINS) { - dh_command_fail(cmd_res, "Unknown ADC channel"); - return; // FAILED - } - } - - // OK, report ADC value - cmd_res->callback(cmd_res->data, DHSTATUS_OK, - RDT_FLOAT, dh_adc_get_value()); -} - - -/* - * dh_handle_adc_int() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, AF_VALUES, &fields); - // TODO: use AF_TIMEOUT here? - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } else if (info.pin_value_readed != DH_ADC_SUITABLE_PINS) { - dh_command_fail(cmd_res, "Unknown ADC channel"); - return; // FAILED - } - - const unsigned int timeout = info.storage.uint_values[0]; - if ((timeout != 0 && timeout < MIN_TIMEOUT_MS) || timeout > MAX_TIMEOUT_MS) { - dh_command_fail(cmd_res, "Wrong period"); - } else { - dh_adc_loop(timeout); - dh_command_done(cmd_res, ""); - } -} - -#endif /* DH_COMMANDS_ADC */ diff --git a/firmware-src/sources/DH/adc.h b/firmware-src/sources/DH/adc.h index bfdb2c0..3372e51 100644 --- a/firmware-src/sources/DH/adc.h +++ b/firmware-src/sources/DH/adc.h @@ -7,8 +7,6 @@ #ifndef _DH_ADC_H_ #define _DH_ADC_H_ -#include "user_config.h" - /** * @brief ADC suitable channels. */ @@ -36,22 +34,4 @@ void dh_adc_loop(unsigned int period_ms); // TODO: consider to use callback function pointer extern void dh_adc_loop_value_cb(float value); - -#ifdef DH_COMMANDS_ADC // ADC command handlers -#include "dhsender_data.h" - -/** - * @brief Handle "adc/read" command. - */ -void dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "adc/int" command. - */ -void dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_ADC */ #endif /* _DH_ADC_H_ */ diff --git a/firmware-src/sources/DH/gpio.c b/firmware-src/sources/DH/gpio.c index 14689c4..1db2a35 100644 --- a/firmware-src/sources/DH/gpio.c +++ b/firmware-src/sources/DH/gpio.c @@ -337,109 +337,3 @@ int ICACHE_FLASH_ATTR dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, return r; } - - -#ifdef DH_COMMANDS_GPIO // GPIO command handlers -#include "dhcommand_parser.h" -#include - -/** - * Minimum notification timeout, milliseconds. - */ -#define MIN_TIMEOUT_MS 50 - - -/** - * Maximum notification timeout, milliseconds. - */ -#define MAX_TIMEOUT_MS 0x7fffff - - -/* - * dh_handle_gpio_write() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, - 0, AF_SET | AF_CLEAR, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else if (!(fields & (AF_SET | AF_CLEAR))) { - dh_command_fail(cmd_res, "Dummy request"); - } else if (!!dh_gpio_write(info.pins_to_set, info.pins_to_clear)) { - dh_command_fail(cmd_res, "Unsuitable pin"); - } else { - dh_command_done(cmd_res, ""); - } -} - - -/* - * dh_handle_gpio_read() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - if (params_len) { - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, 0, - AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - - // initialize GPIO as input - if (!!dh_gpio_input(info.pins_to_init, - info.pins_to_pullup, - info.pins_to_nopull)) { - dh_command_fail(cmd_res, "Wrong initialization parameters"); - return; // FAILED - } - } - - // OK, read GPIO input - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_GPIO, - 0, dh_gpio_read(), system_get_time(), - DH_GPIO_SUITABLE_PINS); -} - - -/* - * dh_handle_gpio_int() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), - AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else if (fields == 0) { - dh_command_fail(cmd_res, "Wrong action"); - } else if (info.timeout < MIN_TIMEOUT_MS || info.timeout > MAX_TIMEOUT_MS) { - dh_command_fail(cmd_res, "Timeout out of range"); - } else if (!!dh_gpio_subscribe_int(info.pins_to_disable, - info.pins_to_rising, - info.pins_to_falling, - info.pins_to_both, - info.timeout)) { - dh_command_fail(cmd_res, "Unsuitable pin"); - } else { - dh_command_done(cmd_res, ""); - } -} - -#endif /* DH_COMMANDS_GPIO */ diff --git a/firmware-src/sources/DH/gpio.h b/firmware-src/sources/DH/gpio.h index d3480d1..f0be8ba 100644 --- a/firmware-src/sources/DH/gpio.h +++ b/firmware-src/sources/DH/gpio.h @@ -8,7 +8,6 @@ #define _DH_GPIO_H_ #include -#include "user_config.h" /** * @brief Pin mask type. @@ -163,29 +162,4 @@ int dh_gpio_subscribe_extra_int(DHGpioPinMask pins_disable, // TODO: consider to use callback function pointer extern void dh_gpio_extra_int_cb(DHGpioPinMask caused_pins); - -#ifdef DH_COMMANDS_GPIO // GPIO command handlers -#include "dhsender_data.h" - -/** - * @brief Handle "gpio/write" command. - */ -void dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "gpio/read" command. - */ -void dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "gpio/int" command. - */ -void dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_GPIO */ #endif /* _DH_GPIO_H_ */ diff --git a/firmware-src/sources/DH/i2c.c b/firmware-src/sources/DH/i2c.c index 9a030f0..2980c13 100644 --- a/firmware-src/sources/DH/i2c.c +++ b/firmware-src/sources/DH/i2c.c @@ -7,6 +7,7 @@ #include "DH/i2c.h" #include "DH/gpio.h" #include "DH/adc.h" +#include "user_config.h" #include #include @@ -284,121 +285,3 @@ int ICACHE_FLASH_ATTR dh_i2c_read(unsigned int address, void *buf, size_t len) { return i2c_act(address, (uint8_t*)buf, len, 1/*send_stop*/, 1); } - - - -#ifdef DH_COMMANDS_I2C // I2C command handlers -#include "dhcommand_parser.h" -#include - - -/* - * dh_i2c_init_helper() implementation. - */ -int ICACHE_FLASH_ATTR dh_i2c_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, const gpio_command_params *params) -{ - if ((fields & AF_ADDRESS) == 0) { - dh_command_fail(cmd_res, "Address not specified"); - return 1; // FAILED - } - - int init = ((fields & AF_SDA) != 0) + ((fields & AF_SCL) != 0); - if (init == 2) { - const int res = dh_i2c_init(params->SDA, params->SCL); - const char *err = dh_i2c_error_string(res); - if (err != 0) { - dh_command_fail(cmd_res, err); - return 1; // FAILED - } - } else if(init == 1) { - dh_command_fail(cmd_res, "Only one pin specified"); - return 1; // FAILED - } else { - dh_i2c_reinit(); - } - - return 0; // continue -} - - -/* - * dh_handle_i2c_master_read() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_i2c_master_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; - } - - if (!(fields & AF_COUNT)) - info.count = 2; - if (info.count == 0 || info.count > INTERFACES_BUF_SIZE) { - dh_command_fail(cmd_res, "Wrong read size"); - return; - } - - if (dh_i2c_init_helper(cmd_res, fields, &info)) - return; - - // write - if (fields & AF_DATA) { - int res = dh_i2c_write(info.address, info.data, info.data_len, 0); - err_msg = dh_i2c_error_string(res); - if (err_msg) { - dh_command_fail(cmd_res, err_msg); - return; - } - } - - // read - int res = dh_i2c_read(info.address, info.data, info.count); - err_msg = dh_i2c_error_string(res); - if (err_msg) { - dh_command_fail(cmd_res, err_msg); - } else { - dh_command_done_buf(cmd_res, info.data, info.count); - } -} - - -/* - * dh_handle_i2c_master_write() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_i2c_master_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; - } - - if((fields & AF_DATA) == 0) { - dh_command_fail(cmd_res, "Data not specified"); - return; - } - - if (dh_i2c_init_helper(cmd_res, fields, &info)) - return; - - const int res = dh_i2c_write(info.address, info.data, info.data_len, 1); - err_msg = dh_i2c_error_string(res); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else { - dh_command_done(cmd_res, ""); - } -} - -#endif /* DH_COMMANDS_I2C */ diff --git a/firmware-src/sources/DH/i2c.h b/firmware-src/sources/DH/i2c.h index cfa63f9..7bde79c 100644 --- a/firmware-src/sources/DH/i2c.h +++ b/firmware-src/sources/DH/i2c.h @@ -7,7 +7,6 @@ #ifndef _DH_I2C_H_ #define _DH_I2C_H_ -#include "user_config.h" #include /** @@ -68,31 +67,4 @@ int dh_i2c_write(unsigned int address, int dh_i2c_read(unsigned int address, void *buf, size_t len); - -#ifdef DH_COMMANDS_I2C // I2C command handlers -#include "dhcommand_parser.h" -#include "dhsender_data.h" - -/** - * @brief Helper function to initialize I2C bus. - * @return Non-zero if I2C was initialized. Zero otherwise. - */ -int dh_i2c_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, - const gpio_command_params *params); - - -/** - * @brief Handle "i2c/master/read" command. - */ -void dh_handle_i2c_master_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "i2c/master/write" command. - */ -void dh_handle_i2c_master_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_I2C */ #endif /* _DH_I2C_H_ */ diff --git a/firmware-src/sources/DH/onewire.c b/firmware-src/sources/DH/onewire.c index fe98448..f78821e 100644 --- a/firmware-src/sources/DH/onewire.c +++ b/firmware-src/sources/DH/onewire.c @@ -7,6 +7,7 @@ #include "DH/onewire.h" #include "DH/adc.h" #include "dhdebug.h" +#include "user_config.h" #include #include @@ -367,224 +368,3 @@ int ICACHE_FLASH_ATTR dh_onewire_int(DHGpioPinMask search_pins, DHGpioPinMask di mIntPins &= ~disable_pins; return 0; // OK } - - -#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers -#include "dhcommand_parser.h" -#include - - -/** - * @brief Initialization helper. - * @return Non-zero if onewire was initialized. Zero otherwise. - */ -int ICACHE_FLASH_ATTR dh_onewire_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, - const gpio_command_params *params) -{ - if (fields & AF_PIN) { - if (!!dh_onewire_set_pin(params->pin)) { - dh_command_fail(cmd_res, "Wrong onewire pin"); - return 1; // FAILED - } - } - - return 0; // continue -} - - -/** - * @brief Handle "onewire/master/read" command. - */ -void ICACHE_FLASH_ATTR dh_handle_onewire_master_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_PIN | AF_DATA | AF_COUNT, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - if ((fields & AF_COUNT) == 0 || info.count == 0 || info.count > INTERFACES_BUF_SIZE) { - dh_command_fail(cmd_res, "Wrong read size"); - return; // FAILED - } - if ((fields & AF_DATA) == 0) { - dh_command_fail(cmd_res, "Command for reading is not specified"); - return; - } - if (dh_onewire_init_helper(cmd_res, fields, &info)) - return; // FAILED - if (!!dh_onewire_write(info.data, info.data_len)) { - dh_command_fail(cmd_res, "No response"); - return; // FAILED - } - dh_onewire_read(info.data, info.count); - dh_command_done_buf(cmd_res, info.data, info.count); -} - - -/** - * @brief Handle "onewire/master/write" commands. - */ -void ICACHE_FLASH_ATTR dh_handle_onewire_master_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_PIN | AF_DATA, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - if (dh_onewire_init_helper(cmd_res, fields, &info)) - return; // FAILED - if (!!dh_onewire_write(info.data, info.data_len)) { - dh_command_fail(cmd_res, "No response"); - return; // FAILED - } - - dh_command_done(cmd_res, ""); -} - - -/** - * Handle "onewire/master/search" or "onewire/master/alarm" commands. - */ -void ICACHE_FLASH_ATTR dh_handle_onewire_master_search(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - if (params_len) { - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - if(dh_onewire_init_helper(cmd_res, fields, &info)) - return; // FAILED - } - - int check = os_strcmp(command, "onewire/master/search"); - size_t data_len = sizeof(info.data); - if (!!dh_onewire_search(info.data, &data_len, (check == 0) ? 0xF0 : 0xEC, dh_onewire_get_pin())) - dh_command_fail(cmd_res, "Error during search"); - else - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_SEARCH64, dh_onewire_get_pin(), info.data, data_len); -} - - -/** - * @brief Handle "onewire/master/int" command. - */ -void ICACHE_FLASH_ATTR dh_handle_onewire_master_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), - AF_DISABLE | AF_PRESENCE, &fields); - if (err_msg != 0) - dh_command_fail(cmd_res, err_msg); - else if (fields == 0) - dh_command_fail(cmd_res, "Wrong action"); - else if (!!dh_onewire_int(info.pins_to_presence, info.pins_to_disable)) - dh_command_fail(cmd_res, "Unsuitable pin"); - else - dh_command_done(cmd_res, ""); -} - - -/** - * Write data to WS2812b device. - */ -/*static*/ void ws2812b_write(const void *buf_, size_t len, DHGpioPinMask pin_mask, - unsigned int T, unsigned int S, unsigned int L) -{ - // due to the strict timings, this method should be in IRAM, - // don't mark it with ICACHE_FLASH_ATTR - - // send each byte in real time - unsigned int ss, se, r; - const uint8_t *buf = (const uint8_t*)buf_; - while (len--) { - int j, v = *buf++; - for (j = 0x80; j > 0; j >>= 1) { - GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pin_mask); - asm volatile("rsr %0, ccount" : "=r"(r)); - ss = r + ((v & j) ? L : S); - se = r + T; - do { - asm volatile("rsr %0, ccount" : "=r"(r)); - } while(r < ss); - GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pin_mask); - do { - asm volatile("rsr %0, ccount" : "=r"(r)); - } while(r < se); - } - } -} - - -/** - * @brief Write data to WS2812b like device - * @param[in] pin 1-wire pin for communication. - * @param[in] buf Pointer to buffer with data. - * @param[in] len Buffer length in bytes. - */ -static void ICACHE_FLASH_ATTR onewire_ws2812b_write(const void *buf, size_t len) -{ - // init number of CPU tacts for delay - // delays are lower that spec on 50ns due to GPIO latency, anyway spec allows 150ns jitter. - const int freq = system_get_cpu_freq(); // MHz - const unsigned S = 350 * freq / 1000; - const unsigned L = 750 * freq / 1000; - - ETS_INTR_LOCK(); - - // send reset, low more then 50 ms - const DHGpioPinMask pin = DH_GPIO_PIN(mOneWirePin); - gpio_output_set(0, pin, pin, 0); // low and initialize - os_delay_us(50); - ws2812b_write(buf, len, pin, S + L, S, L); - - ETS_INTR_UNLOCK(); -} - - -/** - * @brief Handle "onewire/ws2812b/write" command. - */ -// TODO: move this code to dedicated device file! -void ICACHE_FLASH_ATTR dh_handle_onewire_ws2812b_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - - const char *err_msg = parse_params_pins_set(params, params_len, &info, - DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; // FAILED - } - if (!(fields & AF_DATA)) { - dh_command_fail(cmd_res, "Data not specified"); - return; // FAILED - } - if (dh_onewire_init_helper(cmd_res, fields, &info)) - return; // FAILED - - onewire_ws2812b_write(info.data, info.data_len); - dh_command_done(cmd_res, ""); -} - -#endif /* DH_COMMANDS_ONEWIRE */ diff --git a/firmware-src/sources/DH/onewire.h b/firmware-src/sources/DH/onewire.h index e94a471..53eb6e4 100644 --- a/firmware-src/sources/DH/onewire.h +++ b/firmware-src/sources/DH/onewire.h @@ -7,7 +7,6 @@ #ifndef _DH_ONEWIRE_H_ #define _DH_ONEWIRE_H_ -#include "user_config.h" #include "DH/gpio.h" #include @@ -92,54 +91,4 @@ int dh_onewire_int(DHGpioPinMask search_pins, DHGpioPinMask disable_pins); // TODO: consider to use callback function pointer extern void dh_onewire_search_result(unsigned int pin, const void* buf, size_t len); - -#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers -#include "dhsender_data.h" -#include "dhcommand_parser.h" - -/** - * @brief Initialization helper. - * @return Non-zero if onewire was initialized. Zero otherwise. - */ -int dh_onewire_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, - const gpio_command_params *params); - - -/** - * @brief Handle "onewire/master/read" command. - */ -void dh_handle_onewire_master_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "onewire/master/write" commands. - */ -void dh_handle_onewire_master_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * Handle "onewire/master/search" or "onewire/master/alarm" commands. - */ -void dh_handle_onewire_master_search(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "onewire/master/int" command. - */ -void dh_handle_onewire_master_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "onewire/ws2812b/write" command. - */ -// TODO: move this code to dedicated device file! -void dh_handle_onewire_ws2812b_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_ONEWIRE */ - #endif /* _DH_ONEWIRE_H_ */ diff --git a/firmware-src/sources/DH/pwm.c b/firmware-src/sources/DH/pwm.c index 457af04..5e911f2 100644 --- a/firmware-src/sources/DH/pwm.c +++ b/firmware-src/sources/DH/pwm.c @@ -178,35 +178,3 @@ void ICACHE_FLASH_ATTR dh_pwm_disable(DHGpioPinMask pins) } mUsedPins &= ~pins; } - - -#ifdef DH_COMMANDS_PWM // PWM command handlers -#include "dhcommand_parser.h" -#include - -/* - * dh_handle_pwm_control() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_pwm_control(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_VALUES | AF_PERIOD | AF_COUNT, &fields); - - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else if (!!dh_pwm_start(info.storage.uint_values, - info.pin_value_readed, - (fields & AF_PERIOD) ? info.periodus - : dh_pwm_get_period_us(), - info.count)) { - dh_command_fail(cmd_res, "Wrong parameters"); - } else { - dh_command_done(cmd_res, ""); // OK - } -} - -#endif /* DH_COMMANDS_PWM */ diff --git a/firmware-src/sources/DH/pwm.h b/firmware-src/sources/DH/pwm.h index da5ec06..ed070a6 100644 --- a/firmware-src/sources/DH/pwm.h +++ b/firmware-src/sources/DH/pwm.h @@ -11,7 +11,6 @@ #define _DH_PWM_H_ #include "DH/gpio.h" -#include "user_config.h" /** * @brief Default PWM frequency in microseconds. @@ -55,15 +54,4 @@ unsigned int dh_pwm_get_period_us(void); */ void dh_pwm_disable(DHGpioPinMask pins); - -#ifdef DH_COMMANDS_PWM // PWM command handlers -#include "dhsender_data.h" - -/** - * @brief Handle "pwm/control" command. - */ -void dh_handle_pwm_control(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_PWM */ #endif /* _DH_PWM_H_ */ diff --git a/firmware-src/sources/DH/spi.c b/firmware-src/sources/DH/spi.c index 285bab8..0099221 100644 --- a/firmware-src/sources/DH/spi.c +++ b/firmware-src/sources/DH/spi.c @@ -202,96 +202,3 @@ void ICACHE_FLASH_ATTR dh_spi_read(void *buf_, size_t len) spi_disable_cs(); } - - -#ifdef DH_COMMANDS_SPI // SPI command handlers -#include "dhcommand_parser.h" -#include - -/** - * @brief SPI initialization helper. - * @return Non-zero if SPI was initialized. Zero otherwise. - */ -static int ICACHE_FLASH_ATTR spi_init(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, const gpio_command_params *params) -{ - if (fields & AF_CS) { - if (!!dh_spi_set_cs_pin(params->CS)) { - dh_command_fail(cmd_res, "Wrong CS pin"); - return 1; // FAILED - } - } - - if(fields & AF_SPIMODE) { - if (!!dh_spi_set_mode((DHSpiMode)params->spi_mode)) { - dh_command_fail(cmd_res, "Wrong SPI mode"); - return 1; // FAILED - } - } - - return 0; // continue -} - - -/* - * do_spi_master_read() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; - } - - if (!(fields & AF_COUNT)) - info.count = 2; - if (info.count == 0 || info.count > INTERFACES_BUF_SIZE) { - dh_command_fail(cmd_res, "Wrong read size"); - return; - } - - if (spi_init(cmd_res, fields, &info)) - return; - - if (fields & AF_DATA) - dh_spi_write(info.data, info.data_len, 0); - dh_spi_read(info.data, info.count); - - dh_command_done_buf(cmd_res, info.data, info.count); -} - - -/* - * do_spi_master_write() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_spi_master_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_CS | AF_SPIMODE | AF_DATA, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; - } - - if (spi_init(cmd_res, fields, &info)) - return; - - if (!(fields & AF_DATA)) { - dh_command_fail(cmd_res, "Data not specified"); - return; - } - - dh_spi_write(info.data, info.data_len, 1); - dh_command_done(cmd_res, ""); -} - -#endif /* DH_COMMANDS_SPI */ diff --git a/firmware-src/sources/DH/spi.h b/firmware-src/sources/DH/spi.h index 206554d..41281fb 100644 --- a/firmware-src/sources/DH/spi.h +++ b/firmware-src/sources/DH/spi.h @@ -7,8 +7,6 @@ #ifndef _DH_SPI_H_ #define _DH_SPI_H_ -#include "user_config.h" - #include /** @@ -70,22 +68,4 @@ void dh_spi_write(const void *buf, size_t len, int disable_cs); */ void dh_spi_read(void *buf, size_t len); - -#ifdef DH_COMMANDS_SPI // SPI command handlers -#include "dhsender_data.h" - -/** - * @brief Handle "spi/master/read" command. - */ -void dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "spi/master/write" command. - */ -void dh_handle_spi_master_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_SPI */ #endif /* _DH_SPI_H_ */ diff --git a/firmware-src/sources/DH/uart.c b/firmware-src/sources/DH/uart.c index 91a0c76..850ecc0 100644 --- a/firmware-src/sources/DH/uart.c +++ b/firmware-src/sources/DH/uart.c @@ -7,6 +7,7 @@ #include "DH/uart.h" #include "DH/adc.h" #include "dhdebug.h" +#include "user_config.h" #include #include @@ -312,148 +313,3 @@ void ICACHE_FLASH_ATTR dh_uart_enable_buf_interrupt(int enable) { mBufInterrupt = enable; } - - -#ifdef DH_COMMANDS_UART // UART command handlers -#include "dhcommand_parser.h" -#include "dhterminal.h" -#include - -/** - * @brief UART initialization helper. - * @return Non-zero if UART was initialized. Zero otherwise. - */ -static int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, - const gpio_command_params *params, int is_int) -{ - if (fields & AF_UARTMODE) { - if (params->uart_speed == 0 && is_int) { - dh_uart_enable_buf_interrupt(false); - dh_command_done(cmd_res, ""); - return 1; - } else if(!!dh_uart_init(params->uart_speed, params->uart_bits, - params->uart_partity, params->uart_stopbits)) { - dh_command_fail(cmd_res, "Wrong UART mode"); - return 1; - } - } - - return 0; -} - -/* - * dh_handle_uart_write() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_UARTMODE | AF_DATA, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - } else if (!uart_init(cmd_res, fields, &info, false)) { - dh_uart_set_mode(DH_UART_MODE_PER_BUF); - dh_uart_send_buf(info.data, info.data_len); - dh_command_done(cmd_res, ""); - } -} - - -/** - * dh_handle_uart_read() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - if (params_len) { - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, 0, - AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; - } - if (uart_init(cmd_res, fields, &info, false)) - return; - if (fields & AF_TIMEOUT) { - if (info.timeout > 1000) { // TODO: MAX timeout constant - dh_command_fail(cmd_res, "Timeout out of range"); - return; - } - if (!(fields & AF_DATA)) { - dh_command_fail(cmd_res, "Timeout can be specified only with data"); - return; - } - } - } - - if (fields & AF_DATA) { - dh_uart_set_mode(DH_UART_MODE_PER_BUF); - dh_uart_send_buf(info.data, info.data_len); - system_soft_wdt_feed(); - delay_ms((fields & AF_TIMEOUT) ? info.timeout : 250); - system_soft_wdt_feed(); - } - - void *buf = 0; - size_t len = dh_uart_get_buf(&buf); - if (len > INTERFACES_BUF_SIZE) - len = INTERFACES_BUF_SIZE; - dh_command_done_buf(cmd_res, buf, len); - dh_uart_set_mode(DH_UART_MODE_PER_BUF); -} - - -/** - * dh_handle_uart_int() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - if (params_len) { - gpio_command_params info; - ALLOWED_FIELDS fields = 0; - const char *err_msg = parse_params_pins_set(params, params_len, - &info, DH_ADC_SUITABLE_PINS, dh_uart_get_callback_timeout(), - AF_UARTMODE | AF_TIMEOUT, &fields); - if (err_msg != 0) { - dh_command_fail(cmd_res, err_msg); - return; - } - if ((fields & AF_TIMEOUT) && info.timeout > 5000) { // TODO: MAX timeout constant - dh_command_fail(cmd_res, "Timeout out of range"); - return; - } - if (uart_init(cmd_res, fields, &info, true)) - return; - if (fields & AF_TIMEOUT) - dh_uart_set_callback_timeout(info.timeout); - } - - dh_uart_set_mode(DH_UART_MODE_PER_BUF); - dh_uart_enable_buf_interrupt(true); - dh_command_done(cmd_res, ""); -} - - -/** - * dh_handle_uart_terminal() implementation. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_terminal(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len) -{ - if (params_len) { - dh_command_fail(cmd_res, "No parameters expected"); - return; - } - - dhterminal_init(); - dh_command_done(cmd_res, ""); -} - -#endif /* DH_COMMANDS_UART */ diff --git a/firmware-src/sources/DH/uart.h b/firmware-src/sources/DH/uart.h index 69b003d..33a4ff1 100644 --- a/firmware-src/sources/DH/uart.h +++ b/firmware-src/sources/DH/uart.h @@ -17,7 +17,6 @@ #define _DH_UART_H_ #include -#include "user_config.h" /** * @brief UART mode. @@ -152,37 +151,4 @@ extern void dh_uart_char_rcv_cb(int ch); */ extern void dh_uart_buf_rcv_cb(const void *buf, size_t len); - -#ifdef DH_COMMANDS_UART // UART command handlers -#include "dhsender_data.h" - - -/** - * @brief Handle "uart/write" command. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_write(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "uart/read" command. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "uart/int" command. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_int(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - - -/** - * @brief Handle "uart/terminal" command. - */ -void ICACHE_FLASH_ATTR dh_handle_uart_terminal(COMMAND_RESULT *cmd_res, const char *command, - const char *params, unsigned int params_len); - -#endif /* DH_COMMANDS_UART */ #endif /* _DH_UART_H_ */ diff --git a/firmware-src/sources/commands/adc_cmd.c b/firmware-src/sources/commands/adc_cmd.c new file mode 100644 index 0000000..8b5e360 --- /dev/null +++ b/firmware-src/sources/commands/adc_cmd.c @@ -0,0 +1,84 @@ +/** + * @file + * @brief ADC command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/adc_cmd.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_ADC // ADC command handlers +#include "dhcommand_parser.h" +#include + +/** + * Minimum notification timeout, milliseconds. + */ +#define MIN_TIMEOUT_MS 250 + + +/** + * Maximum notification timeout, milliseconds. + */ +#define MAX_TIMEOUT_MS 0x7fffff + + +/* + * dh_handle_adc_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_READ, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + + if (info.pins_to_read != DH_ADC_SUITABLE_PINS) { + dh_command_fail(cmd_res, "Unknown ADC channel"); + return; // FAILED + } + } + + // OK, report ADC value + cmd_res->callback(cmd_res->data, DHSTATUS_OK, + RDT_FLOAT, dh_adc_get_value()); +} + + +/* + * dh_handle_adc_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_VALUES, &fields); + // TODO: use AF_TIMEOUT here? + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } else if (info.pin_value_readed != DH_ADC_SUITABLE_PINS) { + dh_command_fail(cmd_res, "Unknown ADC channel"); + return; // FAILED + } + + const unsigned int timeout = info.storage.uint_values[0]; + if ((timeout != 0 && timeout < MIN_TIMEOUT_MS) || timeout > MAX_TIMEOUT_MS) { + dh_command_fail(cmd_res, "Wrong period"); + } else { + dh_adc_loop(timeout); + dh_command_done(cmd_res, ""); + } +} + +#endif /* DH_COMMANDS_ADC */ diff --git a/firmware-src/sources/commands/adc_cmd.h b/firmware-src/sources/commands/adc_cmd.h new file mode 100644 index 0000000..14c172f --- /dev/null +++ b/firmware-src/sources/commands/adc_cmd.h @@ -0,0 +1,29 @@ +/** + * @file + * @brief ADC command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_ADC_CMD_H_ +#define _COMMANDS_ADC_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_ADC // ADC command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "adc/read" command. + */ +void dh_handle_adc_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "adc/int" command. + */ +void dh_handle_adc_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_ADC */ +#endif /* _COMMANDS_ADC_CMD_H_ */ diff --git a/firmware-src/sources/commands/dht_cmd.c b/firmware-src/sources/commands/dht_cmd.c new file mode 100644 index 0000000..d727d89 --- /dev/null +++ b/firmware-src/sources/commands/dht_cmd.c @@ -0,0 +1,40 @@ +/** + * @file + * @brief DHT command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/dht_cmd.h" +#include "commands/onewire_cmd.h" +#include "devices/dht.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_onewire_dht_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_dht_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + } + + info.count = dhonewire_dht_read(info.data, sizeof(info.data)); + if (info.count) + dh_command_done_buf(cmd_res, info.data, info.count); + else + dh_command_fail(cmd_res, "No response"); +} diff --git a/firmware-src/sources/commands/dht_cmd.h b/firmware-src/sources/commands/dht_cmd.h new file mode 100644 index 0000000..124e573 --- /dev/null +++ b/firmware-src/sources/commands/dht_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief DHT command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_DHT_CMD_H_ +#define _COMMANDS_DHT_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "onewire/dht/read" command. + */ +void dh_handle_onewire_dht_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_DHT_CMD_H_ */ diff --git a/firmware-src/sources/commands/gpio_cmd.c b/firmware-src/sources/commands/gpio_cmd.c new file mode 100644 index 0000000..d46fc1d --- /dev/null +++ b/firmware-src/sources/commands/gpio_cmd.c @@ -0,0 +1,113 @@ +/** + * @file + * @brief GPIO command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/gpio_cmd.h" +#include "DH/gpio.h" + +#ifdef DH_COMMANDS_GPIO // GPIO command handlers +#include "dhcommand_parser.h" +#include + +/** + * Minimum notification timeout, milliseconds. + */ +#define MIN_TIMEOUT_MS 50 + + +/** + * Maximum notification timeout, milliseconds. + */ +#define MAX_TIMEOUT_MS 0x7fffff + + +/* + * dh_handle_gpio_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, + 0, AF_SET | AF_CLEAR, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (!(fields & (AF_SET | AF_CLEAR))) { + dh_command_fail(cmd_res, "Dummy request"); + } else if (!!dh_gpio_write(info.pins_to_set, info.pins_to_clear)) { + dh_command_fail(cmd_res, "Unsuitable pin"); + } else { + dh_command_done(cmd_res, ""); + } +} + + +/* + * dh_handle_gpio_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, 0, + AF_INIT | AF_PULLUP | AF_NOPULLUP, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + + // initialize GPIO as input + if (!!dh_gpio_input(info.pins_to_init, + info.pins_to_pullup, + info.pins_to_nopull)) { + dh_command_fail(cmd_res, "Wrong initialization parameters"); + return; // FAILED + } + } + + // OK, read GPIO input + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_GPIO, + 0, dh_gpio_read(), system_get_time(), + DH_GPIO_SUITABLE_PINS); +} + + +/* + * dh_handle_gpio_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), + AF_DISABLE | AF_RISING | AF_FALLING | AF_BOTH | AF_TIMEOUT, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (fields == 0) { + dh_command_fail(cmd_res, "Wrong action"); + } else if (info.timeout < MIN_TIMEOUT_MS || info.timeout > MAX_TIMEOUT_MS) { + dh_command_fail(cmd_res, "Timeout out of range"); + } else if (!!dh_gpio_subscribe_int(info.pins_to_disable, + info.pins_to_rising, + info.pins_to_falling, + info.pins_to_both, + info.timeout)) { + dh_command_fail(cmd_res, "Unsuitable pin"); + } else { + dh_command_done(cmd_res, ""); + } +} + +#endif /* DH_COMMANDS_GPIO */ diff --git a/firmware-src/sources/commands/gpio_cmd.h b/firmware-src/sources/commands/gpio_cmd.h new file mode 100644 index 0000000..5a1f818 --- /dev/null +++ b/firmware-src/sources/commands/gpio_cmd.h @@ -0,0 +1,36 @@ +/** + * @file + * @brief GPIO command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_GPIO_CMD_H_ +#define _COMMANDS_GPIO_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_GPIO // GPIO command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "gpio/write" command. + */ +void dh_handle_gpio_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "gpio/read" command. + */ +void dh_handle_gpio_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "gpio/int" command. + */ +void dh_handle_gpio_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_GPIO */ +#endif /* _COMMANDS_GPIO_CMD_H_ */ diff --git a/firmware-src/sources/commands/i2c_cmd.c b/firmware-src/sources/commands/i2c_cmd.c new file mode 100644 index 0000000..1dde863 --- /dev/null +++ b/firmware-src/sources/commands/i2c_cmd.c @@ -0,0 +1,125 @@ +/** + * @file + * @brief I2C command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/i2c_cmd.h" +#include "DH/i2c.h" +#include "DH/gpio.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_I2C // I2C command handlers +#include "dhcommand_parser.h" +#include + +/* + * dh_i2c_init_helper() implementation. + */ +int ICACHE_FLASH_ATTR dh_i2c_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, const gpio_command_params *params) +{ + if ((fields & AF_ADDRESS) == 0) { + dh_command_fail(cmd_res, "Address not specified"); + return 1; // FAILED + } + + int init = ((fields & AF_SDA) != 0) + ((fields & AF_SCL) != 0); + if (init == 2) { + const int res = dh_i2c_init(params->SDA, params->SCL); + const char *err = dh_i2c_error_string(res); + if (err != 0) { + dh_command_fail(cmd_res, err); + return 1; // FAILED + } + } else if(init == 1) { + dh_command_fail(cmd_res, "Only one pin specified"); + return 1; // FAILED + } else { + dh_i2c_reinit(); + } + + return 0; // continue +} + + +/* + * dh_handle_i2c_master_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_i2c_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS | AF_COUNT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if (!(fields & AF_COUNT)) + info.count = 2; + if (info.count == 0 || info.count > INTERFACES_BUF_SIZE) { + dh_command_fail(cmd_res, "Wrong read size"); + return; + } + + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; + + // write + if (fields & AF_DATA) { + int res = dh_i2c_write(info.address, info.data, info.data_len, 0); + err_msg = dh_i2c_error_string(res); + if (err_msg) { + dh_command_fail(cmd_res, err_msg); + return; + } + } + + // read + int res = dh_i2c_read(info.address, info.data, info.count); + err_msg = dh_i2c_error_string(res); + if (err_msg) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done_buf(cmd_res, info.data, info.count); + } +} + + +/* + * dh_handle_i2c_master_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_i2c_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if((fields & AF_DATA) == 0) { + dh_command_fail(cmd_res, "Data not specified"); + return; + } + + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; + + const int res = dh_i2c_write(info.address, info.data, info.data_len, 1); + err_msg = dh_i2c_error_string(res); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} + +#endif /* DH_COMMANDS_I2C */ diff --git a/firmware-src/sources/commands/i2c_cmd.h b/firmware-src/sources/commands/i2c_cmd.h new file mode 100644 index 0000000..a6eebfa --- /dev/null +++ b/firmware-src/sources/commands/i2c_cmd.h @@ -0,0 +1,38 @@ +/** + * @file + * @brief I2C command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_I2C_CMD_H_ +#define _COMMANDS_I2C_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_I2C // I2C command handlers +#include "dhcommand_parser.h" +#include "dhsender_data.h" + +/** + * @brief Helper function to initialize I2C bus. + * @return Non-zero if I2C was initialized. Zero otherwise. + */ +int dh_i2c_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params); + + +/** + * @brief Handle "i2c/master/read" command. + */ +void dh_handle_i2c_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "i2c/master/write" command. + */ +void dh_handle_i2c_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_I2C */ +#endif /* _COMMANDS_I2C_CMD_H_ */ diff --git a/firmware-src/sources/commands/onewire_cmd.c b/firmware-src/sources/commands/onewire_cmd.c new file mode 100644 index 0000000..b3e5864 --- /dev/null +++ b/firmware-src/sources/commands/onewire_cmd.c @@ -0,0 +1,146 @@ +/** + * @file + * @brief Onewire command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/onewire_cmd.h" +#include "DH/onewire.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers +#include "dhcommand_parser.h" +#include + +#include +#include + +/** + * @brief Initialization helper. + * @return Non-zero if onewire was initialized. Zero otherwise. + */ +int ICACHE_FLASH_ATTR dh_onewire_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params) +{ + if (fields & AF_PIN) { + if (!!dh_onewire_set_pin(params->pin)) { + dh_command_fail(cmd_res, "Wrong onewire pin"); + return 1; // FAILED + } + } + + return 0; // continue +} + + +/** + * @brief Handle "onewire/master/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_PIN | AF_DATA | AF_COUNT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if ((fields & AF_COUNT) == 0 || info.count == 0 || info.count > INTERFACES_BUF_SIZE) { + dh_command_fail(cmd_res, "Wrong read size"); + return; // FAILED + } + if ((fields & AF_DATA) == 0) { + dh_command_fail(cmd_res, "Command for reading is not specified"); + return; + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + if (!!dh_onewire_write(info.data, info.data_len)) { + dh_command_fail(cmd_res, "No response"); + return; // FAILED + } + dh_onewire_read(info.data, info.count); + dh_command_done_buf(cmd_res, info.data, info.count); +} + + +/** + * @brief Handle "onewire/master/write" commands. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_PIN | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + if (!!dh_onewire_write(info.data, info.data_len)) { + dh_command_fail(cmd_res, "No response"); + return; // FAILED + } + + dh_command_done(cmd_res, ""); +} + + +/** + * Handle "onewire/master/search" or "onewire/master/alarm" commands. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_search(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if(dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + } + + int check = os_strcmp(command, "onewire/master/search"); + size_t data_len = sizeof(info.data); + if (!!dh_onewire_search(info.data, &data_len, (check == 0) ? 0xF0 : 0xEC, dh_onewire_get_pin())) + dh_command_fail(cmd_res, "Error during search"); + else + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_SEARCH64, dh_onewire_get_pin(), info.data, data_len); +} + + +/** + * @brief Handle "onewire/master/int" command. + */ +void ICACHE_FLASH_ATTR dh_handle_onewire_master_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_GPIO_SUITABLE_PINS, dh_gpio_get_timeout(), + AF_DISABLE | AF_PRESENCE, &fields); + if (err_msg != 0) + dh_command_fail(cmd_res, err_msg); + else if (fields == 0) + dh_command_fail(cmd_res, "Wrong action"); + else if (!!dh_onewire_int(info.pins_to_presence, info.pins_to_disable)) + dh_command_fail(cmd_res, "Unsuitable pin"); + else + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_ONEWIRE */ diff --git a/firmware-src/sources/commands/onewire_cmd.h b/firmware-src/sources/commands/onewire_cmd.h new file mode 100644 index 0000000..b403fa5 --- /dev/null +++ b/firmware-src/sources/commands/onewire_cmd.h @@ -0,0 +1,52 @@ +/** + * @file + * @brief Onewire command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_ONEWIRE_CMD_H_ +#define _COMMANDS_ONEWIRE_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers +#include "dhsender_data.h" +#include "dhcommand_parser.h" + +/** + * @brief Initialization helper. + * @return Non-zero if onewire was initialized. Zero otherwise. + */ +int dh_onewire_init_helper(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params); + + +/** + * @brief Handle "onewire/master/read" command. + */ +void dh_handle_onewire_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "onewire/master/write" commands. + */ +void dh_handle_onewire_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * Handle "onewire/master/search" or "onewire/master/alarm" commands. + */ +void dh_handle_onewire_master_search(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "onewire/master/int" command. + */ +void dh_handle_onewire_master_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_ONEWIRE */ +#endif /* _COMMANDS_ONEWIRE_CMD_H_ */ diff --git a/firmware-src/sources/commands/pwm_cmd.c b/firmware-src/sources/commands/pwm_cmd.c new file mode 100644 index 0000000..d25bb81 --- /dev/null +++ b/firmware-src/sources/commands/pwm_cmd.c @@ -0,0 +1,40 @@ +/** + * @file + * @brief PWM command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/pwm_cmd.h" +#include "DH/pwm.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_PWM // PWM command handlers +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_pwm_control() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_pwm_control(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_VALUES | AF_PERIOD | AF_COUNT, &fields); + + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (!!dh_pwm_start(info.storage.uint_values, + info.pin_value_readed, + (fields & AF_PERIOD) ? info.periodus + : dh_pwm_get_period_us(), + info.count)) { + dh_command_fail(cmd_res, "Wrong parameters"); + } else { + dh_command_done(cmd_res, ""); // OK + } +} + +#endif /* DH_COMMANDS_PWM */ diff --git a/firmware-src/sources/commands/pwm_cmd.h b/firmware-src/sources/commands/pwm_cmd.h new file mode 100644 index 0000000..025ae76 --- /dev/null +++ b/firmware-src/sources/commands/pwm_cmd.h @@ -0,0 +1,22 @@ +/** + * @file + * @brief PWM command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_PWM_CMD_H_ +#define _COMMANDS_PWM_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_PWM // PWM command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "pwm/control" command. + */ +void dh_handle_pwm_control(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_PWM */ +#endif /* _COMMANDS_PWM_CMD_H_ */ diff --git a/firmware-src/sources/commands/spi_cmd.c b/firmware-src/sources/commands/spi_cmd.c new file mode 100644 index 0000000..cf74a07 --- /dev/null +++ b/firmware-src/sources/commands/spi_cmd.c @@ -0,0 +1,101 @@ +/** + * @file + * @brief SPI command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/spi_cmd.h" +#include "DH/spi.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_SPI // SPI command handlers +#include "dhcommand_parser.h" +#include + +/** + * @brief SPI initialization helper. + * @return Non-zero if SPI was initialized. Zero otherwise. + */ +static int ICACHE_FLASH_ATTR spi_init(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, const gpio_command_params *params) +{ + if (fields & AF_CS) { + if (!!dh_spi_set_cs_pin(params->CS)) { + dh_command_fail(cmd_res, "Wrong CS pin"); + return 1; // FAILED + } + } + + if(fields & AF_SPIMODE) { + if (!!dh_spi_set_mode((DHSpiMode)params->spi_mode)) { + dh_command_fail(cmd_res, "Wrong SPI mode"); + return 1; // FAILED + } + } + + return 0; // continue +} + + +/* + * do_spi_master_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_CS | AF_SPIMODE | AF_DATA | AF_COUNT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if (!(fields & AF_COUNT)) + info.count = 2; + if (info.count == 0 || info.count > INTERFACES_BUF_SIZE) { + dh_command_fail(cmd_res, "Wrong read size"); + return; + } + + if (spi_init(cmd_res, fields, &info)) + return; + + if (fields & AF_DATA) + dh_spi_write(info.data, info.data_len, 0); + dh_spi_read(info.data, info.count); + + dh_command_done_buf(cmd_res, info.data, info.count); +} + + +/* + * do_spi_master_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_spi_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_CS | AF_SPIMODE | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + + if (spi_init(cmd_res, fields, &info)) + return; + + if (!(fields & AF_DATA)) { + dh_command_fail(cmd_res, "Data not specified"); + return; + } + + dh_spi_write(info.data, info.data_len, 1); + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_SPI */ diff --git a/firmware-src/sources/commands/spi_cmd.h b/firmware-src/sources/commands/spi_cmd.h new file mode 100644 index 0000000..2c49c30 --- /dev/null +++ b/firmware-src/sources/commands/spi_cmd.h @@ -0,0 +1,29 @@ +/** + * @file + * @brief SPI command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_SPI_CMD_H_ +#define _COMMANDS_SPI_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_SPI // SPI command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "spi/master/read" command. + */ +void dh_handle_spi_master_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "spi/master/write" command. + */ +void dh_handle_spi_master_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_SPI */ +#endif /* _COMMANDS_SPI_CMD_H_ */ diff --git a/firmware-src/sources/commands/uart_cmd.c b/firmware-src/sources/commands/uart_cmd.c new file mode 100644 index 0000000..e5d6da7 --- /dev/null +++ b/firmware-src/sources/commands/uart_cmd.c @@ -0,0 +1,153 @@ +/** + * @file + * @brief UART command handler. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/uart_cmd.h" +#include "DH/uart.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_UART // UART command handlers +#include "dhcommand_parser.h" +#include "dhterminal.h" +#include + +/** + * @brief UART initialization helper. + * @return Non-zero if UART was initialized. Zero otherwise. + */ +static int ICACHE_FLASH_ATTR uart_init(COMMAND_RESULT *cmd_res, ALLOWED_FIELDS fields, + const gpio_command_params *params, int is_int) +{ + if (fields & AF_UARTMODE) { + if (params->uart_speed == 0 && is_int) { + dh_uart_enable_buf_interrupt(false); + dh_command_done(cmd_res, ""); + return 1; + } else if(!!dh_uart_init(params->uart_speed, params->uart_bits, + params->uart_partity, params->uart_stopbits)) { + dh_command_fail(cmd_res, "Wrong UART mode"); + return 1; + } + } + + return 0; +} + +/* + * dh_handle_uart_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_UARTMODE | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else if (!uart_init(cmd_res, fields, &info, false)) { + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + dh_uart_send_buf(info.data, info.data_len); + dh_command_done(cmd_res, ""); + } +} + + +/** + * dh_handle_uart_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_UARTMODE | AF_DATA | AF_TIMEOUT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + if (uart_init(cmd_res, fields, &info, false)) + return; + if (fields & AF_TIMEOUT) { + if (info.timeout > 1000) { // TODO: MAX timeout constant + dh_command_fail(cmd_res, "Timeout out of range"); + return; + } + if (!(fields & AF_DATA)) { + dh_command_fail(cmd_res, "Timeout can be specified only with data"); + return; + } + } + } + + if (fields & AF_DATA) { + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + dh_uart_send_buf(info.data, info.data_len); + system_soft_wdt_feed(); + delay_ms((fields & AF_TIMEOUT) ? info.timeout : 250); + system_soft_wdt_feed(); + } + + void *buf = 0; + size_t len = dh_uart_get_buf(&buf); + if (len > INTERFACES_BUF_SIZE) + len = INTERFACES_BUF_SIZE; + dh_command_done_buf(cmd_res, buf, len); + dh_uart_set_mode(DH_UART_MODE_PER_BUF); +} + + +/** + * dh_handle_uart_int() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, dh_uart_get_callback_timeout(), + AF_UARTMODE | AF_TIMEOUT, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; + } + if ((fields & AF_TIMEOUT) && info.timeout > 5000) { // TODO: MAX timeout constant + dh_command_fail(cmd_res, "Timeout out of range"); + return; + } + if (uart_init(cmd_res, fields, &info, true)) + return; + if (fields & AF_TIMEOUT) + dh_uart_set_callback_timeout(info.timeout); + } + + dh_uart_set_mode(DH_UART_MODE_PER_BUF); + dh_uart_enable_buf_interrupt(true); + dh_command_done(cmd_res, ""); +} + + +/** + * dh_handle_uart_terminal() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_terminal(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + dh_command_fail(cmd_res, "No parameters expected"); + return; + } + + dhterminal_init(); + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_UART */ diff --git a/firmware-src/sources/commands/uart_cmd.h b/firmware-src/sources/commands/uart_cmd.h new file mode 100644 index 0000000..8df83ef --- /dev/null +++ b/firmware-src/sources/commands/uart_cmd.h @@ -0,0 +1,43 @@ +/** + * @file + * @brief UART command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_UART_CMD_H_ +#define _COMMANDS_UART_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_UART // UART command handlers +#include "dhsender_data.h" + +/** + * @brief Handle "uart/write" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "uart/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "uart/int" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_int(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "uart/terminal" command. + */ +void ICACHE_FLASH_ATTR dh_handle_uart_terminal(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_UART */ +#endif /* _COMMANDS_UART_CMD_H_ */ diff --git a/firmware-src/sources/commands/ws2812b_cmd.c b/firmware-src/sources/commands/ws2812b_cmd.c new file mode 100644 index 0000000..868b86c --- /dev/null +++ b/firmware-src/sources/commands/ws2812b_cmd.c @@ -0,0 +1,103 @@ +/** + * @file + * @brief Onewire WS2812B command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/ws2812b_cmd.h" +#include "commands/onewire_cmd.h" +#include "DH/onewire.h" +#include "DH/adc.h" + +#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers +#include "dhcommand_parser.h" +#include + +#include +#include + +/** + * Write data to WS2812b device. + */ +/*static*/ void ws2812b_write(const void *buf_, size_t len, DHGpioPinMask pin_mask, + unsigned int T, unsigned int S, unsigned int L) +{ + // due to the strict timings, this method should be in IRAM, + // don't mark it with ICACHE_FLASH_ATTR + + // send each byte in real time + unsigned int ss, se, r; + const uint8_t *buf = (const uint8_t*)buf_; + while (len--) { + int j, v = *buf++; + for (j = 0x80; j > 0; j >>= 1) { + GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pin_mask); + asm volatile("rsr %0, ccount" : "=r"(r)); + ss = r + ((v & j) ? L : S); + se = r + T; + do { + asm volatile("rsr %0, ccount" : "=r"(r)); + } while(r < ss); + GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pin_mask); + do { + asm volatile("rsr %0, ccount" : "=r"(r)); + } while(r < se); + } + } +} + + +/** + * @brief Write data to WS2812b like device + * @param[in] pin 1-wire pin for communication. + * @param[in] buf Pointer to buffer with data. + * @param[in] len Buffer length in bytes. + */ +static void ICACHE_FLASH_ATTR onewire_ws2812b_write(const void *buf, size_t len) +{ + // init number of CPU tacts for delay + // delays are lower that spec on 50ns due to GPIO latency, anyway spec allows 150ns jitter. + const int freq = system_get_cpu_freq(); // MHz + const unsigned S = 350 * freq / 1000; + const unsigned L = 750 * freq / 1000; + + ETS_INTR_LOCK(); + + // send reset, low more then 50 ms + const DHGpioPinMask pin = DH_GPIO_PIN(dh_onewire_get_pin()); + gpio_output_set(0, pin, pin, 0); // low and initialize + os_delay_us(50); + ws2812b_write(buf, len, pin, S + L, S, L); + + ETS_INTR_UNLOCK(); +} + + +/** + * @brief Handle "onewire/ws2812b/write" command. + */ +// TODO: move this code to dedicated device file! +void ICACHE_FLASH_ATTR dh_handle_onewire_ws2812b_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + + const char *err_msg = parse_params_pins_set(params, params_len, &info, + DH_ADC_SUITABLE_PINS, 0, AF_PIN | AF_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (!(fields & AF_DATA)) { + dh_command_fail(cmd_res, "Data not specified"); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + + onewire_ws2812b_write(info.data, info.data_len); + dh_command_done(cmd_res, ""); +} + +#endif /* DH_COMMANDS_ONEWIRE */ diff --git a/firmware-src/sources/commands/ws2812b_cmd.h b/firmware-src/sources/commands/ws2812b_cmd.h new file mode 100644 index 0000000..f47085e --- /dev/null +++ b/firmware-src/sources/commands/ws2812b_cmd.h @@ -0,0 +1,23 @@ +/** + * @file + * @brief Onewire WS2812B command handlers. + * @copyright 2015 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_WS2812B_CMD_H_ +#define _COMMANDS_WS2812B_CMD_H_ + +#include "user_config.h" + +#ifdef DH_COMMANDS_ONEWIRE // onewire WS2812B command handlers +#include "dhsender_data.h" +#include "dhcommand_parser.h" + +/** + * @brief Handle "onewire/ws2812b/write" command. + */ +void dh_handle_onewire_ws2812b_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* DH_COMMANDS_ONEWIRE */ +#endif /* _COMMANDS_WS2812B_CMD_H_ */ diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index e2e01ab..1c8b1dd 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -107,27 +107,3 @@ int ICACHE_FLASH_ATTR dhonewire_dht_read(char *buf, unsigned int len) { return i / 8; } - -/** - * @brief Do "onewire/dht/read" command. - */ -void ICACHE_FLASH_ATTR dh_handle_onewire_dht_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(dh_onewire_init_helper(cb, fields, &parse_pins)) - return; - } - parse_pins.count = dhonewire_dht_read(parse_pins.data, sizeof(parse_pins.data)); - if(parse_pins.count) - dh_command_done_buf(cb, parse_pins.data, parse_pins.count); - else - dh_command_fail(cb, "No response"); -} - diff --git a/firmware-src/sources/devices/dht.h b/firmware-src/sources/devices/dht.h index 2a13d74..1051b02 100644 --- a/firmware-src/sources/devices/dht.h +++ b/firmware-src/sources/devices/dht.h @@ -40,7 +40,4 @@ char *dht22_read(int pin, float *humidity, float *temperature); */ int dhonewire_dht_read(char *buf, unsigned int len); -#include "dhsender_data.h" -void dh_handle_onewire_dht_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen); - #endif /* SOURCES_DEVICES_DHT_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 8722a65..6783c77 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -10,13 +10,16 @@ */ #include "dhcommands.h" #include "dhsender_queue.h" -#include "DH/gpio.h" +#include "commands/gpio_cmd.h" +#include "commands/adc_cmd.h" +#include "commands/uart_cmd.h" +#include "commands/spi_cmd.h" +#include "commands/i2c_cmd.h" +#include "commands/pwm_cmd.h" +#include "commands/onewire_cmd.h" +#include "commands/ws2812b_cmd.h" +#include "commands/dht_cmd.h" #include "DH/adc.h" -#include "DH/uart.h" -#include "DH/spi.h" -#include "DH/i2c.h" -#include "DH/pwm.h" -#include "DH/onewire.h" #include "dhnotification.h" #include "snprintf.h" #include "dhcommand_parser.h" From f1e4b6f212fa1902cee3c6cff5613b98bd1bb6d9 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 26 Apr 2017 17:24:12 +0300 Subject: [PATCH 36/83] review the ADS1115 device and command --- firmware-src/sources/DH/i2c.h | 6 +++ firmware-src/sources/commands/ads1115_cmd.c | 49 +++++++++++++++++ firmware-src/sources/commands/ads1115_cmd.h | 18 +++++++ firmware-src/sources/devices/ads1115.c | 60 ++++++++++++--------- firmware-src/sources/devices/ads1115.h | 40 ++++++-------- firmware-src/sources/dhcommands.c | 38 ++----------- 6 files changed, 130 insertions(+), 81 deletions(-) create mode 100644 firmware-src/sources/commands/ads1115_cmd.c create mode 100644 firmware-src/sources/commands/ads1115_cmd.h diff --git a/firmware-src/sources/DH/i2c.h b/firmware-src/sources/DH/i2c.h index 7bde79c..1d973df 100644 --- a/firmware-src/sources/DH/i2c.h +++ b/firmware-src/sources/DH/i2c.h @@ -21,6 +21,12 @@ typedef enum { } DH_I2C_Status; +/** + * @brief Do not initialize pin indicator. + */ +#define DH_I2C_NO_PIN (-1) + + /** * @brief Get error message based on status. * @return NULL if status is OK, error message otherwise. diff --git a/firmware-src/sources/commands/ads1115_cmd.c b/firmware-src/sources/commands/ads1115_cmd.c new file mode 100644 index 0000000..4eb6d46 --- /dev/null +++ b/firmware-src/sources/commands/ads1115_cmd.c @@ -0,0 +1,49 @@ +/** + * @file + * @brief ADS1115 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/ads1115_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/ads1115.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_ads1115_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_ads1115_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, &info, + DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + ads1115_set_address(info.address); + } + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float values[4]; + int status = ads1115_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, values); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", + values[0], values[1], values[2], values[3]); + } +} diff --git a/firmware-src/sources/commands/ads1115_cmd.h b/firmware-src/sources/commands/ads1115_cmd.h new file mode 100644 index 0000000..3ae3903 --- /dev/null +++ b/firmware-src/sources/commands/ads1115_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief ADS1115 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_ADS1115_CMD_H_ +#define _COMMANDS_ADS1115_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/ads1115/read" command. + */ +void dh_handle_devices_ads1115_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_ADS1115_CMD_H_ */ diff --git a/firmware-src/sources/devices/ads1115.c b/firmware-src/sources/devices/ads1115.c index 484651e..1d81940 100644 --- a/firmware-src/sources/devices/ads1115.c +++ b/firmware-src/sources/devices/ads1115.c @@ -1,66 +1,78 @@ -/* - * ads1115.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with ADS1115 ADC. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ #include "ads1115.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** Default sensor i2c address*/ +#define ADS1115_DEFAULT_ADDRESS 0x90 + +// module variables static int mAddress = ADS1115_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float *values) { - char buf[3]; - DH_I2C_Status status; - int channel; - if(sda != ADS1115_NO_PIN && scl != ADS1115_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * ads1115_read() implementation. + */ +int ICACHE_FLASH_ATTR ads1115_read(int sda, int scl, float values[4]) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("ads1115: failed to set up pins"); return status; } } - for(channel = 0; channel < 4; channel++) { + int channel; + for (channel = 0; channel < 4; channel++) { + char buf[3]; buf[0] = 0x01; // Config register buf[1] = ((0b100 | channel) << 4) | 0x83; // single shot mode, +-4.096V, measure between input and gnd. buf[2] = 0x80; // 128 samples per second, comparator is disabled. - if((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { dhdebug("ads1115: failed to write config"); return status; } + do { - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, &buf[0], 1, 0)) != DH_I2C_OK) { dhdebug("ads1115: failed to write get config"); return status; } - if((status = dh_i2c_read(mAddress, &buf[1], 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, &buf[1], 2)) != DH_I2C_OK) { dhdebug("ads1115: failed to read config"); return status; } - } while((buf[1] & 0x80) == 0); // while conversion is in progress + } while ((buf[1] & 0x80) == 0); // while conversion is in progress buf[0] = 0x00; // get conversation register - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("ads1115: failed to write get conversation register"); return status; } - if((status = dh_i2c_read(mAddress, &buf[1], 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, &buf[1], 2)) != DH_I2C_OK) { dhdebug("ads1115: failed to read coefficients"); return status; } - *values = (float)signedInt16be(buf, 1) / 32768.0f * 4.096f; - values++; + values[channel] = (float)signedInt16be(buf, 1) * (4.096f / 32768.0f); } return DH_I2C_OK; } -void ICACHE_FLASH_ATTR ads1115_set_address(int address) { + +/* + * ads1115_set_address() implementation. + */ +void ICACHE_FLASH_ATTR ads1115_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/ads1115.h b/firmware-src/sources/devices/ads1115.h index f1f3f9f..14ec562 100644 --- a/firmware-src/sources/devices/ads1115.h +++ b/firmware-src/sources/devices/ads1115.h @@ -1,34 +1,26 @@ /** - * \file ads1115.h - * \brief Simple communication with ADS1115 ADC - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with ADS1115 ADC. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_ADS1115_H_ -#define SOURCES_DEVICES_ADS1115_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define ADS1115_DEFAULT_ADDRESS 0x90 -/** Do not initialize pin */ -#define ADS1115_NO_PIN -1 +#ifndef _SOURCES_DEVICES_ADS1115_H_ +#define _SOURCES_DEVICES_ADS1115_H_ /** - * \brief Get ADC voltages. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] values Pointer to four float values to store result in Volts. - * \return Status value, one of DH_I2C_Status enum. + * @brief Get ADC voltages. + * @param[in] sda Pin for I2C's SDA. + * @param[in] scl Pin for I2C's SCL. + * @param[out] values Pointer to four float values to store result in Volts. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status ads1115_read(int sda, int scl, float *values); +int ads1115_read(int sda, int scl, float values[4]); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void ads1115_set_address(int address); -#endif /* SOURCES_DEVICES_ADS1115_H_ */ +#endif /* _SOURCES_DEVICES_ADS1115_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 6783c77..90f84ba 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -38,7 +38,8 @@ #include "devices/mhz19.h" #include "devices/lm75.h" #include "devices/si7021.h" -#include "devices/ads1115.h" +#include "commands/ads1115_cmd.h" +#include "commands/ads1115_cmd.h" #include "devices/pcf8591.h" #include "devices/mcp4725.h" #include "devices/ina219.h" @@ -492,35 +493,6 @@ static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const c } } -/** - * @brief Do "devices/ads1115/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_ads1115_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - ads1115_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float values[4]; - const char *res = dh_i2c_error_string(ads1115_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", - values[0], values[1], values[2], values[3]); - } -} - /** * @brief Do "devices/pcf8591/read" command. */ @@ -550,7 +522,7 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; float values[4]; - const char *res = dh_i2c_error_string(pcf8591_read(ADS1115_NO_PIN, ADS1115_NO_PIN, values)); + const char *res = dh_i2c_error_string(pcf8591_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, values)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -667,7 +639,7 @@ static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const c float voltage; float current; float power; - const char *res = dh_i2c_error_string(ina219_read(ADS1115_NO_PIN, ADS1115_NO_PIN, &voltage, ¤t, &power)); + const char *res = dh_i2c_error_string(ina219_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &voltage, ¤t, &power)); if (res != 0) { dh_command_fail(cb, res); } else { @@ -1002,7 +974,7 @@ RO_DATA struct { { "devices/mhz19/read", do_devices_mhz19_read}, { "devices/lm75/read", do_devices_lm75_read}, { "devices/si7021/read", do_devices_si7021_read}, - { "devices/ads1115/read", do_devices_ads1115_read}, + { "devices/ads1115/read", dh_handle_devices_ads1115_read}, { "devices/pcf8591/read", do_devices_pcf8591_read}, { "devices/pcf8591/write", do_devices_pcf8591_write}, { "devices/mcp4725/write", do_devices_mcp4725_write}, From 72e8f7ea33dff70d3661f70ab8d9211a8d7a5dbd Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 26 Apr 2017 17:45:52 +0300 Subject: [PATCH 37/83] review BH1750 device and command --- firmware-src/sources/commands/ads1115_cmd.c | 2 +- firmware-src/sources/commands/bh1750_cmd.c | 48 +++++++++++++++++++++ firmware-src/sources/commands/bh1750_cmd.h | 19 ++++++++ firmware-src/sources/devices/ads1115.c | 2 +- firmware-src/sources/devices/bh1750.c | 47 ++++++++++++-------- firmware-src/sources/devices/bh1750.h | 40 ++++++++--------- firmware-src/sources/dhcommands.c | 35 +-------------- 7 files changed, 118 insertions(+), 75 deletions(-) create mode 100644 firmware-src/sources/commands/bh1750_cmd.c create mode 100644 firmware-src/sources/commands/bh1750_cmd.h diff --git a/firmware-src/sources/commands/ads1115_cmd.c b/firmware-src/sources/commands/ads1115_cmd.c index 4eb6d46..934a82a 100644 --- a/firmware-src/sources/commands/ads1115_cmd.c +++ b/firmware-src/sources/commands/ads1115_cmd.c @@ -37,7 +37,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ads1115_read(COMMAND_RESULT *cmd_res, c return; // FAILED float values[4]; - int status = ads1115_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, values); + const int status = ads1115_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, values); const char *err_msg = dh_i2c_error_string(status); if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); diff --git a/firmware-src/sources/commands/bh1750_cmd.c b/firmware-src/sources/commands/bh1750_cmd.c new file mode 100644 index 0000000..fe3c403 --- /dev/null +++ b/firmware-src/sources/commands/bh1750_cmd.c @@ -0,0 +1,48 @@ +/** + * @file + * @brief BH1750 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/bh1750_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/bh1750.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_bh1750_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_bh1750_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + bh1750_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float illuminance; + const int status = bh1750_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &illuminance); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); + } +} diff --git a/firmware-src/sources/commands/bh1750_cmd.h b/firmware-src/sources/commands/bh1750_cmd.h new file mode 100644 index 0000000..dfa7efc --- /dev/null +++ b/firmware-src/sources/commands/bh1750_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief BH1750 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_BH1750_CMD_H_ +#define _COMMANDS_BH1750_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/bh1750/read" command. + */ + +void dh_handle_devices_bh1750_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_BH1750_CMD_H_ */ diff --git a/firmware-src/sources/devices/ads1115.c b/firmware-src/sources/devices/ads1115.c index 1d81940..bb0e0d0 100644 --- a/firmware-src/sources/devices/ads1115.c +++ b/firmware-src/sources/devices/ads1115.c @@ -4,7 +4,7 @@ * @copyright 2016 [DeviceHive](http://devicehive.com) * @author Nikolay Khabarov */ -#include "ads1115.h" +#include "devices/ads1115.h" #include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" diff --git a/firmware-src/sources/devices/bh1750.c b/firmware-src/sources/devices/bh1750.c index 15ce521..56bf5d6 100644 --- a/firmware-src/sources/devices/bh1750.c +++ b/firmware-src/sources/devices/bh1750.c @@ -1,37 +1,45 @@ -/* - * bh1750.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with BH1750 illuminance sensor + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "bh1750.h" +#include "devices/bh1750.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** Default sensor i2c address*/ +#define BH1750_DEFAULT_ADDRESS 0x46 + +// module variables static int mAddress = BH1750_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR bh1750_read(int sda, int scl, float *illuminance) { - char buf[2]; - DH_I2C_Status status; - if(sda != BH1750_NO_PIN && scl != BH1750_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * bh1750_read() implementation. + */ +int ICACHE_FLASH_ATTR bh1750_read(int sda, int scl, float illuminance[1]) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("bh1750: failed to set up pins"); return status; } } + + char buf[2]; buf[0] = 0x21; // One Time High Resolution (0.5 lx) - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bh1750: failed to measure"); return status; } delay_ms(180); - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("bh1750: failed to read"); return status; } @@ -40,6 +48,11 @@ DH_I2C_Status ICACHE_FLASH_ATTR bh1750_read(int sda, int scl, float *illuminance return DH_I2C_OK; } -void ICACHE_FLASH_ATTR bh1750_set_address(int address) { + +/* + * bh1750_set_address() implementation. + */ +void ICACHE_FLASH_ATTR bh1750_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/bh1750.h b/firmware-src/sources/devices/bh1750.h index dc07dbc..f61431e 100644 --- a/firmware-src/sources/devices/bh1750.h +++ b/firmware-src/sources/devices/bh1750.h @@ -1,34 +1,28 @@ /** - * \file bh1750.h - * \brief Simple communication with BH1750 illuminance sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with BH1750 illuminance sensor + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_BH1750_H_ +#define _DEVICES_BH1750_H_ -#ifndef SOURCES_DEVICES_BH1750_H_ -#define SOURCES_DEVICES_BH1750_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define BH1750_DEFAULT_ADDRESS 0x46 -/** Do not initialize pin */ -#define BH1750_NO_PIN -1 /** - * \brief Measure illuminance one time. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[in] illuminance Illuminance in lux. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure illuminance one time. + * @param[in] sda Pin for I2C's SDA. + * @param[in] scl Pin for I2C's SCL. + * @param[out] illuminance Illuminance in lux. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status bh1750_read(int sda, int scl, float *illuminance); +int bh1750_read(int sda, int scl, float illuminance[1]); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void bh1750_set_address(int address); -#endif /* SOURCES_DEVICES_BH1750_H_ */ + +#endif /* _DEVICES_BH1750_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 90f84ba..d22d930 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -30,7 +30,7 @@ #include "devices/dht.h" #include "devices/bmp180.h" #include "devices/bmp280.h" -#include "devices/bh1750.h" +#include "commands/bh1750_cmd.h" #include "devices/mpu6050.h" #include "devices/hmc5883l.h" #include "devices/pcf8574.h" @@ -39,7 +39,6 @@ #include "devices/lm75.h" #include "devices/si7021.h" #include "commands/ads1115_cmd.h" -#include "commands/ads1115_cmd.h" #include "devices/pcf8591.h" #include "devices/mcp4725.h" #include "devices/ina219.h" @@ -205,36 +204,6 @@ static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const c } -/** - * @brief Do "devices/bh1750/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_bh1750_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - bh1750_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float illuminance; - const char *res = dh_i2c_error_string(bh1750_read(BH1750_NO_PIN, BH1750_NO_PIN, &illuminance)); - if(res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); - } -} - /** * @brief Do "devices/mpu6050/read" command. */ @@ -965,7 +934,7 @@ RO_DATA struct { { "devices/dht22/read", do_devices_dht22_read}, { "devices/bmp180/read", do_devices_bmp180_read}, { "devices/bmp280/read", do_devices_bmp280_read}, - { "devices/bh1750/read", do_devices_bh1750_read}, + { "devices/bh1750/read", dh_handle_devices_bh1750_read}, { "devices/mpu6050/read", do_devices_mpu6050_read}, { "devices/hmc5883l/read", do_devices_hmc5883l_read}, { "devices/pcf8574/read", do_devices_pcf8574_read}, From 53cbe07c10321aaca1d9e66369cd012b2ac1762e Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 27 Apr 2017 18:32:05 +0300 Subject: [PATCH 38/83] review BMP180 and BMP280 devices --- firmware-src/sources/commands/bmp180_cmd.c | 50 ++++++++++ firmware-src/sources/commands/bmp180_cmd.h | 18 ++++ firmware-src/sources/commands/bmp280_cmd.c | 50 ++++++++++ firmware-src/sources/commands/bmp280_cmd.h | 18 ++++ firmware-src/sources/devices/ads1115.h | 4 +- firmware-src/sources/devices/bh1750.h | 4 +- firmware-src/sources/devices/bmp180.c | 104 +++++++++++---------- firmware-src/sources/devices/bmp180.h | 44 ++++----- firmware-src/sources/devices/bmp280.c | 75 +++++++++------ firmware-src/sources/devices/bmp280.h | 44 ++++----- firmware-src/sources/dhcommands.c | 71 +------------- firmware-src/sources/user_config.h | 2 + 12 files changed, 285 insertions(+), 199 deletions(-) create mode 100644 firmware-src/sources/commands/bmp180_cmd.c create mode 100644 firmware-src/sources/commands/bmp180_cmd.h create mode 100644 firmware-src/sources/commands/bmp280_cmd.c create mode 100644 firmware-src/sources/commands/bmp280_cmd.h diff --git a/firmware-src/sources/commands/bmp180_cmd.c b/firmware-src/sources/commands/bmp180_cmd.c new file mode 100644 index 0000000..d35a70d --- /dev/null +++ b/firmware-src/sources/commands/bmp180_cmd.c @@ -0,0 +1,50 @@ +/** + * @file + * @brief BMP180 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/bmp180_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/bmp180.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_bmp180_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_bmp180_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + bmp180_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float temperature; + int pressure; + const int status = bmp180_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &pressure, &temperature); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); + } +} diff --git a/firmware-src/sources/commands/bmp180_cmd.h b/firmware-src/sources/commands/bmp180_cmd.h new file mode 100644 index 0000000..033f024 --- /dev/null +++ b/firmware-src/sources/commands/bmp180_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief BMP180 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_BMP180_CMD_H_ +#define _COMMANDS_BMP180_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/bmp180/read" command. + */ +void dh_handle_devices_bmp180_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_BMP180_CMD_H_ */ diff --git a/firmware-src/sources/commands/bmp280_cmd.c b/firmware-src/sources/commands/bmp280_cmd.c new file mode 100644 index 0000000..ca21b4f --- /dev/null +++ b/firmware-src/sources/commands/bmp280_cmd.c @@ -0,0 +1,50 @@ +/** + * @file + * @brief BMP280 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/bmp280_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/bmp280.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_bmp280_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_bmp280_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + bmp280_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float temperature; + float pressure; + const int status = bmp280_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &pressure, &temperature); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); + } +} diff --git a/firmware-src/sources/commands/bmp280_cmd.h b/firmware-src/sources/commands/bmp280_cmd.h new file mode 100644 index 0000000..4a188a8 --- /dev/null +++ b/firmware-src/sources/commands/bmp280_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief BMP280 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_BMP280_CMD_H_ +#define _COMMANDS_BMP280_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/bmp280/read" command. + */ +void dh_handle_devices_bmp280_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_BMP280_CMD_H_ */ diff --git a/firmware-src/sources/devices/ads1115.h b/firmware-src/sources/devices/ads1115.h index 14ec562..009a8b1 100644 --- a/firmware-src/sources/devices/ads1115.h +++ b/firmware-src/sources/devices/ads1115.h @@ -9,8 +9,8 @@ /** * @brief Get ADC voltages. - * @param[in] sda Pin for I2C's SDA. - * @param[in] scl Pin for I2C's SCL. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. * @param[out] values Pointer to four float values to store result in Volts. * @return Status value, one of DH_I2C_Status enum. */ diff --git a/firmware-src/sources/devices/bh1750.h b/firmware-src/sources/devices/bh1750.h index f61431e..e11a19b 100644 --- a/firmware-src/sources/devices/bh1750.h +++ b/firmware-src/sources/devices/bh1750.h @@ -10,8 +10,8 @@ /** * @brief Measure illuminance one time. - * @param[in] sda Pin for I2C's SDA. - * @param[in] scl Pin for I2C's SCL. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. * @param[out] illuminance Illuminance in lux. * @return Status value, one of DH_I2C_Status enum. */ diff --git a/firmware-src/sources/devices/bmp180.c b/firmware-src/sources/devices/bmp180.c index b06d981..74e9d69 100644 --- a/firmware-src/sources/devices/bmp180.c +++ b/firmware-src/sources/devices/bmp180.c @@ -1,97 +1,102 @@ -/* - * bmp180.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with BMP180 pressure sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "bmp180.h" +#include "devices/bmp180.h" #include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address*/ +#define BMP180_DEFAULT_ADDRESS 0xEE + +// module variables static int mAddress = BMP180_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, float *temperature) { - char buf[22]; - unsigned int raw_temperature; - unsigned int raw_pressure; - DH_I2C_Status status; - if(sda != BMP180_NO_PIN && scl != BMP180_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * bmp180_read() implementation. + */ +int ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, float *temperature) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("bmp180: failed to set up pins"); return status; } } + + char buf[22]; buf[0] = 0xAA; // get factory parameters - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp180: failed to write get coefficients command"); return status; } - if((status = dh_i2c_read(mAddress, buf, sizeof(buf))) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, sizeof(buf))) != DH_I2C_OK) { dhdebug("bmp180: failed to read coefficients"); return status; } int oss = 0; - int ac1 = signedInt16be(buf, 0); - int ac2 = signedInt16be(buf, 2); - int ac3 = signedInt16be(buf, 4); - unsigned int ac4 = unsignedInt16be(buf, 6); - unsigned int ac5 = unsignedInt16be(buf, 8); - unsigned int ac6 = unsignedInt16be(buf, 10); - int b1 = signedInt16be(buf, 12); - int b2 = signedInt16be(buf, 14); - //int mb = signedInt16(buf, 16); - int mc = signedInt16be(buf, 18); - int md = signedInt16be(buf, 20); + int ac1 = signedInt16be(buf, 0); + int ac2 = signedInt16be(buf, 2); + int ac3 = signedInt16be(buf, 4); + unsigned int ac4 = unsignedInt16be(buf, 6); + unsigned int ac5 = unsignedInt16be(buf, 8); + unsigned int ac6 = unsignedInt16be(buf, 10); + int b1 = signedInt16be(buf, 12); + int b2 = signedInt16be(buf, 14); + //int mb = signedInt16(buf, 16); + int mc = signedInt16be(buf, 18); + int md = signedInt16be(buf, 20); - buf[0] = 0xF4; // measure temperature - buf[1] = 0x2E; - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + buf[0] = 0xF4; // measure temperature + buf[1] = 0x2E; + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp180: failed to stare measure temperature"); return status; } - delay_ms(50); - buf[0] = 0xF6; // get result - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + delay_ms(50); + buf[0] = 0xF6; // get result + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp180: failed to write get temperature command"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("bmp180: failed to read temperature"); return status; } - raw_temperature = unsignedInt16be(buf, 0); + unsigned int raw_temperature = unsignedInt16be(buf, 0); - buf[0] = 0xF4; // measure pressure - buf[1] = 0x34; - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + buf[0] = 0xF4; // measure pressure + buf[1] = 0x34; + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp180: failed to stare measure pressure"); return status; } - delay_ms(50); - buf[0] = 0xF6; // get result - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + delay_ms(50); + buf[0] = 0xF6; // get result + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp180: failed to write get pressure command"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("bmp180: failed to read pressure"); return status; } - raw_pressure = unsignedInt16be(buf, 0); + unsigned int raw_pressure = unsignedInt16be(buf, 0); // calc long x1 = (raw_temperature - ac6) * ac5 >> 15; long x2 = (mc << 11) / (x1 + md); long b5 = x1 + x2; long t = (b5 + 8) >> 4; - if(temperature) { + if (temperature) { *temperature = (t / 10.0f); } @@ -115,6 +120,11 @@ DH_I2C_Status ICACHE_FLASH_ATTR bmp180_read(int sda, int scl, int *pressure, flo return DH_I2C_OK; } -void ICACHE_FLASH_ATTR bmp180_set_address(int address) { + +/* + * bmp180_set_address() implementation. + */ +void ICACHE_FLASH_ATTR bmp180_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/bmp180.h b/firmware-src/sources/devices/bmp180.h index 4dd862f..51f42c6 100644 --- a/firmware-src/sources/devices/bmp180.h +++ b/firmware-src/sources/devices/bmp180.h @@ -1,35 +1,29 @@ /** - * \file bmp180.h - * \brief Simple communication with BMP180 pressure sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with BMP180 pressure sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_BMP180_H_ -#define SOURCES_DEVICES_BMP180_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define BMP180_DEFAULT_ADDRESS 0xEE -/** Do not initialize pin */ -#define BMP180_NO_PIN -1 +#ifndef _DEVICES_BMP180_H_ +#define _DEVICES_BMP180_H_ /** - * \brief Measure pressure one time. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] pressure Pointer for storing pressure result measure in Pascals. - * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure pressure one time. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] pressure Pointer for storing pressure result measure in Pascals. + * @param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status bmp180_read(int sda, int scl, int *pressure, float *temperature); +int bmp180_read(int sda, int scl, + int *pressure, + float *temperature); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void bmp180_set_address(int address); -#endif /* SOURCES_DEVICES_BMP180_H_ */ +#endif /* _DEVICES_BMP180_H_ */ diff --git a/firmware-src/sources/devices/bmp280.c b/firmware-src/sources/devices/bmp280.c index e60cd00..0e711d7 100644 --- a/firmware-src/sources/devices/bmp280.c +++ b/firmware-src/sources/devices/bmp280.c @@ -1,36 +1,43 @@ -/* - * bmp280.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with BMP280 pressure sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#include "bmp280.h" +#include "devices/bmp280.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address*/ +#define BMP280_DEFAULT_ADDRESS 0xEC + +// module variables static int mAddress = BMP280_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, float *temperature) { - char buf[24]; - DH_I2C_Status status; - if(sda != BMP280_NO_PIN && scl != BMP280_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * bmp280_read() implementation. + */ +int ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, float *temperature) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("bmp280: failed to set up pins"); return status; } } + + char buf[24]; buf[0] = 0x88; // get factory parameters - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp280: failed to write get coefficients command"); return status; } - if((status = dh_i2c_read(mAddress, buf, sizeof(buf))) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, sizeof(buf))) != DH_I2C_OK) { dhdebug("bmp280: failed to read coefficients"); return status; } @@ -50,35 +57,35 @@ DH_I2C_Status ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, f // configure buf[0] = 0xF5; // config buf[1] = 0x0C; // filter coefficient 8, spi off, duration 0 - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to configure"); return status; } buf[0] = 0xF4; // control buf[1] = 0xB7; // both oversampling to x16, normal mode - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { - dhdebug("bmp280: failed to configure"); + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + dhdebug("bmp280: failed to control"); return status; } do { // wait until data is ready buf[0] = 0xF3; // status - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp280: failed to get status"); return status; } - if((status = dh_i2c_read(mAddress, buf, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to read status"); return status; } - } while(buf[0] & (1<<3)); + } while (buf[0] & BIT(3)); buf[0] = 0xF7; // read press and temp result - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("bmp280: failed to start reading"); return status; } - if((status = dh_i2c_read(mAddress, buf, 6)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 6)) != DH_I2C_OK) { dhdebug("bmp280: failed to read"); return status; } @@ -91,18 +98,18 @@ DH_I2C_Status ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, f double v1 = (raw_temperature / 16384.0 - T1 / 1024.0) * T2; double v2 = raw_temperature / 131072.0 - T1 / 8192.0; v2 = v2 * v2 * (double)T3; - long int t_fine = v1 + v2; - if(temperature) { + double t_fine = v1 + v2; + if (temperature) { *temperature = (float)t_fine / 5120.0f; } - v1 = ((double)t_fine) / 2.0 - 64000.0; + v1 = (t_fine) / 2.0 - 64000.0; v2 = v1 * v1 * P6 / 32768.0; v2 = v2 + v1 * P5 * 2.0; v2 = v2 / 4.0 + P4 * 65536.0; v1 = (P3 * v1 * v1 / 524288.0 + P2 * v1) / 524288.0; v1 = (1.0 + v1 / 32768.0) * P1; - if(v1 == 0.0) { + if (v1 == 0.0) { // TODO: fix this condition return DH_I2C_DEVICE_ERROR; } double p = 1048576.0 - raw_pressure; @@ -114,13 +121,19 @@ DH_I2C_Status ICACHE_FLASH_ATTR bmp280_read(int sda, int scl, float *pressure, f buf[0] = 0xF4; // control buf[1] = 0x0; // sleep mode - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("bmp280: failed to shutdown"); return status; } + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR bmp280_set_address(int address) { + +/* + * bmp280_set_address() implementation. + */ +void ICACHE_FLASH_ATTR bmp280_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/bmp280.h b/firmware-src/sources/devices/bmp280.h index 71a67fe..3e3316a 100644 --- a/firmware-src/sources/devices/bmp280.h +++ b/firmware-src/sources/devices/bmp280.h @@ -1,35 +1,29 @@ /** - * \file bmp280.h - * \brief Simple communication with BMP280 pressure sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with BMP280 pressure sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_BMP280_H_ -#define SOURCES_DEVICES_BMP280_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define BMP280_DEFAULT_ADDRESS 0xEC -/** Do not initialize pin */ -#define BMP280_NO_PIN -1 +#ifndef _DEVICES_BMP280_H_ +#define _DEVICES_BMP280_H_ /** - * \brief Measure pressure one time. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] pressure Pointer for storing pressure result measure in Pascals. - * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure pressure one time. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] pressure Pointer for storing pressure result measure in Pascals. + * @param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status bmp280_read(int sda, int scl, float *pressure, float *temperature); +int bmp280_read(int sda, int scl, + float *pressure, + float *temperature); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void bmp280_set_address(int address); -#endif /* SOURCES_DEVICES_BMP280_H_ */ +#endif /* _DEVICES_BMP280_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index d22d930..9f00726 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -28,8 +28,8 @@ #include "dhutils.h" #include "devices/ds18b20.h" #include "devices/dht.h" -#include "devices/bmp180.h" -#include "devices/bmp280.h" +#include "commands/bmp180_cmd.h" +#include "commands/bmp280_cmd.h" #include "commands/bh1750_cmd.h" #include "devices/mpu6050.h" #include "devices/hmc5883l.h" @@ -141,69 +141,6 @@ static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const ch } } -/** - * @brief Do "devices/bmp180/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_bmp180_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - bmp180_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float temperature; - int pressure; - const char *res = dh_i2c_error_string(bmp180_read(BMP180_NO_PIN, BMP180_NO_PIN, &pressure, &temperature)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); - } -} - -/** - * @brief Do "devices/bmp280/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_bmp280_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - bmp280_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float temperature; - float pressure; - const char *res = dh_i2c_error_string(bmp280_read(BMP280_NO_PIN, BMP280_NO_PIN, &pressure, &temperature)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); - } -} - - /** * @brief Do "devices/mpu6050/read" command. */ @@ -932,8 +869,8 @@ RO_DATA struct { { "devices/ds18b20/read", do_devices_ds18b20_read}, { "devices/dht11/read", do_devices_dht11_read}, { "devices/dht22/read", do_devices_dht22_read}, - { "devices/bmp180/read", do_devices_bmp180_read}, - { "devices/bmp280/read", do_devices_bmp280_read}, + { "devices/bmp180/read", dh_handle_devices_bmp180_read}, + { "devices/bmp280/read", dh_handle_devices_bmp280_read}, { "devices/bh1750/read", dh_handle_devices_bh1750_read}, { "devices/mpu6050/read", do_devices_mpu6050_read}, { "devices/hmc5883l/read", do_devices_hmc5883l_read}, diff --git a/firmware-src/sources/user_config.h b/firmware-src/sources/user_config.h index c2c5c21..ba75f18 100644 --- a/firmware-src/sources/user_config.h +++ b/firmware-src/sources/user_config.h @@ -45,4 +45,6 @@ #define DH_COMMANDS_SPI // enable SPI commands #define DH_COMMANDS_ONEWIRE // enable onewire commands +// TODO: customize device list + #endif /* _USER_CONFIG_H_ */ From 72ead244cf18812101d2b8a739261d2d7560fe87 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 27 Apr 2017 19:08:11 +0300 Subject: [PATCH 39/83] review DHT devices --- firmware-src/sources/DH/onewire.h | 5 + firmware-src/sources/commands/dht_cmd.c | 66 ++++++++++- firmware-src/sources/commands/dht_cmd.h | 14 +++ firmware-src/sources/devices/dht.c | 139 +++++++++++++++--------- firmware-src/sources/devices/dht.h | 58 +++++----- firmware-src/sources/dhcommands.c | 62 +---------- 6 files changed, 200 insertions(+), 144 deletions(-) diff --git a/firmware-src/sources/DH/onewire.h b/firmware-src/sources/DH/onewire.h index 53eb6e4..78f36bc 100644 --- a/firmware-src/sources/DH/onewire.h +++ b/firmware-src/sources/DH/onewire.h @@ -11,6 +11,11 @@ #include +/** + * @brief Do not initialize pin indicator. + */ +#define DH_ONEWIRE_NO_PIN (-1) + /** * @brief Set pin for onewire, but not initialize it. diff --git a/firmware-src/sources/commands/dht_cmd.c b/firmware-src/sources/commands/dht_cmd.c index d727d89..b1e1d9f 100644 --- a/firmware-src/sources/commands/dht_cmd.c +++ b/firmware-src/sources/commands/dht_cmd.c @@ -7,6 +7,7 @@ #include "commands/dht_cmd.h" #include "commands/onewire_cmd.h" #include "devices/dht.h" +#include "DH/onewire.h" #include "DH/adc.h" #include "dhcommand_parser.h" @@ -32,9 +33,72 @@ void ICACHE_FLASH_ATTR dh_handle_onewire_dht_read(COMMAND_RESULT *cmd_res, const return; // FAILED } - info.count = dhonewire_dht_read(info.data, sizeof(info.data)); + info.count = dht_read(info.data, sizeof(info.data)); if (info.count) dh_command_done_buf(cmd_res, info.data, info.count); else dh_command_fail(cmd_res, "No response"); } + + + +/* + * dh_handle_devices_dht11_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_dht11_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + } + + int temperature; + int humidity; + const char *err_msg = dht11_read(DH_ONEWIRE_NO_PIN, &humidity, &temperature); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); + } +} + + +/* + * dh_handle_devices_dht22_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_dht22_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + } + + float temperature; + float humidity; + const char *err_msg = dht22_read(DH_ONEWIRE_NO_PIN, &humidity, &temperature); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); + } +} diff --git a/firmware-src/sources/commands/dht_cmd.h b/firmware-src/sources/commands/dht_cmd.h index 124e573..20a1d16 100644 --- a/firmware-src/sources/commands/dht_cmd.h +++ b/firmware-src/sources/commands/dht_cmd.h @@ -15,4 +15,18 @@ void dh_handle_onewire_dht_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); + +/** + * @brief Handle "devices/dht11/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_dht11_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "devices/dht22/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_dht22_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + #endif /* _COMMANDS_DHT_CMD_H_ */ diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 1c8b1dd..9ca74da 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -1,12 +1,10 @@ -/* - * dht.h - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with DHT11 humidity sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "dht.h" +#include "devices/dht.h" #include "DH/onewire.h" #include "DH/adc.h" #include "dhdebug.h" @@ -22,88 +20,121 @@ #define DHT_RESET_LENGTH_US 25000 #define DHT_TIMEOUT_US 200 -LOCAL char * ICACHE_FLASH_ATTR dht_read(int pin, char *buf) { - if(pin != DHT_NO_PIN) { +/** + * @brief Read DHT packet of 5 bytes. + */ +static const char* ICACHE_FLASH_ATTR dht_read_pkt(int pin, uint8_t buf[DHT_PACKET_SIZE]) +{ + if (pin != DH_ONEWIRE_NO_PIN) { if (!!dh_onewire_set_pin(pin)) { return "Failed to set up onewire pin"; } } - if(dhonewire_dht_read(buf, DHT_PACKET_SIZE) != DHT_PACKET_SIZE ) { + + if (dht_read(buf, DHT_PACKET_SIZE) != DHT_PACKET_SIZE) { return "Failed to read data"; } - char cs = ((int)buf[0] + (int)buf[1] + (int)buf[2] + (int)buf[3]) & 0xFF; - if(cs != buf[4]) { + + int cs = ((int)buf[0] + (int)buf[1] + (int)buf[2] + (int)buf[3]); + if (cs*0xFF != (int)buf[4]) { return "Bad checksum"; } - return 0; + + return 0; // OK } -char * ICACHE_FLASH_ATTR dht11_read(int pin, int *humidity, int *temperature) { - char buf[DHT_PACKET_SIZE]; - char *r = dht_read(pin, buf); - if(r) - return r; - *humidity = (uint8_t)buf[0]; - if(temperature) - *temperature = (uint8_t)buf[2]; - return NULL; + +/* + * dht11_read() implementation. + */ +const char* ICACHE_FLASH_ATTR dht11_read(int pin, int *humidity, int *temperature) +{ + uint8_t buf[DHT_PACKET_SIZE]; + const char *err_msg = dht_read_pkt(pin, buf); + if (err_msg != 0) + return err_msg; + + *humidity = buf[0]; + if (temperature) + *temperature = buf[2]; + + return NULL; // OK } -char * ICACHE_FLASH_ATTR dht22_read(int pin, float *humidity, float *temperature) { - char buf[DHT_PACKET_SIZE]; - char *r = dht_read(pin, buf); - if(r) - return r; - *humidity = signedInt16be_sm(buf, 0) / 10.0f; - if(temperature) - *temperature = signedInt16be_sm(buf, 2) / 10.0f; - return NULL; +/* + * dht22_read() implementation. + */ +const char* ICACHE_FLASH_ATTR dht22_read(int pin, float *humidity, float *temperature) +{ + uint8_t buf[DHT_PACKET_SIZE]; + const char *err_msg = dht_read_pkt(pin, buf); + if (err_msg != 0) + return err_msg; + + *humidity = signedInt16be_sm((const char*)buf, 0) / 10.0f; + if (temperature) + *temperature = signedInt16be_sm((const char*)buf, 2) / 10.0f; + + return NULL; // OK } -LOCAL unsigned int ICACHE_FLASH_ATTR donewire_dht_measure_high(unsigned int pin) { +/** + * @brief Measure high-level interval. + */ +static unsigned int ICACHE_FLASH_ATTR dht_measure_high(DHGpioPinMask pin_mask) +{ unsigned int counter = 0; - while((gpio_input_get() & pin) == 0) { - if(counter > DHT_TIMEOUT_US) - return 0; + while (!(gpio_input_get() & pin_mask)) { + if (counter > DHT_TIMEOUT_US) + return 0; // timeout! os_delay_us(1); counter++; } + counter = 0; - while((gpio_input_get() & pin)) { - if(counter > DHT_TIMEOUT_US) + while ((gpio_input_get() & pin_mask)) { + if (counter > DHT_TIMEOUT_US) return DHT_TIMEOUT_US; os_delay_us(1); counter++; } + return counter; } -int ICACHE_FLASH_ATTR dhonewire_dht_read(char *buf, unsigned int len) { - const unsigned int pin = DH_GPIO_PIN(dh_onewire_get_pin()); - if (dh_onewire_reset(pin, 1) == 0) - return 0; + +/* + * dht_read() implementation. + */ +int ICACHE_FLASH_ATTR dht_read(void *buf_, size_t len) +{ + const DHGpioPinMask pin_mask = DH_GPIO_PIN(dh_onewire_get_pin()); + if (0 == dh_onewire_reset(pin_mask, 1)) + return 0; // no device present + ETS_INTR_LOCK(); - unsigned int i; - if(donewire_dht_measure_high(pin) >= DHT_TIMEOUT_US) { // wait till response finish + if (dht_measure_high(pin_mask) >= DHT_TIMEOUT_US) { // wait till response finish ETS_INTR_UNLOCK(); - return 0; + return 0; // failed } - for(i = 0; i / 8 < len; i++) { - unsigned int time = donewire_dht_measure_high(pin); - if(time >= DHT_TIMEOUT_US || time <= 10) { + size_t i; + uint8_t *buf = (uint8_t*)buf_; + for(i = 0; i/8 < len; i++) { + unsigned int time = dht_measure_high(pin_mask); + if (time >= DHT_TIMEOUT_US || time <= 10) { break; } else { - const char bit = 1 << (7 - i % 8); - if(time > 25) - buf[i / 8] |= bit; + const int bit = BIT(7 - i%8); + if (time > 25) + buf[i/8] |= bit; else - buf[i / 8] &= ~bit; + buf[i/8] &= ~bit; } system_soft_wdt_feed(); } + ETS_INTR_UNLOCK(); - return i / 8; + return i/8; } - diff --git a/firmware-src/sources/devices/dht.h b/firmware-src/sources/devices/dht.h index 1051b02..4cf2ea2 100644 --- a/firmware-src/sources/devices/dht.h +++ b/firmware-src/sources/devices/dht.h @@ -1,43 +1,43 @@ /** - * \file dht.h - * \brief Simple communication with DHT11 humidity sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with DHT11 humidity sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_DHT_H_ +#define _DEVICES_DHT_H_ -#ifndef SOURCES_DEVICES_DHT_H_ -#define SOURCES_DEVICES_DHT_H_ - -/** Do not initialize pin */ -#define DHT_NO_PIN -1 +#include /** - * \brief Measure relative humidity with DHT11 sensor one time. - * \param[in] pin 1-wire pin for communication. - * \param[out] humidity Pointer for storing relative humidity result measure in percents. - * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return NULL on success, text description on error. + * @brief Measure relative humidity with DHT11 sensor one time. + * @param[in] pin 1-wire pin for communication. Can be DH_ONEWIRE_NO_PIN. + * @param[out] humidity Pointer for storing relative humidity result measure in percents. + * @param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. + * @return NULL on success, text description on error. */ -char *dht11_read(int pin, int *humidity, int *temperature); +const char* dht11_read(int pin, int *humidity, int *temperature); + /** - * \brief Measure relative humidity with DHT22 sensor one time. - * \param[in] pin 1-wire pin for communication. - * \param[out] humidity Pointer for storing relative humidity result measure in percents. - * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return NULL on success, text description on error. + * @brief Measure relative humidity with DHT22 sensor one time. + * @param[in] pin 1-wire pin for communication. Can be DH_ONEWIRE_NO_PIN. + * @param[out] humidity Pointer for storing relative humidity result measure in percents. + * @param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. + * @return NULL on success, text description on error. */ -char *dht22_read(int pin, float *humidity, float *temperature); +const char* dht22_read(int pin, float *humidity, float *temperature); /** - * \brief Read data from DHT like devices. - * \details Checksum will not be checked. - * \param[out] buf Buffer for data. - * \param[in] len Buffer length in bytes. - * \return Number of read bytes on success, zero on error. + * @brief Read data from DHT like devices. + * + * Checksum will not be checked. + * + * @param[out] buf Buffer to read to. + * @param[in] len Buffer length in bytes. + * @return Number of read bytes on success, zero on error. */ -int dhonewire_dht_read(char *buf, unsigned int len); +int dht_read(void *buf, size_t len); -#endif /* SOURCES_DEVICES_DHT_H_ */ +#endif /* _DEVICES_DHT_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 9f00726..9a4edc1 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -83,64 +83,6 @@ static void ICACHE_FLASH_ATTR do_devices_ds18b20_read(COMMAND_RESULT *cb, const } } - -/** - * @brief Do "devices/dht11/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_dht11_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(dh_onewire_init_helper(cb, fields, &parse_pins)) - return; - } - - int temperature; - int humidity; - char *res = dht11_read(DHT_NO_PIN, &humidity, &temperature); - if(res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); - } -} - - -/** - * @brief Do "devices/dht22/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_dht22_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(dh_onewire_init_helper(cb, fields, &parse_pins)) - return; - } - - float temperature; - float humidity; - char *res = dht22_read(DHT_NO_PIN, &humidity, &temperature); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); - } -} - /** * @brief Do "devices/mpu6050/read" command. */ @@ -867,8 +809,8 @@ RO_DATA struct { #endif /* DH_COMMANDS_ONEWIRE */ { "devices/ds18b20/read", do_devices_ds18b20_read}, - { "devices/dht11/read", do_devices_dht11_read}, - { "devices/dht22/read", do_devices_dht22_read}, + { "devices/dht11/read", dh_handle_devices_dht11_read}, + { "devices/dht22/read", dh_handle_devices_dht22_read}, { "devices/bmp180/read", dh_handle_devices_bmp180_read}, { "devices/bmp280/read", dh_handle_devices_bmp280_read}, { "devices/bh1750/read", dh_handle_devices_bh1750_read}, From 63704fc521f8cfd4a97bd251be0c65f2a84dd96f Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 11:36:29 +0300 Subject: [PATCH 40/83] review DS18B20 device --- firmware-src/sources/commands/ds18b20_cmd.c | 43 +++++++++++++++++ firmware-src/sources/commands/ds18b20_cmd.h | 18 ++++++++ firmware-src/sources/devices/ds18b20.c | 51 +++++++++++---------- firmware-src/sources/devices/ds18b20.h | 29 +++++------- firmware-src/sources/dhcommands.c | 30 +----------- 5 files changed, 103 insertions(+), 68 deletions(-) create mode 100644 firmware-src/sources/commands/ds18b20_cmd.c create mode 100644 firmware-src/sources/commands/ds18b20_cmd.h diff --git a/firmware-src/sources/commands/ds18b20_cmd.c b/firmware-src/sources/commands/ds18b20_cmd.c new file mode 100644 index 0000000..cb00699 --- /dev/null +++ b/firmware-src/sources/commands/ds18b20_cmd.c @@ -0,0 +1,43 @@ +/** + * @file + * @brief DS18B20 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/ds18b20_cmd.h" +#include "commands/onewire_cmd.h" +#include "devices/ds18b20.h" +#include "DH/onewire.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_ds18b20_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_ds18b20_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (dh_onewire_init_helper(cmd_res, fields, &info)) + return; // FAILED + } + + float temperature; + const char *err_msg = ds18b20_read(DH_ONEWIRE_NO_PIN, &temperature); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + } +} diff --git a/firmware-src/sources/commands/ds18b20_cmd.h b/firmware-src/sources/commands/ds18b20_cmd.h new file mode 100644 index 0000000..789701c --- /dev/null +++ b/firmware-src/sources/commands/ds18b20_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief DS18B20 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_DS18B20_CMD_H_ +#define _COMMANDS_DS18B20_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/ds18b20/read" command. + */ +void dh_handle_devices_ds18b20_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_DS18B20_CMD_H_ */ diff --git a/firmware-src/sources/devices/ds18b20.c b/firmware-src/sources/devices/ds18b20.c index 8eef037..d658618 100644 --- a/firmware-src/sources/devices/ds18b20.c +++ b/firmware-src/sources/devices/ds18b20.c @@ -1,42 +1,47 @@ -/* - * ds18b20.h - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with DS18B20 temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "ds18b20.h" +#include "devices/ds18b20.h" #include "DH/onewire.h" #include "dhutils.h" #include -#include - -char * ICACHE_FLASH_ATTR ds18b20_read(int pin, float *temperature) { - char in_buf[8]; - char out_buf[2]; - int16_t *res = (int16_t *)&in_buf[0]; - out_buf[0] = 0xCC; - if(pin != DS18B20_NO_PIN) { + + +/* + * ds18b20_read() implementation. + */ +const char* ICACHE_FLASH_ATTR ds18b20_read(int pin, float *temperature) +{ + if (pin != DH_ONEWIRE_NO_PIN) { if(!!dh_onewire_set_pin(pin)) { return "Failed to set up onewire pin"; } } - out_buf[1] = 0x44; // start measure, use defaults - if (!!dh_onewire_write(out_buf, sizeof(out_buf))) { + + uint8_t buf[8]; + buf[0] = 0xCC; + buf[1] = 0x44; // start measure, use defaults + if (!!dh_onewire_write(buf, 2)) { return "No response"; } delay_ms(750); // maximum possible time for measure - out_buf[1] = 0xBE; // read memory - if (!!dh_onewire_write(out_buf, sizeof(out_buf))) { + // buf[0] = 0xCC; + buf[1] = 0xBE; // read memory + if (!!dh_onewire_write(buf, 2)) { return "Failed to read"; } - if (!!dh_onewire_read(in_buf, sizeof(in_buf))) { + if (!!dh_onewire_read(buf, sizeof(buf))) { return "Failed to read data"; } - *temperature = (*res / 16.0f); // default precision - return NULL; + + const int16_t *t = (const int16_t *)&buf[0]; + *temperature = (t[0] / 16.0f); // default precision + + return NULL; // OK } diff --git a/firmware-src/sources/devices/ds18b20.h b/firmware-src/sources/devices/ds18b20.h index 706cb29..f953ac2 100644 --- a/firmware-src/sources/devices/ds18b20.h +++ b/firmware-src/sources/devices/ds18b20.h @@ -1,23 +1,18 @@ /** - * \file ds18b20.h - * \brief Simple communication with DS18B20 temperature sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with DS18B20 temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_DS18B20_H_ -#define SOURCES_DEVICES_DS18B20_H_ - -/** Do not initialize pin */ -#define DS18B20_NO_PIN -1 +#ifndef _DEVICES_DS18B20_H_ +#define _DEVICES_DS18B20_H_ /** - * \brief Measure temperature one time. - * \param[in] pin 1-wire pin for communication. - * \param[out] temperature Pointer to store measure result in degree Celsius. - * \return NULL on success, text description on error. + * @brief Measure temperature one time. + * @param[in] pin 1-wire pin for communication. Can be DH_ONEWIRE_NO_PIN. + * @param[out] temperature Pointer to store measure result in degree Celsius. + * @return NULL on success, text description on error. */ -char *ds18b20_read(int pin, float *temperature); +const char* ds18b20_read(int pin, float *temperature); -#endif /* SOURCES_DEVICES_DS18B20_H_ */ +#endif /* _DEVICES_DS18B20_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 9a4edc1..014d55e 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -26,7 +26,7 @@ #include "dhterminal.h" #include "dhdebug.h" #include "dhutils.h" -#include "devices/ds18b20.h" +#include "commands/ds18b20_cmd.h" #include "devices/dht.h" #include "commands/bmp180_cmd.h" #include "commands/bmp280_cmd.h" @@ -57,32 +57,6 @@ #if 1 // devices commands -/** - * @brief Do "devices/ds18b20/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_ds18b20_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char * parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_PIN, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(dh_onewire_init_helper(cb, fields, &parse_pins)) - return; - } - float temperature; - char *res = ds18b20_read(DS18B20_NO_PIN, &temperature); - if(res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } -} - /** * @brief Do "devices/mpu6050/read" command. */ @@ -808,7 +782,7 @@ RO_DATA struct { { "onewire/ws2812b/write", dh_handle_onewire_ws2812b_write}, #endif /* DH_COMMANDS_ONEWIRE */ - { "devices/ds18b20/read", do_devices_ds18b20_read}, + { "devices/ds18b20/read", dh_handle_devices_ds18b20_read}, { "devices/dht11/read", dh_handle_devices_dht11_read}, { "devices/dht22/read", dh_handle_devices_dht22_read}, { "devices/bmp180/read", dh_handle_devices_bmp180_read}, From 9370e6bad943ea03e726b3cc767810926b076837 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 11:59:32 +0300 Subject: [PATCH 41/83] review HMC5883L device --- firmware-src/sources/commands/hmc5883l_cmd.c | 62 ++++++++++++++++++++ firmware-src/sources/commands/hmc5883l_cmd.h | 19 ++++++ firmware-src/sources/devices/hmc5883l.c | 58 ++++++++++-------- firmware-src/sources/devices/hmc5883l.h | 51 ++++++++-------- firmware-src/sources/dhcommands.c | 45 +------------- 5 files changed, 141 insertions(+), 94 deletions(-) create mode 100644 firmware-src/sources/commands/hmc5883l_cmd.c create mode 100644 firmware-src/sources/commands/hmc5883l_cmd.h diff --git a/firmware-src/sources/commands/hmc5883l_cmd.c b/firmware-src/sources/commands/hmc5883l_cmd.c new file mode 100644 index 0000000..5a40737 --- /dev/null +++ b/firmware-src/sources/commands/hmc5883l_cmd.c @@ -0,0 +1,62 @@ +/** + * @file + * @brief HMC5883L command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/hmc5883l_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/hmc5883l.h" +#include "DH/i2c.h" +#include "DH/adc.h" +#include "snprintf.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_hmc5883l_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_hmc5883l_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + hmc5883l_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + HMC5883L_XYZ compass; + const int status = hmc5883l_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &compass); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + + // TODO: support for NaN in snprintf! + char floatbufx[10] = "NaN"; + char floatbufy[10] = "NaN"; + char floatbufz[10] = "NaN"; + if (compass.X != HMC5883l_OVERFLOWED) + snprintf(floatbufx, sizeof(floatbufx), "%f", compass.X); + if (compass.Y != HMC5883l_OVERFLOWED) + snprintf(floatbufy, sizeof(floatbufy), "%f", compass.Y); + if (compass.Z != HMC5883l_OVERFLOWED) + snprintf(floatbufz, sizeof(floatbufz), "%f", compass.Z); + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"magnetometer\":{\"X\":%s, \"Y\":%s, \"Z\":%s}}", + floatbufx, floatbufy, floatbufz); +} diff --git a/firmware-src/sources/commands/hmc5883l_cmd.h b/firmware-src/sources/commands/hmc5883l_cmd.h new file mode 100644 index 0000000..55c4a3b --- /dev/null +++ b/firmware-src/sources/commands/hmc5883l_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief HMC5883L command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_HMC5883L_CMD_H_ +#define _COMMANDS_HMC5883L_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/hmc5883l/read" command. + */ + +void dh_handle_devices_hmc5883l_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_HMC5883L_CMD_H_ */ diff --git a/firmware-src/sources/devices/hmc5883l.c b/firmware-src/sources/devices/hmc5883l.c index 846fc32..a2f53e9 100644 --- a/firmware-src/sources/devices/hmc5883l.c +++ b/firmware-src/sources/devices/hmc5883l.c @@ -1,36 +1,42 @@ -/* - * hmc5883l.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with HMC5883L compass sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "hmc5883l.h" +#include "devices/hmc5883l.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include + +/** @brief Default sensor i2c address*/ +#define HMC5883L_DEFAULT_ADDRESS 0x3C #define HMC5883l_OVERFLOWED_RAW -4096 +// module variables static int mAddress = HMC5883L_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, - HMC5883L_XYZ *compass) { - char buf[7]; - DH_I2C_Status status; - if(sda != HMC5883L_NO_PIN && scl != HMC5883L_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * hmc5883l_read() implementation. + */ +int ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to set up pins"); return status; } } + uint8_t buf[7]; buf[0] = 0x02; // mode register - buf[1] = 1 << 0; // single run mode - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + buf[1] = BIT(0); // single run mode + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to power up"); return status; } @@ -38,25 +44,31 @@ DH_I2C_Status ICACHE_FLASH_ATTR hmc5883l_read(int sda, int scl, delay_ms(80); buf[0] = 0x03; // get data - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to set read register"); return status; } - if((status = dh_i2c_read(mAddress, buf, 7)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 7)) != DH_I2C_OK) { dhdebug("hmc5883l: failed to read"); return status; } - const int x = signedInt16be(buf, 0); - const int y = signedInt16be(buf, 4); - const int z = signedInt16be(buf, 2); + const int x = signedInt16be((const char*)buf, 0); + const int y = signedInt16be((const char*)buf, 4); + const int z = signedInt16be((const char*)buf, 2); // note: 2048 is a range of possible values, 1.3f is a default sensor field range compass->X = (x == HMC5883l_OVERFLOWED_RAW) ? HMC5883l_OVERFLOWED : (x * 1.3f / 2048.0f); compass->Y = (y == HMC5883l_OVERFLOWED_RAW) ? HMC5883l_OVERFLOWED : (y * 1.3f / 2048.0f); compass->Z = (z == HMC5883l_OVERFLOWED_RAW) ? HMC5883l_OVERFLOWED : (z * 1.3f / 2048.0f); + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR hmc5883l_set_address(int address) { + +/* + * hmc5883l_set_address() implementation. + */ +void ICACHE_FLASH_ATTR hmc5883l_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/hmc5883l.h b/firmware-src/sources/devices/hmc5883l.h index 10659fe..075da40 100644 --- a/firmware-src/sources/devices/hmc5883l.h +++ b/firmware-src/sources/devices/hmc5883l.h @@ -1,43 +1,38 @@ /** - * \file hmc5883l.h - * \brief Simple communication with HMC5883L compass sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with HMC5883L compass sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_HMC5883L_H_ +#define _DEVICES_HMC5883L_H_ -#ifndef SOURCES_DEVICES_HMC5883L_H_ -#define SOURCES_DEVICES_HMC5883L_H_ +/** Measurements in three dimensions. */ +typedef struct { + float X; ///< @brief X axis. + float Y; ///< @brief Y axis. + float Z; ///< @brief Z axis. +} HMC5883L_XYZ; -#include "DH/i2c.h" -/** Default sensor i2c address*/ -#define HMC5883L_DEFAULT_ADDRESS 0x3C -/** Do not initialize pin */ -#define HMC5883L_NO_PIN -1 -/** Axis overflow */ -#define HMC5883l_OVERFLOWED -100000000.0f +/** @brief Axis overflow */ +#define HMC5883l_OVERFLOWED -1.0e8f -/** Struct for results in three dimensions */ -typedef struct { - float X; ///< X axis - float Y; ///< Y axis - float Z; ///< Z axis -} HMC5883L_XYZ; /** - * \brief Measure compass data. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] compass Compass data in normalized vector. If axis is overflowed during measure, HMC5883l_OVERFLOWED is a value. + * @brief Measure compass data. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] compass Compass data in normalized vector. If axis is overflowed during measure, HMC5883l_OVERFLOWED is a value. * \return NULL on success, text description on error. */ -DH_I2C_Status hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass); +int hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void hmc5883l_set_address(int address); -#endif /* SOURCES_DEVICES_HMC5883L_H_ */ +#endif /* _DEVICES_HMC5883L_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 014d55e..fc29e87 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -32,7 +32,7 @@ #include "commands/bmp280_cmd.h" #include "commands/bh1750_cmd.h" #include "devices/mpu6050.h" -#include "devices/hmc5883l.h" +#include "commands/hmc5883l_cmd.h" #include "devices/pcf8574.h" #include "devices/pcf8574_hd44780.h" #include "devices/mhz19.h" @@ -91,47 +91,6 @@ static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const } } -/** - * @brief Do "devices/hmc5883l/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_hmc5883l_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - hmc5883l_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - HMC5883L_XYZ compass; - const char *res = dh_i2c_error_string(hmc5883l_read(HMC5883L_NO_PIN, HMC5883L_NO_PIN, &compass)); - if(res != 0) { - dh_command_fail(cb, res); - return; - } - char floatbufx[10] = "NaN"; - char floatbufy[10] = "NaN"; - char floatbufz[10] = "NaN"; - if(compass.X != HMC5883l_OVERFLOWED) - snprintf(floatbufx, sizeof(floatbufx), "%f", compass.X); - if(compass.Y != HMC5883l_OVERFLOWED) - snprintf(floatbufy, sizeof(floatbufy), "%f", compass.Y); - if(compass.Z != HMC5883l_OVERFLOWED) - snprintf(floatbufz, sizeof(floatbufz), "%f", compass.Z); - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"magnetometer\":{\"X\":%s, \"Y\":%s, \"Z\":%s}}", - floatbufx, floatbufy, floatbufz); -} - /** * @brief Do "devices/pcf8574/read" command. */ @@ -789,7 +748,7 @@ RO_DATA struct { { "devices/bmp280/read", dh_handle_devices_bmp280_read}, { "devices/bh1750/read", dh_handle_devices_bh1750_read}, { "devices/mpu6050/read", do_devices_mpu6050_read}, - { "devices/hmc5883l/read", do_devices_hmc5883l_read}, + { "devices/hmc5883l/read", dh_handle_devices_hmc5883l_read}, { "devices/pcf8574/read", do_devices_pcf8574_read}, { "devices/pcf8574/write", do_devices_pcf8574_write}, { "devices/pcf8574/hd44780/write", do_devices_pcf8574_hd44780_write}, From 45321750f9680371d220464304d230589ea43dda Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 12:56:10 +0300 Subject: [PATCH 42/83] review INA219 and LM75 devices --- firmware-src/sources/commands/ina219_cmd.c | 62 +++++++++++++++++ firmware-src/sources/commands/ina219_cmd.h | 19 ++++++ firmware-src/sources/commands/lm75_cmd.c | 49 ++++++++++++++ firmware-src/sources/commands/lm75_cmd.h | 19 ++++++ firmware-src/sources/devices/hmc5883l.h | 2 +- firmware-src/sources/devices/ina219.c | 75 ++++++++++++-------- firmware-src/sources/devices/ina219.h | 56 +++++++-------- firmware-src/sources/devices/lm75.c | 52 ++++++++------ firmware-src/sources/devices/lm75.h | 40 +++++------ firmware-src/sources/dhcommands.c | 79 ++-------------------- 10 files changed, 275 insertions(+), 178 deletions(-) create mode 100644 firmware-src/sources/commands/ina219_cmd.c create mode 100644 firmware-src/sources/commands/ina219_cmd.h create mode 100644 firmware-src/sources/commands/lm75_cmd.c create mode 100644 firmware-src/sources/commands/lm75_cmd.h diff --git a/firmware-src/sources/commands/ina219_cmd.c b/firmware-src/sources/commands/ina219_cmd.c new file mode 100644 index 0000000..5a02f5a --- /dev/null +++ b/firmware-src/sources/commands/ina219_cmd.c @@ -0,0 +1,62 @@ +/** + * @file + * @brief INA219 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/ina219_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/ina219.h" +#include "DH/i2c.h" +#include "DH/adc.h" +#include "snprintf.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_ina219_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_ina219_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char* err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + ina219_set_address(info.address); + if (fields & AF_REF) { + const int status = ina219_set_shunt(info.ref); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float voltage; + float current; + float power; + + const int status = ina219_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &voltage, ¤t, &power); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"voltage\":%f, \"current\":%f, \"power\":%f}", + voltage, current, power); + } +} diff --git a/firmware-src/sources/commands/ina219_cmd.h b/firmware-src/sources/commands/ina219_cmd.h new file mode 100644 index 0000000..ee0a96d --- /dev/null +++ b/firmware-src/sources/commands/ina219_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief INA219 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_INA219_CMD_H_ +#define _COMMANDS_INA219_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/ina219/read" command. + */ + +void dh_handle_devices_ina219_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_INA219_CMD_H_ */ diff --git a/firmware-src/sources/commands/lm75_cmd.c b/firmware-src/sources/commands/lm75_cmd.c new file mode 100644 index 0000000..5e7f52a --- /dev/null +++ b/firmware-src/sources/commands/lm75_cmd.c @@ -0,0 +1,49 @@ +/** + * @file + * @brief LM75 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/lm75_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/lm75.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_lm75_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_lm75_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char* err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + lm75_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; + + float temperature; + const int status = lm75_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &temperature); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f}", temperature); + } +} diff --git a/firmware-src/sources/commands/lm75_cmd.h b/firmware-src/sources/commands/lm75_cmd.h new file mode 100644 index 0000000..ec361b1 --- /dev/null +++ b/firmware-src/sources/commands/lm75_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief LM75 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_LM75_CMD_H_ +#define _COMMANDS_LM75_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/lm75/read" command. + */ + +void dh_handle_devices_lm75_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_LM75_CMD_H_ */ diff --git a/firmware-src/sources/devices/hmc5883l.h b/firmware-src/sources/devices/hmc5883l.h index 075da40..c8d8555 100644 --- a/firmware-src/sources/devices/hmc5883l.h +++ b/firmware-src/sources/devices/hmc5883l.h @@ -24,7 +24,7 @@ typedef struct { * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. * @param[out] compass Compass data in normalized vector. If axis is overflowed during measure, HMC5883l_OVERFLOWED is a value. - * \return NULL on success, text description on error. + * @return NULL on success, text description on error. */ int hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass); diff --git a/firmware-src/sources/devices/ina219.c b/firmware-src/sources/devices/ina219.c index d10c956..1cba490 100644 --- a/firmware-src/sources/devices/ina219.c +++ b/firmware-src/sources/devices/ina219.c @@ -1,69 +1,90 @@ -/* - * ina219.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with INA219 power monitor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "ina219.h" +#include "devices/ina219.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include #include +/** @brief Default sensor i2c address*/ +#define INA219_DEFAULT_ADDRESS 0x80 + +// module variables static int mAddress = INA219_DEFAULT_ADDRESS; static float mResistance = 0.1f; -DH_I2C_Status ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, float *current, float *power) { - char buf[12]; - DH_I2C_Status status; - if(sda != INA219_NO_PIN && scl != INA219_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * ina219_read() implementation. + */ +int ICACHE_FLASH_ATTR ina219_read(int sda, int scl, float *voltage, float *current, float *power) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("ina219: failed to set up pins"); return status; } } - uint16_t cal = 4096.0f / mResistance; + const uint16_t cal = (int)(4096.0f / mResistance); + + uint8_t buf[12]; buf[0] = 0x05; buf[1] = ((cal >> 8) & 0xFF); buf[2] = (cal & 0xFF); - if((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { dhdebug("ina219: failed to write calibration data"); return status; } os_delay_us(600); - char i; - for(i = 1; i < 5; i++) { - if((status = dh_i2c_write(mAddress, &i, 1, 0)) != DH_I2C_OK) { + int i; + for (i = 1; i < 5; i++) { + const uint8_t addr = i; + if ((status = dh_i2c_write(mAddress, &addr, 1, 0)) != DH_I2C_OK) { dhdebug("ina219: failed to write address"); return status; } - if((status = dh_i2c_read(mAddress, &buf[i * 2], 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, &buf[i*2], 2)) != DH_I2C_OK) { dhdebug("ina219: failed to read data"); return status; } } - //float shunt_voltage = ((float)signedInt16be(buf, 2)) / 100000.0f; - *voltage = (((float)((unsigned int)buf[4]) * 32 + (buf[5] > 3))) / 8000.0f * 32.0f; - *current = ((float)signedInt16be(buf, 8)) / 100000.0f; - *power = ((float)unsignedInt16be(buf, 6)) / 100000.0f * 20.0f; + + // float shunt_voltage = ((float)signedInt16be(buf, 2)) / 100000.0f; + *voltage = (((float)((unsigned int)buf[4]) * 32 + ((char)buf[5] > 3))) / 8000.0f * 32.0f; + *current = ((float)signedInt16be((const char*)buf, 8)) / 100000.0f; + *power = ((float)unsignedInt16be((const char*)buf, 6)) / 100000.0f * 20.0f; return DH_I2C_OK; } -void ICACHE_FLASH_ATTR ina219_set_address(int address) { + +/* + * ina219_set_address() implementation. + */ +void ICACHE_FLASH_ATTR ina219_set_address(int address) +{ mAddress = address; } -DH_I2C_Status ICACHE_FLASH_ATTR ina219_set_shunt(float resistance) { - if(mResistance <= 0.0f) + +/* + * ina219_set_shunt() implementation. + */ +int ICACHE_FLASH_ATTR ina219_set_shunt(float resistance) +{ + if (mResistance <= 0.0f) // TODO: check 4096.0f/mResistance < 64*1024 return DH_I2C_WRONG_PARAMETERS; + mResistance = resistance; return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/ina219.h b/firmware-src/sources/devices/ina219.h index c210a83..ac7a2ce 100644 --- a/firmware-src/sources/devices/ina219.h +++ b/firmware-src/sources/devices/ina219.h @@ -1,44 +1,38 @@ /** - * \file ina219.h - * \brief Simple communication with INA219 power monitor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with INA219 power monitor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_INA219_H_ -#define SOURCES_DEVICES_INA219_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define INA219_DEFAULT_ADDRESS 0x80 -/** Do not initialize pin */ -#define INA219_NO_PIN -1 +#ifndef _DEVICES_INA219_H_ +#define _DEVICES_INA219_H_ /** - * \brief Set DAC voltages. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] voltage Input voltage in Volts. - * \param[out] current Current in Amperes. - * \param[out] power Total power since first call. - * \return Status value, one of DH_I2C_Status enum. + * @brief Get measurements. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] voltage Input voltage in Volts. + * @param[out] current Current in Amperes. + * @param[out] power Total power since first call. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status ina219_read(int sda, int scl, float *voltage, float *current, float *power); +int ina219_read(int sda, int scl, float *voltage, float *current, float *power); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void ina219_set_address(int address); /** - * \brief Set reference shunt resistance. - * \note Default is 0.1 Ohm. - * \param[in] resistance Resistance in Ohms. - * \return Status value, one of DH_I2C_Status enum. + * @brief Set reference shunt resistance. + * + * Default is 0.1 Ohm. + * + * @param[in] resistance Resistance in Ohms. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status ina219_set_shunt(float resistance); +int ina219_set_shunt(float resistance); -#endif /* SOURCES_DEVICES_INA219_H_ */ +#endif /* _DEVICES_INA219_H_ */ diff --git a/firmware-src/sources/devices/lm75.c b/firmware-src/sources/devices/lm75.c index 3b25371..6c905ae 100644 --- a/firmware-src/sources/devices/lm75.c +++ b/firmware-src/sources/devices/lm75.c @@ -1,46 +1,58 @@ -/* - * lm75.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with LM75 temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "lm75.h" +#include "devices/lm75.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include #include +/** @brief Default sensor i2c address*/ +#define LM75_DEFAULT_ADDRESS 0x90 + +// module variables static int mAddress = LM75_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR lm75_read(int sda, int scl, float *temperature) { - char buf[2]; - int raw_temperature; - DH_I2C_Status status; - if(sda != LM75_NO_PIN && scl != LM75_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * lm75_read() implementation. + */ +int ICACHE_FLASH_ATTR lm75_read(int sda, int scl, float *temperature) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("lm75: failed to set up pins"); return status; } } - buf[0] = 0x0; // get temperature - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + uint8_t buf[2]; + buf[0] = 0x0; // get temperature + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("lm75: failed to write get temperature command"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("lm75: failed to read temperature"); return status; } - raw_temperature = signedInt16be(buf, 0); - *temperature = (float)raw_temperature / 256.0f; + const int raw = signedInt16be(buf, 0); + *temperature = (float)raw / 256.0f; return DH_I2C_OK; } -void ICACHE_FLASH_ATTR lm75_set_address(int address) { + +/* + * lm75_set_address() implementation. + */ +void ICACHE_FLASH_ATTR lm75_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/lm75.h b/firmware-src/sources/devices/lm75.h index fcd217b..8d82380 100644 --- a/firmware-src/sources/devices/lm75.h +++ b/firmware-src/sources/devices/lm75.h @@ -1,34 +1,26 @@ /** - * \file lm75.h - * \brief Simple communication with LM75 temperature sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with LM75 temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_LM75_H_ -#define SOURCES_DEVICES_LM75_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define LM75_DEFAULT_ADDRESS 0x90 -/** Do not initialize pin */ -#define LM75_NO_PIN -1 +#ifndef _DEVICES_LM75_H_ +#define _DEVICES_LM75_H_ /** - * \brief Measure temperature one time. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] temperature Pointer for storing temperature result measure in Celsius. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure temperature one time. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] temperature Pointer for storing temperature result measure in Celsius. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status lm75_read(int sda, int scl, float *temperature); +int lm75_read(int sda, int scl, float *temperature); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void lm75_set_address(int address); -#endif /* SOURCES_DEVICES_LM75_H_ */ +#endif /* _DEVICES_LM75_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index fc29e87..8b3ed2d 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -36,12 +36,12 @@ #include "devices/pcf8574.h" #include "devices/pcf8574_hd44780.h" #include "devices/mhz19.h" -#include "devices/lm75.h" +#include "commands/lm75_cmd.h" #include "devices/si7021.h" #include "commands/ads1115_cmd.h" #include "devices/pcf8591.h" #include "devices/mcp4725.h" -#include "devices/ina219.h" +#include "commands/ina219_cmd.h" #include "devices/mfrc522.h" #include "devices/pca9685.h" #include "devices/mlx90614.h" @@ -214,37 +214,6 @@ static void ICACHE_FLASH_ATTR do_devices_mhz19_read(COMMAND_RESULT *cb, const ch } -/** - * @brief Do "devices/lm75/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_lm75_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - lm75_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float temperature; - const char *res = dh_i2c_error_string(lm75_read(LM75_NO_PIN, LM75_NO_PIN, &temperature)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } -} - - /** * @brief Do "devices/si7021/read" command. */ @@ -389,46 +358,6 @@ static void ICACHE_FLASH_ATTR do_devices_mcp4725_write(COMMAND_RESULT *cb, const } } -/** - * @brief Do "devices/ina219/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_ina219_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - ina219_set_address(parse_pins.address); - if(fields & AF_REF) { - const char *res = dh_i2c_error_string(ina219_set_shunt(parse_pins.ref)); - if (res != 0) { - dh_command_fail(cb, res); - return; - } - } - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float voltage; - float current; - float power; - const char *res = dh_i2c_error_string(ina219_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &voltage, ¤t, &power)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"voltage\":%f, \"current\":%f, \"power\":%f}", - voltage, current, power); - } -} /** * @brief Do "devices/mfrc522/read" command. @@ -753,13 +682,13 @@ RO_DATA struct { { "devices/pcf8574/write", do_devices_pcf8574_write}, { "devices/pcf8574/hd44780/write", do_devices_pcf8574_hd44780_write}, { "devices/mhz19/read", do_devices_mhz19_read}, - { "devices/lm75/read", do_devices_lm75_read}, + { "devices/lm75/read", dh_handle_devices_lm75_read}, { "devices/si7021/read", do_devices_si7021_read}, { "devices/ads1115/read", dh_handle_devices_ads1115_read}, { "devices/pcf8591/read", do_devices_pcf8591_read}, { "devices/pcf8591/write", do_devices_pcf8591_write}, { "devices/mcp4725/write", do_devices_mcp4725_write}, - { "devices/ina219/read", do_devices_ina219_read}, + { "devices/ina219/read", dh_handle_devices_ina219_read}, { "devices/mfrc522/read", do_devices_mfrc522_read}, { "devices/mfrc522/mifare/read", do_devices_mfrc522_mifare_read_write}, { "devices/mfrc522/mifare/write", do_devices_mfrc522_mifare_read_write}, From 6920325ba3af1f0bf2ed9e8b111cc8a3667d0536 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 14:35:35 +0300 Subject: [PATCH 43/83] review MAX31855 and MAX6675 devices --- firmware-src/sources/DH/spi.h | 6 +++ firmware-src/sources/commands/max31855_cmd.c | 41 +++++++++++++++ firmware-src/sources/commands/max31855_cmd.h | 19 +++++++ firmware-src/sources/commands/max6675_cmd.c | 41 +++++++++++++++ firmware-src/sources/commands/max6675_cmd.h | 19 +++++++ firmware-src/sources/devices/lm75.c | 2 +- firmware-src/sources/devices/max31855.c | 43 ++++++++------- firmware-src/sources/devices/max31855.h | 29 +++++------ firmware-src/sources/devices/max6675.c | 42 ++++++++------- firmware-src/sources/devices/max6675.h | 26 ++++----- firmware-src/sources/dhcommands.c | 55 ++------------------ 11 files changed, 199 insertions(+), 124 deletions(-) create mode 100644 firmware-src/sources/commands/max31855_cmd.c create mode 100644 firmware-src/sources/commands/max31855_cmd.h create mode 100644 firmware-src/sources/commands/max6675_cmd.c create mode 100644 firmware-src/sources/commands/max6675_cmd.h diff --git a/firmware-src/sources/DH/spi.h b/firmware-src/sources/DH/spi.h index 41281fb..3fb4829 100644 --- a/firmware-src/sources/DH/spi.h +++ b/firmware-src/sources/DH/spi.h @@ -28,6 +28,12 @@ typedef enum { #define DH_SPI_NO_CS (~0U) +/** + * @brief Do not initialize pin indicator. + */ +#define DH_SPI_NO_PIN (-2) + + /** * @brief Set SPI mode. * @param[in] mode SPI mode. diff --git a/firmware-src/sources/commands/max31855_cmd.c b/firmware-src/sources/commands/max31855_cmd.c new file mode 100644 index 0000000..9098d11 --- /dev/null +++ b/firmware-src/sources/commands/max31855_cmd.c @@ -0,0 +1,41 @@ +/** + * @file + * @brief MAX31855 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/max31855_cmd.h" +#include "devices/max31855.h" +#include "DH/spi.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_max31855_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_max31855_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + + float temperature; + const char *err_msg = max31855_read((fields & AF_CS) ? info.CS : DH_SPI_NO_PIN, &temperature); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f}", temperature); + } +} diff --git a/firmware-src/sources/commands/max31855_cmd.h b/firmware-src/sources/commands/max31855_cmd.h new file mode 100644 index 0000000..a879270 --- /dev/null +++ b/firmware-src/sources/commands/max31855_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief MAX31855 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MAX31855_CMD_H_ +#define _COMMANDS_MAX31855_CMD_H_ + +#include "user_config.h" +#include "dhsender_data.h" + +/** + * @brief Handle "devices/max31855/read" command. + */ +void dh_handle_devices_max31855_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MAX31855_CMD_H_ */ diff --git a/firmware-src/sources/commands/max6675_cmd.c b/firmware-src/sources/commands/max6675_cmd.c new file mode 100644 index 0000000..52eb551 --- /dev/null +++ b/firmware-src/sources/commands/max6675_cmd.c @@ -0,0 +1,41 @@ +/** + * @file + * @brief MAX6675 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/max6675_cmd.h" +#include "devices/max6675.h" +#include "DH/spi.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_max6675_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_max6675_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + + float temperature; + const char* err_msg = max6675_read((fields & AF_CS) ? info.CS : DH_SPI_NO_PIN, &temperature); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f}", temperature); + } +} diff --git a/firmware-src/sources/commands/max6675_cmd.h b/firmware-src/sources/commands/max6675_cmd.h new file mode 100644 index 0000000..d8110e7 --- /dev/null +++ b/firmware-src/sources/commands/max6675_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief MAX6675 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MAX6675_CMD_H_ +#define _COMMANDS_MAX6675_CMD_H_ + +#include "user_config.h" +#include "dhsender_data.h" + +/** + * @brief Handle "devices/max6675/read" command. + */ +void dh_handle_devices_max6675_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MAX6675_CMD_H_ */ diff --git a/firmware-src/sources/devices/lm75.c b/firmware-src/sources/devices/lm75.c index 6c905ae..ada4bd2 100644 --- a/firmware-src/sources/devices/lm75.c +++ b/firmware-src/sources/devices/lm75.c @@ -43,7 +43,7 @@ int ICACHE_FLASH_ATTR lm75_read(int sda, int scl, float *temperature) return status; } - const int raw = signedInt16be(buf, 0); + const int raw = signedInt16be((const char*)buf, 0); *temperature = (float)raw / 256.0f; return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/max31855.c b/firmware-src/sources/devices/max31855.c index db5f766..0ee23a8 100644 --- a/firmware-src/sources/devices/max31855.c +++ b/firmware-src/sources/devices/max31855.c @@ -1,51 +1,54 @@ -/* - * max31855.h - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file max31855.h + * @brief Simple communication with MAX31855 thermocouple temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "max31855.h" +#include "devices/max31855.h" #include "DH/gpio.h" #include "DH/spi.h" #include "dhutils.h" #include -#include +// module variables static int mCSPin = 15; -char * ICACHE_FLASH_ATTR max31855_read(int pin, float *temperature) { - char buf[4]; - if(pin == MAX31855_NO_PIN) { + +/* + * max31855_read() implementation. + */ +const char* ICACHE_FLASH_ATTR max31855_read(int pin, float *temperature) +{ + if (pin == DH_SPI_NO_PIN) { dh_spi_set_cs_pin(mCSPin); } else { int ok = (pin != DH_SPI_NO_CS); - if(ok) + if (ok) ok = (0 == dh_spi_set_cs_pin(pin)); - if(!ok) + if (!ok) return "Wrong CS pin"; mCSPin = pin; } dh_spi_set_mode(DH_SPI_CPOL0CPHA0); - //start converting + // start converting dh_gpio_write(DH_GPIO_PIN(mCSPin), 0); delay_ms(100); - dh_spi_read((char *)&buf, sizeof(buf)); + uint8_t buf[4]; + dh_spi_read(buf, sizeof(buf)); - if(buf[3] & 0x01) + if (buf[3] & 0x01) return "Open circuit"; - if(buf[3] & 0x02) + if (buf[3] & 0x02) return "Short to GND"; - if(buf[3] & 0x03) + if (buf[3] & 0x03) return "Short to Vcc"; buf[1] &= 0xFC; int v = signedInt16be(buf, 0); *temperature = v / 16.0f; - return NULL; + return NULL; // OK } diff --git a/firmware-src/sources/devices/max31855.h b/firmware-src/sources/devices/max31855.h index 0b4e79d..7132c29 100644 --- a/firmware-src/sources/devices/max31855.h +++ b/firmware-src/sources/devices/max31855.h @@ -1,23 +1,18 @@ /** - * \file max31855.h - * \brief Simple communication with MAX31855 thermocouple temperature sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file max31855.h + * @brief Simple communication with MAX31855 thermocouple temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_MAX31855_H_ -#define SOURCES_DEVICES_MAX31855_H_ - -/** Do not initialize pin */ -#define MAX31855_NO_PIN -2 +#ifndef _DEVICES_MAX31855_H_ +#define _DEVICES_MAX31855_H_ /** - * \brief Measure temperature one time. - * \param[in] cs Chip select pin. Can be MAX31855_NO_PIN to disable CS. - * \param[out] temperature Pointer to store measure result in degree Celsius. - * \return NULL on success, text description on error. + * @brief Measure temperature one time. + * @param[in] cs Chip select pin. Can be DH_SPI_NO_PIN to disable CS. + * @param[out] temperature Pointer to store measure result in degree Celsius. + * @return NULL on success, text description on error. */ -char *max31855_read(int pin, float *temperature); +const char* max31855_read(int pin, float *temperature); -#endif /* SOURCES_DEVICES_MAX31855_H_ */ +#endif /* _DEVICES_MAX31855_H_ */ diff --git a/firmware-src/sources/devices/max6675.c b/firmware-src/sources/devices/max6675.c index 87bb293..7f2c910 100644 --- a/firmware-src/sources/devices/max6675.c +++ b/firmware-src/sources/devices/max6675.c @@ -1,49 +1,51 @@ -/* - * max6675.h - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with MAX6675 K-thermocouple temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "max6675.h" +#include "devices/max6675.h" #include "DH/gpio.h" #include "DH/spi.h" #include "dhutils.h" #include -#include +// module variables static int mCSPin = 15; -char * ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) { - char buf[2]; - if(pin == MAX6675_NO_PIN) { +/* + * max6675_read() implementation. + */ +const char* ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) +{ + if (pin == DH_SPI_NO_PIN) { dh_spi_set_cs_pin(mCSPin); } else { int ok = (pin != DH_SPI_NO_CS); - if(ok) + if (ok) ok = (0 == dh_spi_set_cs_pin(pin)); - if(!ok) + if (!ok) return "Wrong CS pin"; mCSPin = pin; } dh_spi_set_mode(DH_SPI_CPOL0CPHA0); - //start converting + // start converting dh_gpio_write(DH_GPIO_PIN(mCSPin), 0); delay_ms(250); - dh_spi_read((char *)&buf, sizeof(buf)); + uint8_t buf[2]; + dh_spi_read(buf, sizeof(buf)); - if((buf[0] & 0x80) || (buf[1] & 0x02)) + if ((buf[0] & 0x80) || (buf[1] & 0x02)) return "Protocol error"; - if(buf[1] & 0x04) + if (buf[1] & 0x04) return "Thermocouple is not connected"; buf[1] &= 0xF8; - int v = signedInt16be(buf, 0); + int v = signedInt16be((const char*)buf, 0); *temperature = v / 32.0f; - return NULL; + return NULL; // OK } diff --git a/firmware-src/sources/devices/max6675.h b/firmware-src/sources/devices/max6675.h index 441bd53..41eb1c3 100644 --- a/firmware-src/sources/devices/max6675.h +++ b/firmware-src/sources/devices/max6675.h @@ -1,23 +1,19 @@ /** - * \file max6675.h - * \brief Simple communication with MAX6675 K-thermocouple temperature sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with MAX6675 K-thermocouple temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_MAX6675_H_ +#define _DEVICES_MAX6675_H_ -#ifndef SOURCES_DEVICES_MAX6675_H_ -#define SOURCES_DEVICES_MAX6675_H_ - -/** Do not initialize pin */ -#define MAX6675_NO_PIN -2 /** - * \brief Measure temperature one time. - * \param[in] cs Chip select pin. Can be MAX6675_NO_PIN to disable CS. - * \param[out] temperature Pointer to store measure result in degree Celsius. - * \return NULL on success, text description on error. + * @brief Measure temperature one time. + * @param[in] cs Chip select pin. Can be DH_SPI_NO_PIN to disable CS. + * @param[out] temperature Pointer to store measure result in degree Celsius. + * @return NULL on success, text description on error. */ -char *max6675_read(int pin, float *temperature); +const char* max6675_read(int pin, float *temperature); #endif /* SOURCES_DEVICES_MAX6675_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 8b3ed2d..e258f96 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -45,8 +45,8 @@ #include "devices/mfrc522.h" #include "devices/pca9685.h" #include "devices/mlx90614.h" -#include "devices/max6675.h" -#include "devices/max31855.h" +#include "commands/max6675_cmd.h" +#include "commands/max31855_cmd.h" #include "devices/tm1636.h" #include @@ -544,53 +544,6 @@ static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const } } -/** - * @brief Do "devices/max6675/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_max6675_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - } - float temperature; - char *res = max6675_read((fields & AF_CS) ? parse_pins.CS : MAX6675_NO_PIN, &temperature); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } -} - -/** - * @brief Do "devices/max31855/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_max31855_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - } - float temperature; - char *res = max31855_read((fields & AF_CS) ? parse_pins.CS : MAX31855_NO_PIN, &temperature); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); - } -} - /** * @brief Do "devices/tm1637/write" command. */ @@ -694,8 +647,8 @@ RO_DATA struct { { "devices/mfrc522/mifare/write", do_devices_mfrc522_mifare_read_write}, { "devices/pca9685/control", do_devices_pca9685_control}, { "devices/mlx90614/read", do_devices_mlx90614_read}, - { "devices/max6675/read", do_devices_max6675_read}, - { "devices/max31855/read", do_devices_max31855_read}, + { "devices/max6675/read", dh_handle_devices_max6675_read}, + { "devices/max31855/read", dh_handle_devices_max31855_read}, { "devices/tm1637/write", do_devices_tm1637_write} }; From afd139f5b46fab0257ba268df51f698ae9088244 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 14:58:10 +0300 Subject: [PATCH 44/83] review MCP4725 device --- firmware-src/sources/commands/mcp4725_cmd.c | 58 ++++++++++++++++++++ firmware-src/sources/commands/mcp4725_cmd.h | 18 +++++++ firmware-src/sources/devices/max31855.c | 2 +- firmware-src/sources/devices/mcp4725.c | 60 ++++++++++++++------- firmware-src/sources/devices/mcp4725.h | 53 +++++++++--------- firmware-src/sources/dhcommands.c | 45 ++-------------- 6 files changed, 144 insertions(+), 92 deletions(-) create mode 100644 firmware-src/sources/commands/mcp4725_cmd.c create mode 100644 firmware-src/sources/commands/mcp4725_cmd.h diff --git a/firmware-src/sources/commands/mcp4725_cmd.c b/firmware-src/sources/commands/mcp4725_cmd.c new file mode 100644 index 0000000..bbc135a --- /dev/null +++ b/firmware-src/sources/commands/mcp4725_cmd.c @@ -0,0 +1,58 @@ +/** + * @file + * @brief MCP4725 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/mcp4725_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/mcp4725.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_mcp4725_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_mcp4725_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (info.pin_value_readed != 1) { + dh_command_fail(cmd_res, "Unsuitable pin"); + return; // FAILED + } + if (fields & AF_ADDRESS) + mcp4725_set_address(info.address); + if (fields & AF_REF) { + const int status = mcp4725_set_vref(info.ref); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + const int status = mcp4725_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, info.storage.float_values[0]); + const char *res = dh_i2c_error_string(status); + if (res != 0) { + dh_command_fail(cmd_res, res); + } else { + dh_command_done(cmd_res, ""); + } +} diff --git a/firmware-src/sources/commands/mcp4725_cmd.h b/firmware-src/sources/commands/mcp4725_cmd.h new file mode 100644 index 0000000..eb83d9e --- /dev/null +++ b/firmware-src/sources/commands/mcp4725_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief MCP4725 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MCP4725_CMD_H_ +#define _COMMANDS_MCP4725_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/mcp4725/write" command. + */ +void dh_handle_devices_mcp4725_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MCP4725_CMD_H_ */ diff --git a/firmware-src/sources/devices/max31855.c b/firmware-src/sources/devices/max31855.c index 0ee23a8..d9daa73 100644 --- a/firmware-src/sources/devices/max31855.c +++ b/firmware-src/sources/devices/max31855.c @@ -47,7 +47,7 @@ const char* ICACHE_FLASH_ATTR max31855_read(int pin, float *temperature) return "Short to Vcc"; buf[1] &= 0xFC; - int v = signedInt16be(buf, 0); + int v = signedInt16be((const char*)buf, 0); *temperature = v / 16.0f; return NULL; // OK diff --git a/firmware-src/sources/devices/mcp4725.c b/firmware-src/sources/devices/mcp4725.c index 9215b21..8203075 100644 --- a/firmware-src/sources/devices/mcp4725.c +++ b/firmware-src/sources/devices/mcp4725.c @@ -1,52 +1,72 @@ -/* - * mcp4725.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with MCP4725 DAC. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "mcp4725.h" +#include "devices/mcp4725.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address*/ +#define MCP4725_DEFAULT_ADDRESS 0xC0 + +// module variables static int mAddress = MCP4725_DEFAULT_ADDRESS; static float mVoltage = 3.3f; -DH_I2C_Status ICACHE_FLASH_ATTR mcp4725_write(int sda, int scl, float value) { - char buf[3]; - DH_I2C_Status status; - if(value < 0.0f || value > mVoltage) + +/* + * mcp4725_write() implementation. + */ +int ICACHE_FLASH_ATTR mcp4725_write(int sda, int scl, float value) +{ + if (value < 0.0f || value > mVoltage) return DH_I2C_WRONG_PARAMETERS; - if(sda != MCP4725_NO_PIN && scl != MCP4725_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("mcp4725: failed to set up pins"); return status; } } - uint16_t v = (uint16_t)(value / mVoltage * 4095.0f); + const uint16_t v = (uint16_t)(value / mVoltage * 4095.0f); // TODO: check 4096 scale, 4095 looks suspicious + uint8_t buf[3]; buf[0] = 0x40; // Config(write DAC register) buf[1] = ((v >> 4) & 0xFF); buf[2] = ((v & 0xF) << 4); // LSB bits - if((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 3, 1)) != DH_I2C_OK) { dhdebug("mcp4725: failed to write"); return status; } + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR mcp4725_set_address(int address) { + +/* + * mcp4725_set_address() implementation. + */ +void ICACHE_FLASH_ATTR mcp4725_set_address(int address) +{ mAddress = address; } -DH_I2C_Status ICACHE_FLASH_ATTR mcp4725_set_vref(float voltage) { - if(mVoltage <= 0.0f) + +/* + * mcp4725_set_vref() implementation. + */ +int ICACHE_FLASH_ATTR mcp4725_set_vref(float voltage) +{ + if (mVoltage <= 0.0f) return DH_I2C_WRONG_PARAMETERS; + mVoltage = voltage; return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/mcp4725.h b/firmware-src/sources/devices/mcp4725.h index ffd9139..9c23849 100644 --- a/firmware-src/sources/devices/mcp4725.h +++ b/firmware-src/sources/devices/mcp4725.h @@ -1,42 +1,37 @@ /** - * \file mcp4725.h - * \brief Simple communication with MCP4725 DAC - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with MCP4725 DAC. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_MCP4725_H_ -#define SOURCES_DEVICES_MCP4725_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define MCP4725_DEFAULT_ADDRESS 0xC0 -/** Do not initialize pin */ -#define MCP4725_NO_PIN -1 +#ifndef _DEVICES_MCP4725_H_ +#define _DEVICES_MCP4725_H_ /** - * \brief Set DAC voltages. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] value Voltage in Volts. - * \return Status value, one of DH_I2C_Status enum. + * @brief Set DAC voltages. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] value Voltage in Volts. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status mcp4725_write(int sda, int scl, float value); +int mcp4725_write(int sda, int scl, float value); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void mcp4725_set_address(int address); + /** - * \brief Set reference voltage in volts. - * \note Default is 3.3V. - * \param[in] voltage Voltage in Volts. - * \return Status value, one of DH_I2C_Status enum. + * @brief Set reference voltage in volts. + * + * Default is 3.3V. + * + * @param[in] voltage Voltage in Volts. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status mcp4725_set_vref(float voltage); +int mcp4725_set_vref(float voltage); -#endif /* SOURCES_DEVICES_MCP4725_H_ */ +#endif /* _DEVICES_MCP4725_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index e258f96..01f8c0e 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -40,7 +40,7 @@ #include "devices/si7021.h" #include "commands/ads1115_cmd.h" #include "devices/pcf8591.h" -#include "devices/mcp4725.h" +#include "commands/mcp4725_cmd.h" #include "commands/ina219_cmd.h" #include "devices/mfrc522.h" #include "devices/pca9685.h" @@ -312,7 +312,7 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const fields |= AF_ADDRESS; if(dh_i2c_init_helper(cb, fields, &parse_pins)) return; - const char *res = dh_i2c_error_string(pcf8591_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); + const char *res = dh_i2c_error_string(pcf8591_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, parse_pins.storage.float_values[0])); if (res != 0) { dh_command_fail(cb, res); } else { @@ -320,45 +320,6 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const } } -/** - * @brief Do "devices/mcp4725/write" command. - */ -static void ICACHE_FLASH_ATTR do_devices_mcp4725_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(parse_pins.pin_value_readed != 1) { - dh_command_fail(cb, "Unsuitable pin"); - return; - } - if(fields & AF_ADDRESS) - mcp4725_set_address(parse_pins.address); - if(fields & AF_REF) { - const char *res = dh_i2c_error_string(mcp4725_set_vref(parse_pins.ref)); - if (res != 0) { - dh_command_fail(cb, res); - return; - } - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - const char *res = dh_i2c_error_string(mcp4725_write(MCP4725_NO_PIN, MCP4725_NO_PIN, parse_pins.storage.float_values[0])); - if (res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - - /** * @brief Do "devices/mfrc522/read" command. */ @@ -640,7 +601,7 @@ RO_DATA struct { { "devices/ads1115/read", dh_handle_devices_ads1115_read}, { "devices/pcf8591/read", do_devices_pcf8591_read}, { "devices/pcf8591/write", do_devices_pcf8591_write}, - { "devices/mcp4725/write", do_devices_mcp4725_write}, + { "devices/mcp4725/write", dh_handle_devices_mcp4725_write}, { "devices/ina219/read", dh_handle_devices_ina219_read}, { "devices/mfrc522/read", do_devices_mfrc522_read}, { "devices/mfrc522/mifare/read", do_devices_mfrc522_mifare_read_write}, From b6c62703f3682bacffbe13837bcf3dbbe7303305 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 15:14:10 +0300 Subject: [PATCH 45/83] review MHZ19 device --- firmware-src/sources/commands/mhz19_cmd.c | 33 +++++++++++++++ firmware-src/sources/commands/mhz19_cmd.h | 18 +++++++++ firmware-src/sources/devices/mhz19.c | 49 ++++++++++++----------- firmware-src/sources/devices/mhz19.h | 24 +++++------ firmware-src/sources/dhcommands.c | 22 +--------- 5 files changed, 90 insertions(+), 56 deletions(-) create mode 100644 firmware-src/sources/commands/mhz19_cmd.c create mode 100644 firmware-src/sources/commands/mhz19_cmd.h diff --git a/firmware-src/sources/commands/mhz19_cmd.c b/firmware-src/sources/commands/mhz19_cmd.c new file mode 100644 index 0000000..6842139 --- /dev/null +++ b/firmware-src/sources/commands/mhz19_cmd.c @@ -0,0 +1,33 @@ +/** + * @file + * @brief MHZ19 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/mhz19_cmd.h" +#include "devices/mhz19.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_mhz19_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_mhz19_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + dh_command_fail(cmd_res, "Command does not have parameters"); + return; // FAILED + } + + int co2; + const char *err_msg = mhz19_read(&co2); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, + RDT_FORMAT_STRING, "{\"co2\":%d}", co2); + } +} diff --git a/firmware-src/sources/commands/mhz19_cmd.h b/firmware-src/sources/commands/mhz19_cmd.h new file mode 100644 index 0000000..0d07ec7 --- /dev/null +++ b/firmware-src/sources/commands/mhz19_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief MHZ19 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MHZ19_CMD_H_ +#define _COMMANDS_MHZ19_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/mhz19/read" command. + */ +void dh_handle_devices_mhz19_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MHZ19_CMD_H_ */ diff --git a/firmware-src/sources/devices/mhz19.c b/firmware-src/sources/devices/mhz19.c index 55e5262..2b6ab7d 100644 --- a/firmware-src/sources/devices/mhz19.c +++ b/firmware-src/sources/devices/mhz19.c @@ -1,44 +1,47 @@ -/* - * mhz19.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with MHZ-19 CO2 sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "mhz19.h" +#include "devices/mhz19.h" #include "DH/uart.h" #include "dhdebug.h" #include "dhutils.h" #include -#include - -const char request[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; -char * ICACHE_FLASH_ATTR mhz19_read(int *co2) { - char *result; - int i; - char cs = 0; +/* + * mhz19_read() implementation. + */ +const char* ICACHE_FLASH_ATTR mhz19_read(int *co2) +{ dh_uart_set_mode(DH_UART_MODE_PER_BUF); - if(dh_uart_init(9600, 8, 'N', 1) != 0) + if (!!dh_uart_init(9600, 8, 'N', 1)) return "failed to init UART"; + + const uint8_t request[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; dh_uart_send_buf(request, sizeof(request)); delay_ms(20); + + uint8_t *result = 0; size_t len = dh_uart_get_buf((void**)&result); - if(len != 9){ - if(len) - return "Response length mismatch"; - return "No response"; + if (len != 9){ + return len ? "Response length mismatch" + : "No response"; } + + int i; + uint8_t cs = 0; for(i = 1; i < 8; i++) { cs += result[i]; } cs = ~cs; cs++; - if(cs != result[8]) { + if (cs != result[8]) { return "Checksum mismatch"; } - *co2 = unsignedInt16be(result, 2); - return NULL; + + *co2 = unsignedInt16be((const char*)result, 2); + return NULL; // OK } diff --git a/firmware-src/sources/devices/mhz19.h b/firmware-src/sources/devices/mhz19.h index ac5cbcf..54c5261 100644 --- a/firmware-src/sources/devices/mhz19.h +++ b/firmware-src/sources/devices/mhz19.h @@ -1,19 +1,17 @@ /** - * \file mhz19.h - * \brief Simple communication with MHZ-19 CO2 sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with MHZ-19 CO2 sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_MHZ19_H_ -#define SOURCES_DEVICES_MHZ19_H_ +#ifndef _DEVICES_MHZ19_H_ +#define _DEVICES_MHZ19_H_ /** - * \brief Read CO2 sensor value. - * \param[out] co2 Pointer to store measure result in ppm(parts-per-million). - * \return NULL on success, or string with error description. + * @brief Read CO2 sensor value. + * @param[out] co2 Pointer to store measure result in ppm(parts-per-million). + * @return NULL on success, or string with error description. */ -char *mhz19_read(int *co2); +const char* mhz19_read(int *co2); -#endif /* SOURCES_DEVICES_MHZ19_H_ */ +#endif /* _DEVICES_MHZ19_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 01f8c0e..396c62e 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -35,7 +35,7 @@ #include "commands/hmc5883l_cmd.h" #include "devices/pcf8574.h" #include "devices/pcf8574_hd44780.h" -#include "devices/mhz19.h" +#include "commands/mhz19_cmd.h" #include "commands/lm75_cmd.h" #include "devices/si7021.h" #include "commands/ads1115_cmd.h" @@ -195,24 +195,6 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c } } -/** - * @brief Do "devices/mhz19/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_mhz19_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - dh_command_fail(cb, "Command does not have parameters"); - return; - } - int co2; - char *res = mhz19_read(&co2); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"co2\":%d}", co2); - } -} - /** * @brief Do "devices/si7021/read" command. @@ -595,7 +577,7 @@ RO_DATA struct { { "devices/pcf8574/read", do_devices_pcf8574_read}, { "devices/pcf8574/write", do_devices_pcf8574_write}, { "devices/pcf8574/hd44780/write", do_devices_pcf8574_hd44780_write}, - { "devices/mhz19/read", do_devices_mhz19_read}, + { "devices/mhz19/read", dh_handle_devices_mhz19_read}, { "devices/lm75/read", dh_handle_devices_lm75_read}, { "devices/si7021/read", do_devices_si7021_read}, { "devices/ads1115/read", dh_handle_devices_ads1115_read}, From d9ef2c6199dbe54e07c1b61427e888dbb3ec2a51 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 15:45:54 +0300 Subject: [PATCH 46/83] review MLX90614 and MPU6050 devices --- firmware-src/sources/commands/mlx90614_cmd.c | 49 +++++++++++++ firmware-src/sources/commands/mlx90614_cmd.h | 19 +++++ firmware-src/sources/commands/mpu6050_cmd.c | 52 +++++++++++++ firmware-src/sources/commands/mpu6050_cmd.h | 19 +++++ firmware-src/sources/devices/mlx90614.c | 66 ++++++++++------- firmware-src/sources/devices/mlx90614.h | 42 +++++------ firmware-src/sources/devices/mpu6050.c | 77 +++++++++++--------- firmware-src/sources/devices/mpu6050.h | 53 ++++++-------- firmware-src/sources/dhcommands.c | 73 +------------------ 9 files changed, 267 insertions(+), 183 deletions(-) create mode 100644 firmware-src/sources/commands/mlx90614_cmd.c create mode 100644 firmware-src/sources/commands/mlx90614_cmd.h create mode 100644 firmware-src/sources/commands/mpu6050_cmd.c create mode 100644 firmware-src/sources/commands/mpu6050_cmd.h diff --git a/firmware-src/sources/commands/mlx90614_cmd.c b/firmware-src/sources/commands/mlx90614_cmd.c new file mode 100644 index 0000000..3172b22 --- /dev/null +++ b/firmware-src/sources/commands/mlx90614_cmd.c @@ -0,0 +1,49 @@ +/** + * @file + * @brief MLX90614 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/mlx90614_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/mlx90614.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_mlx90614_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_mlx90614_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + mlx90614_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float ambient, object; + const int status = mlx90614_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &ambient, &object); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"ambient\":%f, \"object\":%f}", ambient, object); + } +} diff --git a/firmware-src/sources/commands/mlx90614_cmd.h b/firmware-src/sources/commands/mlx90614_cmd.h new file mode 100644 index 0000000..c3f2b51 --- /dev/null +++ b/firmware-src/sources/commands/mlx90614_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief MLX90614 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MLX90614_CMD_H_ +#define _COMMANDS_MLX90614_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/mlx90614/read" command. + */ + +void dh_handle_devices_mlx90614_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MLX90614_CMD_H_ */ diff --git a/firmware-src/sources/commands/mpu6050_cmd.c b/firmware-src/sources/commands/mpu6050_cmd.c new file mode 100644 index 0000000..f05d171 --- /dev/null +++ b/firmware-src/sources/commands/mpu6050_cmd.c @@ -0,0 +1,52 @@ +/** + * @file + * @brief MPU6050 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/mpu6050_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/mpu6050.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_mpu6050_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_mpu6050_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char* err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + mpu6050_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + MPU6050_XYZ acc; + MPU6050_XYZ gyro; + float temperature; + const int status = mpu6050_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &acc, &gyro, &temperature); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", + temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); + } +} diff --git a/firmware-src/sources/commands/mpu6050_cmd.h b/firmware-src/sources/commands/mpu6050_cmd.h new file mode 100644 index 0000000..53223bf --- /dev/null +++ b/firmware-src/sources/commands/mpu6050_cmd.h @@ -0,0 +1,19 @@ +/** + * @file + * @brief MPU6050 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MPU6050_CMD_H_ +#define _COMMANDS_MPU6050_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/mpu6050/read" command. + */ + +void dh_handle_devices_mpu6050_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MPU6050_CMD_H_ */ diff --git a/firmware-src/sources/devices/mlx90614.c b/firmware-src/sources/devices/mlx90614.c index a0fc451..5e90d70 100644 --- a/firmware-src/sources/devices/mlx90614.c +++ b/firmware-src/sources/devices/mlx90614.c @@ -1,57 +1,71 @@ -/* - * mlx90614.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with MLX90614 contactless IR temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "mlx90614.h" +#include "devices/mlx90614.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address*/ +#define MLX90614_DEFAULT_ADDRESS 0xB4 + +// module variable static int mAddress = MLX90614_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, float *object) { - char buf[2]; - DH_I2C_Status status; - int raw_temperature; - if(sda != MLX90614_NO_PIN && scl != MLX90614_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * mlx90614_read() implementation. + */ +int ICACHE_FLASH_ATTR mlx90614_read(int sda, int scl, float *ambient, float *object) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("mlx90614: failed to set up pins"); return status; } } - buf[0] = 0x06; // Ta register - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + uint8_t buf[2]; + buf[0] = 0x06; // Ta register + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("mlx90614: failed to get Ta register"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("mlx90614: failed to read Ta"); return status; } - raw_temperature = signedInt16le(buf, 0); - *ambient = raw_temperature * 0.02f - 273.15f; - buf[0] = 0x07; // Tobj1 register - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + int raw = signedInt16le((const char*)buf, 0); + *ambient = raw * 0.02f - 273.15f; + + buf[0] = 0x07; // Tobj1 register + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("mlx90614: failed to get Tobj1 register"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("mlx90614: failed to read Tobj1"); return status; } - raw_temperature = signedInt16le(buf, 0); - *object = raw_temperature * 0.02f - 273.15f; + + raw = signedInt16le((const char*)buf, 0); + *object = raw * 0.02f - 273.15f; + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR mlx90614_set_address(int address) { + +/* + * mlx90614_set_address() implementation. + */ +void ICACHE_FLASH_ATTR mlx90614_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/mlx90614.h b/firmware-src/sources/devices/mlx90614.h index f637443..7d589b3 100644 --- a/firmware-src/sources/devices/mlx90614.h +++ b/firmware-src/sources/devices/mlx90614.h @@ -1,35 +1,27 @@ /** - * \file mlx90614.h - * \brief Simple communication with MLX90614 contactless IR temperature sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with MLX90614 contactless IR temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_MLX90614_H_ -#define SOURCES_DEVICES_MLX90614_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define MLX90614_DEFAULT_ADDRESS 0xB4 -/** Do not initialize pin */ -#define MLX90614_NO_PIN -1 +#ifndef _DEVICES_MLX90614_H_ +#define _DEVICES_MLX90614_H_ /** - * \brief Measure temperature one time. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] ambient Pointer for storing ambient temperature result measure in Celsius. - * \param[out] object Pointer for storing object temperature result measure in Celsius. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure temperature one time. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] ambient Pointer for storing ambient temperature result measure in Celsius. + * @param[out] object Pointer for storing object temperature result measure in Celsius. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status mlx90614_read(int sda, int scl, float *ambient, float *object); +int mlx90614_read(int sda, int scl, float *ambient, float *object); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void mlx90614_set_address(int address); -#endif /* SOURCES_DEVICES_MLX90614_H_ */ +#endif /* _DEVICES_MLX90614_H_ */ diff --git a/firmware-src/sources/devices/mpu6050.c b/firmware-src/sources/devices/mpu6050.c index 43a7e48..937cc84 100644 --- a/firmware-src/sources/devices/mpu6050.c +++ b/firmware-src/sources/devices/mpu6050.c @@ -1,50 +1,55 @@ -/* - * mpu6050.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with MPU6050 accelerometer and gyroscope sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "mpu6050.h" +#include "devices/mpu6050.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address*/ +#define MPU6050_DEFAULT_ADDRESS 0xD0 + +// module variables static int mAddress = MPU6050_DEFAULT_ADDRESS; #define EARTH_GRAVITY_ACCELERATION 9.80665f -DH_I2C_Status ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, - MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature) + +/* + * mpu6050_read() implementation. + */ +int ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature) { - char buf[16]; - DH_I2C_Status status; - if(sda != MPU6050_NO_PIN && scl != MPU6050_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("mpu6050: failed to set up pins"); return status; } } + uint8_t buf[16]; buf[0] = 0x6B; // power up buf[1] = 0; // no sleep bit - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to power up"); return status; } buf[0] = 0x1C; // accelerometer configuration - buf[1] = (1 << 4); // AFS_SEL = 2, range +-8 g - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + buf[1] = BIT(4); // AFS_SEL = 2, range +-8 g + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to configure accelerometer"); return status; } buf[0] = 0x1B; // gyroscope configuration - buf[1] = (1 << 4); // FS_SEL = 2, range +-1000 dps - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + buf[1] = BIT(4); // FS_SEL = 2, range +-1000 dps + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to configure gyroscope"); return status; } @@ -52,7 +57,7 @@ DH_I2C_Status ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, delay_ms(50); buf[0] = 0x3B; // get data - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("mpu6050: failed to set read register"); return status; } @@ -63,28 +68,34 @@ DH_I2C_Status ICACHE_FLASH_ATTR mpu6050_read(int sda, int scl, buf[14] = 0x6B; // power down buf[15] = 1 << 6; // sleep bit - if((status = dh_i2c_write(mAddress, &buf[14], 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, &buf[14], 2, 1)) != DH_I2C_OK) { dhdebug("mpu6050: failed to power up"); return status; } - if(acceleromter) { - acceleromter->X = signedInt16be(buf, 0) * 8.0f * EARTH_GRAVITY_ACCELERATION / 32768.0f; - acceleromter->Y = signedInt16be(buf, 2) * 8.0f * EARTH_GRAVITY_ACCELERATION / 32768.0f; - acceleromter->Z = signedInt16be(buf, 4) * 8.0f * EARTH_GRAVITY_ACCELERATION / 32768.0f; + if (acceleromter) { + acceleromter->X = signedInt16be((const char*)buf, 0) * 8.0f * EARTH_GRAVITY_ACCELERATION / 32768.0f; + acceleromter->Y = signedInt16be((const char*)buf, 2) * 8.0f * EARTH_GRAVITY_ACCELERATION / 32768.0f; + acceleromter->Z = signedInt16be((const char*)buf, 4) * 8.0f * EARTH_GRAVITY_ACCELERATION / 32768.0f; } - if(gyroscope) { - gyroscope->X = signedInt16be(buf, 8) * 1000.0f / 32768.0f; - gyroscope->Y = signedInt16be(buf, 10) * 1000.0f / 32768.0f; - gyroscope->Z = signedInt16be(buf, 12) * 1000.0f / 32768.0f; + if (gyroscope) { + gyroscope->X = signedInt16be((const char*)buf, 8) * 1000.0f / 32768.0f; + gyroscope->Y = signedInt16be((const char*)buf, 10) * 1000.0f / 32768.0f; + gyroscope->Z = signedInt16be((const char*)buf, 12) * 1000.0f / 32768.0f; } - if(temparature) - *temparature = signedInt16be(buf, 6) / 340.0f + 36.53f; + if (temparature) + *temparature = signedInt16be((const char*)buf, 6) / 340.0f + 36.53f; + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR mpu6050_set_address(int address) { + +/* + * mpu6050_set_address() implementation. + */ +void ICACHE_FLASH_ATTR mpu6050_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/mpu6050.h b/firmware-src/sources/devices/mpu6050.h index 511f1fd..182ba54 100644 --- a/firmware-src/sources/devices/mpu6050.h +++ b/firmware-src/sources/devices/mpu6050.h @@ -1,43 +1,36 @@ /** - * \file mpu6050.h - * \brief Simple communication with MPU6050 accelerometer and gyroscope sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with MPU6050 accelerometer and gyroscope sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_MPU6050_H_ +#define _DEVICES_MPU6050_H_ -#ifndef SOURCES_DEVICES_MPU6050_H_ -#define SOURCES_DEVICES_MPU6050_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define MPU6050_DEFAULT_ADDRESS 0xD0 -/** Do not initialize pin */ -#define MPU6050_NO_PIN -1 - -/** Struct for results in three dimensions */ +/** @brief Measurements in three dimensions. */ typedef struct { - float X; ///< X axis - float Y; ///< Y axis - float Z; ///< Z axis + float X; ///< @brief X axis. + float Y; ///< @brief Y axis. + float Z; ///< @brief Z axis. } MPU6050_XYZ; + /** - * \brief Measure accelerometer and gyroscope data. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] acceleromter Accelerometer data in metre per second squared. Can be NULL. - * \param[out] gyroscope Gyroscope data in degree per second. Can be NULL. - * \param[out] temparature Gyroscope data in degree per second. Can be NULL. - * \return NULL on success, text description on error. + * @brief Measure accelerometer and gyroscope data. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] acceleromter Accelerometer data in metre per second squared. Can be NULL. + * @param[out] gyroscope Gyroscope data in degree per second. Can be NULL. + * @param[out] temparature Gyroscope data in degree per second. Can be NULL. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature); +int mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyroscope, float *temparature); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void mpu6050_set_address(int address); -#endif /* SOURCES_DEVICES_MPU6050_H_ */ +#endif /* _DEVICES_MPU6050_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 396c62e..b859f9f 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -31,7 +31,7 @@ #include "commands/bmp180_cmd.h" #include "commands/bmp280_cmd.h" #include "commands/bh1750_cmd.h" -#include "devices/mpu6050.h" +#include "commands/mpu6050_cmd.h" #include "commands/hmc5883l_cmd.h" #include "devices/pcf8574.h" #include "devices/pcf8574_hd44780.h" @@ -44,7 +44,7 @@ #include "commands/ina219_cmd.h" #include "devices/mfrc522.h" #include "devices/pca9685.h" -#include "devices/mlx90614.h" +#include "commands/mlx90614_cmd.h" #include "commands/max6675_cmd.h" #include "commands/max31855_cmd.h" #include "devices/tm1636.h" @@ -57,40 +57,6 @@ #if 1 // devices commands -/** - * @brief Do "devices/mpu6050/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_mpu6050_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - mpu6050_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - MPU6050_XYZ acc; - MPU6050_XYZ gyro; - float temperature; - const char *res = dh_i2c_error_string(mpu6050_read(MPU6050_NO_PIN, MPU6050_NO_PIN, &acc, &gyro, &temperature)); - if(res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", - temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); - } -} - /** * @brief Do "devices/pcf8574/read" command. */ @@ -456,37 +422,6 @@ static void ICACHE_FLASH_ATTR do_devices_pca9685_control(COMMAND_RESULT *cb, con } } -/** - * @brief Do "devices/mlx90614/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_mlx90614_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - mlx90614_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float ambient; - float object; - const char *res = dh_i2c_error_string(mlx90614_read(MLX90614_NO_PIN, MLX90614_NO_PIN, &ambient, &object)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"ambient\":%f, \"object\":%f}", ambient, object); - } -} - /** * @brief Do "devices/tm1637/write" command. */ @@ -572,7 +507,7 @@ RO_DATA struct { { "devices/bmp180/read", dh_handle_devices_bmp180_read}, { "devices/bmp280/read", dh_handle_devices_bmp280_read}, { "devices/bh1750/read", dh_handle_devices_bh1750_read}, - { "devices/mpu6050/read", do_devices_mpu6050_read}, + { "devices/mpu6050/read", dh_handle_devices_mpu6050_read}, { "devices/hmc5883l/read", dh_handle_devices_hmc5883l_read}, { "devices/pcf8574/read", do_devices_pcf8574_read}, { "devices/pcf8574/write", do_devices_pcf8574_write}, @@ -589,7 +524,7 @@ RO_DATA struct { { "devices/mfrc522/mifare/read", do_devices_mfrc522_mifare_read_write}, { "devices/mfrc522/mifare/write", do_devices_mfrc522_mifare_read_write}, { "devices/pca9685/control", do_devices_pca9685_control}, - { "devices/mlx90614/read", do_devices_mlx90614_read}, + { "devices/mlx90614/read", dh_handle_devices_mlx90614_read}, { "devices/max6675/read", dh_handle_devices_max6675_read}, { "devices/max31855/read", dh_handle_devices_max31855_read}, { "devices/tm1637/write", do_devices_tm1637_write} From bd128c5d4408d907ad3865ec58fff69d2bbd5f77 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 17:50:01 +0300 Subject: [PATCH 47/83] review PCA9685 device --- firmware-src/sources/commands/bh1750_cmd.h | 1 - firmware-src/sources/commands/hmc5883l_cmd.h | 1 - firmware-src/sources/commands/ina219_cmd.h | 1 - firmware-src/sources/commands/lm75_cmd.h | 1 - firmware-src/sources/commands/mlx90614_cmd.h | 1 - firmware-src/sources/commands/mpu6050_cmd.h | 1 - firmware-src/sources/commands/pca9685_cmd.c | 46 +++++++++++ firmware-src/sources/commands/pca9685_cmd.h | 18 +++++ firmware-src/sources/devices/pca9685.c | 82 +++++++++++--------- firmware-src/sources/devices/pca9685.h | 49 ++++++------ firmware-src/sources/dhcommands.c | 33 +------- 11 files changed, 137 insertions(+), 97 deletions(-) create mode 100644 firmware-src/sources/commands/pca9685_cmd.c create mode 100644 firmware-src/sources/commands/pca9685_cmd.h diff --git a/firmware-src/sources/commands/bh1750_cmd.h b/firmware-src/sources/commands/bh1750_cmd.h index dfa7efc..edfd9ca 100644 --- a/firmware-src/sources/commands/bh1750_cmd.h +++ b/firmware-src/sources/commands/bh1750_cmd.h @@ -12,7 +12,6 @@ /** * @brief Handle "devices/bh1750/read" command. */ - void dh_handle_devices_bh1750_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/commands/hmc5883l_cmd.h b/firmware-src/sources/commands/hmc5883l_cmd.h index 55c4a3b..3fbb31d 100644 --- a/firmware-src/sources/commands/hmc5883l_cmd.h +++ b/firmware-src/sources/commands/hmc5883l_cmd.h @@ -12,7 +12,6 @@ /** * @brief Handle "devices/hmc5883l/read" command. */ - void dh_handle_devices_hmc5883l_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/commands/ina219_cmd.h b/firmware-src/sources/commands/ina219_cmd.h index ee0a96d..8c03800 100644 --- a/firmware-src/sources/commands/ina219_cmd.h +++ b/firmware-src/sources/commands/ina219_cmd.h @@ -12,7 +12,6 @@ /** * @brief Handle "devices/ina219/read" command. */ - void dh_handle_devices_ina219_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/commands/lm75_cmd.h b/firmware-src/sources/commands/lm75_cmd.h index ec361b1..3d3715d 100644 --- a/firmware-src/sources/commands/lm75_cmd.h +++ b/firmware-src/sources/commands/lm75_cmd.h @@ -12,7 +12,6 @@ /** * @brief Handle "devices/lm75/read" command. */ - void dh_handle_devices_lm75_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/commands/mlx90614_cmd.h b/firmware-src/sources/commands/mlx90614_cmd.h index c3f2b51..4984637 100644 --- a/firmware-src/sources/commands/mlx90614_cmd.h +++ b/firmware-src/sources/commands/mlx90614_cmd.h @@ -12,7 +12,6 @@ /** * @brief Handle "devices/mlx90614/read" command. */ - void dh_handle_devices_mlx90614_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/commands/mpu6050_cmd.h b/firmware-src/sources/commands/mpu6050_cmd.h index 53223bf..1b13dea 100644 --- a/firmware-src/sources/commands/mpu6050_cmd.h +++ b/firmware-src/sources/commands/mpu6050_cmd.h @@ -12,7 +12,6 @@ /** * @brief Handle "devices/mpu6050/read" command. */ - void dh_handle_devices_mpu6050_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); diff --git a/firmware-src/sources/commands/pca9685_cmd.c b/firmware-src/sources/commands/pca9685_cmd.c new file mode 100644 index 0000000..4a1ebac --- /dev/null +++ b/firmware-src/sources/commands/pca9685_cmd.c @@ -0,0 +1,46 @@ +/** + * @file + * @brief PCA9685 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/pca9685_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/pca9685.h" +#include "DH/i2c.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_pca9685_control() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_pca9685_control(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, PCA9685_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_FLOATVALUES | AF_PERIOD, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + pca9685_set_address(info.address); + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + const int status = pca9685_control(DH_I2C_NO_PIN, DH_I2C_NO_PIN, + info.storage.float_values, info.pin_value_readed, + (fields & AF_PERIOD) ? info.periodus : PCA9685_NO_PERIOD); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} diff --git a/firmware-src/sources/commands/pca9685_cmd.h b/firmware-src/sources/commands/pca9685_cmd.h new file mode 100644 index 0000000..f21f932 --- /dev/null +++ b/firmware-src/sources/commands/pca9685_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief PCA9685 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_PCA9685_CMD_H_ +#define _COMMANDS_PCA9685_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/pca9685/control" command. + */ +void dh_handle_devices_pca9685_control(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_PCA9685_CMD_H_ */ diff --git a/firmware-src/sources/devices/pca9685.c b/firmware-src/sources/devices/pca9685.c index 67a8d17..5909fd8 100644 --- a/firmware-src/sources/devices/pca9685.c +++ b/firmware-src/sources/devices/pca9685.c @@ -1,63 +1,70 @@ -/* - * pca9685.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with PCA9685 PWM LED controller + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "pca9685.h" -#include "DH/gpio.h" +#include "devices/pca9685.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include + +/** @brief Default i2c address*/ +#define PCA9685_DEFAULT_ADDRESS 0x80 + +// module variables static int mAddress = PCA9685_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus) { - char buf[5]; - DH_I2C_Status status; - unsigned int i; - for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { - if(pinsmask & DH_GPIO_PIN(i)) { - if(pinsduty[i] > 100.0f || pinsduty[i] < 0.0f) +/* + * pca9685_control() implementation. + */ +int ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, const float pins_duty[DH_GPIO_PIN_COUNT], DHGpioPinMask pins, unsigned int period_us) +{ + int i; + for (i = 0; i < DH_GPIO_PIN_COUNT; i++) { + if (pins & DH_GPIO_PIN(i)) { + if (pins_duty[i] > 100.0f || pins_duty[i] < 0.0f) return DH_I2C_WRONG_PARAMETERS; } } - if(periodus != PCA9685_NO_PERIOD && (periodus > 41667 || periodus < 655)) // hardware limits + if (period_us != PCA9685_NO_PERIOD && (period_us > 41667 || period_us < 655)) // hardware limits return DH_I2C_WRONG_PARAMETERS; - if(sda != PCA9685_NO_PIN && scl != PCA9685_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pca9685: failed to set up pins"); return status; } } - if(periodus != PCA9685_NO_PERIOD) { // check if we need prescaller should be changed - char pb[2]; + uint8_t buf[5]; + if (period_us != PCA9685_NO_PERIOD) { // check if prescaller should be changed + uint8_t pb[2]; pb[0] = 0xFE; // Prescaler - pb[1] = ((25 * periodus) / 4096.0f) - 0.5f; // value + pb[1] = ((25 * period_us) / 4096.0f) - 0.5f; // value // TODO: do we really need float here? buf[0] = 0xFE; // Prescaler - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("pca9685: failed to choose prescaler"); return status; } - if((status = dh_i2c_read(mAddress, buf, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed read prescaler"); return status; } - if(pb[1] != buf[0]) { + + if (pb[1] != buf[0]) { buf[0] = 0x00; // MODE1 buf[1] = 0x31; // turn off oscillator, prescaler can be changed only then - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to shutdown"); return status; } - if((status = dh_i2c_write(mAddress, pb, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, pb, 2, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to set up frequency"); return status; } @@ -66,19 +73,19 @@ DH_I2C_Status ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsdut buf[0] = 0x00; // MODE1 buf[1] = 0x21; // allow auto increment, turn on oscillator - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to init"); return status; } buf[1] = 0; // LED_OFF_L buf[2] = 0; // LED_OFF_H - unsigned short *v = (unsigned short *)&buf[3]; // LED_ON_HL - for(i = 0; i < DH_GPIO_PIN_COUNT; i++) { - if(pinsmask & DH_GPIO_PIN(i)) { - *v = pinsduty[i] * 40.95f; + uint16_t *v = (uint16_t *)&buf[3]; // LED_ON_HL + for (i = 0; i < DH_GPIO_PIN_COUNT; i++) { + if (pins & DH_GPIO_PIN(i)) { + *v = pins_duty[i] * 40.95f; buf[0] = 0x06 + 4 * i; - if((status = dh_i2c_write(mAddress, buf, 5, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 5, 1)) != DH_I2C_OK) { dhdebug("pca9685: failed to write"); return status; } @@ -88,6 +95,11 @@ DH_I2C_Status ICACHE_FLASH_ATTR pca9685_control(int sda, int scl, float *pinsdut return DH_I2C_OK; } -void ICACHE_FLASH_ATTR pca9685_set_address(int address) { + +/* + * pca9685_set_address() implementation. + */ +void ICACHE_FLASH_ATTR pca9685_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/pca9685.h b/firmware-src/sources/devices/pca9685.h index 6b3d7e2..f23893f 100644 --- a/firmware-src/sources/devices/pca9685.h +++ b/firmware-src/sources/devices/pca9685.h @@ -1,40 +1,39 @@ /** - * \file pca9685.h - * \brief Simple communication with PCA9685 PWM LED controller - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with PCA9685 PWM LED controller + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_PCA9685_H_ +#define _DEVICES_PCA9685_H_ -#ifndef SOURCES_DEVICES_PCA9685_H_ -#define SOURCES_DEVICES_PCA9685_H_ +#include "DH/gpio.h" -#include "DH/i2c.h" - -/** Default i2c address*/ -#define PCA9685_DEFAULT_ADDRESS 0x80 -/** Do not initialize pin */ -#define PCA9685_NO_PIN -1 -/** Do not change frequency */ +/** @brief Do not change frequency */ #define PCA9685_NO_PERIOD 0 + /** Pins which are allowed for this chip */ #define PCA9685_SUITABLE_PINS 0xFFFF + /** - * \brief Measure pressure one time. - * \param[in] sda Pin for I2C's SDA. Can be PCA9685_NO_PIN to use current. - * \param[in] scl Pin for I2C's SCL. Can be PCA9685_NO_PIN to use current. - * \param[in] pinsduty Array with pins duty cycles for each pin. - * \param[in] pinsmask Bitwise pins mask with pins that should be enabled, this pins have to have correct value in pinsduty array. - * \param[in] periodus PWM period. Can be PCA9685_NO_PERIOD to use current. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure pressure one time. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN to use current. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN to use current. + * @param[in] pins_duty Array with pins duty cycles for each pin. + * @param[in] pins Bitwise pins mask with pins that should be enabled, + * this pins have to have correct value in pins_duty array. + * @param[in] period_us PWM period. Can be PCA9685_NO_PERIOD to use current. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pca9685_control(int sda, int scl, float *pinsduty, unsigned int pinsmask, unsigned int periodus); +int pca9685_control(int sda, int scl, const float pins_duty[DH_GPIO_PIN_COUNT], + DHGpioPinMask pins, unsigned int period_us); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void pca9685_set_address(int address); -#endif /* SOURCES_DEVICES_PCA9685_H_ */ +#endif /* _DEVICES_PCA9685_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index b859f9f..4ddc2c6 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -43,7 +43,7 @@ #include "commands/mcp4725_cmd.h" #include "commands/ina219_cmd.h" #include "devices/mfrc522.h" -#include "devices/pca9685.h" +#include "commands/pca9685_cmd.h" #include "commands/mlx90614_cmd.h" #include "commands/max6675_cmd.h" #include "commands/max31855_cmd.h" @@ -393,35 +393,6 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL dh_command_fail(cb, MFRC522_GetStatusCodeName(result)); } -/** - * @brief Do "devices/pca9685/control" command. - */ -static void ICACHE_FLASH_ATTR do_devices_pca9685_control(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, PCA9685_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_FLOATVALUES | AF_PERIOD, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - pca9685_set_address(parse_pins.address); - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - const char *res = dh_i2c_error_string(pca9685_control(PCA9685_NO_PIN, PCA9685_NO_PIN, - parse_pins.storage.float_values, parse_pins.pin_value_readed, - (fields & AF_PERIOD) ? parse_pins.periodus : PCA9685_NO_PERIOD)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - /** * @brief Do "devices/tm1637/write" command. */ @@ -523,7 +494,7 @@ RO_DATA struct { { "devices/mfrc522/read", do_devices_mfrc522_read}, { "devices/mfrc522/mifare/read", do_devices_mfrc522_mifare_read_write}, { "devices/mfrc522/mifare/write", do_devices_mfrc522_mifare_read_write}, - { "devices/pca9685/control", do_devices_pca9685_control}, + { "devices/pca9685/control", dh_handle_devices_pca9685_control}, { "devices/mlx90614/read", dh_handle_devices_mlx90614_read}, { "devices/max6675/read", dh_handle_devices_max6675_read}, { "devices/max31855/read", dh_handle_devices_max31855_read}, From b5691c762e04f98824566de9f4f8d28577735cbb Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Fri, 28 Apr 2017 18:29:50 +0300 Subject: [PATCH 48/83] review SI7021 and TM1637 devices --- firmware-src/sources/commands/si7021_cmd.c | 49 ++++++++++++++++ firmware-src/sources/commands/si7021_cmd.h | 18 ++++++ firmware-src/sources/commands/tm1637_cmd.c | 47 +++++++++++++++ firmware-src/sources/commands/tm1637_cmd.h | 18 ++++++ firmware-src/sources/devices/si7021.c | 56 +++++++++++------- firmware-src/sources/devices/si7021.h | 42 ++++++-------- firmware-src/sources/devices/tm1636.h | 28 --------- firmware-src/sources/devices/tm1637.c | 65 +++++++++++---------- firmware-src/sources/devices/tm1637.h | 25 ++++++++ firmware-src/sources/dhcommands.c | 67 ++-------------------- firmware-src/sources/dhutils.c | 4 -- firmware-src/sources/dhutils.h | 11 ++-- 12 files changed, 255 insertions(+), 175 deletions(-) create mode 100644 firmware-src/sources/commands/si7021_cmd.c create mode 100644 firmware-src/sources/commands/si7021_cmd.h create mode 100644 firmware-src/sources/commands/tm1637_cmd.c create mode 100644 firmware-src/sources/commands/tm1637_cmd.h delete mode 100644 firmware-src/sources/devices/tm1636.h create mode 100644 firmware-src/sources/devices/tm1637.h diff --git a/firmware-src/sources/commands/si7021_cmd.c b/firmware-src/sources/commands/si7021_cmd.c new file mode 100644 index 0000000..a7036fc --- /dev/null +++ b/firmware-src/sources/commands/si7021_cmd.c @@ -0,0 +1,49 @@ +/** + * @file + * @brief SI7021 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/si7021_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/si7021.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_si7021_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_si7021_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, &info, + DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + si7021_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float temperature; + float humidity; + const int status = si7021_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &humidity, &temperature); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); + } +} diff --git a/firmware-src/sources/commands/si7021_cmd.h b/firmware-src/sources/commands/si7021_cmd.h new file mode 100644 index 0000000..cbad828 --- /dev/null +++ b/firmware-src/sources/commands/si7021_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief SI7021 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_SI7021_CMD_H_ +#define _COMMANDS_SI7021_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/si7021/read" command. + */ +void dh_handle_devices_si7021_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_SI7021_CMD_H_ */ diff --git a/firmware-src/sources/commands/tm1637_cmd.c b/firmware-src/sources/commands/tm1637_cmd.c new file mode 100644 index 0000000..3ed9b7b --- /dev/null +++ b/firmware-src/sources/commands/tm1637_cmd.c @@ -0,0 +1,47 @@ +/** + * @file + * @brief TM1637 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/tm1637_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/tm1637.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_tm1637_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_tm1637_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if ((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || info.data_len == 0) { + dh_command_fail(cmd_res, "Text not specified"); + return; // FAILED + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + const int status = tm1636_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, info.data, info.data_len); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} diff --git a/firmware-src/sources/commands/tm1637_cmd.h b/firmware-src/sources/commands/tm1637_cmd.h new file mode 100644 index 0000000..85a35fd --- /dev/null +++ b/firmware-src/sources/commands/tm1637_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief TM1637 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_TM1637_CMD_H_ +#define _COMMANDS_TM1637_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/tm1637/write" command. + */ +void dh_handle_devices_tm1637_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_TM1637_CMD_H_ */ diff --git a/firmware-src/sources/devices/si7021.c b/firmware-src/sources/devices/si7021.c index 821046e..eeac631 100644 --- a/firmware-src/sources/devices/si7021.c +++ b/firmware-src/sources/devices/si7021.c @@ -1,57 +1,69 @@ -/* - * si7021.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with SI7021 relative humidity and temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "si7021.h" +#include "devices/si7021.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address*/ +#define SI7021_DEFAULT_ADDRESS 0x80 + +// module variables static int mAddress = SI7021_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR si7021_read(int sda, int scl, float *humidity, float *temperature) { - char buf[2]; - DH_I2C_Status status; - if(sda != SI7021_NO_PIN && scl != SI7021_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * si7021_read() implementation. + */ +int ICACHE_FLASH_ATTR si7021_read(int sda, int scl, float *humidity, float *temperature) +{ + int status; + if(sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("si7021: failed to set up pins"); return status; } } + uint8_t buf[2]; buf[0] = 0xE5; // read humidity, hold master - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("si7021: failed to write get humidity"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("si7021: failed to read humidity"); return status; } - *humidity = ((float)unsignedInt16be(buf, 0)) * 125.0f / 65536.0f - 6.0f; + *humidity = ((float)unsignedInt16be((const char*)buf, 0)) * 125.0f / 65536.0f - 6.0f; - if(temperature) { + if (temperature) { buf[0] = 0xE0; // read temperature from humidity measurement - if((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 0)) != DH_I2C_OK) { dhdebug("si7021: failed to write get temperature"); return status; } - if((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { + if ((status = dh_i2c_read(mAddress, buf, 2)) != DH_I2C_OK) { dhdebug("si7021: failed to read temperature"); return status; } - *temperature = ((float)unsignedInt16be(buf, 0)) * 175.72f / 65536.0f - 46.85f; + *temperature = ((float)unsignedInt16be((const char *)buf, 0)) * 175.72f / 65536.0f - 46.85f; } return DH_I2C_OK; } -void ICACHE_FLASH_ATTR si7021_set_address(int address) { + +/* + * si7021_set_address() implementation. + */ +void ICACHE_FLASH_ATTR si7021_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/si7021.h b/firmware-src/sources/devices/si7021.h index 1c0a7fc..a67c56b 100644 --- a/firmware-src/sources/devices/si7021.h +++ b/firmware-src/sources/devices/si7021.h @@ -1,35 +1,27 @@ /** - * \file si7021.h - * \brief Simple communication with SI7021 relative humidity and temperature sensor - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with SI7021 relative humidity and temperature sensor. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_SI7021_H_ -#define SOURCES_DEVICES_SI7021_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define SI7021_DEFAULT_ADDRESS 0x80 -/** Do not initialize pin */ -#define SI7021_NO_PIN -1 +#ifndef _DEVICES_SI7021_H_ +#define _DEVICES_SI7021_H_ /** - * \brief Measure temperature and relative humidity one time. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] humidity Pointer for storing relative humidity result measure in percents. - * \param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. - * \return Status value, one of DH_I2C_Status enum. + * @brief Measure temperature and relative humidity one time. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] humidity Pointer for storing relative humidity result measure in percents. + * @param[out] temperature Pointer for storing temperature result measure in degree Celsius. Can be NULL. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status si7021_read(int sda, int scl, float *humidity, float *temperature); +int si7021_read(int sda, int scl, float *humidity, float *temperature); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void si7021_set_address(int address); -#endif /* SOURCES_DEVICES_SI7021_H_ */ +#endif /* _DEVICES_SI7021_H_ */ diff --git a/firmware-src/sources/devices/tm1636.h b/firmware-src/sources/devices/tm1636.h deleted file mode 100644 index 608e4c9..0000000 --- a/firmware-src/sources/devices/tm1636.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * \file tm1636.h - * \brief Simple communication with tm1636 LED 8 segment driver. - * \author Nikolay Khabarov - * \date 2017 - * \copyright DeviceHive MIT - */ - -#ifndef SOURCES_DEVICES_TM1636_H_ -#define SOURCES_DEVICES_TM1636_H_ - -#include "DH/i2c.h" - -/** Do not initialize pin */ -#define TM1636_NO_PIN -1 - -/** - * \brief Set text on screen. - * \details Old text will be erased. - * \param[in] sda Pin for I2C's SDA. Use TM1636_NO_PIN to prevent initialization. - * \param[in] scl Pin for I2C's SCL. Use TM1636_NO_PIN to prevent initialization. - * \param[in] text Chars to write on display. Only digits and colon are allowed. - * \param[in] len Number of chars to write. - * \return NULL on success, text description on error. - */ -DH_I2C_Status tm1636_write(int sda, int scl, const char *text, unsigned int len); - -#endif /* SOURCES_DEVICES_TM1636_H_ */ diff --git a/firmware-src/sources/devices/tm1637.c b/firmware-src/sources/devices/tm1637.c index ac49fbc..64b6611 100644 --- a/firmware-src/sources/devices/tm1637.c +++ b/firmware-src/sources/devices/tm1637.c @@ -1,21 +1,20 @@ -/* - * tm1637.c - * - * Copyright 2017 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with TM1637 LED 8 segment driver. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "tm1636.h" -#include "irom.h" +#include "devices/tm1637.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" +#include "irom.h" #include -#include #include -RO_DATA const unsigned char segments_table[] = { +// segments table for digits +RO_DATA const uint8_t segments_table[] = { 0b11111100, // 0 0b01100000, // 1 0b11011010, // 2 @@ -28,39 +27,47 @@ RO_DATA const unsigned char segments_table[] = { 0b11110110 // 9 }; -DH_I2C_Status ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, unsigned int len) { + +/* + * tm1636_write() implementation. + */ +int ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, size_t len) +{ int i, j; - DH_I2C_Status status; - char v; char buf[6]; // convert text to 8 segments digits os_memset(buf, 0, sizeof(buf)); - for(i = 0, j = 0; i < len; i++) { - if(j >= sizeof(buf)) + for (i = 0, j = 0; i < len; i++) { + if (j >= sizeof(buf)) return DH_I2C_WRONG_PARAMETERS; - if(text[i] >= 0x30 && text[i] <= 0x39) { - v = irom_char(&segments_table[text[i] - 0x30]); - } else if(text[i] == ' ') { + + const int ch = text[i]; + int v; + if (ch >= '0' && ch <= '9') { + v = irom_char(&segments_table[ch - '0']); + } else if (ch == ' ') { v = 0b00000000; - } else if(text[i] == '-') { + } else if (ch == '-') { v = 0b00000010; } else { return DH_I2C_WRONG_PARAMETERS; } - if((i + 1) < len) { - if((text[i + 1] == ':' || text[i + 1] == '.')) { + + if ((i + 1) < len) { + if ((text[i+1] == ':' || text[i+1] == '.')) { v |= 0b1; i++; } } - buf[j] = v; - j++; + + buf[j++] = v; } // init pins - if(sda != TM1636_NO_PIN && scl != TM1636_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("tm1636: failed to set up pins"); return status; } @@ -68,21 +75,21 @@ DH_I2C_Status ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, // write data to display register command status = dh_i2c_write(bitwise_reverse_byte(0x40), NULL, 0 , 1); - if(status != DH_I2C_OK) { + if (status != DH_I2C_OK) { dhdebug("tm1636: failed to init"); return status; } // write segments status = dh_i2c_write(bitwise_reverse_byte(0xC0), buf, sizeof(buf), 1); - if(status != DH_I2C_OK) { + if (status != DH_I2C_OK) { dhdebug("tm1636: failed to write segments"); return status; } // control display, max brightness status = dh_i2c_read(bitwise_reverse_byte(0x8F), NULL, 0); - if(status != DH_I2C_OK) { + if (status != DH_I2C_OK) { dhdebug("tm1636: failed to control"); return status; } diff --git a/firmware-src/sources/devices/tm1637.h b/firmware-src/sources/devices/tm1637.h new file mode 100644 index 0000000..ca65459 --- /dev/null +++ b/firmware-src/sources/devices/tm1637.h @@ -0,0 +1,25 @@ +/** + * @file + * @brief Simple communication with TM1637 LED 8 segment driver. + * @copyright 2017 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _DEVICES_TM1637_H_ +#define _DEVICES_TM1637_H_ + +#include + +/** + * @brief Set text on screen. + * + * Old text will be erased. + * + * @param[in] sda Pin for I2C's SDA. Use DH_I2C_NO_PIN to prevent initialization. + * @param[in] scl Pin for I2C's SCL. Use DH_I2C_NO_PIN to prevent initialization. + * @param[in] text Chars to write on display. Only digits and colon are allowed. + * @param[in] len Number of chars to write. + * @return Status value, one of DH_I2C_Status enum. + */ +int tm1636_write(int sda, int scl, const char *text, size_t len); + +#endif /* _DEVICES_TM1637_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 4ddc2c6..3c87b95 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -37,7 +37,7 @@ #include "devices/pcf8574_hd44780.h" #include "commands/mhz19_cmd.h" #include "commands/lm75_cmd.h" -#include "devices/si7021.h" +#include "commands/si7021_cmd.h" #include "commands/ads1115_cmd.h" #include "devices/pcf8591.h" #include "commands/mcp4725_cmd.h" @@ -47,7 +47,7 @@ #include "commands/mlx90614_cmd.h" #include "commands/max6675_cmd.h" #include "commands/max31855_cmd.h" -#include "devices/tm1636.h" +#include "commands/tm1637_cmd.h" #include #include @@ -162,35 +162,6 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c } -/** - * @brief Do "devices/si7021/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_si7021_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_SDA | AF_SCL | AF_ADDRESS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - si7021_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float temperature; - float humidity; - const char *res = dh_i2c_error_string(si7021_read(SI7021_NO_PIN, SI7021_NO_PIN, &humidity, &temperature)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); - } -} - /** * @brief Do "devices/pcf8591/read" command. */ @@ -393,36 +364,6 @@ static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESUL dh_command_fail(cb, MFRC522_GetStatusCodeName(result)); } -/** - * @brief Do "devices/tm1637/write" command. - */ -static void ICACHE_FLASH_ATTR do_devices_tm1637_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_DATA | AF_TEXT_DATA, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { - dh_command_fail(cb, "Text not specified"); - return; - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - const char *res = dh_i2c_error_string(tm1636_write(TM1636_NO_PIN, TM1636_NO_PIN, - parse_pins.data, parse_pins.data_len)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - #endif // devices commands RO_DATA struct { @@ -485,7 +426,7 @@ RO_DATA struct { { "devices/pcf8574/hd44780/write", do_devices_pcf8574_hd44780_write}, { "devices/mhz19/read", dh_handle_devices_mhz19_read}, { "devices/lm75/read", dh_handle_devices_lm75_read}, - { "devices/si7021/read", do_devices_si7021_read}, + { "devices/si7021/read", dh_handle_devices_si7021_read}, { "devices/ads1115/read", dh_handle_devices_ads1115_read}, { "devices/pcf8591/read", do_devices_pcf8591_read}, { "devices/pcf8591/write", do_devices_pcf8591_write}, @@ -498,7 +439,7 @@ RO_DATA struct { { "devices/mlx90614/read", dh_handle_devices_mlx90614_read}, { "devices/max6675/read", dh_handle_devices_max6675_read}, { "devices/max31855/read", dh_handle_devices_max31855_read}, - { "devices/tm1637/write", do_devices_tm1637_write} + { "devices/tm1637/write", dh_handle_devices_tm1637_write} }; diff --git a/firmware-src/sources/dhutils.c b/firmware-src/sources/dhutils.c index e77c063..7852e4f 100644 --- a/firmware-src/sources/dhutils.c +++ b/firmware-src/sources/dhutils.c @@ -169,7 +169,3 @@ void ICACHE_FLASH_ATTR delay_ms(unsigned int ms) { if(ms) os_delay_us(ms * 1000); } - -unsigned char ICACHE_FLASH_ATTR bitwise_reverse_byte(unsigned char v) { - return ((v * 0x0802LU & 0x22110LU) | (v * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; -} diff --git a/firmware-src/sources/dhutils.h b/firmware-src/sources/dhutils.h index 0483c1a..ed65054 100644 --- a/firmware-src/sources/dhutils.h +++ b/firmware-src/sources/dhutils.h @@ -140,10 +140,13 @@ static inline int signedInt16le(const char *buf, int pos) { void delay_ms(unsigned int ms); /** - * \brief Reverse bits in byte. - * \param[in] v Byte. - * \return Byte in reverse bit order. + * @brief Reverse bits in byte. + * @param[in] v Byte. + * @return Byte in reverse bit order. */ -unsigned char bitwise_reverse_byte(unsigned char v); +static inline uint8_t bitwise_reverse_byte(uint8_t v) +{ + return ((v * 0x0802LU & 0x22110LU) | (v * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; +} #endif /* _DHUTILS_H_ */ From 4a6431f660adab4fe4f7a8a0282f69c6495c6944 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 2 May 2017 14:52:12 +0300 Subject: [PATCH 49/83] review PCF8591 device --- firmware-src/sources/commands/pcf8591_cmd.c | 104 ++++++++++++++++++++ firmware-src/sources/commands/pcf8591_cmd.h | 25 +++++ firmware-src/sources/devices/pcf8591.c | 91 +++++++++++------ firmware-src/sources/devices/pcf8591.h | 66 ++++++------- firmware-src/sources/dhcommands.c | 83 +--------------- 5 files changed, 222 insertions(+), 147 deletions(-) create mode 100644 firmware-src/sources/commands/pcf8591_cmd.c create mode 100644 firmware-src/sources/commands/pcf8591_cmd.h diff --git a/firmware-src/sources/commands/pcf8591_cmd.c b/firmware-src/sources/commands/pcf8591_cmd.c new file mode 100644 index 0000000..80bbdd0 --- /dev/null +++ b/firmware-src/sources/commands/pcf8591_cmd.c @@ -0,0 +1,104 @@ +/** + * @file + * @brief PCF8591 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/pcf8591_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/pcf8591.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_pcf8591_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_pcf8591_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + pcf8591_set_address(info.address); + + if (fields & AF_REF) { + const int status = pcf8591_set_vref(info.ref); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + float values[4]; + const int status = pcf8591_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, values); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", + values[0], values[1], values[2], values[3]); + } +} + + +/* + * dh_handle_devices_pcf8591_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_pcf8591_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (info.pin_value_readed != 1) { + dh_command_fail(cmd_res, "Unsuitable pin"); + return; + } + if (fields & AF_ADDRESS) + pcf8591_set_address(info.address); + + if (fields & AF_REF) { + const int status = pcf8591_set_vref(info.ref); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + const int status = pcf8591_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, info.storage.float_values[0]); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} diff --git a/firmware-src/sources/commands/pcf8591_cmd.h b/firmware-src/sources/commands/pcf8591_cmd.h new file mode 100644 index 0000000..5453858 --- /dev/null +++ b/firmware-src/sources/commands/pcf8591_cmd.h @@ -0,0 +1,25 @@ +/** + * @file + * @brief PCF8591 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_PCF8591_CMD_H_ +#define _COMMANDS_PCF8591_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/pcf8591/read" command. + */ +void dh_handle_devices_pcf8591_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "devices/pcf8591/write" command. + */ +void dh_handle_devices_pcf8591_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_PCF8591_CMD_H_ */ diff --git a/firmware-src/sources/devices/pcf8591.c b/firmware-src/sources/devices/pcf8591.c index 41a0325..8c5acc6 100644 --- a/firmware-src/sources/devices/pcf8591.c +++ b/firmware-src/sources/devices/pcf8591.c @@ -1,85 +1,112 @@ -/* - * pcf8591.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with PCF8591 ADC/DAC. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "pcf8591.h" +#include "devices/pcf8591.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include #include +/** @brief Default sensor i2c address. */ +#define PCF8591_DEFAULT_ADDRESS 0x90 + +// module variables static int mAddress = PCF8591_DEFAULT_ADDRESS; static float mVoltage = 3.3f; -DH_I2C_Status ICACHE_FLASH_ATTR pcf8591_read(int sda, int scl, float *values) { - char buf[4]; - DH_I2C_Status status; - if(sda != PCF8591_NO_PIN && scl != PCF8591_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * pcf8591_read() implementation. + */ +int ICACHE_FLASH_ATTR pcf8591_read(int sda, int scl, float values[4]) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8591: failed to set up pins"); return status; } } + uint8_t buf[4]; buf[0] = 0x45; // Config - if((status = dh_i2c_write(mAddress, buf, 1, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 1, 1)) != DH_I2C_OK) { dhdebug("pcf8591: failed to write"); return status; } - //dummy read to make sure all values was updated - if((status = dh_i2c_read(mAddress, buf, 4)) != DH_I2C_OK) { - dhdebug("pcf8591: failed to write"); + // dummy read to make sure all values was updated + if ((status = dh_i2c_read(mAddress, buf, 4)) != DH_I2C_OK) { + dhdebug("pcf8591: failed to read"); return status; } os_delay_us(250); - if((status = dh_i2c_read(mAddress, buf, 4)) != DH_I2C_OK) { - dhdebug("pcf8591: failed to write"); + if ((status = dh_i2c_read(mAddress, buf, 4)) != DH_I2C_OK) { + dhdebug("pcf8591: failed to read"); return status; } + int i; - for(i = 0; i < sizeof(buf); i++) { - values[i] = mVoltage * ((float)buf[i]) / 255.0f; + for (i = 0; i < sizeof(buf); i++) { + values[i] = mVoltage * ((float)(int8_t)buf[i]) / 255.0f; // TODO: check 256 scale? } + return DH_I2C_OK; } -DH_I2C_Status ICACHE_FLASH_ATTR pcf8591_write(int sda, int scl, float value) { - char buf[3]; - DH_I2C_Status status; - if(value < 0.0f || value > mVoltage) + +/* + * pcf8591_write() implementation. + */ +int ICACHE_FLASH_ATTR pcf8591_write(int sda, int scl, float value) +{ + if (value < 0.0f || value > mVoltage) return DH_I2C_WRONG_PARAMETERS; - if(sda != PCF8591_NO_PIN && scl != PCF8591_NO_PIN) { + + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8591: failed to set up pins"); return status; } } - char v = (value / mVoltage * 255.0f); + const int8_t v = (value / mVoltage * 255.0f); // TODO: check 256 scale? + uint8_t buf[2]; buf[0] = 0x44; // Config buf[1] = v; - if((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { + if ((status = dh_i2c_write(mAddress, buf, 2, 1)) != DH_I2C_OK) { dhdebug("pcf8591: failed to write"); return status; } + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR pcf8591_set_address(int address) { + +/* + * pcf8591_set_address() implementation. + */ +void ICACHE_FLASH_ATTR pcf8591_set_address(int address) +{ mAddress = address; } -DH_I2C_Status ICACHE_FLASH_ATTR pcf8591_set_vref(float voltage) { - if(mVoltage <= 0.0f) + +/* + * pcf8591_set_vref() implementation. + */ +int ICACHE_FLASH_ATTR pcf8591_set_vref(float voltage) +{ + if (mVoltage <= 0.0f) return DH_I2C_WRONG_PARAMETERS; + mVoltage = voltage; return DH_I2C_OK; } diff --git a/firmware-src/sources/devices/pcf8591.h b/firmware-src/sources/devices/pcf8591.h index 51be4b9..570cad1 100644 --- a/firmware-src/sources/devices/pcf8591.h +++ b/firmware-src/sources/devices/pcf8591.h @@ -1,51 +1,47 @@ /** - * \file pcf8591.h - * \brief Simple communication with PCF8591 ADC/DAC - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with PCF8591 ADC/DAC. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ - -#ifndef SOURCES_DEVICES_PCF8591_H_ -#define SOURCES_DEVICES_PCF8591_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define PCF8591_DEFAULT_ADDRESS 0x90 -/** Do not initialize pin */ -#define PCF8591_NO_PIN -1 +#ifndef _DEVICES_PCF8591_H_ +#define _DEVICES_PCF8591_H_ /** - * \brief Get ADC voltages. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] values Pointer to four float values to store result in Volts. - * \return Status value, one of DH_I2C_Status enum. + * @brief Get ADC voltages. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] values Pointer to four float values to store result in Volts. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8591_read(int sda, int scl, float *values); +int pcf8591_read(int sda, int scl, float values[4]); + /** - * \brief Set DAC voltages. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] value Voltage in Volts. - * \return Status value, one of DH_I2C_Status enum. + * @brief Set DAC voltages. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[in] value Voltage in Volts. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8591_write(int sda, int scl, float value); +int pcf8591_write(int sda, int scl, float value); + /** - * \brief Set sensor address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set sensor address which should be used while reading. + * @param[in] address I2C end device address. */ void pcf8591_set_address(int address); + /** - * \brief Set reference voltage in volts. - * \note Default is 3.3V. - * \param[in] voltage Voltage in Volts. - * \return Status value, one of DH_I2C_Status enum. + * @brief Set reference voltage in volts. + * + * Default is 3.3V. + * + * @param[in] voltage Reference voltage in Volts. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8591_set_vref(float voltage); +int pcf8591_set_vref(float voltage); -#endif /* SOURCES_DEVICES_PCF8591_H_ */ +#endif /* _DEVICES_PCF8591_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 3c87b95..019e42e 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -39,7 +39,7 @@ #include "commands/lm75_cmd.h" #include "commands/si7021_cmd.h" #include "commands/ads1115_cmd.h" -#include "devices/pcf8591.h" +#include "commands/pcf8591_cmd.h" #include "commands/mcp4725_cmd.h" #include "commands/ina219_cmd.h" #include "devices/mfrc522.h" @@ -162,83 +162,6 @@ static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *c } -/** - * @brief Do "devices/pcf8591/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_pcf8591_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_REF, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - pcf8591_set_address(parse_pins.address); - if(fields & AF_REF) { - const char *res = dh_i2c_error_string(pcf8591_set_vref(parse_pins.ref)); - if (res != 0) { - dh_command_fail(cb, res); - return; - } - } - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - float values[4]; - const char *res = dh_i2c_error_string(pcf8591_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, values)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", - values[0], values[1], values[2], values[3]); - } -} - - -/** - * @brief Do "devices/pcf8591/write" command. - */ -static void ICACHE_FLASH_ATTR do_devices_pcf8591_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_REF | AF_FLOATVALUES, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(parse_pins.pin_value_readed != 1) { - dh_command_fail(cb, "Unsuitable pin"); - return; - } - if(fields & AF_ADDRESS) - pcf8591_set_address(parse_pins.address); - if(fields & AF_REF) { - const char *res = dh_i2c_error_string(pcf8591_set_vref(parse_pins.ref)); - if (res != 0) { - dh_command_fail(cb, res); - return; - } - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - const char *res = dh_i2c_error_string(pcf8591_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, parse_pins.storage.float_values[0])); - if (res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - /** * @brief Do "devices/mfrc522/read" command. */ @@ -428,8 +351,8 @@ RO_DATA struct { { "devices/lm75/read", dh_handle_devices_lm75_read}, { "devices/si7021/read", dh_handle_devices_si7021_read}, { "devices/ads1115/read", dh_handle_devices_ads1115_read}, - { "devices/pcf8591/read", do_devices_pcf8591_read}, - { "devices/pcf8591/write", do_devices_pcf8591_write}, + { "devices/pcf8591/read", dh_handle_devices_pcf8591_read}, + { "devices/pcf8591/write", dh_handle_devices_pcf8591_write}, { "devices/mcp4725/write", dh_handle_devices_mcp4725_write}, { "devices/ina219/read", dh_handle_devices_ina219_read}, { "devices/mfrc522/read", do_devices_mfrc522_read}, From e442c80e7ee024cee120fb022855edbca05585ba Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 2 May 2017 16:52:30 +0300 Subject: [PATCH 50/83] review PCF8574 and HD44780 devices --- firmware-src/sources/commands/pcf8574_cmd.c | 98 +++++++++++ firmware-src/sources/commands/pcf8574_cmd.h | 25 +++ .../sources/commands/pcf8574_hd44780_cmd.c | 53 ++++++ .../sources/commands/pcf8574_hd44780_cmd.h | 18 ++ firmware-src/sources/devices/pcf8574.c | 90 ++++++---- firmware-src/sources/devices/pcf8574.h | 73 ++++---- .../sources/devices/pcf8574_hd44780.c | 159 ++++++++++-------- .../sources/devices/pcf8574_hd44780.h | 36 ++-- firmware-src/sources/dhcommands.c | 131 ++------------- 9 files changed, 410 insertions(+), 273 deletions(-) create mode 100644 firmware-src/sources/commands/pcf8574_cmd.c create mode 100644 firmware-src/sources/commands/pcf8574_cmd.h create mode 100644 firmware-src/sources/commands/pcf8574_hd44780_cmd.c create mode 100644 firmware-src/sources/commands/pcf8574_hd44780_cmd.h diff --git a/firmware-src/sources/commands/pcf8574_cmd.c b/firmware-src/sources/commands/pcf8574_cmd.c new file mode 100644 index 0000000..816ac56 --- /dev/null +++ b/firmware-src/sources/commands/pcf8574_cmd.c @@ -0,0 +1,98 @@ +/** + * @file + * @brief PCF8574 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/pcf8574_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/pcf8574.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + +/* + * dh_handle_devices_pcf8574_read() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_pcf8574_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + if (params_len) { + const char *err_msg = parse_params_pins_set(params, params_len, + &info, PCF8574_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_PULLUP, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_ADDRESS) + pcf8574_set_address(info.address); + } + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + if (fields & AF_PULLUP) { + const int status = pcf8574_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, info.pins_to_pullup, 0); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + } + + unsigned int pins; + const int status = pcf8574_read(DH_I2C_NO_PIN, DH_I2C_NO_PIN, &pins); + const char *err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_GPIO, 0, + pins, system_get_time(), PCF8574_SUITABLE_PINS); + } +} + + +/* + * dh_handle_devices_pcf8574_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_pcf8574_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, PCF8574_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_SET | AF_CLEAR, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } else if (!(fields & (AF_SET | AF_CLEAR))) { + dh_command_fail(cmd_res, "Dummy request"); + return; // FAILED + } else if ((info.pins_to_set | info.pins_to_clear) & ~PCF8574_SUITABLE_PINS) { + dh_command_fail(cmd_res, "Unsuitable pin"); + return; + } + + if (fields & AF_ADDRESS) + pcf8574_set_address(info.address); + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + const int status = pcf8574_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, + info.pins_to_set, info.pins_to_clear); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} diff --git a/firmware-src/sources/commands/pcf8574_cmd.h b/firmware-src/sources/commands/pcf8574_cmd.h new file mode 100644 index 0000000..cb17905 --- /dev/null +++ b/firmware-src/sources/commands/pcf8574_cmd.h @@ -0,0 +1,25 @@ +/** + * @file + * @brief PCF8574 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_PCF8574_CMD_H_ +#define _COMMANDS_PCF8574_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/pcf8574/read" command. + */ +void dh_handle_devices_pcf8574_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "devices/pcf8574/write" command. + */ +void dh_handle_devices_pcf8574_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_PCF8574_CMD_H_ */ diff --git a/firmware-src/sources/commands/pcf8574_hd44780_cmd.c b/firmware-src/sources/commands/pcf8574_hd44780_cmd.c new file mode 100644 index 0000000..006c332 --- /dev/null +++ b/firmware-src/sources/commands/pcf8574_hd44780_cmd.c @@ -0,0 +1,53 @@ +/** + * @file + * @brief HD44780 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/pcf8574_hd44780_cmd.h" +#include "commands/i2c_cmd.h" +#include "devices/pcf8574_hd44780.h" +#include "devices/pcf8574.h" +#include "DH/i2c.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include + + +/* + * dh_handle_devices_pcf8574_hd44780_write() implementation. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_pcf8574_hd44780_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, PCF8574_SUITABLE_PINS, 0, + AF_SDA | AF_SCL | AF_ADDRESS | AF_DATA | AF_TEXT_DATA, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + + if ((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || info.data_len == 0) { + dh_command_fail(cmd_res, "Text not specified"); + return; // FAILED + } + + if (fields & AF_ADDRESS) + pcf8574_set_address(info.address); + + fields |= AF_ADDRESS; + if (dh_i2c_init_helper(cmd_res, fields, &info)) + return; // FAILED + + const int status = pcf8574_hd44780_write(DH_I2C_NO_PIN, DH_I2C_NO_PIN, info.data, info.data_len); + err_msg = dh_i2c_error_string(status); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + } else { + dh_command_done(cmd_res, ""); + } +} diff --git a/firmware-src/sources/commands/pcf8574_hd44780_cmd.h b/firmware-src/sources/commands/pcf8574_hd44780_cmd.h new file mode 100644 index 0000000..def5871 --- /dev/null +++ b/firmware-src/sources/commands/pcf8574_hd44780_cmd.h @@ -0,0 +1,18 @@ +/** + * @file + * @brief HD44780 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_PCF8574_HD44780_CMD_H_ +#define _COMMANDS_PCF8574_HD44780_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/pcf8574/hd44780/write" command. + */ +void dh_handle_devices_pcf8574_hd44780_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_PCF8574_HD44780_CMD_H_ */ diff --git a/firmware-src/sources/devices/pcf8574.c b/firmware-src/sources/devices/pcf8574.c index a265538..2702fa5 100644 --- a/firmware-src/sources/devices/pcf8574.c +++ b/firmware-src/sources/devices/pcf8574.c @@ -1,72 +1,98 @@ -/* - * pcf8574.c - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with PCF8574 GPIO extender. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "pcf8574.h" +#include "devices/pcf8574.h" +#include "DH/i2c.h" #include "dhdebug.h" #include "dhutils.h" #include -#include +/** @brief Default sensor i2c address. */ +#define PCF8574_DEFAULT_ADDRESS 0x4E + +// module variables static int mAddress = PCF8574_DEFAULT_ADDRESS; -DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_read(int sda, int scl, unsigned int *pins) { - char buf; - DH_I2C_Status status; - if(sda != PCF8574_NO_PIN && scl != PCF8574_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * pcf8574_read() implementation. + */ +int ICACHE_FLASH_ATTR pcf8574_read(int sda, int scl, unsigned int *pins) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8574: failed to set up pins"); return status; } } - if((status = dh_i2c_read(mAddress, &buf, 1)) != DH_I2C_OK) { + + uint8_t buf; + if ((status = dh_i2c_read(mAddress, &buf, 1)) != DH_I2C_OK) { dhdebug("pcf8574: failed to read"); return status; } - *pins = (unsigned char)buf; + *pins = buf; return DH_I2C_OK; } -DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear) { - char buf; - DH_I2C_Status status; - unsigned int current_state; - if(pins_to_set & pins_to_clear) + +/* + * pcf8574_write() implementation. + */ +int ICACHE_FLASH_ATTR pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear) +{ + if (pins_to_set & pins_to_clear) return DH_I2C_WRONG_PARAMETERS; - if((status = pcf8574_read(sda, scl, ¤t_state)) != DH_I2C_OK) { + + int status; + unsigned int current_state; + if ((status = pcf8574_read(sda, scl, ¤t_state)) != DH_I2C_OK) { return status; } - buf = (char)((current_state | pins_to_set) & (~pins_to_clear) & PCF8574_SUITABLE_PINS); - if((status = dh_i2c_write(mAddress, &buf, 1, 1)) != DH_I2C_OK) { + + uint8_t buf = ((current_state | pins_to_set) & ~pins_to_clear) & PCF8574_SUITABLE_PINS; + if ((status = dh_i2c_write(mAddress, &buf, 1, 1)) != DH_I2C_OK) { dhdebug("pcf8574: failed to write"); return status; } + return DH_I2C_OK; } -DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_set(int sda, int scl, unsigned int pins) { - char buf; - DH_I2C_Status status; - if(sda != PCF8574_NO_PIN && scl != PCF8574_NO_PIN) { - if((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { + +/* + * pcf8574_set() implementation. + */ +int ICACHE_FLASH_ATTR pcf8574_set(int sda, int scl, unsigned int pins) +{ + int status; + if (sda != DH_I2C_NO_PIN && scl != DH_I2C_NO_PIN) { + if ((status = dh_i2c_init(sda, scl)) != DH_I2C_OK) { dhdebug("pcf8574: failed to set up pins"); return status; } } - buf = pins & PCF8574_SUITABLE_PINS; - if((status = dh_i2c_write(mAddress, &buf, 1, 1)) != DH_I2C_OK) { + + uint8_t buf = pins & PCF8574_SUITABLE_PINS; + if ((status = dh_i2c_write(mAddress, &buf, 1, 1)) != DH_I2C_OK) { dhdebug("pcf8574: failed to write"); return status; } + return DH_I2C_OK; } -void ICACHE_FLASH_ATTR pcf8574_set_address(int address) { + +/* + * pcf8574_set_address() implementation. + */ +void ICACHE_FLASH_ATTR pcf8574_set_address(int address) +{ mAddress = address; } diff --git a/firmware-src/sources/devices/pcf8574.h b/firmware-src/sources/devices/pcf8574.h index 98b6a05..80e3d05 100644 --- a/firmware-src/sources/devices/pcf8574.h +++ b/firmware-src/sources/devices/pcf8574.h @@ -1,55 +1,54 @@ /** - * \file pcf8574.h - * \brief Simple communication with PCF8574 GPIO extender - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with PCF8574 GPIO extender. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_PCF8574_H_ +#define _DEVICES_PCF8574_H_ -#ifndef SOURCES_DEVICES_PCF8574_H_ -#define SOURCES_DEVICES_PCF8574_H_ - -#include "DH/i2c.h" - -/** Default sensor i2c address*/ -#define PCF8574_DEFAULT_ADDRESS 0x4E -/** Do not initialize pin */ -#define PCF8574_NO_PIN -1 -/** Pins which can be used with extender */ +/** @brief Pins which can be used with extender. */ #define PCF8574_SUITABLE_PINS 0b11111111 + /** - * \brief Read data on extender pins. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[out] pins Pointer where pin mask will be stored. - * \return Status value, one of DH_I2C_Status enum. + * @brief Read data on extender pins. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[out] pins Pointer where pin mask will be stored. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8574_read(int sda, int scl, unsigned int *pins); +int pcf8574_read(int sda, int scl, unsigned int *pins); + /** - * \brief Write data on extender pins. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[in] pins_to_set Pin mask to set up high level. - * \param[in] pins_to_clear Pin mask to set up low level. - * \return Status value, one of DH_I2C_Status enum. + * @brief Write data on extender pins. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[in] pins_to_set Pin mask to set up high level. + * @param[in] pins_to_clear Pin mask to set up low level. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8574_write(int sda, int scl, unsigned int pins_to_set, unsigned int pins_to_clear); +int pcf8574_write(int sda, int scl, + unsigned int pins_to_set, + unsigned int pins_to_clear); + /** - * \brief Set all pins. - * \param[in] sda Pin for I2C's SDA. - * \param[in] scl Pin for I2C's SCL. - * \param[in] pins Pin mask of pins state. - * \return Status value, one of DH_I2C_Status enum. + * @brief Set all pins. + * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. + * @param[in] scl Pin for I2C's SCL. Can be DH_I2C_NO_PIN. + * @param[in] pins Pin mask of pins state. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8574_set(int sda, int scl, unsigned int pins); +int pcf8574_set(int sda, int scl, + unsigned int pins); + /** - * \brief Set extender address which should be used while reading. - * \param[in] address Pin for I2C's SDA. + * @brief Set extender address which should be used while reading. + * @param[in] address I2C end device address. */ void pcf8574_set_address(int address); -#endif /* SOURCES_DEVICES_PCF8574_H_ */ +#endif /* _DEVICES_PCF8574_H_ */ diff --git a/firmware-src/sources/devices/pcf8574_hd44780.c b/firmware-src/sources/devices/pcf8574_hd44780.c index 88a0842..9f8f080 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.c +++ b/firmware-src/sources/devices/pcf8574_hd44780.c @@ -1,110 +1,133 @@ -/* - * pcf8574_hd44780.h - * - * Copyright 2016 DeviceHive - * - * Author: Nikolay Khabarov - * +/** + * @file + * @brief Simple communication with HD44780 like displays via PCF8574 GPIO extender with I2C bus. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ -#include "pcf8574_hd44780.h" -#include "pcf8574.h" +#include "devices/pcf8574_hd44780.h" +#include "devices/pcf8574.h" +#include "DH/i2c.h" #include -#include #include -#define PIN_RS (1 << 0) -#define PIN_RW (1 << 1) -#define PIN_E (1 << 2) -#define PIN_BACKLIGHT (1 << 3) -#define PIN_D4 (1 << 4) -#define PIN_D5 (1 << 5) -#define PIN_D6 (1 << 6) -#define PIN_D7 (1 << 7) - -LOCAL DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write_half(int sda, - int scl, char half, int is_command) { - DH_I2C_Status status; - char pins = ((half & (1 << 3)) ? PIN_D7 : 0) | ((half & (1 << 2)) ? PIN_D6 : 0) - | ((half & (1 << 1)) ? PIN_D5 : 0) | ((half & (1 << 0)) ? PIN_D4 : 0); +#define PIN_RS BIT(0) +#define PIN_RW BIT(1) +#define PIN_E BIT(2) +#define PIN_BACKLIGHT BIT(3) +#define PIN_D4 BIT(4) +#define PIN_D5 BIT(5) +#define PIN_D6 BIT(6) +#define PIN_D7 BIT(7) + + +/** + * @brief Write a half of byte. + */ +static int ICACHE_FLASH_ATTR hd44780_write_half(int sda, int scl, int half, int is_command) +{ + /*unsigned int pins = ((half & BIT(3)) ? PIN_D7 : 0) + | ((half & BIT(2)) ? PIN_D6 : 0) + | ((half & BIT(1)) ? PIN_D5 : 0) + | ((half & BIT(0)) ? PIN_D4 : 0);*/ + unsigned int pins = half << 4; // NOTE: check D4,D5,D6,D7 position pins |= PIN_BACKLIGHT | (is_command ? 0 : PIN_RS); + // set enable HIGH - if((status = pcf8574_set(sda, scl, pins | PIN_E)) != DH_I2C_OK) + int status; + if ((status = pcf8574_set(sda, scl, pins | PIN_E)) != DH_I2C_OK) return status; os_delay_us(1); + // set enable to LOW - if((status = pcf8574_set(sda, scl, pins)) != DH_I2C_OK) + if ((status = pcf8574_set(sda, scl, pins)) != DH_I2C_OK) return status; + return DH_I2C_OK; } -LOCAL DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write_byte(int sda, - int scl, char byte, int is_command) { - DH_I2C_Status status; - if((status = pcf8574_hd44780_write_half(sda, scl, (byte >> 4) & 0x0F, is_command)) != DH_I2C_OK) + +/** + * @brief Write a byte. + */ +static int ICACHE_FLASH_ATTR hd44780_write_byte(int sda, int scl, int byte, int is_command) +{ + int status; + if ((status = hd44780_write_half(sda, scl, (byte >> 4) & 0x0F, is_command)) != DH_I2C_OK) return status; - if((status = pcf8574_hd44780_write_half(sda, scl, byte & 0x0F, is_command)) != DH_I2C_OK) + if ((status = hd44780_write_half(sda, scl, byte & 0x0F, is_command)) != DH_I2C_OK) return status; + return DH_I2C_OK; } -LOCAL DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_set_line(int sda, - int scl, unsigned int line) { - DH_I2C_Status status; + +/** + * @brief Set output line. + */ +static int ICACHE_FLASH_ATTR hd44780_set_line(int sda, int scl, unsigned int line) +{ + int status; + switch (line) { case 0: - if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x14, 1)) - != DH_I2C_OK) + if ((status = hd44780_write_byte(sda, scl, 0x80 | 0x14, 1)) != DH_I2C_OK) return status; break; + case 1: - if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x40, 1)) - != DH_I2C_OK) + if ((status = hd44780_write_byte(sda, scl, 0x80 | 0x40, 1)) != DH_I2C_OK) return status; break; + case 2: - if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x14, 1)) - != DH_I2C_OK) + if ((status = hd44780_write_byte(sda, scl, 0x80 | 0x14, 1)) != DH_I2C_OK) return status; break; + case 3: - if( (status = pcf8574_hd44780_write_byte(sda, scl, 0x80 | 0x54, 1)) - != DH_I2C_OK) + if ((status = hd44780_write_byte(sda, scl, 0x80 | 0x54, 1)) != DH_I2C_OK) return status; break; + default: - break; + return DH_I2C_WRONG_PARAMETERS; } + return DH_I2C_OK; } -DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const char *text, unsigned int len) { - DH_I2C_Status status; - int i; - const static char init_data[] = { - 0b00101100, // function set - 0b00001100, // display on - 0b00000001, // cursor clear - 0b00000110 // entry mode set - }; +/* + * pcf8574_hd44780_write() implementation. + */ +int ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const char *text, int len) +{ // clear enable - if((status = pcf8574_set(sda, scl, ~((char)(PIN_E | PIN_RW)))) != DH_I2C_OK) + int status; + if ((status = pcf8574_set(sda, scl, ~((uint8_t)(PIN_E | PIN_RW)))) != DH_I2C_OK) return status; // initialization - for(i = 0; i < 3; i++) { - if((status = pcf8574_hd44780_write_half(sda, scl, 0b0011, 1)) != DH_I2C_OK) + int i; + for (i = 0; i < 3; i++) { + if ((status = hd44780_write_half(sda, scl, 0b0011, 1)) != DH_I2C_OK) return status; os_delay_us(5000); } - if((status = pcf8574_hd44780_write_half(sda, scl, 0b0010, 1)) != DH_I2C_OK) + if ((status = hd44780_write_half(sda, scl, 0b0010, 1)) != DH_I2C_OK) return status; os_delay_us(100); // configure - for(i = 0; i < sizeof(init_data); i++) { - if((status = pcf8574_hd44780_write_byte(sda, scl, init_data[i], 1)) != DH_I2C_OK) + const static uint8_t init_data[] = { + 0b00101100, // function set + 0b00001100, // display on + 0b00000001, // cursor clear + 0b00000110 // entry mode set + }; + for (i = 0; i < sizeof(init_data); i++) { + if ((status = hd44780_write_byte(sda, scl, init_data[i], 1)) != DH_I2C_OK) return status; os_delay_us(2000); } @@ -112,24 +135,24 @@ DH_I2C_Status ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const ch int line = 0; int ch = 0; // write text to display RAM - for(i = 0; i < len; i++) { - int nla = text[i] == '\n'; - int nlc = (i + 1 < len) ? (text[i] == '\\' && text[i + 1] == 'n') : 0; - if(ch == 20 || nla || nlc) { + for (i = 0; i < len; i++) { + int nla = (text[i] == '\n'); + int nlc = (i+1 < len) ? (text[i] == '\\' && text[i+1] == 'n') : 0; + if (ch == 20 || nla || nlc) { line++; - if(ch == 20 && (nla || nlc)) + if (ch == 20 && (nla || nlc)) line++; - if(line > 3) + if (line > 3) break; - if((status = pcf8574_hd44780_set_line(sda, scl, line)) != DH_I2C_OK) + if ((status = hd44780_set_line(sda, scl, line)) != DH_I2C_OK) return status; ch = 0; - if(nlc) + if (nlc) i++; - if(nla || nlc) + if (nla || nlc) continue; } - if((status = pcf8574_hd44780_write_byte(sda, scl, text[i], 0)) != DH_I2C_OK) + if ((status = hd44780_write_byte(sda, scl, text[i], 0)) != DH_I2C_OK) return status; ch++; } diff --git a/firmware-src/sources/devices/pcf8574_hd44780.h b/firmware-src/sources/devices/pcf8574_hd44780.h index a29f8cd..6501da3 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.h +++ b/firmware-src/sources/devices/pcf8574_hd44780.h @@ -1,25 +1,25 @@ /** - * \file pcf8574_hd44780.h - * \brief Simple communication with HD44780 like displays via PCF8574 GPIO extender with I2C bus. - * \author Nikolay Khabarov - * \date 2016 - * \copyright DeviceHive MIT + * @file + * @brief Simple communication with HD44780 like displays via PCF8574 GPIO extender with I2C bus. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov */ +#ifndef _DEVICES_PCF8574_HD44780_H_ +#define _DEVICES_PCF8574_HD44780_H_ -#ifndef SOURCES_DEVICES_PCF8574_HD44780_H_ -#define SOURCES_DEVICES_PCF8574_HD44780_H_ - -#include "DH/i2c.h" +#include /** - * \brief Set text on screen. - * \details Old text will be erased. '\n'(0x0A) char is supported. - * \param[in] sda Pin for I2C's SDA. Use PCF8574_NO_PIN to prevent initialization. - * \param[in] scl Pin for I2C's SCL. Use PCF8574_NO_PIN to prevent initialization. - * \param[in] text Chars to write on display. - * \param[in] len Number of chars to write. Data more then 80 bytes is ignored. - * \return NULL on success, text description on error. + * @brief Set text on screen. + * + * Old text will be erased. '\n'(0x0A) char is supported. + * + * @param[in] sda Pin for I2C's SDA. Use DH_I2C_NO_PIN to prevent initialization. + * @param[in] scl Pin for I2C's SCL. Use DH_I2C_NO_PIN to prevent initialization. + * @param[in] text Chars to write on display. + * @param[in] len Number of chars to write. Data more then 80 bytes is ignored. + * @return Status value, one of DH_I2C_Status enum. */ -DH_I2C_Status pcf8574_hd44780_write(int sda, int scl, const char *text, unsigned int len); +int pcf8574_hd44780_write(int sda, int scl, const char *text, int len); -#endif /* SOURCES_DEVICES_PCF8574_HD44780_H_ */ +#endif /* _DEVICES_PCF8574_HD44780_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 019e42e..5b524eb 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -10,6 +10,14 @@ */ #include "dhcommands.h" #include "dhsender_queue.h" +#include "DH/adc.h" +#include "dhnotification.h" +#include "snprintf.h" +#include "dhcommand_parser.h" +#include "dhterminal.h" +#include "dhdebug.h" +#include "dhutils.h" +#include "devices/dht.h" #include "commands/gpio_cmd.h" #include "commands/adc_cmd.h" #include "commands/uart_cmd.h" @@ -19,22 +27,14 @@ #include "commands/onewire_cmd.h" #include "commands/ws2812b_cmd.h" #include "commands/dht_cmd.h" -#include "DH/adc.h" -#include "dhnotification.h" -#include "snprintf.h" -#include "dhcommand_parser.h" -#include "dhterminal.h" -#include "dhdebug.h" -#include "dhutils.h" #include "commands/ds18b20_cmd.h" -#include "devices/dht.h" #include "commands/bmp180_cmd.h" #include "commands/bmp280_cmd.h" #include "commands/bh1750_cmd.h" #include "commands/mpu6050_cmd.h" #include "commands/hmc5883l_cmd.h" -#include "devices/pcf8574.h" -#include "devices/pcf8574_hd44780.h" +#include "commands/pcf8574_cmd.h" +#include "commands/pcf8574_hd44780_cmd.h" #include "commands/mhz19_cmd.h" #include "commands/lm75_cmd.h" #include "commands/si7021_cmd.h" @@ -57,111 +57,6 @@ #if 1 // devices commands -/** - * @brief Do "devices/pcf8574/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_pcf8574_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - if(paramslen) { - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, PCF8574_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_PULLUP, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_ADDRESS) - pcf8574_set_address(parse_pins.address); - } - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - if(fields & AF_PULLUP) { - const char *res = dh_i2c_error_string(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, parse_pins.pins_to_pullup, 0)); - if (res != 0) { - dh_command_fail(cb, res); - return; - } - } - unsigned int pins; - const char *res = dh_i2c_error_string(pcf8574_read(PCF8574_NO_PIN, PCF8574_NO_PIN, &pins)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - cb->callback(cb->data, DHSTATUS_OK, RDT_GPIO, 0, pins, system_get_time(), PCF8574_SUITABLE_PINS); - } -} - -/** - * @brief Do "devices/pcf8574/write" command. - */ -static void ICACHE_FLASH_ATTR do_devices_pcf8574_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, PCF8574_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_SET | AF_CLEAR, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } else if( (fields & (AF_SET | AF_CLEAR)) == 0) { - dh_command_fail(cb, "Dummy request"); - return; - } else if( (parse_pins.pins_to_set | parse_pins.pins_to_clear | PCF8574_SUITABLE_PINS) - != PCF8574_SUITABLE_PINS ) { - dh_command_fail(cb, "Unsuitable pin"); - return; - } - if(fields & AF_ADDRESS) - pcf8574_set_address(parse_pins.address); - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - const char *res = dh_i2c_error_string(pcf8574_write(PCF8574_NO_PIN, PCF8574_NO_PIN, - parse_pins.pins_to_set, parse_pins.pins_to_clear)); - if(res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - -/** - * @brief Do "devices/pcf8574/hd44780/write" command. - */ -static void ICACHE_FLASH_ATTR do_devices_pcf8574_hd44780_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, PCF8574_SUITABLE_PINS, 0, - AF_SDA | AF_SCL | AF_ADDRESS | AF_DATA | AF_TEXT_DATA, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if((fields & (AF_DATA | AF_TEXT_DATA)) == 0 || parse_pins.data_len == 0) { - dh_command_fail(cb, "Text not specified"); - return; - } - if(fields & AF_ADDRESS) - pcf8574_set_address(parse_pins.address); - fields |= AF_ADDRESS; - if(dh_i2c_init_helper(cb, fields, &parse_pins)) - return; - const char *res = dh_i2c_error_string(pcf8574_hd44780_write(PCF8574_NO_PIN, PCF8574_NO_PIN, - parse_pins.data, parse_pins.data_len)); - if (res != 0) { - dh_command_fail(cb, res); - } else { - dh_command_done(cb, ""); - } -} - - /** * @brief Do "devices/mfrc522/read" command. */ @@ -344,9 +239,9 @@ RO_DATA struct { { "devices/bh1750/read", dh_handle_devices_bh1750_read}, { "devices/mpu6050/read", dh_handle_devices_mpu6050_read}, { "devices/hmc5883l/read", dh_handle_devices_hmc5883l_read}, - { "devices/pcf8574/read", do_devices_pcf8574_read}, - { "devices/pcf8574/write", do_devices_pcf8574_write}, - { "devices/pcf8574/hd44780/write", do_devices_pcf8574_hd44780_write}, + { "devices/pcf8574/read", dh_handle_devices_pcf8574_read}, + { "devices/pcf8574/write", dh_handle_devices_pcf8574_write}, + { "devices/pcf8574/hd44780/write", dh_handle_devices_pcf8574_hd44780_write}, { "devices/mhz19/read", dh_handle_devices_mhz19_read}, { "devices/lm75/read", dh_handle_devices_lm75_read}, { "devices/si7021/read", dh_handle_devices_si7021_read}, From eaaa68bf4f76d0bc7800ee072d230073eeef6099 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 2 May 2017 17:20:47 +0300 Subject: [PATCH 51/83] review MFRC522 commands --- firmware-src/sources/commands/mfrc522_cmd.c | 147 +++++++++++++++++++ firmware-src/sources/commands/mfrc522_cmd.h | 25 ++++ firmware-src/sources/dhcommands.c | 154 ++------------------ 3 files changed, 181 insertions(+), 145 deletions(-) create mode 100644 firmware-src/sources/commands/mfrc522_cmd.c create mode 100644 firmware-src/sources/commands/mfrc522_cmd.h diff --git a/firmware-src/sources/commands/mfrc522_cmd.c b/firmware-src/sources/commands/mfrc522_cmd.c new file mode 100644 index 0000000..b4ab1da --- /dev/null +++ b/firmware-src/sources/commands/mfrc522_cmd.c @@ -0,0 +1,147 @@ +/** + * @file + * @brief MFRC522 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#include "commands/mfrc522_cmd.h" +#include "devices/mfrc522.h" +#include "DH/adc.h" + +#include "dhcommand_parser.h" +#include +#include +#include + + +/** + * @brief Do "devices/mfrc522/read" command. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_mfrc522_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + if (params_len) { + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_CS) { + if (MFRC522_Set_CS(info.CS) != MFRC522_STATUS_OK) { + dh_command_fail(cmd_res, "Unsuitable pin"); + return; // FAILED + } + } + } + + MFRC522_PCD_Init(); + uint8_t bufferATQA[2]; + uint8_t bufferSize = sizeof(bufferATQA); + MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); + if (result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { + MFRC522_Uid *uid = MFRC522_Get_Uid(); + result = MFRC522_PICC_Select(uid, 0); + if (result == MFRC522_STATUS_OK) { + char hexbuf[uid->size * 2 + 1]; + unsigned int i; + for (i = 0; i < uid->size; i++) + byteToHex(uid->uidByte[i], &hexbuf[i * 2]); + hexbuf[sizeof(hexbuf) - 1] = 0; + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + "{\"uid\":\"0x%s\", \"type\":\"%s\"}", hexbuf, + MFRC522_PICC_GetTypeName(MFRC522_PICC_GetType(uid->sak))); + MFRC522_PCD_AntennaOff(); + return; + } + } + + MFRC522_PICC_HaltA(); + MFRC522_PCD_AntennaOff(); + dh_command_fail(cmd_res, MFRC522_GetStatusCodeName(result)); +} + + +/** + * @brief Do "devices/mfrc522/mifare/read" and "devices/mfrc522/mifare/write" commands. + */ +void ICACHE_FLASH_ATTR dh_handle_devices_mfrc522_mifare_read_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + gpio_command_params info; + ALLOWED_FIELDS fields = 0; + const int is_write = (0 != os_strcmp(command, "devices/mfrc522/mifare/read")); + const char *err_msg = parse_params_pins_set(params, params_len, + &info, DH_ADC_SUITABLE_PINS, 0, + AF_CS | AF_ADDRESS | AF_KEY | (is_write ? AF_DATA : 0), &fields); + if (err_msg != 0) { + dh_command_fail(cmd_res, err_msg); + return; // FAILED + } + if (fields & AF_CS) { + if (MFRC522_Set_CS(info.CS) != MFRC522_STATUS_OK) { + dh_command_fail(cmd_res, "Unsuitable pin"); + return; // FAILED + } + } + if ((fields & AF_ADDRESS) == 0) { + dh_command_fail(cmd_res, "Block address not specified"); + return; // FAILED + } + if ((fields & AF_KEY) == 0) { + // default key + os_memset(info.storage.key.key_data, 0xFF, MF_KEY_SIZE); + info.storage.key.key_len = MF_KEY_SIZE; + } else if(info.storage.key.key_len != MF_KEY_SIZE) { + dh_command_fail(cmd_res, "Wrong key length"); + return; // FAILED + } + if (is_write) { + if((fields & AF_DATA) == 0) { + dh_command_fail(cmd_res, "Data not specified"); + return; // FAILED + } else if(info.data_len != 16) { + dh_command_fail(cmd_res, "Data length should be 16 bytes"); + return; // FAILED + } + } + + MFRC522_PCD_Init(); + uint8_t bufferATQA[2]; + uint8_t bufferSize = sizeof(bufferATQA); + MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); + if (result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { + MFRC522_Uid *uid = MFRC522_Get_Uid(); + result = MFRC522_PICC_Select(uid, 0); + MIFARE_Key key; + os_memcpy(key.keyByte, info.storage.key.key_data, MF_KEY_SIZE); + if (result == MFRC522_STATUS_OK) { + result = MFRC522_PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, info.address, &key, uid); + if (result == MFRC522_STATUS_OK) { + uint8_t len = (sizeof(info.data) > 0xFF) ? 0xFF : sizeof(info.data); + if (is_write) + result = MFRC522_MIFARE_Write(info.address, (uint8_t*)info.data, info.data_len); + else + result = MFRC522_MIFARE_Read(info.address, (uint8_t*)info.data, &len); + if (result == MFRC522_STATUS_OK) { + info.count = len; + if (is_write) + dh_command_done(cmd_res, ""); + else + dh_command_done_buf(cmd_res, info.data, info.count); + MFRC522_PICC_HaltA(); + MFRC522_PCD_StopCrypto1(); + MFRC522_PCD_AntennaOff(); + return; + } + } + } + } + + MFRC522_PICC_HaltA(); + MFRC522_PCD_StopCrypto1(); + MFRC522_PCD_AntennaOff(); + dh_command_fail(cmd_res, MFRC522_GetStatusCodeName(result)); +} diff --git a/firmware-src/sources/commands/mfrc522_cmd.h b/firmware-src/sources/commands/mfrc522_cmd.h new file mode 100644 index 0000000..4eef05b --- /dev/null +++ b/firmware-src/sources/commands/mfrc522_cmd.h @@ -0,0 +1,25 @@ +/** + * @file + * @brief MFRC522 command handlers. + * @copyright 2016 [DeviceHive](http://devicehive.com) + * @author Nikolay Khabarov + */ +#ifndef _COMMANDS_MFRC522_CMD_H_ +#define _COMMANDS_MFRC522_CMD_H_ + +#include "dhsender_data.h" + +/** + * @brief Handle "devices/mfrc522/read" command. + */ +void dh_handle_devices_mfrc522_read(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + +/** + * @brief Handle "devices/mfrc522/mifare/read" and "devices/mfrc522/mifare/write" commands. + */ +void dh_handle_devices_mfrc522_mifare_read_write(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + +#endif /* _COMMANDS_MFRC522_CMD_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index 5b524eb..f7e24d1 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -9,15 +9,8 @@ * */ #include "dhcommands.h" -#include "dhsender_queue.h" -#include "DH/adc.h" -#include "dhnotification.h" -#include "snprintf.h" -#include "dhcommand_parser.h" -#include "dhterminal.h" #include "dhdebug.h" -#include "dhutils.h" -#include "devices/dht.h" + #include "commands/gpio_cmd.h" #include "commands/adc_cmd.h" #include "commands/uart_cmd.h" @@ -42,148 +35,17 @@ #include "commands/pcf8591_cmd.h" #include "commands/mcp4725_cmd.h" #include "commands/ina219_cmd.h" -#include "devices/mfrc522.h" +#include "commands/mfrc522_cmd.h" #include "commands/pca9685_cmd.h" #include "commands/mlx90614_cmd.h" #include "commands/max6675_cmd.h" #include "commands/max31855_cmd.h" #include "commands/tm1637_cmd.h" -#include #include -#include #include #include -#if 1 // devices commands - -/** - * @brief Do "devices/mfrc522/read" command. - */ -static void ICACHE_FLASH_ATTR do_devices_mfrc522_read(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - if(paramslen) { - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, AF_CS, &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_CS) { - if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { - dh_command_fail(cb, "Unsuitable pin"); - return; - } - } - } - MFRC522_PCD_Init(); - uint8_t bufferATQA[2]; - uint8_t bufferSize = sizeof(bufferATQA); - MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); - if(result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { - MFRC522_Uid *uid = MFRC522_Get_Uid(); - result = MFRC522_PICC_Select(uid, 0); - if(result == MFRC522_STATUS_OK) { - char hexbuf[uid->size * 2 + 1]; - unsigned int i; - for(i = 0; i < uid->size; i++) - byteToHex(uid->uidByte[i], &hexbuf[i * 2]); - hexbuf[sizeof(hexbuf) - 1] = 0; - cb->callback(cb->data, DHSTATUS_OK, RDT_FORMAT_STRING, - "{\"uid\":\"0x%s\", \"type\":\"%s\"}", hexbuf, - MFRC522_PICC_GetTypeName(MFRC522_PICC_GetType(uid->sak))); - MFRC522_PCD_AntennaOff(); - return; - } - } - MFRC522_PICC_HaltA(); - MFRC522_PCD_AntennaOff(); - dh_command_fail(cb, MFRC522_GetStatusCodeName(result)); -} - -/** - * @brief Do "devices/mfrc522/mifare/read" and "devices/mfrc522/mifare/write" commands. - */ -static void ICACHE_FLASH_ATTR do_devices_mfrc522_mifare_read_write(COMMAND_RESULT *cb, const char *command, const char *params, unsigned int paramslen) -{ - gpio_command_params parse_pins; - ALLOWED_FIELDS fields = 0; - const int check = os_strcmp(command, "devices/mfrc522/mifare/read"); - char *parse_res = parse_params_pins_set(params, paramslen, - &parse_pins, DH_ADC_SUITABLE_PINS, 0, - AF_CS | AF_ADDRESS | AF_KEY | (check ? AF_DATA : 0), &fields); - if (parse_res != 0) { - dh_command_fail(cb, parse_res); - return; - } - if(fields & AF_CS) { - if(MFRC522_Set_CS(parse_pins.CS) != MFRC522_STATUS_OK) { - dh_command_fail(cb, "Unsuitable pin"); - return; - } - } - if((fields & AF_ADDRESS) == 0) { - dh_command_fail(cb, "Block address not specified"); - return; - } - if((fields & AF_KEY) == 0) { - // default key - os_memset(parse_pins.storage.key.key_data, 0xFF, MF_KEY_SIZE); - parse_pins.storage.key.key_len = MF_KEY_SIZE; - } else if(parse_pins.storage.key.key_len != MF_KEY_SIZE) { - dh_command_fail(cb, "Wrong key length"); - return; - } - if(check) { - if((fields & AF_DATA) == 0) { - dh_command_fail(cb, "Data not specified"); - return; - } else if(parse_pins.data_len != 16) { - dh_command_fail(cb, "Data length should be 16 bytes"); - return; - } - } - MFRC522_PCD_Init(); - uint8_t bufferATQA[2]; - uint8_t bufferSize = sizeof(bufferATQA); - MFRC522_StatusCode result = MFRC522_PICC_RequestA(bufferATQA, &bufferSize); - if(result == MFRC522_STATUS_OK || result == MFRC522_STATUS_COLLISION) { - MFRC522_Uid *uid = MFRC522_Get_Uid(); - result = MFRC522_PICC_Select(uid, 0); - MIFARE_Key key; - os_memcpy(key.keyByte, parse_pins.storage.key.key_data, MF_KEY_SIZE); - if(result == MFRC522_STATUS_OK) { - result = MFRC522_PCD_Authenticate(PICC_CMD_MF_AUTH_KEY_A, parse_pins.address, &key, uid); - if(result == MFRC522_STATUS_OK) { - uint8_t len = (sizeof(parse_pins.data) > 0xFF) ? 0xFF : sizeof(parse_pins.data); - if(check) - result = MFRC522_MIFARE_Write(parse_pins.address, (uint8_t*)parse_pins.data, parse_pins.data_len); - else - result = MFRC522_MIFARE_Read(parse_pins.address, (uint8_t*)parse_pins.data, &len); - if(result == MFRC522_STATUS_OK) { - parse_pins.count = len; - if(check) - dh_command_done(cb, ""); - else - dh_command_done_buf(cb, parse_pins.data, parse_pins.count); - MFRC522_PICC_HaltA(); - MFRC522_PCD_StopCrypto1(); - MFRC522_PCD_AntennaOff(); - return; - } - } - } - } - MFRC522_PICC_HaltA(); - MFRC522_PCD_StopCrypto1(); - MFRC522_PCD_AntennaOff(); - dh_command_fail(cb, MFRC522_GetStatusCodeName(result)); -} - -#endif // devices commands - RO_DATA struct { const char *name; void (*func)(COMMAND_RESULT*, const char*, const char*, unsigned int); @@ -250,14 +112,16 @@ RO_DATA struct { { "devices/pcf8591/write", dh_handle_devices_pcf8591_write}, { "devices/mcp4725/write", dh_handle_devices_mcp4725_write}, { "devices/ina219/read", dh_handle_devices_ina219_read}, - { "devices/mfrc522/read", do_devices_mfrc522_read}, - { "devices/mfrc522/mifare/read", do_devices_mfrc522_mifare_read_write}, - { "devices/mfrc522/mifare/write", do_devices_mfrc522_mifare_read_write}, + { "devices/mfrc522/read", dh_handle_devices_mfrc522_read}, + { "devices/mfrc522/mifare/read", dh_handle_devices_mfrc522_mifare_read_write}, + { "devices/mfrc522/mifare/write", dh_handle_devices_mfrc522_mifare_read_write}, { "devices/pca9685/control", dh_handle_devices_pca9685_control}, { "devices/mlx90614/read", dh_handle_devices_mlx90614_read}, { "devices/max6675/read", dh_handle_devices_max6675_read}, { "devices/max31855/read", dh_handle_devices_max31855_read}, - { "devices/tm1637/write", dh_handle_devices_tm1637_write} + { "devices/tm1637/write", dh_handle_devices_tm1637_write}, + + { "-", 0 } // END }; @@ -272,7 +136,7 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co dhdebug("Got command: %s %d", command, cb->data.id); for (i = 0; i < NUM_OF_COMMANDS; ++i) { - if (0 == os_strcmp(command, g_command_table[i].name)) { + if (0 == os_strcmp(command, g_command_table[i].name) && g_command_table[i].func) { g_command_table[i].func(cb, command, params, paramslen); return; // done } From 125126ecfa060d494cb2f7ccab2476a292caec84 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Tue, 2 May 2017 18:43:12 +0300 Subject: [PATCH 52/83] introduce feature macro for each device and corresponding commands. see user_config.h file. --- firmware-src/sources/commands/adc_cmd.h | 3 +- firmware-src/sources/commands/ads1115_cmd.c | 3 + firmware-src/sources/commands/ads1115_cmd.h | 3 + firmware-src/sources/commands/bh1750_cmd.c | 4 + firmware-src/sources/commands/bh1750_cmd.h | 3 + firmware-src/sources/commands/bmp180_cmd.c | 3 + firmware-src/sources/commands/bmp180_cmd.h | 3 + firmware-src/sources/commands/bmp280_cmd.c | 3 + firmware-src/sources/commands/bmp280_cmd.h | 3 + firmware-src/sources/commands/dht_cmd.c | 10 +++ firmware-src/sources/commands/dht_cmd.h | 7 ++ firmware-src/sources/commands/ds18b20_cmd.c | 3 + firmware-src/sources/commands/ds18b20_cmd.h | 3 + firmware-src/sources/commands/gpio_cmd.h | 3 +- firmware-src/sources/commands/hmc5883l_cmd.c | 4 + firmware-src/sources/commands/hmc5883l_cmd.h | 3 + firmware-src/sources/commands/i2c_cmd.h | 3 +- firmware-src/sources/commands/ina219_cmd.c | 4 + firmware-src/sources/commands/ina219_cmd.h | 3 + firmware-src/sources/commands/lm75_cmd.c | 4 + firmware-src/sources/commands/lm75_cmd.h | 3 + firmware-src/sources/commands/max31855_cmd.c | 3 + firmware-src/sources/commands/max31855_cmd.h | 2 + firmware-src/sources/commands/max6675_cmd.c | 3 + firmware-src/sources/commands/max6675_cmd.h | 2 + firmware-src/sources/commands/mcp4725_cmd.c | 3 + firmware-src/sources/commands/mcp4725_cmd.h | 3 + firmware-src/sources/commands/mfrc522_cmd.c | 3 + firmware-src/sources/commands/mfrc522_cmd.h | 3 + firmware-src/sources/commands/mhz19_cmd.c | 3 + firmware-src/sources/commands/mhz19_cmd.h | 3 + firmware-src/sources/commands/mlx90614_cmd.c | 4 + firmware-src/sources/commands/mlx90614_cmd.h | 3 + firmware-src/sources/commands/mpu6050_cmd.c | 4 + firmware-src/sources/commands/mpu6050_cmd.h | 3 + firmware-src/sources/commands/onewire_cmd.h | 3 +- firmware-src/sources/commands/pca9685_cmd.c | 4 + firmware-src/sources/commands/pca9685_cmd.h | 3 + firmware-src/sources/commands/pcf8574_cmd.c | 4 + firmware-src/sources/commands/pcf8574_cmd.h | 3 + .../sources/commands/pcf8574_hd44780_cmd.c | 3 + .../sources/commands/pcf8574_hd44780_cmd.h | 3 + firmware-src/sources/commands/pcf8591_cmd.c | 4 + firmware-src/sources/commands/pcf8591_cmd.h | 3 + firmware-src/sources/commands/pwm_cmd.h | 3 +- firmware-src/sources/commands/si7021_cmd.c | 4 + firmware-src/sources/commands/si7021_cmd.h | 3 + firmware-src/sources/commands/spi_cmd.h | 3 +- firmware-src/sources/commands/tm1637_cmd.c | 4 + firmware-src/sources/commands/tm1637_cmd.h | 3 + firmware-src/sources/commands/uart_cmd.h | 3 +- firmware-src/sources/commands/ws2812b_cmd.h | 3 +- firmware-src/sources/devices/ads1115.c | 4 + firmware-src/sources/devices/ads1115.h | 4 + firmware-src/sources/devices/bh1750.c | 4 + firmware-src/sources/devices/bh1750.h | 4 +- firmware-src/sources/devices/bmp180.c | 4 + firmware-src/sources/devices/bmp180.h | 4 + firmware-src/sources/devices/bmp280.c | 4 + firmware-src/sources/devices/bmp280.h | 4 + firmware-src/sources/devices/dht.c | 16 ++++ firmware-src/sources/devices/dht.h | 7 ++ firmware-src/sources/devices/ds18b20.c | 3 + firmware-src/sources/devices/ds18b20.h | 4 + firmware-src/sources/devices/hmc5883l.c | 4 + firmware-src/sources/devices/hmc5883l.h | 4 + firmware-src/sources/devices/ina219.c | 4 + firmware-src/sources/devices/ina219.h | 4 + firmware-src/sources/devices/lm75.c | 4 + firmware-src/sources/devices/lm75.h | 4 + firmware-src/sources/devices/max31855.c | 4 + firmware-src/sources/devices/max31855.h | 4 + firmware-src/sources/devices/max6675.c | 4 + firmware-src/sources/devices/max6675.h | 3 + firmware-src/sources/devices/mcp4725.c | 4 + firmware-src/sources/devices/mcp4725.h | 4 + firmware-src/sources/devices/mfrc522.c | 6 +- firmware-src/sources/devices/mfrc522.h | 4 + firmware-src/sources/devices/mhz19.c | 4 + firmware-src/sources/devices/mhz19.h | 4 + firmware-src/sources/devices/mlx90614.c | 4 + firmware-src/sources/devices/mlx90614.h | 4 + firmware-src/sources/devices/mpu6050.c | 4 + firmware-src/sources/devices/mpu6050.h | 4 + firmware-src/sources/devices/pca9685.c | 3 + firmware-src/sources/devices/pca9685.h | 4 + firmware-src/sources/devices/pcf8574.c | 4 + firmware-src/sources/devices/pcf8574.h | 4 + .../sources/devices/pcf8574_hd44780.c | 4 + .../sources/devices/pcf8574_hd44780.h | 4 + firmware-src/sources/devices/pcf8591.c | 4 + firmware-src/sources/devices/pcf8591.h | 4 + firmware-src/sources/devices/si7021.c | 4 + firmware-src/sources/devices/si7021.h | 4 + firmware-src/sources/devices/tm1637.c | 4 + firmware-src/sources/devices/tm1637.h | 4 + firmware-src/sources/dhcommands.c | 82 +++++++++++++++++-- firmware-src/sources/user_config.h | 66 +++++++++++++-- 98 files changed, 481 insertions(+), 33 deletions(-) diff --git a/firmware-src/sources/commands/adc_cmd.h b/firmware-src/sources/commands/adc_cmd.h index 14c172f..d489191 100644 --- a/firmware-src/sources/commands/adc_cmd.h +++ b/firmware-src/sources/commands/adc_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_ADC_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_ADC // ADC command handlers +#if defined(DH_COMMANDS_ADC) // ADC command handlers #include "dhsender_data.h" /** diff --git a/firmware-src/sources/commands/ads1115_cmd.c b/firmware-src/sources/commands/ads1115_cmd.c index 934a82a..f27c06b 100644 --- a/firmware-src/sources/commands/ads1115_cmd.c +++ b/firmware-src/sources/commands/ads1115_cmd.c @@ -13,6 +13,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_ADS1115) && defined(DH_DEVICE_ADS1115) /* * dh_handle_devices_ads1115_read() implementation. @@ -47,3 +48,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ads1115_read(COMMAND_RESULT *cmd_res, c values[0], values[1], values[2], values[3]); } } + +#endif /* DH_COMMANDS_ADS1115 && DH_DEVICE_ADS1115 */ diff --git a/firmware-src/sources/commands/ads1115_cmd.h b/firmware-src/sources/commands/ads1115_cmd.h index 3ae3903..efac74a 100644 --- a/firmware-src/sources/commands/ads1115_cmd.h +++ b/firmware-src/sources/commands/ads1115_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_ADS1115_CMD_H_ #define _COMMANDS_ADS1115_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_ADS1115) && defined(DH_DEVICE_ADS1115) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_ads1115_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_ADS1115 && DH_DEVICE_ADS1115 */ #endif /* _COMMANDS_ADS1115_CMD_H_ */ diff --git a/firmware-src/sources/commands/bh1750_cmd.c b/firmware-src/sources/commands/bh1750_cmd.c index fe3c403..ec7200a 100644 --- a/firmware-src/sources/commands/bh1750_cmd.c +++ b/firmware-src/sources/commands/bh1750_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_BH1750) && defined(DH_DEVICE_BH1750) + /* * dh_handle_devices_bh1750_read() implementation. */ @@ -46,3 +48,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_bh1750_read(COMMAND_RESULT *cmd_res, co cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); } } + +#endif /* DH_COMMANDS_BH1750 && DH_DEVICE_BH1750 */ diff --git a/firmware-src/sources/commands/bh1750_cmd.h b/firmware-src/sources/commands/bh1750_cmd.h index edfd9ca..499d5d6 100644 --- a/firmware-src/sources/commands/bh1750_cmd.h +++ b/firmware-src/sources/commands/bh1750_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_BH1750_CMD_H_ #define _COMMANDS_BH1750_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_BH1750) && defined(DH_DEVICE_BH1750) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_bh1750_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_BH1750 && DH_DEVICE_BH1750 */ #endif /* _COMMANDS_BH1750_CMD_H_ */ diff --git a/firmware-src/sources/commands/bmp180_cmd.c b/firmware-src/sources/commands/bmp180_cmd.c index d35a70d..64ac9b3 100644 --- a/firmware-src/sources/commands/bmp180_cmd.c +++ b/firmware-src/sources/commands/bmp180_cmd.c @@ -13,6 +13,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_BMP180) && defined(DH_DEVICE_BMP180) /* * dh_handle_devices_bmp180_read() implementation. @@ -48,3 +49,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_bmp180_read(COMMAND_RESULT *cmd_res, co cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); } } + +#endif /* DH_COMMANDS_BMP180 && DH_DEVICE_BMP180 */ diff --git a/firmware-src/sources/commands/bmp180_cmd.h b/firmware-src/sources/commands/bmp180_cmd.h index 033f024..a165bbe 100644 --- a/firmware-src/sources/commands/bmp180_cmd.h +++ b/firmware-src/sources/commands/bmp180_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_BMP180_CMD_H_ #define _COMMANDS_BMP180_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_BMP180) && defined(DH_DEVICE_BMP180) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_bmp180_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_BMP180 && DH_DEVICE_BMP180 */ #endif /* _COMMANDS_BMP180_CMD_H_ */ diff --git a/firmware-src/sources/commands/bmp280_cmd.c b/firmware-src/sources/commands/bmp280_cmd.c index ca21b4f..0170531 100644 --- a/firmware-src/sources/commands/bmp280_cmd.c +++ b/firmware-src/sources/commands/bmp280_cmd.c @@ -13,6 +13,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_BMP280) && defined(DH_DEVICE_BMP280) /* * dh_handle_devices_bmp280_read() implementation. @@ -48,3 +49,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_bmp280_read(COMMAND_RESULT *cmd_res, co cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); } } + +#endif /* DH_COMMANDS_BMP280 && DH_DEVICE_BMP280 */ diff --git a/firmware-src/sources/commands/bmp280_cmd.h b/firmware-src/sources/commands/bmp280_cmd.h index 4a188a8..5e1bb86 100644 --- a/firmware-src/sources/commands/bmp280_cmd.h +++ b/firmware-src/sources/commands/bmp280_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_BMP280_CMD_H_ #define _COMMANDS_BMP280_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_BMP280) && defined(DH_DEVICE_BMP280) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_bmp280_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_BMP280 && DH_DEVICE_BMP280 */ #endif /* _COMMANDS_BMP280_CMD_H_ */ diff --git a/firmware-src/sources/commands/dht_cmd.c b/firmware-src/sources/commands/dht_cmd.c index b1e1d9f..a5d2bc6 100644 --- a/firmware-src/sources/commands/dht_cmd.c +++ b/firmware-src/sources/commands/dht_cmd.c @@ -13,6 +13,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_ONEWIRE) /* * dh_handle_onewire_dht_read() implementation. @@ -40,8 +41,11 @@ void ICACHE_FLASH_ATTR dh_handle_onewire_dht_read(COMMAND_RESULT *cmd_res, const dh_command_fail(cmd_res, "No response"); } +#endif /* DH_COMMANDS_ONEWIRE */ +#if defined(DH_COMMANDS_DHT11) && defined(DH_DEVICE_DHT11) + /* * dh_handle_devices_dht11_read() implementation. */ @@ -72,6 +76,10 @@ void ICACHE_FLASH_ATTR dh_handle_devices_dht11_read(COMMAND_RESULT *cmd_res, con } } +#endif /* DH_COMMANDS_DHT11 && DH_DEVICE_DHT11 */ + + +#if defined(DH_COMMANDS_DHT22) && defined(DH_DEVICE_DHT22) /* * dh_handle_devices_dht22_read() implementation. @@ -102,3 +110,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_dht22_read(COMMAND_RESULT *cmd_res, con "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); } } + +#endif /* DH_COMMANDS_DHT22 || DH_DEVICE_DHT22 */ diff --git a/firmware-src/sources/commands/dht_cmd.h b/firmware-src/sources/commands/dht_cmd.h index 20a1d16..9201107 100644 --- a/firmware-src/sources/commands/dht_cmd.h +++ b/firmware-src/sources/commands/dht_cmd.h @@ -7,26 +7,33 @@ #ifndef _COMMANDS_DHT_CMD_H_ #define _COMMANDS_DHT_CMD_H_ +#include "user_config.h" #include "dhsender_data.h" +#if defined(DH_COMMANDS_ONEWIRE) /** * @brief Handle "onewire/dht/read" command. */ void dh_handle_onewire_dht_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_ONEWIRE */ +#if defined(DH_COMMANDS_DHT11) && defined(DH_DEVICE_DHT11) /** * @brief Handle "devices/dht11/read" command. */ void ICACHE_FLASH_ATTR dh_handle_devices_dht11_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_DHT11 && DH_DEVICE_DHT11 */ +#if defined(DH_COMMANDS_DHT22) && defined(DH_DEVICE_DHT22) /** * @brief Handle "devices/dht22/read" command. */ void ICACHE_FLASH_ATTR dh_handle_devices_dht22_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_DHT22 || DH_DEVICE_DHT22 */ #endif /* _COMMANDS_DHT_CMD_H_ */ diff --git a/firmware-src/sources/commands/ds18b20_cmd.c b/firmware-src/sources/commands/ds18b20_cmd.c index cb00699..9b2f2ec 100644 --- a/firmware-src/sources/commands/ds18b20_cmd.c +++ b/firmware-src/sources/commands/ds18b20_cmd.c @@ -13,6 +13,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_DS18B20) && defined(DH_DEVICE_DS18B20) /* * dh_handle_devices_ds18b20_read() implementation. @@ -41,3 +42,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ds18b20_read(COMMAND_RESULT *cmd_res, c cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); } } + +#endif /* DH_COMMANDS_DS18B20 && DH_DEVICE_DS18B20 */ diff --git a/firmware-src/sources/commands/ds18b20_cmd.h b/firmware-src/sources/commands/ds18b20_cmd.h index 789701c..e8d7ea9 100644 --- a/firmware-src/sources/commands/ds18b20_cmd.h +++ b/firmware-src/sources/commands/ds18b20_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_DS18B20_CMD_H_ #define _COMMANDS_DS18B20_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_DS18B20) && defined(DH_DEVICE_DS18B20) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_ds18b20_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_DS18B20 && DH_DEVICE_DS18B20 */ #endif /* _COMMANDS_DS18B20_CMD_H_ */ diff --git a/firmware-src/sources/commands/gpio_cmd.h b/firmware-src/sources/commands/gpio_cmd.h index 5a1f818..9091202 100644 --- a/firmware-src/sources/commands/gpio_cmd.h +++ b/firmware-src/sources/commands/gpio_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_GPIO_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_GPIO // GPIO command handlers +#if defined(DH_COMMANDS_GPIO) // GPIO command handlers #include "dhsender_data.h" /** diff --git a/firmware-src/sources/commands/hmc5883l_cmd.c b/firmware-src/sources/commands/hmc5883l_cmd.c index 5a40737..8b93589 100644 --- a/firmware-src/sources/commands/hmc5883l_cmd.c +++ b/firmware-src/sources/commands/hmc5883l_cmd.c @@ -14,6 +14,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_HMC5883L) && defined(DH_DEVICE_HMC5883L) + /* * dh_handle_devices_hmc5883l_read() implementation. */ @@ -60,3 +62,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_hmc5883l_read(COMMAND_RESULT *cmd_res, "{\"magnetometer\":{\"X\":%s, \"Y\":%s, \"Z\":%s}}", floatbufx, floatbufy, floatbufz); } + +#endif /* DH_COMMANDS_HMC5883L && DH_DEVICE_HMC5883L */ diff --git a/firmware-src/sources/commands/hmc5883l_cmd.h b/firmware-src/sources/commands/hmc5883l_cmd.h index 3fbb31d..d03f7e4 100644 --- a/firmware-src/sources/commands/hmc5883l_cmd.h +++ b/firmware-src/sources/commands/hmc5883l_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_HMC5883L_CMD_H_ #define _COMMANDS_HMC5883L_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_HMC5883L) && defined(DH_DEVICE_HMC5883L) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_hmc5883l_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_HMC5883L && DH_DEVICE_HMC5883L */ #endif /* _COMMANDS_HMC5883L_CMD_H_ */ diff --git a/firmware-src/sources/commands/i2c_cmd.h b/firmware-src/sources/commands/i2c_cmd.h index a6eebfa..4083adf 100644 --- a/firmware-src/sources/commands/i2c_cmd.h +++ b/firmware-src/sources/commands/i2c_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_I2C_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_I2C // I2C command handlers +#if defined(DH_COMMANDS_I2C) // I2C command handlers #include "dhcommand_parser.h" #include "dhsender_data.h" diff --git a/firmware-src/sources/commands/ina219_cmd.c b/firmware-src/sources/commands/ina219_cmd.c index 5a02f5a..556edae 100644 --- a/firmware-src/sources/commands/ina219_cmd.c +++ b/firmware-src/sources/commands/ina219_cmd.c @@ -14,6 +14,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_INA219) && defined(DH_DEVICE_INA219) + /* * dh_handle_devices_ina219_read() implementation. */ @@ -60,3 +62,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ina219_read(COMMAND_RESULT *cmd_res, co voltage, current, power); } } + +#endif /* DH_COMMANDS_INA219 && DH_DEVICE_INA219 */ diff --git a/firmware-src/sources/commands/ina219_cmd.h b/firmware-src/sources/commands/ina219_cmd.h index 8c03800..811560c 100644 --- a/firmware-src/sources/commands/ina219_cmd.h +++ b/firmware-src/sources/commands/ina219_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_INA219_CMD_H_ #define _COMMANDS_INA219_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_INA219) && defined(DH_DEVICE_INA219) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_ina219_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_INA219 && DH_DEVICE_INA219 */ #endif /* _COMMANDS_INA219_CMD_H_ */ diff --git a/firmware-src/sources/commands/lm75_cmd.c b/firmware-src/sources/commands/lm75_cmd.c index 5e7f52a..a72ce22 100644 --- a/firmware-src/sources/commands/lm75_cmd.c +++ b/firmware-src/sources/commands/lm75_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_LM75) && defined(DH_DEVICE_LM75) + /* * dh_handle_devices_lm75_read() implementation. */ @@ -47,3 +49,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_lm75_read(COMMAND_RESULT *cmd_res, cons "{\"temperature\":%f}", temperature); } } + +#endif /* DH_COMMANDS_LM75 && DH_DEVICE_LM75 */ diff --git a/firmware-src/sources/commands/lm75_cmd.h b/firmware-src/sources/commands/lm75_cmd.h index 3d3715d..258e868 100644 --- a/firmware-src/sources/commands/lm75_cmd.h +++ b/firmware-src/sources/commands/lm75_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_LM75_CMD_H_ #define _COMMANDS_LM75_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_LM75) && defined(DH_DEVICE_LM75) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_lm75_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_LM75 && DH_DEVICE_LM75 */ #endif /* _COMMANDS_LM75_CMD_H_ */ diff --git a/firmware-src/sources/commands/max31855_cmd.c b/firmware-src/sources/commands/max31855_cmd.c index 9098d11..6fbfb01 100644 --- a/firmware-src/sources/commands/max31855_cmd.c +++ b/firmware-src/sources/commands/max31855_cmd.c @@ -12,6 +12,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_MAX31855) && defined(DH_DEVICE_MAX31855) /* * dh_handle_devices_max31855_read() implementation. @@ -39,3 +40,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_max31855_read(COMMAND_RESULT *cmd_res, "{\"temperature\":%f}", temperature); } } + +#endif /* DH_COMMANDS_MAX31855 && DH_DEVICE_MAX31855 */ diff --git a/firmware-src/sources/commands/max31855_cmd.h b/firmware-src/sources/commands/max31855_cmd.h index a879270..26f9727 100644 --- a/firmware-src/sources/commands/max31855_cmd.h +++ b/firmware-src/sources/commands/max31855_cmd.h @@ -8,6 +8,7 @@ #define _COMMANDS_MAX31855_CMD_H_ #include "user_config.h" +#if defined(DH_COMMANDS_MAX31855) && defined(DH_DEVICE_MAX31855) #include "dhsender_data.h" /** @@ -16,4 +17,5 @@ void dh_handle_devices_max31855_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MAX31855 && DH_DEVICE_MAX31855 */ #endif /* _COMMANDS_MAX31855_CMD_H_ */ diff --git a/firmware-src/sources/commands/max6675_cmd.c b/firmware-src/sources/commands/max6675_cmd.c index 52eb551..8d14290 100644 --- a/firmware-src/sources/commands/max6675_cmd.c +++ b/firmware-src/sources/commands/max6675_cmd.c @@ -12,6 +12,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_MAX6675) && defined(DH_DEVICE_MAX6675) /* * dh_handle_devices_max6675_read() implementation. @@ -39,3 +40,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_max6675_read(COMMAND_RESULT *cmd_res, c "{\"temperature\":%f}", temperature); } } + +#endif /* DH_COMMANDS_MAX6675 && DH_DEVICE_MAX6675 */ diff --git a/firmware-src/sources/commands/max6675_cmd.h b/firmware-src/sources/commands/max6675_cmd.h index d8110e7..1def83d 100644 --- a/firmware-src/sources/commands/max6675_cmd.h +++ b/firmware-src/sources/commands/max6675_cmd.h @@ -8,6 +8,7 @@ #define _COMMANDS_MAX6675_CMD_H_ #include "user_config.h" +#if defined(DH_COMMANDS_MAX6675) && defined(DH_DEVICE_MAX6675) #include "dhsender_data.h" /** @@ -16,4 +17,5 @@ void dh_handle_devices_max6675_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MAX6675 && DH_DEVICE_MAX6675 */ #endif /* _COMMANDS_MAX6675_CMD_H_ */ diff --git a/firmware-src/sources/commands/mcp4725_cmd.c b/firmware-src/sources/commands/mcp4725_cmd.c index bbc135a..a902a16 100644 --- a/firmware-src/sources/commands/mcp4725_cmd.c +++ b/firmware-src/sources/commands/mcp4725_cmd.c @@ -13,6 +13,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_MCP4725) && defined(DH_DEVICE_MCP4725) /* * dh_handle_devices_mcp4725_read() implementation. @@ -56,3 +57,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mcp4725_write(COMMAND_RESULT *cmd_res, dh_command_done(cmd_res, ""); } } + +#endif /* DH_COMMANDS_MCP4725 && DH_DEVICE_MCP4725 */ diff --git a/firmware-src/sources/commands/mcp4725_cmd.h b/firmware-src/sources/commands/mcp4725_cmd.h index eb83d9e..e0208ee 100644 --- a/firmware-src/sources/commands/mcp4725_cmd.h +++ b/firmware-src/sources/commands/mcp4725_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_MCP4725_CMD_H_ #define _COMMANDS_MCP4725_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_MCP4725) && defined(DH_DEVICE_MCP4725) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_mcp4725_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MCP4725 && DH_DEVICE_MCP4725 */ #endif /* _COMMANDS_MCP4725_CMD_H_ */ diff --git a/firmware-src/sources/commands/mfrc522_cmd.c b/firmware-src/sources/commands/mfrc522_cmd.c index b4ab1da..41e8098 100644 --- a/firmware-src/sources/commands/mfrc522_cmd.c +++ b/firmware-src/sources/commands/mfrc522_cmd.c @@ -13,6 +13,7 @@ #include #include +#if defined(DH_COMMANDS_MFRC522) && defined(DH_DEVICE_MFRC522) /** * @brief Do "devices/mfrc522/read" command. @@ -145,3 +146,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mfrc522_mifare_read_write(COMMAND_RESUL MFRC522_PCD_AntennaOff(); dh_command_fail(cmd_res, MFRC522_GetStatusCodeName(result)); } + +#endif /* DH_COMMANDS_MFRC522 && DH_DEVICE_MFRC522 */ diff --git a/firmware-src/sources/commands/mfrc522_cmd.h b/firmware-src/sources/commands/mfrc522_cmd.h index 4eef05b..e209828 100644 --- a/firmware-src/sources/commands/mfrc522_cmd.h +++ b/firmware-src/sources/commands/mfrc522_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_MFRC522_CMD_H_ #define _COMMANDS_MFRC522_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_MFRC522) && defined(DH_DEVICE_MFRC522) #include "dhsender_data.h" /** @@ -22,4 +24,5 @@ void dh_handle_devices_mfrc522_read(COMMAND_RESULT *cmd_res, const char *command void dh_handle_devices_mfrc522_mifare_read_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MFRC522 && DH_DEVICE_MFRC522 */ #endif /* _COMMANDS_MFRC522_CMD_H_ */ diff --git a/firmware-src/sources/commands/mhz19_cmd.c b/firmware-src/sources/commands/mhz19_cmd.c index 6842139..31dc65d 100644 --- a/firmware-src/sources/commands/mhz19_cmd.c +++ b/firmware-src/sources/commands/mhz19_cmd.c @@ -10,6 +10,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_MHZ19) && defined(DH_DEVICE_MHZ19) /* * dh_handle_devices_mhz19_read() implementation. @@ -31,3 +32,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mhz19_read(COMMAND_RESULT *cmd_res, con RDT_FORMAT_STRING, "{\"co2\":%d}", co2); } } + +#endif /* DH_COMMANDS_MHZ19 && DH_DEVICE_MHZ19 */ diff --git a/firmware-src/sources/commands/mhz19_cmd.h b/firmware-src/sources/commands/mhz19_cmd.h index 0d07ec7..3701a8f 100644 --- a/firmware-src/sources/commands/mhz19_cmd.h +++ b/firmware-src/sources/commands/mhz19_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_MHZ19_CMD_H_ #define _COMMANDS_MHZ19_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_MHZ19) && defined(DH_DEVICE_MHZ19) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_mhz19_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MHZ19 && DH_DEVICE_MHZ19 */ #endif /* _COMMANDS_MHZ19_CMD_H_ */ diff --git a/firmware-src/sources/commands/mlx90614_cmd.c b/firmware-src/sources/commands/mlx90614_cmd.c index 3172b22..487ddb6 100644 --- a/firmware-src/sources/commands/mlx90614_cmd.c +++ b/firmware-src/sources/commands/mlx90614_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_MLX90614) && defined(DH_DEVICE_MLX90614) + /* * dh_handle_devices_mlx90614_read() implementation. */ @@ -47,3 +49,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mlx90614_read(COMMAND_RESULT *cmd_res, "{\"ambient\":%f, \"object\":%f}", ambient, object); } } + +#endif /* DH_COMMANDS_MLX90614 && DH_DEVICE_MLX90614 */ diff --git a/firmware-src/sources/commands/mlx90614_cmd.h b/firmware-src/sources/commands/mlx90614_cmd.h index 4984637..c64f06f 100644 --- a/firmware-src/sources/commands/mlx90614_cmd.h +++ b/firmware-src/sources/commands/mlx90614_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_MLX90614_CMD_H_ #define _COMMANDS_MLX90614_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_MLX90614) && defined(DH_DEVICE_MLX90614) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_mlx90614_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MLX90614 && DH_DEVICE_MLX90614 */ #endif /* _COMMANDS_MLX90614_CMD_H_ */ diff --git a/firmware-src/sources/commands/mpu6050_cmd.c b/firmware-src/sources/commands/mpu6050_cmd.c index f05d171..dd101cd 100644 --- a/firmware-src/sources/commands/mpu6050_cmd.c +++ b/firmware-src/sources/commands/mpu6050_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_MPU6050) && defined(DH_DEVICE_MPU6050) + /* * dh_handle_devices_mpu6050_read() implementation. */ @@ -50,3 +52,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mpu6050_read(COMMAND_RESULT *cmd_res, c temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); } } + +#endif /* DH_COMMANDS_MPU6050 && DH_DEVICE_MPU6050 */ diff --git a/firmware-src/sources/commands/mpu6050_cmd.h b/firmware-src/sources/commands/mpu6050_cmd.h index 1b13dea..5ec1b49 100644 --- a/firmware-src/sources/commands/mpu6050_cmd.h +++ b/firmware-src/sources/commands/mpu6050_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_MPU6050_CMD_H_ #define _COMMANDS_MPU6050_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_MPU6050) && defined(DH_DEVICE_MPU6050) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_mpu6050_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_MPU6050 && DH_DEVICE_MPU6050 */ #endif /* _COMMANDS_MPU6050_CMD_H_ */ diff --git a/firmware-src/sources/commands/onewire_cmd.h b/firmware-src/sources/commands/onewire_cmd.h index b403fa5..0bf891e 100644 --- a/firmware-src/sources/commands/onewire_cmd.h +++ b/firmware-src/sources/commands/onewire_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_ONEWIRE_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_ONEWIRE // onewire command handlers +#if defined(DH_COMMANDS_ONEWIRE) // onewire command handlers #include "dhsender_data.h" #include "dhcommand_parser.h" diff --git a/firmware-src/sources/commands/pca9685_cmd.c b/firmware-src/sources/commands/pca9685_cmd.c index 4a1ebac..9883e9e 100644 --- a/firmware-src/sources/commands/pca9685_cmd.c +++ b/firmware-src/sources/commands/pca9685_cmd.c @@ -12,6 +12,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_PCA9685) && defined(DH_DEVICE_PCA9685) + /* * dh_handle_devices_pca9685_control() implementation. */ @@ -44,3 +46,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_pca9685_control(COMMAND_RESULT *cmd_res dh_command_done(cmd_res, ""); } } + +#endif /* DH_COMMANDS_PCA9685 && DH_DEVICE_PCA9685 */ diff --git a/firmware-src/sources/commands/pca9685_cmd.h b/firmware-src/sources/commands/pca9685_cmd.h index f21f932..9e7ab72 100644 --- a/firmware-src/sources/commands/pca9685_cmd.h +++ b/firmware-src/sources/commands/pca9685_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_PCA9685_CMD_H_ #define _COMMANDS_PCA9685_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_PCA9685) && defined(DH_DEVICE_PCA9685) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_pca9685_control(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_PCA9685 && DH_DEVICE_PCA9685 */ #endif /* _COMMANDS_PCA9685_CMD_H_ */ diff --git a/firmware-src/sources/commands/pcf8574_cmd.c b/firmware-src/sources/commands/pcf8574_cmd.c index 816ac56..9b291a1 100644 --- a/firmware-src/sources/commands/pcf8574_cmd.c +++ b/firmware-src/sources/commands/pcf8574_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_PCF8574) && defined(DH_DEVICE_PCF8574) + /* * dh_handle_devices_pcf8574_read() implementation. */ @@ -96,3 +98,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_pcf8574_write(COMMAND_RESULT *cmd_res, dh_command_done(cmd_res, ""); } } + +#endif /* DH_COMMANDS_PCF8574 && DH_DEVICE_PCF8574 */ diff --git a/firmware-src/sources/commands/pcf8574_cmd.h b/firmware-src/sources/commands/pcf8574_cmd.h index cb17905..57b60a6 100644 --- a/firmware-src/sources/commands/pcf8574_cmd.h +++ b/firmware-src/sources/commands/pcf8574_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_PCF8574_CMD_H_ #define _COMMANDS_PCF8574_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_PCF8574) && defined(DH_DEVICE_PCF8574) #include "dhsender_data.h" /** @@ -22,4 +24,5 @@ void dh_handle_devices_pcf8574_read(COMMAND_RESULT *cmd_res, const char *command void dh_handle_devices_pcf8574_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_PCF8574 && DH_DEVICE_PCF8574 */ #endif /* _COMMANDS_PCF8574_CMD_H_ */ diff --git a/firmware-src/sources/commands/pcf8574_hd44780_cmd.c b/firmware-src/sources/commands/pcf8574_hd44780_cmd.c index 006c332..cd9ed49 100644 --- a/firmware-src/sources/commands/pcf8574_hd44780_cmd.c +++ b/firmware-src/sources/commands/pcf8574_hd44780_cmd.c @@ -14,6 +14,7 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_PCF8574_HD44780) && defined(DH_DEVICE_PCF8574_HD44780) /* * dh_handle_devices_pcf8574_hd44780_write() implementation. @@ -51,3 +52,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_pcf8574_hd44780_write(COMMAND_RESULT *c dh_command_done(cmd_res, ""); } } + +#endif /* DH_COMMANDS_PCF8574_HD44780 && DH_DEVICE_PCF8574_HD44780 */ diff --git a/firmware-src/sources/commands/pcf8574_hd44780_cmd.h b/firmware-src/sources/commands/pcf8574_hd44780_cmd.h index def5871..50840af 100644 --- a/firmware-src/sources/commands/pcf8574_hd44780_cmd.h +++ b/firmware-src/sources/commands/pcf8574_hd44780_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_PCF8574_HD44780_CMD_H_ #define _COMMANDS_PCF8574_HD44780_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_PCF8574_HD44780) && defined(DH_DEVICE_PCF8574_HD44780) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_pcf8574_hd44780_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_PCF8574_HD44780 && DH_DEVICE_PCF8574_HD44780 */ #endif /* _COMMANDS_PCF8574_HD44780_CMD_H_ */ diff --git a/firmware-src/sources/commands/pcf8591_cmd.c b/firmware-src/sources/commands/pcf8591_cmd.c index 80bbdd0..d896160 100644 --- a/firmware-src/sources/commands/pcf8591_cmd.c +++ b/firmware-src/sources/commands/pcf8591_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_PCF8591) && defined(DH_DEVICE_PCF8591) + /* * dh_handle_devices_pcf8591_read() implementation. */ @@ -102,3 +104,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_pcf8591_write(COMMAND_RESULT *cmd_res, dh_command_done(cmd_res, ""); } } + +#endif /* DH_COMMANDS_PCF8591 && DH_DEVICE_PCF8591 */ diff --git a/firmware-src/sources/commands/pcf8591_cmd.h b/firmware-src/sources/commands/pcf8591_cmd.h index 5453858..1c0b2ff 100644 --- a/firmware-src/sources/commands/pcf8591_cmd.h +++ b/firmware-src/sources/commands/pcf8591_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_PCF8591_CMD_H_ #define _COMMANDS_PCF8591_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_PCF8591) && defined(DH_DEVICE_PCF8591) #include "dhsender_data.h" /** @@ -22,4 +24,5 @@ void dh_handle_devices_pcf8591_read(COMMAND_RESULT *cmd_res, const char *command void dh_handle_devices_pcf8591_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_PCF8591 && DH_DEVICE_PCF8591 */ #endif /* _COMMANDS_PCF8591_CMD_H_ */ diff --git a/firmware-src/sources/commands/pwm_cmd.h b/firmware-src/sources/commands/pwm_cmd.h index 025ae76..014c9bf 100644 --- a/firmware-src/sources/commands/pwm_cmd.h +++ b/firmware-src/sources/commands/pwm_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_PWM_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_PWM // PWM command handlers +#if defined(DH_COMMANDS_PWM) // PWM command handlers #include "dhsender_data.h" /** diff --git a/firmware-src/sources/commands/si7021_cmd.c b/firmware-src/sources/commands/si7021_cmd.c index a7036fc..8371362 100644 --- a/firmware-src/sources/commands/si7021_cmd.c +++ b/firmware-src/sources/commands/si7021_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_SI7021) && defined(DH_DEVICE_SI7021) + /* * dh_handle_devices_si7021_read() implementation. */ @@ -47,3 +49,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_si7021_read(COMMAND_RESULT *cmd_res, co "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); } } + +#endif /* DH_COMMANDS_SI7021 && DH_DEVICE_SI7021 */ diff --git a/firmware-src/sources/commands/si7021_cmd.h b/firmware-src/sources/commands/si7021_cmd.h index cbad828..b5fdd33 100644 --- a/firmware-src/sources/commands/si7021_cmd.h +++ b/firmware-src/sources/commands/si7021_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_SI7021_CMD_H_ #define _COMMANDS_SI7021_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_SI7021) && defined(DH_DEVICE_SI7021) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_si7021_read(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_SI7021 && DH_DEVICE_SI7021 */ #endif /* _COMMANDS_SI7021_CMD_H_ */ diff --git a/firmware-src/sources/commands/spi_cmd.h b/firmware-src/sources/commands/spi_cmd.h index 2c49c30..80aef66 100644 --- a/firmware-src/sources/commands/spi_cmd.h +++ b/firmware-src/sources/commands/spi_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_SPI_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_SPI // SPI command handlers +#if defined(DH_COMMANDS_SPI) // SPI command handlers #include "dhsender_data.h" /** diff --git a/firmware-src/sources/commands/tm1637_cmd.c b/firmware-src/sources/commands/tm1637_cmd.c index 3ed9b7b..621c905 100644 --- a/firmware-src/sources/commands/tm1637_cmd.c +++ b/firmware-src/sources/commands/tm1637_cmd.c @@ -13,6 +13,8 @@ #include "dhcommand_parser.h" #include +#if defined(DH_COMMANDS_TM1637) && defined(DH_DEVICE_TM1637) + /* * dh_handle_devices_tm1637_write() implementation. */ @@ -45,3 +47,5 @@ void ICACHE_FLASH_ATTR dh_handle_devices_tm1637_write(COMMAND_RESULT *cmd_res, c dh_command_done(cmd_res, ""); } } + +#endif /* DH_COMMANDS_TM1637 && DH_DEVICE_TM1637 */ diff --git a/firmware-src/sources/commands/tm1637_cmd.h b/firmware-src/sources/commands/tm1637_cmd.h index 85a35fd..8f51b74 100644 --- a/firmware-src/sources/commands/tm1637_cmd.h +++ b/firmware-src/sources/commands/tm1637_cmd.h @@ -7,6 +7,8 @@ #ifndef _COMMANDS_TM1637_CMD_H_ #define _COMMANDS_TM1637_CMD_H_ +#include "user_config.h" +#if defined(DH_COMMANDS_TM1637) && defined(DH_DEVICE_TM1637) #include "dhsender_data.h" /** @@ -15,4 +17,5 @@ void dh_handle_devices_tm1637_write(COMMAND_RESULT *cmd_res, const char *command, const char *params, unsigned int params_len); +#endif /* DH_COMMANDS_TM1637 && DH_DEVICE_TM1637 */ #endif /* _COMMANDS_TM1637_CMD_H_ */ diff --git a/firmware-src/sources/commands/uart_cmd.h b/firmware-src/sources/commands/uart_cmd.h index 8df83ef..6ef2f57 100644 --- a/firmware-src/sources/commands/uart_cmd.h +++ b/firmware-src/sources/commands/uart_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_UART_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_UART // UART command handlers +#if defined(DH_COMMANDS_UART) // UART command handlers #include "dhsender_data.h" /** diff --git a/firmware-src/sources/commands/ws2812b_cmd.h b/firmware-src/sources/commands/ws2812b_cmd.h index f47085e..5dc15e1 100644 --- a/firmware-src/sources/commands/ws2812b_cmd.h +++ b/firmware-src/sources/commands/ws2812b_cmd.h @@ -8,8 +8,7 @@ #define _COMMANDS_WS2812B_CMD_H_ #include "user_config.h" - -#ifdef DH_COMMANDS_ONEWIRE // onewire WS2812B command handlers +#if defined(DH_COMMANDS_ONEWIRE) // onewire WS2812B command handlers #include "dhsender_data.h" #include "dhcommand_parser.h" diff --git a/firmware-src/sources/devices/ads1115.c b/firmware-src/sources/devices/ads1115.c index bb0e0d0..cdf728d 100644 --- a/firmware-src/sources/devices/ads1115.c +++ b/firmware-src/sources/devices/ads1115.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_ADS1115) + /** Default sensor i2c address*/ #define ADS1115_DEFAULT_ADDRESS 0x90 @@ -76,3 +78,5 @@ void ICACHE_FLASH_ATTR ads1115_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_ADS1115 */ diff --git a/firmware-src/sources/devices/ads1115.h b/firmware-src/sources/devices/ads1115.h index 009a8b1..02d88cd 100644 --- a/firmware-src/sources/devices/ads1115.h +++ b/firmware-src/sources/devices/ads1115.h @@ -7,6 +7,9 @@ #ifndef _SOURCES_DEVICES_ADS1115_H_ #define _SOURCES_DEVICES_ADS1115_H_ +#include "user_config.h" +#if defined(DH_DEVICE_ADS1115) + /** * @brief Get ADC voltages. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -23,4 +26,5 @@ int ads1115_read(int sda, int scl, float values[4]); */ void ads1115_set_address(int address); +#endif /* DH_DEVICE_ADS1115 */ #endif /* _SOURCES_DEVICES_ADS1115_H_ */ diff --git a/firmware-src/sources/devices/bh1750.c b/firmware-src/sources/devices/bh1750.c index 56bf5d6..27ddcca 100644 --- a/firmware-src/sources/devices/bh1750.c +++ b/firmware-src/sources/devices/bh1750.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_BH1750) + /** Default sensor i2c address*/ #define BH1750_DEFAULT_ADDRESS 0x46 @@ -56,3 +58,5 @@ void ICACHE_FLASH_ATTR bh1750_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_BH1750 */ diff --git a/firmware-src/sources/devices/bh1750.h b/firmware-src/sources/devices/bh1750.h index e11a19b..ad901ab 100644 --- a/firmware-src/sources/devices/bh1750.h +++ b/firmware-src/sources/devices/bh1750.h @@ -7,6 +7,8 @@ #ifndef _DEVICES_BH1750_H_ #define _DEVICES_BH1750_H_ +#include "user_config.h" +#if defined(DH_DEVICE_BH1750) /** * @brief Measure illuminance one time. @@ -24,5 +26,5 @@ int bh1750_read(int sda, int scl, float illuminance[1]); */ void bh1750_set_address(int address); - +#endif /* DH_DEVICE_BH1750 */ #endif /* _DEVICES_BH1750_H_ */ diff --git a/firmware-src/sources/devices/bmp180.c b/firmware-src/sources/devices/bmp180.c index 74e9d69..4e9a48d 100644 --- a/firmware-src/sources/devices/bmp180.c +++ b/firmware-src/sources/devices/bmp180.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_BMP180) + /** @brief Default sensor i2c address*/ #define BMP180_DEFAULT_ADDRESS 0xEE @@ -128,3 +130,5 @@ void ICACHE_FLASH_ATTR bmp180_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_BMP180 */ diff --git a/firmware-src/sources/devices/bmp180.h b/firmware-src/sources/devices/bmp180.h index 51f42c6..4fced8d 100644 --- a/firmware-src/sources/devices/bmp180.h +++ b/firmware-src/sources/devices/bmp180.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_BMP180_H_ #define _DEVICES_BMP180_H_ +#include "user_config.h" +#if defined(DH_DEVICE_BMP180) + /** * @brief Measure pressure one time. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -26,4 +29,5 @@ int bmp180_read(int sda, int scl, */ void bmp180_set_address(int address); +#endif /* DH_DEVICE_BMP180 */ #endif /* _DEVICES_BMP180_H_ */ diff --git a/firmware-src/sources/devices/bmp280.c b/firmware-src/sources/devices/bmp280.c index 0e711d7..2fbc567 100644 --- a/firmware-src/sources/devices/bmp280.c +++ b/firmware-src/sources/devices/bmp280.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_BMP280) + /** @brief Default sensor i2c address*/ #define BMP280_DEFAULT_ADDRESS 0xEC @@ -137,3 +139,5 @@ void ICACHE_FLASH_ATTR bmp280_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_BMP280 */ diff --git a/firmware-src/sources/devices/bmp280.h b/firmware-src/sources/devices/bmp280.h index 3e3316a..2bf732f 100644 --- a/firmware-src/sources/devices/bmp280.h +++ b/firmware-src/sources/devices/bmp280.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_BMP280_H_ #define _DEVICES_BMP280_H_ +#include "user_config.h" +#if defined(DH_DEVICE_BMP280) + /** * @brief Measure pressure one time. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -26,4 +29,5 @@ int bmp280_read(int sda, int scl, */ void bmp280_set_address(int address); +#endif /* DH_DEVICE_BMP280 */ #endif /* _DEVICES_BMP280_H_ */ diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 9ca74da..10c116a 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -20,6 +20,8 @@ #define DHT_RESET_LENGTH_US 25000 #define DHT_TIMEOUT_US 200 +#if defined(DH_DEVICE_DHT11) || defined(DH_DEVICE_DHT22) + /** * @brief Read DHT packet of 5 bytes. */ @@ -43,6 +45,10 @@ static const char* ICACHE_FLASH_ATTR dht_read_pkt(int pin, uint8_t buf[DHT_PACKE return 0; // OK } +#endif /* DH_DEVICE_DHT11 || DH_DEVICE_DHT22 */ + + +#if defined(DH_DEVICE_DHT11) /* * dht11_read() implementation. @@ -61,6 +67,10 @@ const char* ICACHE_FLASH_ATTR dht11_read(int pin, int *humidity, int *temperatur return NULL; // OK } +#endif /* DH_DEVICE_DHT11 */ + + +#if defined(DH_DEVICE_DHT22) /* * dht22_read() implementation. @@ -79,6 +89,10 @@ const char* ICACHE_FLASH_ATTR dht22_read(int pin, float *humidity, float *temper return NULL; // OK } +#endif /* DH_DEVICE_DHT22 */ + + +#if defined(DH_COMMANDS_ONEWIRE) /** * @brief Measure high-level interval. @@ -138,3 +152,5 @@ int ICACHE_FLASH_ATTR dht_read(void *buf_, size_t len) ETS_INTR_UNLOCK(); return i/8; } + +#endif /* DH_COMMANDS_ONEWIRE */ diff --git a/firmware-src/sources/devices/dht.h b/firmware-src/sources/devices/dht.h index 4cf2ea2..4dec9ac 100644 --- a/firmware-src/sources/devices/dht.h +++ b/firmware-src/sources/devices/dht.h @@ -7,8 +7,10 @@ #ifndef _DEVICES_DHT_H_ #define _DEVICES_DHT_H_ +#include "user_config.h" #include +#if defined(DH_DEVICE_DHT11) /** * @brief Measure relative humidity with DHT11 sensor one time. * @param[in] pin 1-wire pin for communication. Can be DH_ONEWIRE_NO_PIN. @@ -17,8 +19,10 @@ * @return NULL on success, text description on error. */ const char* dht11_read(int pin, int *humidity, int *temperature); +#endif /* DH_DEVICE_DHT11 */ +#if defined(DH_DEVICE_DHT22) /** * @brief Measure relative humidity with DHT22 sensor one time. * @param[in] pin 1-wire pin for communication. Can be DH_ONEWIRE_NO_PIN. @@ -27,8 +31,10 @@ const char* dht11_read(int pin, int *humidity, int *temperature); * @return NULL on success, text description on error. */ const char* dht22_read(int pin, float *humidity, float *temperature); +#endif /* DH_DEVICE_DHT22 */ +#if defined(DH_COMMANDS_ONEWIRE) /** * @brief Read data from DHT like devices. * @@ -40,4 +46,5 @@ const char* dht22_read(int pin, float *humidity, float *temperature); */ int dht_read(void *buf, size_t len); +#endif /* DH_COMMANDS_ONEWIRE */ #endif /* _DEVICES_DHT_H_ */ diff --git a/firmware-src/sources/devices/ds18b20.c b/firmware-src/sources/devices/ds18b20.c index d658618..91e812b 100644 --- a/firmware-src/sources/devices/ds18b20.c +++ b/firmware-src/sources/devices/ds18b20.c @@ -10,6 +10,7 @@ #include +#if defined(DH_DEVICE_DS18B20) /* * ds18b20_read() implementation. @@ -45,3 +46,5 @@ const char* ICACHE_FLASH_ATTR ds18b20_read(int pin, float *temperature) return NULL; // OK } + +#endif /* DH_DEVICE_DS18B20 */ diff --git a/firmware-src/sources/devices/ds18b20.h b/firmware-src/sources/devices/ds18b20.h index f953ac2..5aff885 100644 --- a/firmware-src/sources/devices/ds18b20.h +++ b/firmware-src/sources/devices/ds18b20.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_DS18B20_H_ #define _DEVICES_DS18B20_H_ +#include "user_config.h" +#if defined(DH_DEVICE_DS18B20) + /** * @brief Measure temperature one time. * @param[in] pin 1-wire pin for communication. Can be DH_ONEWIRE_NO_PIN. @@ -15,4 +18,5 @@ */ const char* ds18b20_read(int pin, float *temperature); +#endif /* DH_DEVICE_DS18B20 */ #endif /* _DEVICES_DS18B20_H_ */ diff --git a/firmware-src/sources/devices/hmc5883l.c b/firmware-src/sources/devices/hmc5883l.c index a2f53e9..a21ecab 100644 --- a/firmware-src/sources/devices/hmc5883l.c +++ b/firmware-src/sources/devices/hmc5883l.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_HMC5883L) + /** @brief Default sensor i2c address*/ #define HMC5883L_DEFAULT_ADDRESS 0x3C @@ -72,3 +74,5 @@ void ICACHE_FLASH_ATTR hmc5883l_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_HMC5883L */ diff --git a/firmware-src/sources/devices/hmc5883l.h b/firmware-src/sources/devices/hmc5883l.h index c8d8555..e083d86 100644 --- a/firmware-src/sources/devices/hmc5883l.h +++ b/firmware-src/sources/devices/hmc5883l.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_HMC5883L_H_ #define _DEVICES_HMC5883L_H_ +#include "user_config.h" +#if defined(DH_DEVICE_HMC5883L) + /** Measurements in three dimensions. */ typedef struct { float X; ///< @brief X axis. @@ -35,4 +38,5 @@ int hmc5883l_read(int sda, int scl, HMC5883L_XYZ *compass); */ void hmc5883l_set_address(int address); +#endif /* DH_DEVICE_HMC5883L */ #endif /* _DEVICES_HMC5883L_H_ */ diff --git a/firmware-src/sources/devices/ina219.c b/firmware-src/sources/devices/ina219.c index 1cba490..d736143 100644 --- a/firmware-src/sources/devices/ina219.c +++ b/firmware-src/sources/devices/ina219.c @@ -12,6 +12,8 @@ #include #include +#if defined(DH_DEVICE_INA219) + /** @brief Default sensor i2c address*/ #define INA219_DEFAULT_ADDRESS 0x80 @@ -88,3 +90,5 @@ int ICACHE_FLASH_ATTR ina219_set_shunt(float resistance) mResistance = resistance; return DH_I2C_OK; } + +#endif /* DH_DEVICE_INA219 */ diff --git a/firmware-src/sources/devices/ina219.h b/firmware-src/sources/devices/ina219.h index ac7a2ce..effd00d 100644 --- a/firmware-src/sources/devices/ina219.h +++ b/firmware-src/sources/devices/ina219.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_INA219_H_ #define _DEVICES_INA219_H_ +#include "user_config.h" +#if defined(DH_DEVICE_INA219) + /** * @brief Get measurements. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -35,4 +38,5 @@ void ina219_set_address(int address); */ int ina219_set_shunt(float resistance); +#endif /* DH_DEVICE_INA219 */ #endif /* _DEVICES_INA219_H_ */ diff --git a/firmware-src/sources/devices/lm75.c b/firmware-src/sources/devices/lm75.c index ada4bd2..5a72126 100644 --- a/firmware-src/sources/devices/lm75.c +++ b/firmware-src/sources/devices/lm75.c @@ -12,6 +12,8 @@ #include #include +#if defined(DH_DEVICE_LM75) + /** @brief Default sensor i2c address*/ #define LM75_DEFAULT_ADDRESS 0x90 @@ -56,3 +58,5 @@ void ICACHE_FLASH_ATTR lm75_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_LM75 */ diff --git a/firmware-src/sources/devices/lm75.h b/firmware-src/sources/devices/lm75.h index 8d82380..609f06f 100644 --- a/firmware-src/sources/devices/lm75.h +++ b/firmware-src/sources/devices/lm75.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_LM75_H_ #define _DEVICES_LM75_H_ +#include "user_config.h" +#if defined(DH_DEVICE_LM75) + /** * @brief Measure temperature one time. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -23,4 +26,5 @@ int lm75_read(int sda, int scl, float *temperature); */ void lm75_set_address(int address); +#endif /* DH_DEVICE_LM75 */ #endif /* _DEVICES_LM75_H_ */ diff --git a/firmware-src/sources/devices/max31855.c b/firmware-src/sources/devices/max31855.c index d9daa73..66ca1b5 100644 --- a/firmware-src/sources/devices/max31855.c +++ b/firmware-src/sources/devices/max31855.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_MAX31855) + // module variables static int mCSPin = 15; @@ -52,3 +54,5 @@ const char* ICACHE_FLASH_ATTR max31855_read(int pin, float *temperature) return NULL; // OK } + +#endif /* DH_DEVICE_MAX31855 */ diff --git a/firmware-src/sources/devices/max31855.h b/firmware-src/sources/devices/max31855.h index 7132c29..797875c 100644 --- a/firmware-src/sources/devices/max31855.h +++ b/firmware-src/sources/devices/max31855.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_MAX31855_H_ #define _DEVICES_MAX31855_H_ +#include "user_config.h" +#if defined(DH_DEVICE_MAX31855) + /** * @brief Measure temperature one time. * @param[in] cs Chip select pin. Can be DH_SPI_NO_PIN to disable CS. @@ -15,4 +18,5 @@ */ const char* max31855_read(int pin, float *temperature); +#endif /* DH_DEVICE_MAX31855 */ #endif /* _DEVICES_MAX31855_H_ */ diff --git a/firmware-src/sources/devices/max6675.c b/firmware-src/sources/devices/max6675.c index 7f2c910..53040e3 100644 --- a/firmware-src/sources/devices/max6675.c +++ b/firmware-src/sources/devices/max6675.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_MAX6675) + // module variables static int mCSPin = 15; @@ -49,3 +51,5 @@ const char* ICACHE_FLASH_ATTR max6675_read(int pin, float *temperature) return NULL; // OK } + +#endif /* DH_DEVICE_MAX6675 */ diff --git a/firmware-src/sources/devices/max6675.h b/firmware-src/sources/devices/max6675.h index 41eb1c3..fb2138a 100644 --- a/firmware-src/sources/devices/max6675.h +++ b/firmware-src/sources/devices/max6675.h @@ -7,6 +7,8 @@ #ifndef _DEVICES_MAX6675_H_ #define _DEVICES_MAX6675_H_ +#include "user_config.h" +#if defined(DH_DEVICE_MAX6675) /** * @brief Measure temperature one time. @@ -16,4 +18,5 @@ */ const char* max6675_read(int pin, float *temperature); +#endif /* DH_DEVICE_MAX6675 */ #endif /* SOURCES_DEVICES_MAX6675_H_ */ diff --git a/firmware-src/sources/devices/mcp4725.c b/firmware-src/sources/devices/mcp4725.c index 8203075..6b9a028 100644 --- a/firmware-src/sources/devices/mcp4725.c +++ b/firmware-src/sources/devices/mcp4725.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_MCP4725) + /** @brief Default sensor i2c address*/ #define MCP4725_DEFAULT_ADDRESS 0xC0 @@ -70,3 +72,5 @@ int ICACHE_FLASH_ATTR mcp4725_set_vref(float voltage) mVoltage = voltage; return DH_I2C_OK; } + +#endif /* DH_DEVICE_MCP4725 */ diff --git a/firmware-src/sources/devices/mcp4725.h b/firmware-src/sources/devices/mcp4725.h index 9c23849..39275f7 100644 --- a/firmware-src/sources/devices/mcp4725.h +++ b/firmware-src/sources/devices/mcp4725.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_MCP4725_H_ #define _DEVICES_MCP4725_H_ +#include "user_config.h" +#if defined(DH_DEVICE_MCP4725) + /** * @brief Set DAC voltages. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -34,4 +37,5 @@ void mcp4725_set_address(int address); */ int mcp4725_set_vref(float voltage); +#endif /* DH_DEVICE_MCP4725 */ #endif /* _DEVICES_MCP4725_H_ */ diff --git a/firmware-src/sources/devices/mfrc522.c b/firmware-src/sources/devices/mfrc522.c index 98ffe75..ffbb02c 100644 --- a/firmware-src/sources/devices/mfrc522.c +++ b/firmware-src/sources/devices/mfrc522.c @@ -4,7 +4,7 @@ * Released into the public domain. */ -#include "mfrc522.h" +#include "devices/mfrc522.h" #include "DH/spi.h" #include "dhdebug.h" #include "snprintf.h" @@ -12,6 +12,8 @@ #include #include +#if defined(DH_DEVICE_MFRC522) + static int _chipSelectPin = 15; // pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low) // Member variables static MFRC522_Uid uid; // Used by MFRC522_PICC_ReadCardSerial(). @@ -1834,3 +1836,5 @@ bool ICACHE_FLASH_ATTR MFRC522_PICC_ReadCardSerial() { MFRC522_StatusCode result = MFRC522_PICC_Select(&uid, 0); return (result == MFRC522_STATUS_OK); } // End + +#endif /* DH_DEVICE_MFRC522 */ diff --git a/firmware-src/sources/devices/mfrc522.h b/firmware-src/sources/devices/mfrc522.h index e758496..8c892c7 100644 --- a/firmware-src/sources/devices/mfrc522.h +++ b/firmware-src/sources/devices/mfrc522.h @@ -76,6 +76,9 @@ #ifndef MFRC522_h #define MFRC522_h +#include "user_config.h" +#if defined(DH_DEVICE_MFRC522) + #include "irom.h" // Firmware data for self-test @@ -401,4 +404,5 @@ bool MFRC522_MIFARE_UnbrickUidSector(bool logErrors); bool MFRC522_PICC_IsNewCardPresent(); bool MFRC522_PICC_ReadCardSerial(); +#endif /* DH_DEVICE_MFRC522 */ #endif diff --git a/firmware-src/sources/devices/mhz19.c b/firmware-src/sources/devices/mhz19.c index 2b6ab7d..135a3ed 100644 --- a/firmware-src/sources/devices/mhz19.c +++ b/firmware-src/sources/devices/mhz19.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_MHZ19) + /* * mhz19_read() implementation. */ @@ -45,3 +47,5 @@ const char* ICACHE_FLASH_ATTR mhz19_read(int *co2) *co2 = unsignedInt16be((const char*)result, 2); return NULL; // OK } + +#endif /* DH_DEVICE_MHZ19 */ diff --git a/firmware-src/sources/devices/mhz19.h b/firmware-src/sources/devices/mhz19.h index 54c5261..cfc9497 100644 --- a/firmware-src/sources/devices/mhz19.h +++ b/firmware-src/sources/devices/mhz19.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_MHZ19_H_ #define _DEVICES_MHZ19_H_ +#include "user_config.h" +#if defined(DH_DEVICE_MHZ19) + /** * @brief Read CO2 sensor value. * @param[out] co2 Pointer to store measure result in ppm(parts-per-million). @@ -14,4 +17,5 @@ */ const char* mhz19_read(int *co2); +#endif /* DH_DEVICE_MHZ19 */ #endif /* _DEVICES_MHZ19_H_ */ diff --git a/firmware-src/sources/devices/mlx90614.c b/firmware-src/sources/devices/mlx90614.c index 5e90d70..8a8281c 100644 --- a/firmware-src/sources/devices/mlx90614.c +++ b/firmware-src/sources/devices/mlx90614.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_MLX90614) + /** @brief Default sensor i2c address*/ #define MLX90614_DEFAULT_ADDRESS 0xB4 @@ -69,3 +71,5 @@ void ICACHE_FLASH_ATTR mlx90614_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_MLX90614 */ diff --git a/firmware-src/sources/devices/mlx90614.h b/firmware-src/sources/devices/mlx90614.h index 7d589b3..84575d0 100644 --- a/firmware-src/sources/devices/mlx90614.h +++ b/firmware-src/sources/devices/mlx90614.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_MLX90614_H_ #define _DEVICES_MLX90614_H_ +#include "user_config.h" +#if defined(DH_DEVICE_MLX90614) + /** * @brief Measure temperature one time. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -24,4 +27,5 @@ int mlx90614_read(int sda, int scl, float *ambient, float *object); */ void mlx90614_set_address(int address); +#endif /* DH_DEVICE_MLX90614 */ #endif /* _DEVICES_MLX90614_H_ */ diff --git a/firmware-src/sources/devices/mpu6050.c b/firmware-src/sources/devices/mpu6050.c index 937cc84..81cbbf3 100644 --- a/firmware-src/sources/devices/mpu6050.c +++ b/firmware-src/sources/devices/mpu6050.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_MPU6050) + /** @brief Default sensor i2c address*/ #define MPU6050_DEFAULT_ADDRESS 0xD0 @@ -99,3 +101,5 @@ void ICACHE_FLASH_ATTR mpu6050_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_MPU6050 */ diff --git a/firmware-src/sources/devices/mpu6050.h b/firmware-src/sources/devices/mpu6050.h index 182ba54..75461e5 100644 --- a/firmware-src/sources/devices/mpu6050.h +++ b/firmware-src/sources/devices/mpu6050.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_MPU6050_H_ #define _DEVICES_MPU6050_H_ +#include "user_config.h" +#if defined(DH_DEVICE_MPU6050) + /** @brief Measurements in three dimensions. */ typedef struct { float X; ///< @brief X axis. @@ -33,4 +36,5 @@ int mpu6050_read(int sda, int scl, MPU6050_XYZ *acceleromter, MPU6050_XYZ *gyros */ void mpu6050_set_address(int address); +#endif /* DH_DEVICE_MPU6050 */ #endif /* _DEVICES_MPU6050_H_ */ diff --git a/firmware-src/sources/devices/pca9685.c b/firmware-src/sources/devices/pca9685.c index 5909fd8..18c6d6a 100644 --- a/firmware-src/sources/devices/pca9685.c +++ b/firmware-src/sources/devices/pca9685.c @@ -11,6 +11,7 @@ #include +#if defined(DH_DEVICE_PCA9685) /** @brief Default i2c address*/ #define PCA9685_DEFAULT_ADDRESS 0x80 @@ -103,3 +104,5 @@ void ICACHE_FLASH_ATTR pca9685_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_PCA9685 */ diff --git a/firmware-src/sources/devices/pca9685.h b/firmware-src/sources/devices/pca9685.h index f23893f..ca89b76 100644 --- a/firmware-src/sources/devices/pca9685.h +++ b/firmware-src/sources/devices/pca9685.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_PCA9685_H_ #define _DEVICES_PCA9685_H_ +#include "user_config.h" +#if defined(DH_DEVICE_PCA9685) + #include "DH/gpio.h" /** @brief Do not change frequency */ @@ -36,4 +39,5 @@ int pca9685_control(int sda, int scl, const float pins_duty[DH_GPIO_PIN_COUNT], */ void pca9685_set_address(int address); +#endif /* DH_DEVICE_PCA9685 */ #endif /* _DEVICES_PCA9685_H_ */ diff --git a/firmware-src/sources/devices/pcf8574.c b/firmware-src/sources/devices/pcf8574.c index 2702fa5..2ac8b52 100644 --- a/firmware-src/sources/devices/pcf8574.c +++ b/firmware-src/sources/devices/pcf8574.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_PCF8574) + /** @brief Default sensor i2c address. */ #define PCF8574_DEFAULT_ADDRESS 0x4E @@ -96,3 +98,5 @@ void ICACHE_FLASH_ATTR pcf8574_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_PCF8574 */ diff --git a/firmware-src/sources/devices/pcf8574.h b/firmware-src/sources/devices/pcf8574.h index 80e3d05..f7c4c75 100644 --- a/firmware-src/sources/devices/pcf8574.h +++ b/firmware-src/sources/devices/pcf8574.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_PCF8574_H_ #define _DEVICES_PCF8574_H_ +#include "user_config.h" +#if defined(DH_DEVICE_PCF8574) + /** @brief Pins which can be used with extender. */ #define PCF8574_SUITABLE_PINS 0b11111111 @@ -51,4 +54,5 @@ int pcf8574_set(int sda, int scl, */ void pcf8574_set_address(int address); +#endif /* DH_DEVICE_PCF8574 */ #endif /* _DEVICES_PCF8574_H_ */ diff --git a/firmware-src/sources/devices/pcf8574_hd44780.c b/firmware-src/sources/devices/pcf8574_hd44780.c index 9f8f080..7213f31 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.c +++ b/firmware-src/sources/devices/pcf8574_hd44780.c @@ -11,6 +11,8 @@ #include #include +#if defined(DH_DEVICE_PCF8574_HD44780) + #define PIN_RS BIT(0) #define PIN_RW BIT(1) #define PIN_E BIT(2) @@ -159,3 +161,5 @@ int ICACHE_FLASH_ATTR pcf8574_hd44780_write(int sda, int scl, const char *text, return DH_I2C_OK; } + +#endif /* DH_DEVICE_PCF8574_HD44780 */ diff --git a/firmware-src/sources/devices/pcf8574_hd44780.h b/firmware-src/sources/devices/pcf8574_hd44780.h index 6501da3..22ebe06 100644 --- a/firmware-src/sources/devices/pcf8574_hd44780.h +++ b/firmware-src/sources/devices/pcf8574_hd44780.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_PCF8574_HD44780_H_ #define _DEVICES_PCF8574_HD44780_H_ +#include "user_config.h" +#if defined(DH_DEVICE_PCF8574_HD44780) + #include /** @@ -22,4 +25,5 @@ */ int pcf8574_hd44780_write(int sda, int scl, const char *text, int len); +#endif /* DH_DEVICE_PCF8574_HD44780 */ #endif /* _DEVICES_PCF8574_HD44780_H_ */ diff --git a/firmware-src/sources/devices/pcf8591.c b/firmware-src/sources/devices/pcf8591.c index 8c5acc6..2463c7b 100644 --- a/firmware-src/sources/devices/pcf8591.c +++ b/firmware-src/sources/devices/pcf8591.c @@ -12,6 +12,8 @@ #include #include +#if defined(DH_DEVICE_PCF8591) + /** @brief Default sensor i2c address. */ #define PCF8591_DEFAULT_ADDRESS 0x90 @@ -110,3 +112,5 @@ int ICACHE_FLASH_ATTR pcf8591_set_vref(float voltage) mVoltage = voltage; return DH_I2C_OK; } + +#endif /* DH_DEVICE_PCF8591 */ diff --git a/firmware-src/sources/devices/pcf8591.h b/firmware-src/sources/devices/pcf8591.h index 570cad1..972ec24 100644 --- a/firmware-src/sources/devices/pcf8591.h +++ b/firmware-src/sources/devices/pcf8591.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_PCF8591_H_ #define _DEVICES_PCF8591_H_ +#include "user_config.h" +#if defined(DH_DEVICE_PCF8591) + /** * @brief Get ADC voltages. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -44,4 +47,5 @@ void pcf8591_set_address(int address); */ int pcf8591_set_vref(float voltage); +#endif /* DH_DEVICE_PCF8591 */ #endif /* _DEVICES_PCF8591_H_ */ diff --git a/firmware-src/sources/devices/si7021.c b/firmware-src/sources/devices/si7021.c index eeac631..3b8be3d 100644 --- a/firmware-src/sources/devices/si7021.c +++ b/firmware-src/sources/devices/si7021.c @@ -11,6 +11,8 @@ #include +#if defined(DH_DEVICE_SI7021) + /** @brief Default sensor i2c address*/ #define SI7021_DEFAULT_ADDRESS 0x80 @@ -67,3 +69,5 @@ void ICACHE_FLASH_ATTR si7021_set_address(int address) { mAddress = address; } + +#endif /* DH_DEVICE_SI7021 */ diff --git a/firmware-src/sources/devices/si7021.h b/firmware-src/sources/devices/si7021.h index a67c56b..62b1ad5 100644 --- a/firmware-src/sources/devices/si7021.h +++ b/firmware-src/sources/devices/si7021.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_SI7021_H_ #define _DEVICES_SI7021_H_ +#include "user_config.h" +#if defined(DH_DEVICE_SI7021) + /** * @brief Measure temperature and relative humidity one time. * @param[in] sda Pin for I2C's SDA. Can be DH_I2C_NO_PIN. @@ -24,4 +27,5 @@ int si7021_read(int sda, int scl, float *humidity, float *temperature); */ void si7021_set_address(int address); +#endif /* DH_DEVICE_SI7021 */ #endif /* _DEVICES_SI7021_H_ */ diff --git a/firmware-src/sources/devices/tm1637.c b/firmware-src/sources/devices/tm1637.c index 64b6611..479f45e 100644 --- a/firmware-src/sources/devices/tm1637.c +++ b/firmware-src/sources/devices/tm1637.c @@ -13,6 +13,8 @@ #include #include +#if defined(DH_DEVICE_TM1637) + // segments table for digits RO_DATA const uint8_t segments_table[] = { 0b11111100, // 0 @@ -96,3 +98,5 @@ int ICACHE_FLASH_ATTR tm1636_write(int sda, int scl, const char *text, size_t le return DH_I2C_OK; } + +#endif /* DH_DEVICE_TM1637 */ diff --git a/firmware-src/sources/devices/tm1637.h b/firmware-src/sources/devices/tm1637.h index ca65459..74e3d30 100644 --- a/firmware-src/sources/devices/tm1637.h +++ b/firmware-src/sources/devices/tm1637.h @@ -7,6 +7,9 @@ #ifndef _DEVICES_TM1637_H_ #define _DEVICES_TM1637_H_ +#include "user_config.h" +#if defined(DH_DEVICE_TM1637) + #include /** @@ -22,4 +25,5 @@ */ int tm1636_write(int sda, int scl, const char *text, size_t len); +#endif /* DH_DEVICE_TM1637 */ #endif /* _DEVICES_TM1637_H_ */ diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index f7e24d1..cca8763 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -51,39 +51,39 @@ RO_DATA struct { void (*func)(COMMAND_RESULT*, const char*, const char*, unsigned int); } g_command_table[] = { -#ifdef DH_COMMANDS_GPIO +#if defined(DH_COMMANDS_GPIO) {"gpio/write", dh_handle_gpio_write}, {"gpio/read", dh_handle_gpio_read}, {"gpio/int", dh_handle_gpio_int}, #endif /* DH_COMMANDS_GPIO */ -#ifdef DH_COMMANDS_ADC +#if defined(DH_COMMANDS_ADC) {"adc/read", dh_handle_adc_read}, {"adc/int", dh_handle_adc_int}, #endif /* DH_COMMANDS_ADC */ -#ifdef DH_COMMANDS_PWM +#if defined(DH_COMMANDS_PWM) {"pwm/control", dh_handle_pwm_control}, #endif /* DH_COMMANDS_PWM */ -#ifdef DH_COMMANDS_UART +#if defined(DH_COMMANDS_UART) {"uart/write", dh_handle_uart_write}, {"uart/read", dh_handle_uart_read}, {"uart/int", dh_handle_uart_int}, {"uart/terminal", dh_handle_uart_terminal}, #endif /* DH_COMMANDS_UART */ -#ifdef DH_COMMANDS_I2C +#if defined(DH_COMMANDS_I2C) { "i2c/master/read", dh_handle_i2c_master_read}, { "i2c/master/write", dh_handle_i2c_master_write}, #endif /* DH_COMMANDS_I2C */ -#ifdef DH_COMMANDS_SPI +#if defined(DH_COMMANDS_SPI) { "spi/master/read", dh_handle_spi_master_read}, { "spi/master/write", dh_handle_spi_master_write}, #endif /* DH_COMMANDS_SPI */ -#ifdef DH_COMMANDS_ONEWIRE +#if defined(DH_COMMANDS_ONEWIRE) { "onewire/master/read", dh_handle_onewire_master_read}, { "onewire/master/write", dh_handle_onewire_master_write}, { "onewire/master/search", dh_handle_onewire_master_search}, @@ -93,33 +93,101 @@ RO_DATA struct { { "onewire/ws2812b/write", dh_handle_onewire_ws2812b_write}, #endif /* DH_COMMANDS_ONEWIRE */ +#if defined(DH_COMMANDS_DS18B20) && defined(DH_DEVICE_DS18B20) { "devices/ds18b20/read", dh_handle_devices_ds18b20_read}, +#endif + +#if defined(DH_COMMANDS_DHT11) && defined(DH_DEVICE_DHT11) { "devices/dht11/read", dh_handle_devices_dht11_read}, +#endif + +#if defined(DH_COMMANDS_DHT22) && defined(DH_DEVICE_DHT22) { "devices/dht22/read", dh_handle_devices_dht22_read}, +#endif + +#if defined(DH_COMMANDS_BMP180) && defined(DH_DEVICE_BMP180) { "devices/bmp180/read", dh_handle_devices_bmp180_read}, +#endif + +#if defined(DH_COMMANDS_BMP280) && defined(DH_DEVICE_BMP280) { "devices/bmp280/read", dh_handle_devices_bmp280_read}, +#endif + +#if defined(DH_COMMANDS_BH1750) && defined(DH_DEVICE_BH1750) { "devices/bh1750/read", dh_handle_devices_bh1750_read}, +#endif + +#if defined(DH_COMMANDS_MPU6050) && defined(DH_DEVICE_MPU6050) { "devices/mpu6050/read", dh_handle_devices_mpu6050_read}, +#endif + +#if defined(DH_COMMANDS_HMC5883L) && defined(DH_DEVICE_HMC5883L) { "devices/hmc5883l/read", dh_handle_devices_hmc5883l_read}, +#endif + +#if defined(DH_COMMANDS_PCF8574) && defined(DH_DEVICE_PCF8574) { "devices/pcf8574/read", dh_handle_devices_pcf8574_read}, { "devices/pcf8574/write", dh_handle_devices_pcf8574_write}, +#endif + +#if defined(DH_COMMANDS_PCF8574_HD44780) && defined(DH_DEVICE_PCF8574_HD44780) { "devices/pcf8574/hd44780/write", dh_handle_devices_pcf8574_hd44780_write}, +#endif + +#if defined(DH_COMMANDS_MHZ19) && defined(DH_DEVICE_MHZ19) { "devices/mhz19/read", dh_handle_devices_mhz19_read}, +#endif + +#if defined(DH_COMMANDS_LM75) && defined(DH_DEVICE_LM75) { "devices/lm75/read", dh_handle_devices_lm75_read}, +#endif + +#if defined(DH_COMMANDS_SI7021) && defined(DH_DEVICE_SI7021) { "devices/si7021/read", dh_handle_devices_si7021_read}, +#endif + +#if defined(DH_COMMANDS_ADS1115) && defined(DH_DEVICE_ADS1115) { "devices/ads1115/read", dh_handle_devices_ads1115_read}, +#endif + +#if defined(DH_COMMANDS_PCF8591) && defined(DH_DEVICE_PCF8591) { "devices/pcf8591/read", dh_handle_devices_pcf8591_read}, { "devices/pcf8591/write", dh_handle_devices_pcf8591_write}, +#endif + +#if defined(DH_COMMANDS_MCP4725) && defined(DH_DEVICE_MCP4725) { "devices/mcp4725/write", dh_handle_devices_mcp4725_write}, +#endif + +#if defined(DH_COMMANDS_INA219) && defined(DH_DEVICE_INA219) { "devices/ina219/read", dh_handle_devices_ina219_read}, +#endif + +#if defined(DH_COMMANDS_MFRC522) && defined(DH_DEVICE_MFRC522) { "devices/mfrc522/read", dh_handle_devices_mfrc522_read}, { "devices/mfrc522/mifare/read", dh_handle_devices_mfrc522_mifare_read_write}, { "devices/mfrc522/mifare/write", dh_handle_devices_mfrc522_mifare_read_write}, +#endif + +#if defined(DH_COMMANDS_PCA9685) && defined(DH_DEVICE_PCA9685) { "devices/pca9685/control", dh_handle_devices_pca9685_control}, +#endif + +#if defined(DH_COMMANDS_MLX90614) && defined(DH_DEVICE_MLX90614) { "devices/mlx90614/read", dh_handle_devices_mlx90614_read}, +#endif + +#if defined(DH_COMMANDS_MAX6675) && defined(DH_DEVICE_MAX6675) { "devices/max6675/read", dh_handle_devices_max6675_read}, +#endif + +#if defined(DH_COMMANDS_MAX31855) && defined(DH_DEVICE_MAX31855) { "devices/max31855/read", dh_handle_devices_max31855_read}, +#endif + +#if defined(DH_COMMANDS_TM1637) && defined(DH_DEVICE_TM1637) { "devices/tm1637/write", dh_handle_devices_tm1637_write}, +#endif { "-", 0 } // END }; diff --git a/firmware-src/sources/user_config.h b/firmware-src/sources/user_config.h index ba75f18..5bbd831 100644 --- a/firmware-src/sources/user_config.h +++ b/firmware-src/sources/user_config.h @@ -36,14 +36,64 @@ /** HTTP webserver and RESTful service port. */ #define HTTPD_PORT 80 -// customize command set -#define DH_COMMANDS_GPIO // enable GPIO commands -#define DH_COMMANDS_ADC // enable ADC commands -#define DH_COMMANDS_PWM // enable PWM commands -#define DH_COMMANDS_UART // enable UART commands -#define DH_COMMANDS_I2C // enable I2C commands -#define DH_COMMANDS_SPI // enable SPI commands -#define DH_COMMANDS_ONEWIRE // enable onewire commands +// customize supported devices (compile time) +#define DH_DEVICE_DS18B20 +#define DH_DEVICE_DHT11 +#define DH_DEVICE_DHT22 +#define DH_DEVICE_BMP180 +#define DH_DEVICE_BMP280 +#define DH_DEVICE_BH1750 +#define DH_DEVICE_MPU6050 +#define DH_DEVICE_HMC5883L +#define DH_DEVICE_PCF8574 +#define DH_DEVICE_PCF8574_HD44780 +#define DH_DEVICE_MHZ19 +#define DH_DEVICE_LM75 +#define DH_DEVICE_SI7021 +#define DH_DEVICE_ADS1115 +#define DH_DEVICE_PCF8591 +#define DH_DEVICE_MCP4725 +#define DH_DEVICE_INA219 +#define DH_DEVICE_MFRC522 +#define DH_DEVICE_PCA9685 +#define DH_DEVICE_MLX90614 +#define DH_DEVICE_MAX6675 +#define DH_DEVICE_MAX31855 +#define DH_DEVICE_TM1637 + +// customize device commands (compile time) +#define DH_COMMANDS_DS18B20 +#define DH_COMMANDS_DHT11 +#define DH_COMMANDS_DHT22 +#define DH_COMMANDS_BMP180 +#define DH_COMMANDS_BMP280 +#define DH_COMMANDS_BH1750 +#define DH_COMMANDS_MPU6050 +#define DH_COMMANDS_HMC5883L +#define DH_COMMANDS_PCF8574 +#define DH_COMMANDS_PCF8574_HD44780 +#define DH_COMMANDS_MHZ19 +#define DH_COMMANDS_LM75 +#define DH_COMMANDS_SI7021 +#define DH_COMMANDS_ADS1115 +#define DH_COMMANDS_PCF8591 +#define DH_COMMANDS_MCP4725 +#define DH_COMMANDS_INA219 +#define DH_COMMANDS_MFRC522 +#define DH_COMMANDS_PCA9685 +#define DH_COMMANDS_MLX90614 +#define DH_COMMANDS_MAX6675 +#define DH_COMMANDS_MAX31855 +#define DH_COMMANDS_TM1637 + +// customize command set (compile time) +#define DH_COMMANDS_GPIO // enable GPIO commands +#define DH_COMMANDS_ADC // enable ADC commands +#define DH_COMMANDS_PWM // enable PWM commands +#define DH_COMMANDS_UART // enable UART commands +#define DH_COMMANDS_I2C // enable I2C commands +#define DH_COMMANDS_SPI // enable SPI commands +#define DH_COMMANDS_ONEWIRE // enable onewire commands // TODO: customize device list From 89549a50a1212a5c43a0de6d71ec8536cb3aa3a5 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 3 May 2017 14:11:24 +0300 Subject: [PATCH 53/83] fix unittests (update expected error messages) --- firmware-tests/requests.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/firmware-tests/requests.html b/firmware-tests/requests.html index 8f685da..a0c5ee9 100644 --- a/firmware-tests/requests.html +++ b/firmware-tests/requests.html @@ -108,7 +108,7 @@ addtest("uart/int", {"mode":"57600 G3F", "timeout":2000}, false, "Wrong mode framing"); addtest("uart/int", {"mode":"57600 8E3"}, false, "Wrong UART mode"); addtest("uart/int", {"mode":"9600 7O2", "timeout":2000}, true, ""); - addtest("uart/int", {"mode":"9600 7O2", "timeout":5001}, false, "Timeout is too long"); + addtest("uart/int", {"mode":"9600 7O2", "timeout":5001}, false, "Timeout out of range"); addtest("uart/int", {"mode":"115200 8N1"}, true, ""); addtest("uart/int", {"mode":"disable"}, true, ""); addtest("uart/int", {"mode":"0"}, true, ""); @@ -120,21 +120,21 @@ addtest("uart/read", {"data":"SGVsbG8sIHdvcmxkIQ=="}, true, null); addtest("uart/read", {"mode":"115200 8N1", "data":"SGVsbG8sIHdvcmxkIQ==", "timeout":100}, true, null); addtest("uart/read", {"mode":"115200 8N1", "timeout":100}, false, "Timeout can be specified only with data"); - addtest("uart/read", {"mode":"115200 8N1", "data":"AA==", "timeout":1001}, false, "Timeout is too long"); - addtest("uart/terminal", {"4":"disable"}, false, "Command does not have parameters"); + addtest("uart/read", {"mode":"115200 8N1", "data":"AA==", "timeout":1001}, false, "Timeout out of range"); + addtest("uart/terminal", {"4":"disable"}, false, "No parameters expected"); addtest("uart/terminal", null, true, ""); addtest("i2c/master/read", null, false, "No parameters specified"); - addtest("i2c/master/read", {"address":"EE"}, false, "ACK response not detected"); + addtest("i2c/master/read", {"address":"EE"}, false, "no ACK response"); addtest("i2c/master/read", {"address":"ggg"}, false, "Address is wrong"); - addtest("i2c/master/read", {"address":"EE"}, false, "ACK response not detected"); - addtest("i2c/master/read", {"address":"EE","data":"AA=="}, false, "ACK response not detected"); + addtest("i2c/master/read", {"address":"EE"}, false, "no ACK response"); + addtest("i2c/master/read", {"address":"EE","data":"AA=="}, false, "no ACK response"); addtest("i2c/master/read", {"address":"EE","data":"AA==","count":0}, false, "Wrong read size"); - addtest("i2c/master/read", {"address":"0xED","data":"AA==","count":3}, false, "ACK response not detected"); + addtest("i2c/master/read", {"address":"0xED","data":"AA==","count":3}, false, "no ACK response"); addtest("i2c/master/read", {"address":"EE", "count":9999999}, false, "Wrong read size"); addtest("i2c/master/write", {"address":"EE","data":""}, false, "Data is broken"); addtest("i2c/master/write", {"address":"EE","data":"AA==","SDA":0}, false, "Only one pin specified"); addtest("i2c/master/write", {"address":"EE","data":"AA==","SDA":0,"SCL":0}, false, "Wrong parameters"); - addtest("i2c/master/write", {"address":"0xFF","data":"AA==","SDA":0,"SCL":2}, false, "ACK response not detected"); + addtest("i2c/master/write", {"address":"0xFF","data":"AA==","SDA":0,"SCL":2}, false, "no ACK response"); addtest("i2c/master/write", {"address":"0xFF","data":"AA==","SDA":0,"SCL":22}, false, "Wrong parameters"); addtest("spi/master/read", {"count": 1}, true, null); addtest("spi/master/read", {"count": 1, "CS":"x"}, true, null); From 871c7a5b3b71eb16bd702b35be82ef3f3229af17 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 3 May 2017 16:18:25 +0300 Subject: [PATCH 54/83] rename RDT_FORMAT_STRING to RDT_FORMAT_JSON and remove quotes JSON value should be used without surrounding quotes! --- firmware-src/sources/commands/ads1115_cmd.c | 2 +- firmware-src/sources/commands/bh1750_cmd.c | 3 ++- firmware-src/sources/commands/bmp180_cmd.c | 3 ++- firmware-src/sources/commands/bmp280_cmd.c | 3 ++- firmware-src/sources/commands/dht_cmd.c | 4 ++-- firmware-src/sources/commands/ds18b20_cmd.c | 2 +- firmware-src/sources/commands/hmc5883l_cmd.c | 2 +- firmware-src/sources/commands/ina219_cmd.c | 2 +- firmware-src/sources/commands/lm75_cmd.c | 2 +- firmware-src/sources/commands/max31855_cmd.c | 2 +- firmware-src/sources/commands/max6675_cmd.c | 2 +- firmware-src/sources/commands/mfrc522_cmd.c | 2 +- firmware-src/sources/commands/mhz19_cmd.c | 2 +- firmware-src/sources/commands/mlx90614_cmd.c | 2 +- firmware-src/sources/commands/mpu6050_cmd.c | 2 +- firmware-src/sources/commands/pcf8591_cmd.c | 2 +- firmware-src/sources/commands/si7021_cmd.c | 2 +- firmware-src/sources/dhsender_data.c | 6 +++--- firmware-src/sources/dhsender_data.h | 2 +- 19 files changed, 25 insertions(+), 22 deletions(-) diff --git a/firmware-src/sources/commands/ads1115_cmd.c b/firmware-src/sources/commands/ads1115_cmd.c index f27c06b..54d588c 100644 --- a/firmware-src/sources/commands/ads1115_cmd.c +++ b/firmware-src/sources/commands/ads1115_cmd.c @@ -43,7 +43,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ads1115_read(COMMAND_RESULT *cmd_res, c if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", values[0], values[1], values[2], values[3]); } diff --git a/firmware-src/sources/commands/bh1750_cmd.c b/firmware-src/sources/commands/bh1750_cmd.c index ec7200a..441a718 100644 --- a/firmware-src/sources/commands/bh1750_cmd.c +++ b/firmware-src/sources/commands/bh1750_cmd.c @@ -45,7 +45,8 @@ void ICACHE_FLASH_ATTR dh_handle_devices_bh1750_read(COMMAND_RESULT *cmd_res, co if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"illuminance\":%f}", illuminance); + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, + "{\"illuminance\":%f}", illuminance); } } diff --git a/firmware-src/sources/commands/bmp180_cmd.c b/firmware-src/sources/commands/bmp180_cmd.c index 64ac9b3..622487f 100644 --- a/firmware-src/sources/commands/bmp180_cmd.c +++ b/firmware-src/sources/commands/bmp180_cmd.c @@ -46,7 +46,8 @@ void ICACHE_FLASH_ATTR dh_handle_devices_bmp180_read(COMMAND_RESULT *cmd_res, co if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, + "{\"temperature\":%f, \"pressure\":%d}", temperature, pressure); } } diff --git a/firmware-src/sources/commands/bmp280_cmd.c b/firmware-src/sources/commands/bmp280_cmd.c index 0170531..64bc0d6 100644 --- a/firmware-src/sources/commands/bmp280_cmd.c +++ b/firmware-src/sources/commands/bmp280_cmd.c @@ -46,7 +46,8 @@ void ICACHE_FLASH_ATTR dh_handle_devices_bmp280_read(COMMAND_RESULT *cmd_res, co if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, + "{\"temperature\":%f, \"pressure\":%f}", temperature, pressure); } } diff --git a/firmware-src/sources/commands/dht_cmd.c b/firmware-src/sources/commands/dht_cmd.c index a5d2bc6..088af14 100644 --- a/firmware-src/sources/commands/dht_cmd.c +++ b/firmware-src/sources/commands/dht_cmd.c @@ -71,7 +71,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_dht11_read(COMMAND_RESULT *cmd_res, con if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%d, \"humidity\":%d}", temperature, humidity); } } @@ -106,7 +106,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_dht22_read(COMMAND_RESULT *cmd_res, con if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); } } diff --git a/firmware-src/sources/commands/ds18b20_cmd.c b/firmware-src/sources/commands/ds18b20_cmd.c index 9b2f2ec..05d6ad0 100644 --- a/firmware-src/sources/commands/ds18b20_cmd.c +++ b/firmware-src/sources/commands/ds18b20_cmd.c @@ -39,7 +39,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ds18b20_read(COMMAND_RESULT *cmd_res, c if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, "{\"temperature\":%f}", temperature); + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f}", temperature); } } diff --git a/firmware-src/sources/commands/hmc5883l_cmd.c b/firmware-src/sources/commands/hmc5883l_cmd.c index 8b93589..2cd78cd 100644 --- a/firmware-src/sources/commands/hmc5883l_cmd.c +++ b/firmware-src/sources/commands/hmc5883l_cmd.c @@ -58,7 +58,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_hmc5883l_read(COMMAND_RESULT *cmd_res, snprintf(floatbufy, sizeof(floatbufy), "%f", compass.Y); if (compass.Z != HMC5883l_OVERFLOWED) snprintf(floatbufz, sizeof(floatbufz), "%f", compass.Z); - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"magnetometer\":{\"X\":%s, \"Y\":%s, \"Z\":%s}}", floatbufx, floatbufy, floatbufz); } diff --git a/firmware-src/sources/commands/ina219_cmd.c b/firmware-src/sources/commands/ina219_cmd.c index 556edae..1ad5b93 100644 --- a/firmware-src/sources/commands/ina219_cmd.c +++ b/firmware-src/sources/commands/ina219_cmd.c @@ -57,7 +57,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_ina219_read(COMMAND_RESULT *cmd_res, co if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"voltage\":%f, \"current\":%f, \"power\":%f}", voltage, current, power); } diff --git a/firmware-src/sources/commands/lm75_cmd.c b/firmware-src/sources/commands/lm75_cmd.c index a72ce22..c614641 100644 --- a/firmware-src/sources/commands/lm75_cmd.c +++ b/firmware-src/sources/commands/lm75_cmd.c @@ -45,7 +45,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_lm75_read(COMMAND_RESULT *cmd_res, cons if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f}", temperature); } } diff --git a/firmware-src/sources/commands/max31855_cmd.c b/firmware-src/sources/commands/max31855_cmd.c index 6fbfb01..44fc5db 100644 --- a/firmware-src/sources/commands/max31855_cmd.c +++ b/firmware-src/sources/commands/max31855_cmd.c @@ -36,7 +36,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_max31855_read(COMMAND_RESULT *cmd_res, if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f}", temperature); } } diff --git a/firmware-src/sources/commands/max6675_cmd.c b/firmware-src/sources/commands/max6675_cmd.c index 8d14290..2d76d10 100644 --- a/firmware-src/sources/commands/max6675_cmd.c +++ b/firmware-src/sources/commands/max6675_cmd.c @@ -36,7 +36,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_max6675_read(COMMAND_RESULT *cmd_res, c if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f}", temperature); } } diff --git a/firmware-src/sources/commands/mfrc522_cmd.c b/firmware-src/sources/commands/mfrc522_cmd.c index 41e8098..e3b981b 100644 --- a/firmware-src/sources/commands/mfrc522_cmd.c +++ b/firmware-src/sources/commands/mfrc522_cmd.c @@ -51,7 +51,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mfrc522_read(COMMAND_RESULT *cmd_res, c for (i = 0; i < uid->size; i++) byteToHex(uid->uidByte[i], &hexbuf[i * 2]); hexbuf[sizeof(hexbuf) - 1] = 0; - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"uid\":\"0x%s\", \"type\":\"%s\"}", hexbuf, MFRC522_PICC_GetTypeName(MFRC522_PICC_GetType(uid->sak))); MFRC522_PCD_AntennaOff(); diff --git a/firmware-src/sources/commands/mhz19_cmd.c b/firmware-src/sources/commands/mhz19_cmd.c index 31dc65d..e4b2347 100644 --- a/firmware-src/sources/commands/mhz19_cmd.c +++ b/firmware-src/sources/commands/mhz19_cmd.c @@ -29,7 +29,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mhz19_read(COMMAND_RESULT *cmd_res, con dh_command_fail(cmd_res, err_msg); } else { cmd_res->callback(cmd_res->data, DHSTATUS_OK, - RDT_FORMAT_STRING, "{\"co2\":%d}", co2); + RDT_FORMAT_JSON, "{\"co2\":%d}", co2); } } diff --git a/firmware-src/sources/commands/mlx90614_cmd.c b/firmware-src/sources/commands/mlx90614_cmd.c index 487ddb6..03553be 100644 --- a/firmware-src/sources/commands/mlx90614_cmd.c +++ b/firmware-src/sources/commands/mlx90614_cmd.c @@ -45,7 +45,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mlx90614_read(COMMAND_RESULT *cmd_res, if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"ambient\":%f, \"object\":%f}", ambient, object); } } diff --git a/firmware-src/sources/commands/mpu6050_cmd.c b/firmware-src/sources/commands/mpu6050_cmd.c index dd101cd..a730d86 100644 --- a/firmware-src/sources/commands/mpu6050_cmd.c +++ b/firmware-src/sources/commands/mpu6050_cmd.c @@ -47,7 +47,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_mpu6050_read(COMMAND_RESULT *cmd_res, c if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f, \"acceleration\":{\"X\":%f, \"Y\":%f, \"Z\":%f}, \"rotation\":{\"X\":%f, \"Y\":%f, \"Z\":%f}}", temperature, acc.X, acc.Y, acc.Z, gyro.X, gyro.Y, gyro.Z); } diff --git a/firmware-src/sources/commands/pcf8591_cmd.c b/firmware-src/sources/commands/pcf8591_cmd.c index d896160..51f9e48 100644 --- a/firmware-src/sources/commands/pcf8591_cmd.c +++ b/firmware-src/sources/commands/pcf8591_cmd.c @@ -54,7 +54,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_pcf8591_read(COMMAND_RESULT *cmd_res, c if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"0\":%f, \"1\":%f, \"2\":%f, \"3\":%f}", values[0], values[1], values[2], values[3]); } diff --git a/firmware-src/sources/commands/si7021_cmd.c b/firmware-src/sources/commands/si7021_cmd.c index 8371362..37daf8d 100644 --- a/firmware-src/sources/commands/si7021_cmd.c +++ b/firmware-src/sources/commands/si7021_cmd.c @@ -45,7 +45,7 @@ void ICACHE_FLASH_ATTR dh_handle_devices_si7021_read(COMMAND_RESULT *cmd_res, co if (err_msg != 0) { dh_command_fail(cmd_res, err_msg); } else { - cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_STRING, + cmd_res->callback(cmd_res->data, DHSTATUS_OK, RDT_FORMAT_JSON, "{\"temperature\":%f, \"humidity\":%f}", temperature, humidity); } } diff --git a/firmware-src/sources/dhsender_data.c b/firmware-src/sources/dhsender_data.c index 24c6478..ce516d4 100644 --- a/firmware-src/sources/dhsender_data.c +++ b/firmware-src/sources/dhsender_data.c @@ -49,7 +49,7 @@ void ICACHE_FLASH_ATTR dhsender_data_parse_va(va_list ap, *d++ = *s++; } break; - case RDT_FORMAT_STRING: + case RDT_FORMAT_JSON: *data_len = vsnprintf(data->array, sizeof(data->array), va_arg(ap, char *), ap); break; default: @@ -98,8 +98,8 @@ int ICACHE_FLASH_ATTR dhsender_data_to_json(char *buf, unsigned int buf_len, int is_notification, REQUEST_DATA_TYPE data_type, SENDERDATA *data, unsigned int data_len, unsigned int pin) { switch(data_type) { - case RDT_FORMAT_STRING: - return snprintf(buf, buf_len, "\"%s\"", data->array); + case RDT_FORMAT_JSON: + return snprintf(buf, buf_len, "%s", data->array); // TODO: strncpy to simple string copy! case RDT_CONST_STRING: return snprintf(buf, buf_len, "\"%s\"", data->string); case RDT_DATA_WITH_LEN: diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index 2a58483..6dc2802 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -23,7 +23,7 @@ typedef enum { RDT_FLOAT, ///< Float should be passed. Will be formatted as json with this value. RDT_GPIO, ///< Four 32bit value should be passed(caused, state, tick, suitable). Will be formatted as json. RDT_SEARCH64, ///< Data with groups of 64bit addresses. Pin number, pointer to data and integer length of data should be passed. - RDT_FORMAT_STRING ///< Formated string, like sprintf. Text should be valid json. + RDT_FORMAT_JSON ///< Formated JSON, with sprintf syntax. Text should be valid JSON. } REQUEST_DATA_TYPE; /** Request type. */ From 9458d22aaba19f863c669bff30b27c070a8db8f1 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Wed, 3 May 2017 18:50:49 +0300 Subject: [PATCH 55/83] support for new "command/list" command returns a list of supported commands as an JSON array. --- firmware-src/sources/dhcommands.c | 47 +++++++++++++++++++++++++++- firmware-src/sources/dhsender_data.h | 3 +- firmware-src/sources/rest.c | 4 +++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/firmware-src/sources/dhcommands.c b/firmware-src/sources/dhcommands.c index cca8763..179dc22 100644 --- a/firmware-src/sources/dhcommands.c +++ b/firmware-src/sources/dhcommands.c @@ -43,9 +43,14 @@ #include "commands/tm1637_cmd.h" #include +#include #include #include +static void do_handle_command_list(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len); + + RO_DATA struct { const char *name; void (*func)(COMMAND_RESULT*, const char*, const char*, unsigned int); @@ -189,7 +194,7 @@ RO_DATA struct { { "devices/tm1637/write", dh_handle_devices_tm1637_write}, #endif - { "-", 0 } // END + { "command/list", do_handle_command_list } // END }; @@ -212,3 +217,43 @@ void ICACHE_FLASH_ATTR dhcommands_do(COMMAND_RESULT *cb, const char *command, co dh_command_fail(cb, "Unknown command"); } + + +/** + * @brief Handle "command/list" command. + * + * Just prints out all available commands. + */ +static void ICACHE_FLASH_ATTR do_handle_command_list(COMMAND_RESULT *cmd_res, const char *command, + const char *params, unsigned int params_len) +{ + // estimate memory space + int i, n = 2; // note [] + for (i = 0; i < NUM_OF_COMMANDS; ++i) { + n += os_strlen(g_command_table[i].name) + 2+1; // note ,"" + } + + // allocate buffer + void *buf = os_malloc(n); + if (!buf) { + dh_command_fail(cmd_res, "Out of memory"); + return; + } + + // format response + char *p = (char*)buf; + *p++ = '['; + for (i = 0; i < NUM_OF_COMMANDS; ++i) { + if (i) *p++ = ','; + *p++ = '"'; + int nn = os_strlen(g_command_table[i].name); + os_memcpy(p, g_command_table[i].name, nn); p += nn; + *p++ = '"'; + } + *p++ = ']'; + *p = 0; // guard + + cmd_res->callback(cmd_res->data, + DHSTATUS_OK, RDT_MALLOC_PTR, + buf, p - (char*)buf); +} diff --git a/firmware-src/sources/dhsender_data.h b/firmware-src/sources/dhsender_data.h index 6dc2802..ea7b761 100644 --- a/firmware-src/sources/dhsender_data.h +++ b/firmware-src/sources/dhsender_data.h @@ -23,7 +23,8 @@ typedef enum { RDT_FLOAT, ///< Float should be passed. Will be formatted as json with this value. RDT_GPIO, ///< Four 32bit value should be passed(caused, state, tick, suitable). Will be formatted as json. RDT_SEARCH64, ///< Data with groups of 64bit addresses. Pin number, pointer to data and integer length of data should be passed. - RDT_FORMAT_JSON ///< Formated JSON, with sprintf syntax. Text should be valid JSON. + RDT_FORMAT_JSON, ///< Formated JSON, with sprintf syntax. Text should be valid JSON. + RDT_MALLOC_PTR ///< Dynamically allocated data. Will be freed by DH core once data are sent. Pointer and data length should be passed. } REQUEST_DATA_TYPE; /** Request type. */ diff --git a/firmware-src/sources/rest.c b/firmware-src/sources/rest.c index 6ca43e7..48e9097 100644 --- a/firmware-src/sources/rest.c +++ b/firmware-src/sources/rest.c @@ -36,6 +36,10 @@ LOCAL void ICACHE_FLASH_ATTR rest_command_callback(CommandResultArgument cid, if(data_type == RDT_CONST_STRING) { // optimization answer->content.data = va_arg(ap, const char *);; answer->content.len = os_strlen(answer->content.data); + } else if (data_type == RDT_MALLOC_PTR) { // optimization + answer->content.data = va_arg(ap, const char *); + answer->content.len = va_arg(ap, size_t); + answer->free_content = 1; } else { SENDERDATA data; unsigned int data_len; From 32f0332e2af72703ec5066cfd58881a3e7488cf4 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 4 May 2017 16:42:46 +0300 Subject: [PATCH 56/83] fix typo in DHT packet reading --- firmware-src/sources/devices/dht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware-src/sources/devices/dht.c b/firmware-src/sources/devices/dht.c index 10c116a..a4904b3 100644 --- a/firmware-src/sources/devices/dht.c +++ b/firmware-src/sources/devices/dht.c @@ -38,7 +38,7 @@ static const char* ICACHE_FLASH_ATTR dht_read_pkt(int pin, uint8_t buf[DHT_PACKE } int cs = ((int)buf[0] + (int)buf[1] + (int)buf[2] + (int)buf[3]); - if (cs*0xFF != (int)buf[4]) { + if ((cs&0xFF) != (int)buf[4]) { return "Bad checksum"; } From 0a0efd1be9ed2df5d09c612620cf12cdd9afe584 Mon Sep 17 00:00:00 2001 From: Sergey Polichnoy Date: Thu, 4 May 2017 17:39:08 +0300 Subject: [PATCH 57/83] add command suggestion list on tryapi page this command list is obtained from device dynamically using "command/list" command. --- firmware-src/pages/tryapi.html | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/firmware-src/pages/tryapi.html b/firmware-src/pages/tryapi.html index 16a9ae1..ef65d7b 100644 --- a/firmware-src/pages/tryapi.html +++ b/firmware-src/pages/tryapi.html @@ -48,7 +48,20 @@ } function init() { - byId('accesskey').value = localStorage['accesskey']; + var key = localStorage['accesskey']; + byId('accesskey').value = key; + + var base = location.protocol + '//' + location.host; + ajax('POST', '/api/command/list', '', key, function (xmlhttp) { + if (xmlhttp.status == 200) { + var cmd_list = JSON.parse(xmlhttp.responseText); + var options = ''; + for (var i = 0; i < cmd_list.length; i++) { + options += '