initial commit
This commit is contained in:
commit
85196faccd
14 changed files with 1095 additions and 0 deletions
48
CMakeLists.txt
Normal file
48
CMakeLists.txt
Normal file
|
@ -0,0 +1,48 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
project(dhtserver LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network REQUIRED)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(DHT_SOURCES
|
||||
src/dht/linux/common_dht_read.c
|
||||
src/dht/linux/common_dht_read.h
|
||||
src/dht/linux/libdht.c
|
||||
src/dht/linux/libdht.h
|
||||
src/dht/linux/pi_2_dht_read.c
|
||||
src/dht/linux/pi_2_dht_read.h
|
||||
src/dht/linux/pi_2_mmio.c
|
||||
src/dht/linux/pi_2_mmio.h
|
||||
)
|
||||
list(APPEND DHT_INCLUDEDIR
|
||||
src/dht/linux
|
||||
)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
set(DHT_SOURCES
|
||||
src/dht/freebsd/gpio.c
|
||||
src/dht/freebsd/libdht.c
|
||||
src/dht/freebsd/libdht.h
|
||||
src/dht/freebsd/libgpio.h
|
||||
)
|
||||
list(APPEND DHT_INCLUDEDIR
|
||||
src/dht/freebsd
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(dhtserver
|
||||
src/main.cpp
|
||||
${DHT_SOURCES}
|
||||
)
|
||||
target_include_directories(dhtserver PRIVATE ${DHT_INCLUDEDIR})
|
||||
target_link_libraries(dhtserver Qt${QT_VERSION_MAJOR}::Network)
|
260
src/dht/freebsd/gpio.c
Normal file
260
src/dht/freebsd/gpio.c
Normal file
|
@ -0,0 +1,260 @@
|
|||
/*-
|
||||
* Copyright (c) 2013-2014 Rui Paulo <rpaulo@felyko.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <libgpio.h>
|
||||
|
||||
gpio_handle_t
|
||||
gpio_open(unsigned int unit)
|
||||
{
|
||||
char device[16];
|
||||
|
||||
snprintf(device, sizeof(device), "/dev/gpioc%u", unit);
|
||||
|
||||
return (gpio_open_device(device));
|
||||
}
|
||||
|
||||
gpio_handle_t
|
||||
gpio_open_device(const char *device)
|
||||
{
|
||||
int fd, maxpins;
|
||||
int serr;
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return (GPIO_INVALID_HANDLE);
|
||||
/*
|
||||
* Check whether a simple ioctl works.
|
||||
*/
|
||||
if (ioctl(fd, GPIOMAXPIN, &maxpins) < 0) {
|
||||
serr = errno;
|
||||
close(fd);
|
||||
errno = serr;
|
||||
return (GPIO_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
void
|
||||
gpio_close(gpio_handle_t handle)
|
||||
{
|
||||
close(handle);
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_list(gpio_handle_t handle, gpio_config_t **pcfgs)
|
||||
{
|
||||
int maxpins, i;
|
||||
gpio_config_t *cfgs;
|
||||
|
||||
*pcfgs = NULL;
|
||||
if (ioctl(handle, GPIOMAXPIN, &maxpins) < 0)
|
||||
return (-1);
|
||||
/* Reasonable values. */
|
||||
if (maxpins < 0 || maxpins > 4096) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
cfgs = calloc(maxpins, sizeof(*cfgs));
|
||||
if (cfgs == NULL)
|
||||
return (-1);
|
||||
for (i = 0; i <= maxpins; i++) {
|
||||
cfgs[i].g_pin = i;
|
||||
gpio_pin_config(handle, &cfgs[i]);
|
||||
}
|
||||
*pcfgs = cfgs;
|
||||
|
||||
return (maxpins);
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_config(gpio_handle_t handle, gpio_config_t *cfg)
|
||||
{
|
||||
struct gpio_pin gppin;
|
||||
|
||||
if (cfg == NULL)
|
||||
return (-1);
|
||||
gppin.gp_pin = cfg->g_pin;
|
||||
if (ioctl(handle, GPIOGETCONFIG, &gppin) < 0)
|
||||
return (-1);
|
||||
strlcpy(cfg->g_name, gppin.gp_name, GPIOMAXNAME);
|
||||
cfg->g_caps = gppin.gp_caps;
|
||||
cfg->g_flags = gppin.gp_flags;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_set_flags(gpio_handle_t handle, gpio_config_t *cfg)
|
||||
{
|
||||
struct gpio_pin gppin;
|
||||
|
||||
if (cfg == NULL)
|
||||
return (-1);
|
||||
gppin.gp_pin = cfg->g_pin;
|
||||
gppin.gp_flags = cfg->g_flags;
|
||||
if (ioctl(handle, GPIOSETCONFIG, &gppin) < 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
gpio_value_t
|
||||
gpio_pin_get(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
struct gpio_req gpreq;
|
||||
|
||||
bzero(&gpreq, sizeof(gpreq));
|
||||
gpreq.gp_pin = pin;
|
||||
if (ioctl(handle, GPIOGET, &gpreq) < 0)
|
||||
return (GPIO_VALUE_INVALID);
|
||||
|
||||
return (gpreq.gp_value);
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_set(gpio_handle_t handle, gpio_pin_t pin, gpio_value_t value)
|
||||
{
|
||||
struct gpio_req gpreq;
|
||||
|
||||
if (value == GPIO_VALUE_INVALID)
|
||||
return (-1);
|
||||
bzero(&gpreq, sizeof(gpreq));
|
||||
gpreq.gp_pin = pin;
|
||||
gpreq.gp_value = value;
|
||||
if (ioctl(handle, GPIOSET, &gpreq) < 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_toggle(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
gpio_value_t value;
|
||||
|
||||
value = gpio_pin_get(handle, pin);
|
||||
if (value == GPIO_VALUE_INVALID)
|
||||
return (-1);
|
||||
value = !value;
|
||||
|
||||
return (gpio_pin_set(handle, pin, value));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_low(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set(handle, pin, GPIO_VALUE_LOW));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_high(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set(handle, pin, GPIO_VALUE_HIGH));
|
||||
}
|
||||
|
||||
static int
|
||||
gpio_pin_set_flag(gpio_handle_t handle, gpio_pin_t pin, uint32_t flag)
|
||||
{
|
||||
gpio_config_t cfg;
|
||||
|
||||
bzero(&cfg, sizeof(cfg));
|
||||
cfg.g_pin = pin;
|
||||
if (gpio_pin_config(handle, &cfg) < 0)
|
||||
return (-1);
|
||||
cfg.g_flags = flag;
|
||||
|
||||
return (gpio_pin_set_flags(handle, &cfg));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_input(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_INPUT));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_output(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_OUTPUT));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_opendrain(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_OPENDRAIN));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_pushpull(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_PUSHPULL));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_tristate(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_TRISTATE));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_pullup(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_PULLUP));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_pulldown(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_PULLDOWN));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_invin(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_INVIN));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_invout(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_INVOUT));
|
||||
}
|
||||
|
||||
int
|
||||
gpio_pin_pulsate(gpio_handle_t handle, gpio_pin_t pin)
|
||||
{
|
||||
return (gpio_pin_set_flag(handle, pin, GPIO_PIN_PULSATE));
|
||||
}
|
119
src/dht/freebsd/libdht.c
Normal file
119
src/dht/freebsd/libdht.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*-
|
||||
* Copyright (c) 2015 lex
|
||||
* Copyright (c) 2020-2021 Syping
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libdht.h"
|
||||
#include "libgpio.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define DHT_PULSES 40
|
||||
#define DHT_MAXCOUNT 32000
|
||||
|
||||
int getdhtstring(int PIN, char* string)
|
||||
{
|
||||
// these values seem to work best
|
||||
int firstSleep = 5000;
|
||||
int secondSleep = 200;
|
||||
|
||||
uint8_t rawData[DHT_PULSES] = {0};
|
||||
uint8_t values[4] = {0};
|
||||
|
||||
gpio_handle_t handle = gpio_open(0);
|
||||
|
||||
// wake up the sensor
|
||||
gpio_pin_output(handle, PIN);
|
||||
gpio_pin_low(handle, PIN);
|
||||
usleep(firstSleep);
|
||||
gpio_pin_high(handle, PIN);
|
||||
usleep(secondSleep);
|
||||
|
||||
// begin to receive data
|
||||
gpio_pin_input(handle, PIN);
|
||||
|
||||
for (volatile int i = 0; i < 50; ++i) {
|
||||
}
|
||||
|
||||
uint total = 0;
|
||||
|
||||
for (int i = 0; i < DHT_MAXCOUNT; ++i) {
|
||||
int c = 0;
|
||||
while (gpio_pin_get(handle, PIN) != 1) {
|
||||
}
|
||||
while (gpio_pin_get(handle, PIN) != 0 && c < 256) {
|
||||
// transmitting, 26-28 us = 0, 70 us = 1
|
||||
// results should be something like 3-4 c for 0, 12-14 for 1
|
||||
c++;
|
||||
}
|
||||
|
||||
if (c == 256) {
|
||||
// reading probably failed
|
||||
break;
|
||||
}
|
||||
|
||||
total++;
|
||||
rawData[i] = c;
|
||||
|
||||
if (total == DHT_PULSES) {
|
||||
// got all we need
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (total != DHT_PULSES) {
|
||||
gpio_close(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
uint8_t value = 0;
|
||||
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
uint8_t measuredLength = rawData[i * 8 + j];
|
||||
|
||||
// hax
|
||||
if (measuredLength > 9)
|
||||
value |= 0x01;
|
||||
|
||||
if (j != 7)
|
||||
value <<= 1;
|
||||
}
|
||||
|
||||
values[i] = value;
|
||||
}
|
||||
|
||||
float humid = (values[0] * 256 + values[1]) / 10.0f;
|
||||
float temp = ((values[2] & 0x7F) * 256 + values[3]) / 10.0f;
|
||||
if (values[2] & 0x80) {
|
||||
temp *= -1.0f;
|
||||
}
|
||||
|
||||
sprintf(string, "{\"humidity\": %.1f, \"temp\": %.1f}\n", humid, temp);
|
||||
|
||||
gpio_close(handle);
|
||||
return 0;
|
||||
}
|
38
src/dht/freebsd/libdht.h
Normal file
38
src/dht/freebsd/libdht.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-
|
||||
* Copyright (c) 2021 Syping
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBDHT_H_
|
||||
#define _LIBDHT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int getdhtstring(int PIN, char* string);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _LIBDHT_H_ */
|
105
src/dht/freebsd/libgpio.h
Normal file
105
src/dht/freebsd/libgpio.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*-
|
||||
* Copyright (c) 2013-2014 Rui Paulo <rpaulo@felyko.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBGPIO_H_
|
||||
#define _LIBGPIO_H_
|
||||
|
||||
#include <sys/gpio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define GPIO_INVALID_HANDLE -1
|
||||
typedef int gpio_handle_t;
|
||||
|
||||
typedef uint32_t gpio_pin_t;
|
||||
|
||||
/*
|
||||
* Structure describing a GPIO pin configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_pin_t g_pin;
|
||||
char g_name[GPIOMAXNAME];
|
||||
uint32_t g_caps;
|
||||
uint32_t g_flags;
|
||||
} gpio_config_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_VALUE_INVALID = -1,
|
||||
GPIO_VALUE_LOW = GPIO_PIN_LOW,
|
||||
GPIO_VALUE_HIGH = GPIO_PIN_HIGH
|
||||
} gpio_value_t;
|
||||
|
||||
/*
|
||||
* Open /dev/gpiocN or a specific device.
|
||||
*/
|
||||
gpio_handle_t gpio_open(unsigned int);
|
||||
gpio_handle_t gpio_open_device(const char *);
|
||||
void gpio_close(gpio_handle_t);
|
||||
/*
|
||||
* Get a list of all the GPIO pins.
|
||||
*/
|
||||
int gpio_pin_list(gpio_handle_t, gpio_config_t **);
|
||||
/*
|
||||
* GPIO pin configuration.
|
||||
*
|
||||
* Retrieve the configuration of a specific GPIO pin. The pin number is
|
||||
* passed through the gpio_config_t structure.
|
||||
*/
|
||||
int gpio_pin_config(gpio_handle_t, gpio_config_t *);
|
||||
/*
|
||||
* Sets the GPIO flags on a specific GPIO pin. The pin number and the flags
|
||||
* to be set are passed through the gpio_config_t structure.
|
||||
*/
|
||||
int gpio_pin_set_flags(gpio_handle_t, gpio_config_t *);
|
||||
/*
|
||||
* GPIO pin values.
|
||||
*/
|
||||
int gpio_pin_get(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_set(gpio_handle_t, gpio_pin_t, int);
|
||||
int gpio_pin_toggle(gpio_handle_t, gpio_pin_t);
|
||||
/*
|
||||
* Helper functions to set pin states.
|
||||
*/
|
||||
int gpio_pin_low(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_high(gpio_handle_t, gpio_pin_t);
|
||||
/*
|
||||
* Helper functions to configure pins.
|
||||
*/
|
||||
int gpio_pin_input(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_output(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_opendrain(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_pushpull(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_tristate(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_pullup(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_pulldown(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_invin(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_invout(gpio_handle_t, gpio_pin_t);
|
||||
int gpio_pin_pulsate(gpio_handle_t, gpio_pin_t);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _LIBGPIO_H_ */
|
66
src/dht/linux/common_dht_read.c
Normal file
66
src/dht/linux/common_dht_read.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) 2014 Adafruit Industries
|
||||
// Author: Tony DiCola
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "common_dht_read.h"
|
||||
|
||||
void busy_wait_milliseconds(uint32_t millis) {
|
||||
// Set delay time period.
|
||||
struct timeval deltatime;
|
||||
deltatime.tv_sec = millis / 1000;
|
||||
deltatime.tv_usec = (millis % 1000) * 1000;
|
||||
struct timeval walltime;
|
||||
// Get current time and add delay to find end time.
|
||||
gettimeofday(&walltime, NULL);
|
||||
struct timeval endtime;
|
||||
timeradd(&walltime, &deltatime, &endtime);
|
||||
// Tight loop to waste time (and CPU) until enough time as elapsed.
|
||||
while (timercmp(&walltime, &endtime, <)) {
|
||||
gettimeofday(&walltime, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void sleep_milliseconds(uint32_t millis) {
|
||||
struct timespec sleep;
|
||||
sleep.tv_sec = millis / 1000;
|
||||
sleep.tv_nsec = (millis % 1000) * 1000000L;
|
||||
while (clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep, &sleep) && errno == EINTR);
|
||||
}
|
||||
|
||||
void set_max_priority(void) {
|
||||
struct sched_param sched;
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
// Use FIFO scheduler with highest priority for the lowest chance of the kernel context switching.
|
||||
sched.sched_priority = sched_get_priority_max(SCHED_FIFO);
|
||||
sched_setscheduler(0, SCHED_FIFO, &sched);
|
||||
}
|
||||
|
||||
void set_default_priority(void) {
|
||||
struct sched_param sched;
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
// Go back to default scheduler with default 0 priority.
|
||||
sched.sched_priority = 0;
|
||||
sched_setscheduler(0, SCHED_OTHER, &sched);
|
||||
}
|
51
src/dht/linux/common_dht_read.h
Normal file
51
src/dht/linux/common_dht_read.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2014 Adafruit Industries
|
||||
// Author: Tony DiCola
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#ifndef COMMON_DHT_READ_H
|
||||
#define COMMON_DHT_READ_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Define errors and return values.
|
||||
#define DHT_ERROR_TIMEOUT -1
|
||||
#define DHT_ERROR_CHECKSUM -2
|
||||
#define DHT_ERROR_ARGUMENT -3
|
||||
#define DHT_ERROR_GPIO -4
|
||||
#define DHT_SUCCESS 0
|
||||
|
||||
// Define sensor types.
|
||||
#define DHT11 11
|
||||
#define DHT22 22
|
||||
#define AM2302 22
|
||||
|
||||
// Busy wait delay for most accurate timing, but high CPU usage.
|
||||
// Only use this for short periods of time (a few hundred milliseconds at most)!
|
||||
void busy_wait_milliseconds(uint32_t millis);
|
||||
|
||||
// General delay that sleeps so CPU usage is low, but accuracy is potentially bad.
|
||||
void sleep_milliseconds(uint32_t millis);
|
||||
|
||||
// Increase scheduling priority and algorithm to try to get 'real time' results.
|
||||
void set_max_priority(void);
|
||||
|
||||
// Drop scheduling priority back to normal/default.
|
||||
void set_default_priority(void);
|
||||
|
||||
#endif
|
17
src/dht/linux/libdht.c
Normal file
17
src/dht/linux/libdht.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "libdht.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pi_2_dht_read.h>
|
||||
|
||||
int getdhtstring(int PIN, char* string)
|
||||
{
|
||||
float humid;
|
||||
float temp;
|
||||
while (1) {
|
||||
if (pi_2_dht_read(PIN, PIN, &humid, &temp) == DHT_SUCCESS) {
|
||||
sprintf(string, "{\"humidity\": %.1f, \"temp\": %.1f}", humid, temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
12
src/dht/linux/libdht.h
Normal file
12
src/dht/linux/libdht.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef _LIBDHT_H_
|
||||
#define _LIBDHT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int getdhtstring(int PIN, char* string);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _LIBDHT_H_ */
|
158
src/dht/linux/pi_2_dht_read.c
Normal file
158
src/dht/linux/pi_2_dht_read.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
// Copyright (c) 2014 Adafruit Industries
|
||||
// Author: Tony DiCola
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pi_2_dht_read.h"
|
||||
#include "pi_2_mmio.h"
|
||||
|
||||
// This is the only processor specific magic value, the maximum amount of time to
|
||||
// spin in a loop before bailing out and considering the read a timeout. This should
|
||||
// be a high value, but if you're running on a much faster platform than a Raspberry
|
||||
// Pi or Beaglebone Black then it might need to be increased.
|
||||
#define DHT_MAXCOUNT 32000
|
||||
|
||||
// Number of bit pulses to expect from the DHT. Note that this is 41 because
|
||||
// the first pulse is a constant 50 microsecond pulse, with 40 pulses to represent
|
||||
// the data afterwards.
|
||||
#define DHT_PULSES 41
|
||||
|
||||
int pi_2_dht_read(int type, int pin, float* humidity, float* temperature) {
|
||||
// Validate humidity and temperature arguments and set them to zero.
|
||||
if (humidity == NULL || temperature == NULL) {
|
||||
return DHT_ERROR_ARGUMENT;
|
||||
}
|
||||
*temperature = 0.0f;
|
||||
*humidity = 0.0f;
|
||||
|
||||
// Initialize GPIO library.
|
||||
if (pi_2_mmio_init() < 0) {
|
||||
return DHT_ERROR_GPIO;
|
||||
}
|
||||
|
||||
// Store the count that each DHT bit pulse is low and high.
|
||||
// Make sure array is initialized to start at zero.
|
||||
int pulseCounts[DHT_PULSES*2] = {0};
|
||||
|
||||
// Set pin to output.
|
||||
pi_2_mmio_set_output(pin);
|
||||
|
||||
// Bump up process priority and change scheduler to try to try to make process more 'real time'.
|
||||
set_max_priority();
|
||||
|
||||
// Set pin high for ~500 milliseconds.
|
||||
pi_2_mmio_set_high(pin);
|
||||
sleep_milliseconds(500);
|
||||
|
||||
// The next calls are timing critical and care should be taken
|
||||
// to ensure no unnecssary work is done below.
|
||||
|
||||
// Set pin low for ~20 milliseconds.
|
||||
pi_2_mmio_set_low(pin);
|
||||
busy_wait_milliseconds(20);
|
||||
|
||||
// Set pin at input.
|
||||
pi_2_mmio_set_input(pin);
|
||||
// Need a very short delay before reading pins or else value is sometimes still low.
|
||||
for (volatile int i = 0; i < 50; ++i) {
|
||||
}
|
||||
|
||||
// Wait for DHT to pull pin low.
|
||||
uint32_t count = 0;
|
||||
while (pi_2_mmio_input(pin)) {
|
||||
if (++count >= DHT_MAXCOUNT) {
|
||||
// Timeout waiting for response.
|
||||
set_default_priority();
|
||||
return DHT_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
// Record pulse widths for the expected result bits.
|
||||
for (int i=0; i < DHT_PULSES*2; i+=2) {
|
||||
// Count how long pin is low and store in pulseCounts[i]
|
||||
while (!pi_2_mmio_input(pin)) {
|
||||
if (++pulseCounts[i] >= DHT_MAXCOUNT) {
|
||||
// Timeout waiting for response.
|
||||
set_default_priority();
|
||||
return DHT_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
// Count how long pin is high and store in pulseCounts[i+1]
|
||||
while (pi_2_mmio_input(pin)) {
|
||||
if (++pulseCounts[i+1] >= DHT_MAXCOUNT) {
|
||||
// Timeout waiting for response.
|
||||
set_default_priority();
|
||||
return DHT_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Done with timing critical code, now interpret the results.
|
||||
|
||||
// Drop back to normal priority.
|
||||
set_default_priority();
|
||||
|
||||
// Compute the average low pulse width to use as a 50 microsecond reference threshold.
|
||||
// Ignore the first two readings because they are a constant 80 microsecond pulse.
|
||||
uint32_t threshold = 0;
|
||||
for (int i=2; i < DHT_PULSES*2; i+=2) {
|
||||
threshold += pulseCounts[i];
|
||||
}
|
||||
threshold /= DHT_PULSES-1;
|
||||
|
||||
// Interpret each high pulse as a 0 or 1 by comparing it to the 50us reference.
|
||||
// If the count is less than 50us it must be a ~28us 0 pulse, and if it's higher
|
||||
// then it must be a ~70us 1 pulse.
|
||||
uint8_t data[5] = {0};
|
||||
for (int i=3; i < DHT_PULSES*2; i+=2) {
|
||||
int index = (i-3)/16;
|
||||
data[index] <<= 1;
|
||||
if (pulseCounts[i] >= threshold) {
|
||||
// One bit for long pulse.
|
||||
data[index] |= 1;
|
||||
}
|
||||
// Else zero bit for short pulse.
|
||||
}
|
||||
|
||||
// Useful debug info:
|
||||
//printf("Data: 0x%x 0x%x 0x%x 0x%x 0x%x\n", data[0], data[1], data[2], data[3], data[4]);
|
||||
|
||||
// Verify checksum of received data.
|
||||
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
|
||||
if (type == DHT11) {
|
||||
// Get humidity and temp for DHT11 sensor.
|
||||
*humidity = (float)data[0];
|
||||
*temperature = (float)data[2];
|
||||
}
|
||||
else if (type == DHT22) {
|
||||
// Calculate humidity and temp for DHT22 sensor.
|
||||
*humidity = (data[0] * 256 + data[1]) / 10.0f;
|
||||
*temperature = ((data[2] & 0x7F) * 256 + data[3]) / 10.0f;
|
||||
if (data[2] & 0x80) {
|
||||
*temperature *= -1.0f;
|
||||
}
|
||||
}
|
||||
return DHT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return DHT_ERROR_CHECKSUM;
|
||||
}
|
||||
}
|
32
src/dht/linux/pi_2_dht_read.h
Normal file
32
src/dht/linux/pi_2_dht_read.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2014 Adafruit Industries
|
||||
// Author: Tony DiCola
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#ifndef PI_2_DHT_READ_H
|
||||
#define PI_2_DHT_READ_H
|
||||
|
||||
#include "common_dht_read.h"
|
||||
|
||||
// Read DHT sensor connected to GPIO pin (using BCM numbering). Humidity and temperature will be
|
||||
// returned in the provided parameters. If a successfull reading could be made a value of 0
|
||||
// (DHT_SUCCESS) will be returned. If there was an error reading the sensor a negative value will
|
||||
// be returned. Some errors can be ignored and retried, specifically DHT_ERROR_TIMEOUT or DHT_ERROR_CHECKSUM.
|
||||
int pi_2_dht_read(int sensor, int pin, float* humidity, float* temperature);
|
||||
|
||||
#endif
|
71
src/dht/linux/pi_2_mmio.c
Normal file
71
src/dht/linux/pi_2_mmio.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) 2014 Adafruit Industries
|
||||
// Author: Tony DiCola
|
||||
// Based on code from Gert van Loo & Dom: http://elinux.org/RPi_Low-level_peripherals#GPIO_Code_examples
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pi_2_mmio.h"
|
||||
|
||||
#define GPIO_BASE_OFFSET 0x200000
|
||||
#define GPIO_LENGTH 4096
|
||||
|
||||
volatile uint32_t* pi_2_mmio_gpio = NULL;
|
||||
|
||||
int pi_2_mmio_init(void) {
|
||||
if (pi_2_mmio_gpio == NULL) {
|
||||
// Check for GPIO and peripheral addresses from device tree.
|
||||
// Adapted from code in the RPi.GPIO library at:
|
||||
// http://sourceforge.net/p/raspberry-gpio-python/
|
||||
FILE *fp = fopen("/proc/device-tree/soc/ranges", "rb");
|
||||
if (fp == NULL) {
|
||||
return MMIO_ERROR_OFFSET;
|
||||
}
|
||||
fseek(fp, 4, SEEK_SET);
|
||||
unsigned char buf[4];
|
||||
if (fread(buf, 1, sizeof(buf), fp) != sizeof(buf)) {
|
||||
return MMIO_ERROR_OFFSET;
|
||||
}
|
||||
uint32_t peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
|
||||
uint32_t gpio_base = peri_base + GPIO_BASE_OFFSET;
|
||||
fclose(fp);
|
||||
|
||||
int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
|
||||
if (fd == -1) {
|
||||
// Error opening /dev/gpiomem.
|
||||
return MMIO_ERROR_DEVMEM;
|
||||
}
|
||||
// Map GPIO memory to location in process space.
|
||||
pi_2_mmio_gpio = (uint32_t*)mmap(NULL, GPIO_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, gpio_base);
|
||||
close(fd);
|
||||
if (pi_2_mmio_gpio == MAP_FAILED) {
|
||||
// Don't save the result if the memory mapping failed.
|
||||
pi_2_mmio_gpio = NULL;
|
||||
return MMIO_ERROR_MMAP;
|
||||
}
|
||||
}
|
||||
return MMIO_SUCCESS;
|
||||
}
|
62
src/dht/linux/pi_2_mmio.h
Normal file
62
src/dht/linux/pi_2_mmio.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) 2014 Adafruit Industries
|
||||
// Author: Tony DiCola
|
||||
// Based on code from Gert van Loo & Dom: http://elinux.org/RPi_Low-level_peripherals#GPIO_Code_examples
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// Simple fast memory-mapped GPIO library for the Raspberry Pi.
|
||||
#ifndef PI_2_MMIO_H
|
||||
#define PI_2_MMIO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MMIO_SUCCESS 0
|
||||
#define MMIO_ERROR_DEVMEM -1
|
||||
#define MMIO_ERROR_MMAP -2
|
||||
#define MMIO_ERROR_OFFSET -3
|
||||
|
||||
extern volatile uint32_t* pi_2_mmio_gpio;
|
||||
|
||||
int pi_2_mmio_init(void);
|
||||
|
||||
static inline void pi_2_mmio_set_input(const int gpio_number) {
|
||||
// Set GPIO register to 000 for specified GPIO number.
|
||||
*(pi_2_mmio_gpio+((gpio_number)/10)) &= ~(7<<(((gpio_number)%10)*3));
|
||||
}
|
||||
|
||||
static inline void pi_2_mmio_set_output(const int gpio_number) {
|
||||
// First set to 000 using input function.
|
||||
pi_2_mmio_set_input(gpio_number);
|
||||
// Next set bit 0 to 1 to set output.
|
||||
*(pi_2_mmio_gpio+((gpio_number)/10)) |= (1<<(((gpio_number)%10)*3));
|
||||
}
|
||||
|
||||
static inline void pi_2_mmio_set_high(const int gpio_number) {
|
||||
*(pi_2_mmio_gpio+7) = 1 << gpio_number;
|
||||
}
|
||||
|
||||
static inline void pi_2_mmio_set_low(const int gpio_number) {
|
||||
*(pi_2_mmio_gpio+10) = 1 << gpio_number;
|
||||
}
|
||||
|
||||
static inline uint32_t pi_2_mmio_input(const int gpio_number) {
|
||||
return *(pi_2_mmio_gpio+13) & (1 << gpio_number);
|
||||
}
|
||||
|
||||
#endif
|
56
src/main.cpp
Normal file
56
src/main.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QTextStream>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
extern "C" {
|
||||
#include "libdht.h"
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
const QStringList args = a.arguments();
|
||||
|
||||
int PIN = 22; // PIN 22 is default for dhtserver
|
||||
if (args.length() == 2) {
|
||||
bool ok;
|
||||
const int aPIN = args.at(1).toInt(&ok);
|
||||
if (ok) {
|
||||
PIN = aPIN;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray dhtJson;
|
||||
QLocalServer localServer;
|
||||
localServer.setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
bool isListen = localServer.listen("/var/run/dhtserver/dhtserver.sock");
|
||||
if (!isListen) {
|
||||
QTextStream(stderr) << "dhtserver: Unix socket can't listen!" << Qt::endl;
|
||||
return -1;
|
||||
}
|
||||
QObject::connect(&localServer, &QLocalServer::newConnection, [&]() {
|
||||
QLocalSocket *localSocket = localServer.nextPendingConnection();
|
||||
if (localSocket) {
|
||||
QObject::connect(localSocket, &QLocalSocket::disconnected, localSocket, &QLocalSocket::deleteLater);
|
||||
localSocket->write(dhtJson);
|
||||
localSocket->flush();
|
||||
localSocket->disconnectFromServer();
|
||||
}
|
||||
});
|
||||
QTimer timer;
|
||||
QObject::connect(&timer, &QTimer::timeout, [&]() {
|
||||
char *dhtstring = static_cast<char*>(malloc(512));
|
||||
int result = getdhtstring(PIN, dhtstring);
|
||||
if (result == 0) {
|
||||
dhtJson = QByteArray(dhtstring).trimmed();
|
||||
}
|
||||
free(dhtstring);
|
||||
});
|
||||
timer.start(1000);
|
||||
|
||||
QTextStream(stderr) << "dhtserver: Server started successfully!" << Qt::endl;
|
||||
|
||||
return a.exec();
|
||||
}
|
Loading…
Reference in a new issue