├── AUTHORS ├── NEWS ├── README ├── ChangeLog ├── src ├── motor │ └── servo.c ├── fs │ ├── KConfig │ ├── cfs │ │ ├── KConfig │ │ ├── Makefile │ │ ├── cfs-posix-dir.c │ │ ├── cfs-posix.c │ │ ├── cfs-eeprom.c │ │ ├── cfs-ram.c │ │ ├── cfs-coffee-arch.h │ │ ├── cfs-coffee.h │ │ └── cfs-xmem.c │ ├── Makefile │ └── spiffs │ │ ├── test │ │ ├── main.c │ │ ├── testsuites.c │ │ ├── params_test.h │ │ ├── test_spiffs.h │ │ ├── testrunner.h │ │ ├── test_dev.c │ │ └── testrunner.c │ │ ├── Makefile │ │ └── params_test.h ├── disp │ ├── ascii_display.c │ ├── ascii_display.h │ ├── Makefile │ ├── KConfig │ ├── ssd1306.h │ ├── lcd7seg.h │ ├── lcd.h │ ├── ledmatrix88.h │ ├── ssd1306_priv.h │ ├── ledmatrix88.c │ ├── ks0713.h │ ├── interface.h │ ├── lcd7seg.c │ └── ledpanel.c ├── can │ └── ds402.c ├── rfid │ ├── Makefile │ └── KConfig ├── hid │ ├── Makefile │ ├── KConfig │ └── wiinunchuck.h ├── radio │ ├── Makefile │ ├── KConfig │ ├── nrf24l01.h │ └── nrf24l01registers.h ├── net │ ├── nettypes.h │ ├── KConfig │ ├── Makefile │ └── enc28j60.h ├── accgyro │ ├── Makefile.am │ ├── adxl345.h │ ├── mma7455.h │ ├── l3g4200d.h │ └── mpu6000.h ├── io │ ├── Makefile │ ├── KConfig │ ├── pcf8574.h │ ├── l74hc165.h │ ├── l74hc4051.h │ ├── l74hc595.h │ ├── l74hc4051.c │ ├── l74hc595.c │ ├── l74hc165.c │ └── pcf8574.c ├── sensors │ ├── amt1001.h │ ├── bh1750.h │ ├── dht.h │ ├── bh1750.c │ ├── dht.c │ └── amt1001.c ├── analog │ ├── 74LV4051.c │ ├── SN74LV4051.c │ └── mcp4461.c ├── range │ ├── hcsr04.h │ └── hcsr04.c ├── current │ ├── acs712.h │ └── acs712.c ├── Makefile.am ├── compass │ └── hmc5883l.h ├── baro │ └── bmp085.h ├── waterflow │ ├── fs300a.h │ └── fs300a.c ├── temperature │ ├── ds18b20.h │ └── ds18b20.c ├── mem │ └── at24.c ├── tty │ └── vt100.h ├── gpio │ └── max14890.c ├── fpga │ └── ice40.c ├── vardir.c └── usb │ └── usbd_cdc.c ├── .gitignore ├── tests ├── mock │ ├── gpio.cpp │ ├── driver.hpp │ ├── memory.hpp │ ├── printk.hpp │ ├── thread.hpp │ ├── regmap.cpp │ └── timestamp.cpp ├── m25.dts ├── Makefile.am ├── mpu6050.cpp ├── m25-dtb.h └── m25.cpp ├── include ├── Makefile.am ├── dts │ └── mcp2317.h └── hbridge │ └── drv8302.h ├── Makefile.am ├── libdriver.pc.in ├── LICENSE ├── configure.ac ├── m4 ├── ltversion.m4 └── ltsugar.m4 ├── .config ├── .clang-format └── config └── test-driver /AUTHORS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/motor/servo.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/fs/KConfig: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/disp/ascii_display.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/disp/ascii_display.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/fs/cfs/KConfig: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/can/ds402.c: -------------------------------------------------------------------------------- 1 | #include "ds402.h" 2 | -------------------------------------------------------------------------------- /src/rfid/Makefile: -------------------------------------------------------------------------------- 1 | obj-y += rfid/mfrc522.o 2 | -------------------------------------------------------------------------------- /src/fs/cfs/Makefile: -------------------------------------------------------------------------------- 1 | obj-y += fs/cfs/cfs-coffee.o 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | autom4te.cache 3 | docs/_build/ 4 | -------------------------------------------------------------------------------- /src/hid/Makefile: -------------------------------------------------------------------------------- 1 | obj-$(CONFIG_WIINUNCHUK) += hid/wiinunchuck.o 2 | -------------------------------------------------------------------------------- /src/radio/Makefile: -------------------------------------------------------------------------------- 1 | obj-$(CONFIG_NRF24L01) += radio/nrf24l01.o 2 | -------------------------------------------------------------------------------- /src/fs/Makefile: -------------------------------------------------------------------------------- 1 | include fs/cfs/Makefile 2 | include fs/spiffs/Makefile 3 | -------------------------------------------------------------------------------- /src/hid/KConfig: -------------------------------------------------------------------------------- 1 | menu "HID support" 2 | config WIINUNCHUK 3 | bool "WII nunchuck support" 4 | endmenu 5 | -------------------------------------------------------------------------------- /tests/mock/gpio.cpp: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | uint32_t gpio_read(gpio_device_t dev, uint32_t pin) { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /include/Makefile.am: -------------------------------------------------------------------------------- 1 | nobase_pkginclude_HEADERS = \ 2 | can/ds402.h\ 3 | dts/mcp2317.h\ 4 | hbridge/drv8302.h 5 | -------------------------------------------------------------------------------- /tests/mock/driver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" { 4 | #include 5 | 6 | 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/rfid/KConfig: -------------------------------------------------------------------------------- 1 | menu "RFID readers support" 2 | config MFRC522 3 | bool "MFRC522 13mhz RFID reader support" 4 | endmenu 5 | -------------------------------------------------------------------------------- /src/radio/KConfig: -------------------------------------------------------------------------------- 1 | menu "Radio modem support" 2 | config NRF24L01 3 | depends on HAVE_SPI 4 | bool "NRF24L01 SPI module" 5 | endmenu 6 | -------------------------------------------------------------------------------- /include/dts/mcp2317.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MCP2317_DIR_IN 1 4 | #define MCP2317_DIR_OUT 0 5 | #define MCP2317_NOPULL 0 6 | #define MCP2317_PULL_UP (1 << 1) 7 | -------------------------------------------------------------------------------- /src/net/nettypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * Common structures used in IP code 5 | */ 6 | 7 | typedef uint8_t ip_addr_t[4]; 8 | typedef uint8_t eth_mac_t[6]; 9 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/main.c: -------------------------------------------------------------------------------- 1 | #include "testrunner.h" 2 | #include 3 | 4 | int main(int argc, char **args) { 5 | run_tests(argc, args); 6 | exit(EXIT_SUCCESS); 7 | } 8 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | @CODE_COVERAGE_RULES@ 2 | pkgconfig_DATA=libdriver.pc 3 | ACLOCAL_AMFLAGS=-I m4 4 | SUBDIRS=include src tests 5 | EXTRA_DIST=autogen.mk 6 | AUTOMAKE_OPTIONS = subdir-objects 7 | -------------------------------------------------------------------------------- /src/accgyro/Makefile.am: -------------------------------------------------------------------------------- 1 | include_HEADERS=adxl345.h 2 | lib_LTLIBRARIES=libaccgyro.la 3 | libaccgyro_la_SOURCES=adxl345.c 4 | libaccgyro_la_CFLAGS=$(CODE_COVERAGE_CFLAGS) -std=gnu99 -Wall -Werror 5 | -------------------------------------------------------------------------------- /src/io/Makefile: -------------------------------------------------------------------------------- 1 | obj-$(CONFIG_L74HC165) += io/l74hc165.o 2 | obj-$(CONFIG_L74HC4051) += io/l74hc4051.o 3 | obj-$(CONFIG_L74HC595) += io/l74hc595.o 4 | obj-$(CONFIG_PCF8574) += io/pcf8574.o 5 | -------------------------------------------------------------------------------- /src/fs/spiffs/Makefile: -------------------------------------------------------------------------------- 1 | #obj-y += fs/spiffs/spiffs_cache.o 2 | #obj-y += fs/spiffs/spiffs_check.o 3 | #obj-y += fs/spiffs/spiffs_gc.o 4 | #obj-y += fs/spiffs/spiffs_hydrogen.o 5 | #obj-y += fs/spiffs/spiffs_nucleus.o 6 | 7 | -------------------------------------------------------------------------------- /libdriver.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | includedir=@includedir@ 4 | libdir=@libdir@ 5 | 6 | Name: libdriver 7 | Description: Portable micro drivers for embedded programming 8 | Version: @VERSION@ 9 | Cflags: 10 | Libs: -ldriver 11 | -------------------------------------------------------------------------------- /src/disp/Makefile: -------------------------------------------------------------------------------- 1 | obj-$(CONFIG_ILI9340) += disp/ili9340.o 2 | obj-$(CONFIG_LCDPAR) += disp/lcd.o 3 | obj-$(CONFIG_LEDMATRIX88) += disp/ledmatrix88.o 4 | obj-$(CONFIG_SEVSEG) += disp/lcd7seg.o 5 | obj-$(CONFIG_SSD1306) += disp/ssd1306.o 6 | obj-y += disp/ks0713.o 7 | -------------------------------------------------------------------------------- /tests/mock/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" { 4 | #include 5 | 6 | void *kzmalloc(size_t size){ 7 | return calloc(size, 1); 8 | } 9 | 10 | #include 11 | 12 | DEFINE_DEVICE_CLASS(memory) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/testsuites.c: -------------------------------------------------------------------------------- 1 | /* 2 | * testsuites.c 3 | * 4 | * Created on: Jun 19, 2013 5 | * Author: petera 6 | */ 7 | 8 | #include "testrunner.h" 9 | 10 | void add_suites() { 11 | //ADD_SUITE(dev_tests); 12 | ADD_SUITE(check_tests); 13 | ADD_SUITE(hydrogen_tests) 14 | } 15 | -------------------------------------------------------------------------------- /tests/mock/printk.hpp: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | #include 3 | #include 4 | 5 | 6 | int printk(const char *str, ...){ 7 | va_list arg; 8 | int done; 9 | va_start (arg, str); 10 | done = vfprintf(stdout, str, arg); 11 | va_end (arg); 12 | return done; 13 | } 14 | 15 | }; 16 | -------------------------------------------------------------------------------- /tests/m25.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | /* 4 | dtc -I dts -O dtb -o m25.dtb m25.dts 5 | xxd -i m25.dtb > m25-dtb.h 6 | */ 7 | 8 | / { 9 | gpio: gpio { 10 | compatible = "mock,gpio"; 11 | }; 12 | spi: spi { 13 | compatible = "mock,spi"; 14 | }; 15 | m25: m25 { 16 | compatible = "fw,m25"; 17 | spi = <&spi>; 18 | gpio = <&gpio>; 19 | cs_pin = <2>; 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /src/disp/KConfig: -------------------------------------------------------------------------------- 1 | menu "Display support" 2 | config ILI9340 3 | bool "ILI9340 serial display driver" 4 | 5 | config LCDPAR 6 | bool "Generic parallel LCD driver" 7 | 8 | config LEDMATRIX88 9 | bool "Led matrix driver" 10 | 11 | config SSD1306 12 | bool "SSD1306 OLED display driver" 13 | 14 | config SEVSEG 15 | bool "Seven segment display driver" 16 | 17 | endmenu 18 | -------------------------------------------------------------------------------- /src/io/KConfig: -------------------------------------------------------------------------------- 1 | menu "IO logic support" 2 | config L74HC165 3 | depends on HAVE_SPI 4 | bool "L74HC165 parallel to serial shift register" 5 | 6 | config L74HC4051 7 | depends on HAVE_SPI 8 | bool "L74HC4051 multiplexer support" 9 | 10 | config L74HC595 11 | depends on HAVE_SPI 12 | bool "L74HC595 serial to parallel shift register" 13 | 14 | config PCF8574 15 | bool "PCF8574 I2C io expander" 16 | endmenu 17 | -------------------------------------------------------------------------------- /src/net/KConfig: -------------------------------------------------------------------------------- 1 | menu "Network support" 2 | config ENC28J60 3 | bool "ENC28J60 SPI LAN Network Chip" 4 | 5 | config DHCP 6 | bool "DHCP protocol support" 7 | 8 | config DNS 9 | bool "DNS protocol support" 10 | 11 | config RFNET 12 | depends on NRF24L01 && AES 13 | bool "RFNET radio protocol support" 14 | 15 | config TCPIP 16 | depends on ENC28J60 17 | bool "TCPIP/UDP/ICMP protocol support" 18 | endmenu 19 | -------------------------------------------------------------------------------- /tests/mock/thread.hpp: -------------------------------------------------------------------------------- 1 | 2 | extern "C" { 3 | #include 4 | 5 | uint32_t thread_ticks_count() { 6 | } 7 | 8 | int thread_sleep_ms_until(uint32_t *time, uint32_t ms) { 9 | } 10 | 11 | int thread_sleep_ms(uint32_t ms) { 12 | } 13 | unsigned long thread_get_total_heap(void) { 14 | return 1000; 15 | } 16 | unsigned long thread_get_free_heap(void) { 17 | return 1000; 18 | } 19 | void thread_meminfo() { 20 | } 21 | 22 | int thread_create(void (*thread)(void*), const char *name, uint32_t stack, void *ptr, uint8_t prio, thread_t *handle) { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | _ ___ ____ ____ ____ _____ _______ ____ 2 | | | |_ _| __ )| _ \| _ \|_ _\ \ / / ____| _ \ 3 | | | | || _ \| | | | |_) || | \ \ / /| _| | |_) | 4 | | |___ | || |_) | |_| | _ < | | \ V / | |___| _ < 5 | |_____|___|____/|____/|_| \_\___| \_/ |_____|_| \_\ 6 | 7 | This library is distributed under GPLv2 8 | 9 | You can integrate commercial code with Rocket project without having to distribute your application under GPLv2 as long as your application only uses abstract interfaces to interact with device drivers. 10 | 11 | For commercial license email info@swedishembedded.com. 12 | 13 | -------------------------------------------------------------------------------- /include/hbridge/drv8302.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef memory_device_t drv8302_t; 6 | 7 | typedef enum { 8 | DRV8302_OC_MODE_CYCLE_BY_CYCLE, 9 | DRV8302_OC_MODE_SHUTDOWN 10 | } drv8302_oc_mode_t; 11 | 12 | typedef enum { 13 | DRV8302_GAIN_10V, 14 | DRV8302_GAIN_40V 15 | } drv8302_gain_t; 16 | 17 | void drv8302_enable_calibration(drv8302_t dev, bool en); 18 | void drv8302_set_oc_mode(drv8302_t dev, drv8302_oc_mode_t mode); 19 | void drv8302_enable(drv8302_t dev, bool en); 20 | void drv8302_set_gain(drv8302_t dev, drv8302_gain_t gain); 21 | bool drv8302_is_in_error(drv8302_t dev); 22 | bool drv8302_is_in_overcurrent(drv8302_t dev); 23 | int drv8302_get_gain(drv8302_t dev); 24 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOTEST = $(AUTOM4TE) --language=autotest 2 | 3 | TESTS =\ 4 | m25 5 | check_PROGRAMS=$(TESTS) 6 | 7 | AM_CFLAGS=\ 8 | $(COVERAGE_FLAGS)\ 9 | -I$(abs_top_builddir)/include\ 10 | -I$(srcdir)/../include 11 | AM_CXXFLAGS=\ 12 | $(COVERAGE_FLAGS)\ 13 | -include gtest/gtest.h -include gmock/gmock.h\ 14 | -ffunction-sections\ 15 | -I$(abs_top_builddir)/include\ 16 | -I$(srcdir)/../include\ 17 | -L$(abs_top_builddir)/lib\ 18 | -L/usr/local/lib 19 | AM_LDFLAGS=\ 20 | -Wl,--gc-sections -lm -lgtest -lgmock -lpthread -lfdt -lfirmware 21 | 22 | mpu6050_SOURCES=\ 23 | ../src/accgyro/mpu6050.c\ 24 | mpu6050.cpp 25 | 26 | m25_SOURCES=\ 27 | ../src/mem/m25.c\ 28 | m25.cpp 29 | 30 | AUTOMAKE_OPTIONS=subdir-objects 31 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl Process this file with autoconf to produce a configure script 2 | AC_INIT(libdriver,[0.1.0],mkschreder.uk@gmail.com) 3 | AC_CONFIG_AUX_DIR(config) 4 | AC_CONFIG_SRCDIR(./src/) 5 | AC_CONFIG_MACRO_DIR([m4]) 6 | 7 | m4_pattern_allow([AM_DEFAULT_VERBOSITY]) 8 | 9 | AM_INIT_AUTOMAKE 10 | AX_CODE_COVERAGE 11 | 12 | LT_INIT 13 | 14 | AC_PROG_CC 15 | AC_PROG_CXX 16 | 17 | AC_ARG_WITH(pkgconfigdir, 18 | AC_HELP_STRING([--with-pkgconfigdir], 19 | [Use the specified pkgconfig dir (default is libdir/pkgconfig)]), 20 | [pkgconfigdir=${withval}], 21 | [pkgconfigdir='${libdir}/pkgconfig']) 22 | AC_SUBST([pkgconfigdir]) 23 | AC_MSG_NOTICE([pkgconfig directory is ${pkgconfigdir}]) 24 | 25 | AC_CONFIG_FILES([libdriver.pc]) 26 | 27 | AC_OUTPUT(Makefile src/Makefile include/Makefile tests/Makefile) 28 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 4179 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4.6]) 16 | m4_define([LT_PACKAGE_REVISION], [2.4.6]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4.6' 20 | macro_revision='2.4.6' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /src/net/Makefile: -------------------------------------------------------------------------------- 1 | #obj-y += net/uip/psock.o net/uip/uip_arp.o net/uip/uip-fw.o net/uip/uip-neighbor.o net/uip/timer.o net/uip/uip.o net/uip/uiplib.o net/uip/uip-split.o 2 | #obj-n += net/lwip/def.o net/lwip/init.o net/lwip/netif.o net/lwip/stats.o net/lwip/tcp_in.o net/lwip/udp.o net/lwip/dhcp.o net/lwip/pbuf.o net/lwip/sys.o net/lwip/tcp_out.o net/lwip/dns.o net/lwip/raw.o net/lwip/tcp.o net/lwip/timers.o 3 | #obj-n += net/lwip/mem.o net/lwip/memp.o 4 | #obj-n += net/lwip/ipv4/autoip.o net/lwip/ipv4/igmp.o net/lwip/ipv4/inet_chksum.o net/lwip/ipv4/ip.o net/lwip/ipv4/icmp.o net/lwip/ipv4/inet.o net/lwip/ipv4/ip_addr.o net/lwip/ipv4/ip_frag.o 5 | INCLUDES += -Iinclude/ipv4/ 6 | 7 | #obj-$(CONFIG_DHCP) += dhcp.o 8 | #obj-$(CONFIG_DNS) += dns.o 9 | obj-$(CONFIG_ENC28J60) += net/enc28j60.o 10 | #obj-$(CONFIG_RFNET) += rfnet.o 11 | #obj-$(CONFIG_TCPIP) += tcpip.o 12 | -------------------------------------------------------------------------------- /src/disp/ssd1306.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "interface.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #define SSD1306_128_64 10 | // #define SSD1306_128_32 11 | 12 | typedef struct ssd1306 { 13 | i2c_dev_t i2c; 14 | uint8_t r_row_start, r_row_end; 15 | } ssd1306_t; 16 | 17 | void ssd1306_init(ssd1306_t *dev, i2c_dev_t i2c); 18 | void ssd1306_set_region(ssd1306_t *dev, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); 19 | void ssd1306_fill(ssd1306_t *dev, fb_color_t color, size_t len); 20 | void ssd1306_draw(ssd1306_t *dev, uint16_t x, uint16_t y, fb_image_t img); 21 | void ssd1306_gotoChar(ssd1306_t *dev, uint8_t x, uint8_t y); 22 | void ssd1306_clear(ssd1306_t *dev); 23 | int16_t ssd1306_puts(ssd1306_t *dev, const char *str, uint8_t col); 24 | int16_t ssd1306_printf(ssd1306_t *dev, uint8_t col, const char *str, ...); 25 | void ssd1306_reset(ssd1306_t *dev); 26 | 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /tests/mock/regmap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" { 4 | int regmap_write_u32(regmap_device_t dev, uint32_t id, uint32_t value) { 5 | printf("fb_test: regmap write %08x %08x\n", id, value); 6 | return 0; 7 | } 8 | 9 | int regmap_mem_to_u16(regmap_value_type_t type, const void *data, size_t size, 10 | uint16_t *out) { 11 | return 0; 12 | } 13 | int regmap_mem_to_u32(regmap_value_type_t type, const void *data, size_t size, 14 | uint32_t *out) { 15 | return 0; 16 | } 17 | 18 | int regmap_convert_u32(uint32_t value, regmap_value_type_t type, void *data, 19 | size_t size) { 20 | return 0; 21 | } 22 | 23 | int regmap_convert_u16(uint16_t value, regmap_value_type_t type, void *data, 24 | size_t size) { 25 | return 0; 26 | } 27 | 28 | void regmap_range_init(struct regmap_range *self, uint32_t start, uint32_t end, 29 | const struct regmap_range_ops *ops) { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/mpu6050.cpp: -------------------------------------------------------------------------------- 1 | /** :ms-top-comment 2 | * _____ _ _ ____ 3 | * | ___| |_ _(_)_ __ __ _| __ ) ___ _ __ __ _ _ __ ___ __ _ _ __ 4 | * | |_ | | | | | | '_ \ / _` | _ \ / _ \ '__/ _` | '_ ` _ \ / _` | '_ \ 5 | * | _| | | |_| | | | | | (_| | |_) | __/ | | (_| | | | | | | (_| | | | | 6 | * |_| |_|\__, |_|_| |_|\__, |____/ \___|_| \__, |_| |_| |_|\__,_|_| |_| 7 | * |___/ |___/ |___/ 8 | **/ 9 | 10 | extern "C" { 11 | 12 | } 13 | 14 | #include "mock/timestamp.cpp" 15 | #include "mock/regmap.cpp" 16 | #include "mock/thread.cpp" 17 | #include "mock/gpio.cpp" 18 | 19 | class MPU6050Test : public ::testing::Test { 20 | protected: 21 | void SetUp() { 22 | //fb_init(&fb); 23 | } 24 | void TearDown() { 25 | } 26 | void clock(unsigned cycles) { 27 | 28 | } 29 | }; 30 | 31 | TEST_F(MPU6050Test, check_init) { 32 | } 33 | 34 | int main(int argc, char **argv) { 35 | ::testing::InitGoogleMock(&argc, argv); 36 | return RUN_ALL_TESTS(); 37 | } 38 | -------------------------------------------------------------------------------- /src/disp/lcd7seg.h: -------------------------------------------------------------------------------- 1 | /* 2 | sevseg lib 0x03 3 | 4 | copyright (c) Davide Gironi, 2012 5 | 6 | Released under GPLv3. 7 | Please refer to LICENSE file for licensing information. 8 | */ 9 | #ifndef SEVSEG_H_ 10 | #define SEVSEG_H_ 11 | 12 | #include 13 | 14 | //definitions 15 | typedef enum { 16 | SEVSEG_TYPECC, //common cathode 17 | SEVSEG_TYPECA, //common anode type 18 | SEVSEG_TYPECCT, //common cathode / full transistor type 19 | SEVSEG_TYPECAT //common anode type / full transistor type 20 | } lcd7seg_type; 21 | 22 | struct led7seg { 23 | pio_dev_t port; 24 | uint8_t type; 25 | uint8_t cs_pin; 26 | uint8_t data_port; 27 | uint8_t data; 28 | }; 29 | 30 | //functions 31 | void led7seg_init(struct led7seg *self, 32 | pio_dev_t port, uint8_t data_port, gpio_pin_t cs_pin, lcd7seg_type type); 33 | void led7seg_putc(struct led7seg *self, uint8_t c, uint8_t dot); 34 | 35 | void led7seg_on(struct led7seg *self); 36 | void led7seg_off(struct led7seg *self); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/fs/spiffs/params_test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * params_test.h 3 | * 4 | * Created on: May 26, 2013 5 | * Author: petera 6 | */ 7 | 8 | #ifndef PARAMS_TEST_H_ 9 | #define PARAMS_TEST_H_ 10 | 11 | // total emulated spi flash size 12 | #define PHYS_FLASH_SIZE (16*1024*1024) 13 | // spiffs file system size 14 | #define SPIFFS_FLASH_SIZE (2*1024*1024) 15 | // spiffs file system offset in emulated spi flash 16 | #define SPIFFS_PHYS_ADDR (4*1024*1024) 17 | 18 | #define SECTOR_SIZE 65536 19 | #define LOG_BLOCK (SECTOR_SIZE*2) 20 | #define LOG_PAGE (SECTOR_SIZE/256) 21 | 22 | #define FD_BUF_SIZE 64*6 23 | #define CACHE_BUF_SIZE (LOG_PAGE + 32)*8 24 | 25 | #define ASSERT(c, m) real_assert((c),(m), __FILE__, __LINE__); 26 | 27 | typedef signed int s32_t; 28 | typedef unsigned int u32_t; 29 | typedef signed short s16_t; 30 | typedef unsigned short u16_t; 31 | typedef signed char s8_t; 32 | typedef unsigned char u8_t; 33 | 34 | void real_assert(int c, const char *n, const char *file, int l); 35 | 36 | #endif /* PARAMS_TEST_H_ */ 37 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/params_test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * params_test.h 3 | * 4 | * Created on: May 26, 2013 5 | * Author: petera 6 | */ 7 | 8 | #ifndef PARAMS_TEST_H_ 9 | #define PARAMS_TEST_H_ 10 | 11 | // total emulated spi flash size 12 | #define PHYS_FLASH_SIZE (16*1024*1024) 13 | // spiffs file system size 14 | #define SPIFFS_FLASH_SIZE (2*1024*1024) 15 | // spiffs file system offset in emulated spi flash 16 | #define SPIFFS_PHYS_ADDR (4*1024*1024) 17 | 18 | #define SECTOR_SIZE 65536 19 | #define LOG_BLOCK (SECTOR_SIZE*2) 20 | #define LOG_PAGE (SECTOR_SIZE/256) 21 | 22 | #define FD_BUF_SIZE 64*6 23 | #define CACHE_BUF_SIZE (LOG_PAGE + 32)*8 24 | 25 | #define ASSERT(c, m) real_assert((c),(m), __FILE__, __LINE__); 26 | 27 | typedef signed int s32_t; 28 | typedef unsigned int u32_t; 29 | typedef signed short s16_t; 30 | typedef unsigned short u16_t; 31 | typedef signed char s8_t; 32 | typedef unsigned char u8_t; 33 | 34 | void real_assert(int c, const char *n, const char *file, int l); 35 | 36 | #endif /* PARAMS_TEST_H_ */ 37 | -------------------------------------------------------------------------------- /src/io/pcf8574.h: -------------------------------------------------------------------------------- 1 | /* 2 | pcf8574 lib 0x01 3 | 4 | copyright (c) Davide Gironi, 2012 5 | 6 | Released under GPLv3. 7 | Please refer to LICENSE file for licensing information. 8 | */ 9 | 10 | 11 | #ifndef PCF8574_H_ 12 | #define PCF8574_H_ 13 | 14 | struct pcf8574 { 15 | i2c_dev_t i2c; 16 | uint8_t device_id; 17 | uint8_t in_reg, out_reg; 18 | }; 19 | 20 | void pcf8574_init(struct pcf8574 *self, i2c_dev_t i2c, uint8_t device_id); 21 | 22 | uint8_t pcf8574_write_word(struct pcf8574 *self, uint8_t data); 23 | uint8_t pcf8574_write_pin(struct pcf8574 *self, uint8_t pin, uint8_t value); 24 | uint8_t pcf8574_read_word(struct pcf8574 *self); 25 | uint8_t pcf8574_read_pin(struct pcf8574 *self, uint8_t pin); 26 | 27 | //extern int8_t pcf8574_getoutput(uint8_t deviceid); 28 | //extern int8_t pcf8574_getoutputpin(uint8_t deviceid, uint8_t pin); 29 | //extern int8_t pcf8574_setoutputpinhigh(uint8_t deviceid, uint8_t pin); 30 | //extern int8_t pcf8574_setoutputpinlow(uint8_t deviceid, uint8_t pin); 31 | //extern int8_t pcf8574_setoutputpins(uint8_t deviceid, uint8_t pinstart, uint8_t pinlength, int8_t data); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/sensors/amt1001.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Github: https://github.com/mkschreder 18 | 19 | Contributors: 20 | * Davide Gironi - developing original driver 21 | * Martin K. Schröder - maintenance since Oct 2014 22 | */ 23 | 24 | #ifndef AMT1001_H_ 25 | #define AMT1001_H_ 26 | 27 | 28 | 29 | //functions 30 | extern int16_t amt1001_gethumidity(double voltage); 31 | extern int16_t amt1001_gettemperature(uint16_t adcvalue); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/analog/74LV4051.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of libdriver 3 | * 4 | * Copyright (c) 2019 Martin Schröder 5 | * 6 | * Ninjaflight is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Ninjaflight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Ninjaflight. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/disp/lcd.h: -------------------------------------------------------------------------------- 1 | /* 2 | Parallel LCD library for use with parallel interfaces 3 | 4 | copyright (c) 5 | * Martin Schröder 2014 6 | * Davide Gironi, 2013 7 | 8 | Released under GPLv3. 9 | Please refer to LICENSE file for licensing information. 10 | 11 | References: 12 | + based on lcd library by Peter Fleury 13 | http://jump.to/fleury 14 | */ 15 | 16 | 17 | #ifndef LCD_H 18 | #define LCD_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | struct lcd { 25 | pio_dev_t port; 26 | uint8_t dataport; 27 | }; 28 | 29 | extern void lcd_init(struct lcd *self, pio_dev_t port, uint8_t dispAttr); 30 | extern void lcd_clrscr(struct lcd *self); 31 | extern void lcd_home(struct lcd *self); 32 | extern void lcd_gotoxy(struct lcd *self, uint8_t x, uint8_t y); 33 | extern void lcd_led(struct lcd *self, uint8_t onoff); 34 | extern void lcd_putc(struct lcd *self, char c); 35 | extern void lcd_puts(struct lcd *self, const char *s); 36 | extern void lcd_puts_p(struct lcd *self, const char *progmem_s); 37 | extern void lcd_command(struct lcd *self, uint8_t cmd); 38 | extern void lcd_data(struct lcd *self, uint8_t data); 39 | 40 | /*@}*/ 41 | #endif //LCD_H 42 | -------------------------------------------------------------------------------- /src/range/hcsr04.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Github: https://github.com/mkschreder 18 | 19 | Contributors: 20 | * Martin K. Schröder - original driver 21 | */ 22 | 23 | #ifndef HCSR04_H 24 | #define HCSR04_H 25 | 26 | struct hcsr04 { 27 | pio_dev_t gpio; 28 | gpio_pin_t trigger_pin, echo_pin; 29 | uint8_t state; 30 | timestamp_t pulse_timeout; 31 | int16_t distance; 32 | }; 33 | 34 | void hcsr04_init(struct hcsr04 *self, pio_dev_t gpio, 35 | gpio_pin_t trigger_pin, gpio_pin_t echo_pin); 36 | int16_t hcsr04_read_distance_in_cm(struct hcsr04 *self); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/sensors/bh1750.h: -------------------------------------------------------------------------------- 1 | /* 2 | Light sensor driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #ifndef BH1750_H_ 26 | #define BH1750_H_ 27 | 28 | #define BH1750_ADDR (0x23<<1) //device address 29 | 30 | struct bh1750 { 31 | i2c_dev_t i2c; 32 | uint8_t addr; 33 | }; 34 | 35 | void bh1750_init(struct bh1750 *self, i2c_dev_t i2c, uint8_t addr); 36 | uint16_t bh1750_read_intensity_lux(struct bh1750 *self); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/analog/SN74LV4051.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of libdriver 3 | * 4 | * Copyright (c) 2019 Martin Schröder 5 | * 6 | * Ninjaflight is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Ninjaflight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Ninjaflight. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | static int _744051_probe(void *fdt, int fdt_node){ 33 | return 0; 34 | } 35 | 36 | static int _744051_remove(void *fdt, int fdt_node){ 37 | return 0; 38 | } 39 | 40 | DEVICE_DRIVER(sn74lv4051, "fw,sn74lv4051", _744051_probe, _744051_remove) 41 | -------------------------------------------------------------------------------- /src/current/acs712.h: -------------------------------------------------------------------------------- 1 | /* 2 | Current sensor driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | #pragma once 25 | 26 | #include 27 | 28 | //defined sensitivity 29 | #define ACS712_SENSITIVITY5 0.185 30 | #define ACS712_SENSITIVITY20 0.100 31 | #define ACS712_SENSITIVITY30 0.066 32 | 33 | //setup sensitivity 34 | #define ACS712_SENSITIVITY ACS712_SENSITIVITY30 35 | 36 | float acs712_read_current(uint8_t adc_chan, 37 | float sensitivity, float vcc_volt); 38 | -------------------------------------------------------------------------------- /tests/mock/timestamp.cpp: -------------------------------------------------------------------------------- 1 | /** :ms-top-comment 2 | * _____ _ _ ____ 3 | * | ___| |_ _(_)_ __ __ _| __ ) ___ _ __ __ _ _ __ ___ __ _ _ __ 4 | * | |_ | | | | | | '_ \ / _` | _ \ / _ \ '__/ _` | '_ ` _ \ / _` | '_ \ 5 | * | _| | | |_| | | | | | (_| | |_) | __/ | | (_| | | | | | | (_| | | | | 6 | * |_| |_|\__, |_|_| |_|\__, |____/ \___|_| \__, |_| |_| |_|\__,_|_| |_| 7 | * |___/ |___/ |___/ 8 | **/ 9 | #include 10 | 11 | extern "C" { 12 | static uint32_t _usec = 0; 13 | 14 | timestamp_t _us_to_timestamp(uint32_t us) { 15 | return (timestamp_t){.sec = _usec / 1000000U, .usec = _usec % 1000000U}; 16 | } 17 | 18 | uint32_t _timestamp_to_us(timestamp_t ts) { 19 | return ts.sec * 1000000 + ts.usec; 20 | } 21 | 22 | uint32_t micros(){ 23 | return _usec; 24 | } 25 | 26 | timestamp_t timestamp() { 27 | _us_to_timestamp(_usec); 28 | } 29 | 30 | timestamp_t timestamp_from_now_us(usec_t us) { 31 | _us_to_timestamp(_usec + us); 32 | } 33 | 34 | timestamp_t timestamp_from_now_ms(usec_t ms) { 35 | _us_to_timestamp(_usec + ms * 1000); 36 | } 37 | 38 | int timestamp_expired(timestamp_t ts) { 39 | uint32_t us = _timestamp_to_us(ts); 40 | return us > _usec; 41 | } 42 | 43 | timestamp_t timestamp_add_us(timestamp_t ts, uint32_t us){ 44 | return _us_to_timestamp(_timestamp_to_us(ts) + us); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/accgyro/adxl345.h: -------------------------------------------------------------------------------- 1 | /* 2 | Accelerometer driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #define ADXL345_ADDR (0x53<<1) //device address 26 | 27 | #include "../i2c/i2c.h" 28 | 29 | struct adxl345 { 30 | i2c_dev_t i2c; 31 | uint8_t addr; 32 | }; 33 | 34 | void adxl345_init(struct adxl345 *self, i2c_dev_t i2c, uint8_t addr); 35 | int8_t adxl345_read_raw(struct adxl345 *self, int16_t *ax, int16_t *ay, int16_t *az); 36 | int8_t adxl345_read_adjusted(struct adxl345 *self, float *ax, float *ay, float *az); 37 | -------------------------------------------------------------------------------- /src/io/l74hc165.h: -------------------------------------------------------------------------------- 1 | /** 2 | input shift register driver for generic parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #ifndef L74HC165_H_ 26 | #define L74HC165_H_ 27 | 28 | struct l74hc165 { 29 | pio_dev_t port; 30 | gpio_pin_t clock_pin; 31 | gpio_pin_t load_pin; 32 | gpio_pin_t data_pin; 33 | }; 34 | 35 | void l74hc165_init(struct l74hc165 *self, pio_dev_t port, 36 | gpio_pin_t clock_pin, gpio_pin_t load_pin, gpio_pin_t data_pin); 37 | void l74hc165_read(struct l74hc165 *self, uint8_t *data, uint8_t count); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/io/l74hc4051.h: -------------------------------------------------------------------------------- 1 | /** 2 | 8 bit multiplexer driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #ifndef L74HC4051_H_ 26 | #define L74HC4051_H_ 27 | 28 | #define L74HC4051_MAXCH 8 29 | 30 | struct l74hc4051 { 31 | pio_dev_t port; 32 | gpio_pin_t s0_pin; 33 | gpio_pin_t s1_pin; 34 | gpio_pin_t s2_pin; 35 | }; 36 | 37 | void l74hc4051_init(struct l74hc4051 *self, pio_dev_t port, 38 | gpio_pin_t s0_pin, gpio_pin_t s1_pin, gpio_pin_t s2_pin); 39 | void l74hc4051_set_channel(struct l74hc4051 *self, uint8_t channel); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/current/acs712.c: -------------------------------------------------------------------------------- 1 | /* 2 | Current sensor driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | /* 26 | * get the current 27 | * current = (V - Vref/2) / sensitivity 28 | */ 29 | 30 | #include 31 | 32 | #include "acs712.h" 33 | 34 | float acs712_read_current(uint8_t adc_chan, 35 | float sensitivity, float vcc_volt) { 36 | (void)(adc_chan); 37 | uint16_t adc_value = adc0_read_immediate_ref(adc_chan, ADC_REF_AVCC_CAP_AREF); 38 | float volt = ((float)(adc_value) / (float)(65535)) * vcc_volt; 39 | return (volt - (vcc_volt / 2)) / sensitivity; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LIBRARIES=libdriver.a 2 | libdriver_a_SOURCES=\ 3 | accgyro/mpu6500.c\ 4 | analog/lp55231.c\ 5 | analog/mcp4461.c\ 6 | baro/bmp280.c\ 7 | can/canopen.c\ 8 | disp/ili9340.c\ 9 | disp/ledpanel.c\ 10 | fpga/ice40.c\ 11 | gpio/mcp2317.c\ 12 | gpio/max14890.c\ 13 | hbridge/drv8302.c\ 14 | mem/at24.c\ 15 | mem/m25.c\ 16 | pointer/pmw3360.c\ 17 | pointer/adns3080.c\ 18 | range/vl6180.c\ 19 | usb/usbd_cdc.c\ 20 | tty/console.c\ 21 | vardir.c 22 | libdriver_a_LIBADD= 23 | libdriver_a_CFLAGS = -I$(top_srcdir)/include 24 | 25 | other_sources =\ 26 | accgyro/adxl345.c\ 27 | accgyro/mpu6000.c\ 28 | accgyro/l3g4200d.c\ 29 | accgyro/mma7455.c\ 30 | accgyro/mpu6050.c\ 31 | accgyro/mpu6050dmp6.c\ 32 | baro/bmp085.c\ 33 | block/at24.c\ 34 | block/serial_flash.c\ 35 | compass/hmc5883l.c\ 36 | current/acs712.c\ 37 | disp/ascii_display.c\ 38 | disp/ili9340.c\ 39 | disp/ks0713.c\ 40 | disp/lcd.c\ 41 | disp/lcd7seg.c\ 42 | disp/ledmatrix88.c\ 43 | disp/ssd1306.c\ 44 | io/l74hc165.c\ 45 | io/l74hc4051.c\ 46 | io/l74hc595.c\ 47 | io/pcf8574.c\ 48 | net/enc28j60.c\ 49 | radio/nrf24l01.c\ 50 | range/hcsr04.c\ 51 | rfid/mfrc522.c\ 52 | sensors/amt1001.c\ 53 | sensors/bh1750.c\ 54 | sensors/dht.c\ 55 | temperature/ds18b20.c\ 56 | tty/vt100.c\ 57 | waterflow/fs300a.c 58 | 59 | libdriver_a_CFLAGS+=-I$(top_srcdir)/include/libdriver 60 | AUTOMAKE_OPTIONS = subdir-objects 61 | -------------------------------------------------------------------------------- /src/io/l74hc595.h: -------------------------------------------------------------------------------- 1 | /** 2 | output shift register driver for generic parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #pragma once 26 | 27 | //setup ports 28 | #define L74HC595_DDR DDRB 29 | #define L74HC595_PORT PORTB 30 | #define L74HC595_STCPIN PB1 31 | //#define L74HC595_CEPIN PB2 32 | struct l74hc595 { 33 | serial_dev_t spi; 34 | pio_dev_t gpio; 35 | gpio_pin_t ce_pin; 36 | gpio_pin_t stc_pin; 37 | }; 38 | 39 | void l74hc595_init(struct l74hc595 *self, serial_dev_t spi, 40 | pio_dev_t gpio, gpio_pin_t ce_pin, gpio_pin_t stc_pin); 41 | void l74hc595_write(struct l74hc595 *self, uint8_t val); 42 | 43 | -------------------------------------------------------------------------------- /src/net/enc28j60.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nettypes.h" 4 | 5 | struct enc28j60 { 6 | serial_dev_t serial; // for serial com 7 | pio_dev_t port; // for cs pin 8 | gpio_pin_t cs_pin; 9 | 10 | uint16_t next_packet_ptr; 11 | uint8_t bank; 12 | 13 | // exported interfaces 14 | struct serial_if *_ex_serial; 15 | }; 16 | 17 | 18 | // functions 19 | /* 20 | uint8_t enc28j60_ReadOp(struct enc28j60 *self, uint8_t op, uint8_t address); 21 | void enc28j60_WriteOp(struct enc28j60 *self, uint8_t op, uint8_t address, uint8_t data); 22 | void enc28j60_ReadBuffer(struct enc28j60 *self, uint16_t len, uint8_t* data); 23 | void enc28j60_WriteBuffer(struct enc28j60 *self, uint16_t len, uint8_t* data); 24 | void enc28j60_SetBank(struct enc28j60 *self, uint8_t address); 25 | uint8_t enc28j60_Read(struct enc28j60 *self, uint8_t address); 26 | void enc28j60_Write(struct enc28j60 *self, uint8_t address, uint8_t data); 27 | void enc28j60_PhyWrite(struct enc28j60 *self, uint8_t address, uint16_t data); 28 | void enc28j60_clkout(struct enc28j60 *self, uint8_t clk); 29 | void InitPhy (struct enc28j60 *self); 30 | */ 31 | 32 | void enc28j60_init(struct enc28j60 *self, serial_dev_t serial, pio_dev_t port, gpio_pin_t cs_pin); 33 | void enc28j60_set_mac_addr(struct enc28j60 *self, const eth_mac_t macaddr); 34 | void enc28j60_send(struct enc28j60 *self, const uint8_t* packet, uint16_t size); 35 | uint16_t enc28j60_recv(struct enc28j60 *self, uint8_t* packet, uint16_t maxlen); 36 | uint8_t enc28j60_read_version(struct enc28j60 *self); 37 | 38 | struct serial_interface *enc28j60_get_serial_interface(struct enc28j60 *self); 39 | -------------------------------------------------------------------------------- /src/accgyro/mma7455.h: -------------------------------------------------------------------------------- 1 | /* 2 | MMA7455 accelerometer driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #ifndef MMA7455_H_ 26 | #define MMA7455_H_ 27 | 28 | #include 29 | 30 | //definitions 31 | #define MMA7455_ADDR (0x1D<<1) //device address 32 | 33 | struct mma7455 { 34 | i2c_device_t i2c; 35 | uint8_t addr; 36 | uint8_t mode; 37 | }; 38 | 39 | //functions declarations 40 | void mma7455_init(struct mma7455 *self, i2c_device_t i2c, uint8_t addr, uint8_t mode); 41 | void mma7455_getdata(struct mma7455 *self, float *ax, float *ay, float *az); 42 | #if MMA7455_GETATTITUDE == 1 43 | void mma7455_getpitchroll(struct mma7455 *self, float ax, float ay, float az, float *pitch, float *roll); 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/disp/ledmatrix88.h: -------------------------------------------------------------------------------- 1 | /** 2 | 8x8 led matrix display driver for 8 bit parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #ifndef LEDMATRIX88_H_ 26 | #define LEDMATRIX88_H_ 27 | 28 | #include 29 | 30 | struct ledmatrix88 { 31 | pio_dev_t port; 32 | uint8_t x_bank, y_bank; 33 | uint8_t data[8]; // pixel data 34 | uint8_t cur_x, cur_y; // for updates 35 | }; 36 | 37 | //functions 38 | extern void ledmatrix88_init(struct ledmatrix88 *self, 39 | pio_dev_t port, uint8_t x_bank, uint8_t y_bank); 40 | extern void ledmatrix88_write_row(struct ledmatrix88 *self, uint8_t row, uint8_t data); 41 | extern uint8_t ledmatrix88_read_row(struct ledmatrix88 *self, uint8_t row); 42 | extern void ledmatrix88_clear(struct ledmatrix88 *self); 43 | extern void ledmatrix88_update(struct ledmatrix88 *self); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/compass/hmc5883l.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Github: https://github.com/mkschreder 18 | 19 | Contributors: 20 | * Davide Gironi - developing original driver 21 | * Martin K. Schröder - maintenance since Oct 2014 22 | */ 23 | #ifndef HMC5883L_H_ 24 | #define HMC5883L_H_ 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | //definitions 31 | #define HMC5883L_ADDR (0x1E<<1) //device address 32 | 33 | struct hmc5883l { 34 | i2c_dev_t i2c; 35 | uint8_t addr; 36 | float scale; 37 | }; 38 | 39 | //functions 40 | void hmc5883l_init(struct hmc5883l *self, i2c_dev_t i2c, uint8_t addr); 41 | void hmc5883l_readRawMag(struct hmc5883l *self, int16_t *mxraw, int16_t *myraw, int16_t *mzraw); 42 | void hmc5883l_read_adjusted(struct hmc5883l *self, float *mx, float *my, float *mz); 43 | void hmc5883l_convertMag(struct hmc5883l *self, 44 | int16_t mxraw, int16_t myraw, int16_t mzraw, 45 | float *mx, float *my, float *mz); 46 | uint32_t hmc5883l_read_id(struct hmc5883l *self); 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/sensors/dht.h: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | */ 22 | 23 | #pragma once 24 | 25 | /* 26 | //setup port 27 | #define DHT_DDR DDRD 28 | #define DHT_PORT PORTD 29 | #define DHT_PIN PIND 30 | #define DHT_INPUTPIN PD2 31 | */ 32 | 33 | //sensor type 34 | #define DHT_DHT11 1 35 | #define DHT_DHT22 2 36 | #define DHT_TYPE DHT_DHT11 37 | 38 | //enable decimal precision (float) 39 | #if DHT_TYPE == DHT_DHT11 40 | #define DHT_FLOAT 0 41 | #elif DHT_TYPE == DHT_DHT22 42 | #define DHT_FLOAT 1 43 | #endif 44 | 45 | //timeout retries 46 | #define DHT_TIMEOUT 200 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | struct dht { 53 | pio_dev_t gpio; 54 | gpio_pin_t signal_pin; 55 | uint8_t sensor_type; 56 | }; 57 | 58 | void dht_init(struct dht *self, 59 | pio_dev_t gpio, gpio_pin_t signal_pin, uint8_t sensor_type); 60 | int8_t dht_read(struct dht *self, int8_t *temperature, int8_t *humidity); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /src/sensors/bh1750.c: -------------------------------------------------------------------------------- 1 | /* 2 | Light sensor driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #include 26 | 27 | #include 28 | 29 | #include "bh1750.h" 30 | 31 | //resolution modes 32 | #define BH1750_MODEH 0x10 //continuously h-resolution mode, 1lx resolution, 120ms 33 | #define BH1750_MODEH2 0x11 //continuously h-resolution mode, 0.5lx resolution, 120ms 34 | #define BH1750_MODEL 0x13 //continuously l-resolution mode, 4x resolution, 16ms 35 | //define active resolution mode 36 | #define BH1750_MODE BH1750_MODEH 37 | 38 | void bh1750_init(struct bh1750 *self, i2c_dev_t i2c, uint8_t addr) { 39 | self->i2c = i2c; 40 | self->addr = addr; 41 | uint8_t mode = BH1750_MODE; 42 | i2c_start_write(i2c, addr, &mode, 1); 43 | i2c_stop(i2c); 44 | } 45 | 46 | uint16_t bh1750_read_intensity_lux(struct bh1750 *self) { 47 | uint16_t ret = 0; 48 | 49 | i2c_start_read(self->i2c, self->addr, (uint8_t*)&ret, 2); 50 | i2c_stop(self->i2c); 51 | return ret / 1.2f; 52 | } 53 | -------------------------------------------------------------------------------- /src/accgyro/l3g4200d.h: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | */ 22 | 23 | #ifndef L3G4200D_H_ 24 | #define L3G4200D_H_ 25 | 26 | #ifdef __cplusplus 27 | "C" { 28 | #endif 29 | 30 | #include 31 | 32 | //definitions 33 | #define L3G4200D_ADDR (0x69<<1) //device address 34 | 35 | struct l3g4200d { 36 | i2c_device_t i2c; 37 | uint8_t addr; 38 | int8_t temperatureref; 39 | float offsetx, offsety, offsetz; 40 | }; 41 | 42 | //functions 43 | void l3g4200d_init(struct l3g4200d *self, i2c_device_t i2c, uint8_t addr); 44 | void l3g4200d_setoffset(struct l3g4200d *self, float offsetx, float offsety, float offsetz); 45 | void l3g4200d_read_raw(struct l3g4200d *self, int16_t *gxraw, int16_t *gyraw, int16_t *gzraw); 46 | void l3g4200d_read_converted(struct l3g4200d *self, float* gx, float* gy, float* gz); 47 | void l3g4200d_settemperatureref(struct l3g4200d *self); 48 | int8_t l3g4200d_gettemperaturediff(struct l3g4200d *self); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/baro/bmp085.h: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * this library is a porting of the bmp085driver 0.4 ardunio library 21 | http://code.google.com/p/bmp085driver/ 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #ifndef BMP085_H_ 26 | #define BMP085_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #define BMP085_ADDR (0x77<<1) //0x77 default I2C address 35 | 36 | struct bmp085 { 37 | i2c_dev_t i2c; 38 | uint8_t addr; 39 | int regac1, regac2, regac3, regb1, regb2, regmb, regmc, regmd; 40 | unsigned int regac4, regac5, regac6; 41 | }; 42 | 43 | //functions 44 | /// inits the device over the interface supplied 45 | void bmp085_init(struct bmp085 *self, i2c_dev_t i2c, uint8_t addr); 46 | /// returns pressure 47 | long bmp085_read_pressure(struct bmp085 *self); 48 | /// returns altitude 49 | float bmp085_read_altitude(struct bmp085 *self); 50 | /// returns temperature 51 | float bmp085_read_temperature(struct bmp085 *self); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | #endif 57 | -------------------------------------------------------------------------------- /src/waterflow/fs300a.h: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | */ 22 | 23 | #ifndef FS300A_H_ 24 | #define FS300A_H_ 25 | 26 | #include 27 | 28 | //setup button port 29 | #define FS300A_DDR DDRC 30 | #define FS300A_PIN PINC 31 | #define FS300A_PORT PORTC 32 | #define FS300A_INPUT1 PC5 33 | 34 | /* 35 | * timer setting 36 | * TIMER0_MSREPEATMS is the frequency of the timer 37 | * TIMER0_FS300ARESET is the countdown timer and it is = 1/TIMER0_MSREPEATMS 38 | * freq = 1 / time 39 | * es. 500hz = 1 / 0.002 (2ms) 40 | * timerfreq = (FCPU / prescaler) / timerscale 41 | * timerscale 8-bit = 256 42 | * es. 488 = (1000000 / 8) / 256 43 | * 1 / 488 = 0.002s 44 | */ 45 | #define TIMER0_PRESCALER (1<> 4) & 0x0f), // set higher 4 bit of the col adr to 0 44 | 0x0b0, // | row & 0x0f, // page address 45 | U8G_ESC_END, // end of sequence 46 | }; 47 | -------------------------------------------------------------------------------- /src/hid/wiinunchuck.h: -------------------------------------------------------------------------------- 1 | /* 2 | wiinunchuck 0x02 3 | 4 | copyright (c) Davide Gironi, 2011 5 | 6 | Released under GPLv3. 7 | Please refer to LICENSE file for licensing information. 8 | */ 9 | 10 | #ifndef WIINUNCHUCK_H_ 11 | #define WIINUNCHUCK_H_ 12 | 13 | 14 | //enable a more precise function for centering joypad 15 | //0 to select o static offset center 16 | //1 to enable a math function to center the joypad 17 | #define WIINUNCHUCK_JOYCENTERB 1 18 | 19 | //get non calibrated values, use this function to calibrate the device 20 | #define WIINUNCHUCK_GETNONCALIBRATED 0 21 | 22 | //pulse button enabled 23 | #define WIINUNCHUCK_PULSEBUTTON 0 24 | 25 | //angle filter enabled 26 | #define WIINUNCHUCK_ANGLEFILTER 1 27 | #define WIINUNCHUCK_ANGLEAVARAGECOEF 21 //number of samples to avarage 28 | 29 | struct wiinunchuck { 30 | i2c_dev_t i2c; 31 | 32 | uint8_t joyX; 33 | uint8_t joyY; 34 | #if WIINUNCHUCK_PULSEBUTTON == 1 35 | uint8_t lastbuttonZ; 36 | uint8_t lastbuttonC; 37 | #endif 38 | uint8_t buttonZ; 39 | uint8_t buttonC; 40 | int angleX; 41 | int angleY; 42 | int angleZ; 43 | #if WIINUNCHUCK_ANGLEFILTER == 1 44 | int avarageangleX[WIINUNCHUCK_ANGLEAVARAGECOEF]; 45 | int avarageangleY[WIINUNCHUCK_ANGLEAVARAGECOEF]; 46 | int avarageangleZ[WIINUNCHUCK_ANGLEAVARAGECOEF]; 47 | #endif 48 | }; 49 | 50 | //functions 51 | extern void wiinunchuck_calibratejoy(struct wiinunchuck *self); 52 | extern void wiinunchuck_init(struct wiinunchuck *self, i2c_dev_t i2c); 53 | extern int wiinunchuck_getjoyX(struct wiinunchuck *self); 54 | extern int wiinunchuck_getjoyY(struct wiinunchuck *self); 55 | extern uint8_t wiinunchuck_getbuttonZ(struct wiinunchuck *self); 56 | extern uint8_t wiinunchuck_getbuttonC(struct wiinunchuck *self); 57 | extern int wiinunchuck_getangleX(struct wiinunchuck *self); 58 | extern int wiinunchuck_getangleY(struct wiinunchuck *self); 59 | extern int wiinunchuck_getangleZ(struct wiinunchuck *self); 60 | extern void wiinunchuck_update(struct wiinunchuck *self); 61 | extern void wiinunchuck_getpitchroll(struct wiinunchuck *self, double ax, double ay, double az, double *pitch, double *roll); 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /src/accgyro/mpu6000.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Github: https://github.com/mkschreder 18 | 19 | Contributors: 20 | * John Ihlein - developing original driver 21 | * Martin K. Schröder - maintenance since Jan 2015 22 | */ 23 | 24 | #pragma once 25 | 26 | struct mpu6000{ 27 | serial_port_t port; 28 | pio_dev_t gpio; 29 | gpio_pin_t cs_pin; 30 | }; 31 | 32 | void mpu6000_init(struct mpu6000 *self, serial_dev_t port, pio_dev_t gpio, gpio_pin_t cs_pin); 33 | uint8_t mpu6000_probe(struct mpu6000 *self); 34 | 35 | void mpu6000_readRawAcc(struct mpu6000 *self, int16_t* ax, int16_t* ay, int16_t* az); 36 | void mpu6000_readRawGyr(struct mpu6000 *self, int16_t* gx, int16_t* gy, int16_t* gz); 37 | void mpu6000_convertAcc(struct mpu6000 *self, int16_t ax, int16_t ay, int16_t az, float *axg, float *ayg, float *azg); 38 | void mpu6000_convertGyr(struct mpu6000 *self, int16_t gx, int16_t gy, int16_t gz, float *gxd, float *gyd, float *gyz); 39 | /* 40 | void mpu6000_getRawData(struct mpu6000 *self, int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz); 41 | void mpu6000_convertData(struct mpu6000 *self, 42 | int16_t ax, int16_t ay, int16_t az, 43 | int16_t gx, int16_t gy, int16_t gz, 44 | float *axg, float *ayg, float *azg, 45 | float *gxd, float *gyd, float *gyz 46 | ); */ 47 | //void mpu6000_getConvAcc(struct mpu6000 *self, double* axg, double* ayg, double* azg); 48 | //void mpu6000_getConvGyr(struct mpu6000 *self, double* gxds, double* gyds, double* gzds); 49 | -------------------------------------------------------------------------------- /src/io/l74hc4051.c: -------------------------------------------------------------------------------- 1 | /** 2 | 8 bit multiplexer driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include "l74hc4051.h" 30 | 31 | /* 32 | * init the shift register 33 | */ 34 | void l74hc4051_init(struct l74hc4051 *self, pio_dev_t port, 35 | gpio_pin_t s0_pin, gpio_pin_t s1_pin, gpio_pin_t s2_pin) { 36 | self->port = port; 37 | self->s0_pin = s0_pin; 38 | self->s1_pin = s1_pin; 39 | self->s2_pin = s2_pin; 40 | 41 | pio_configure_pin(port, s0_pin, GP_OUTPUT); 42 | pio_configure_pin(port, s1_pin, GP_OUTPUT); 43 | pio_configure_pin(port, s2_pin, GP_OUTPUT); 44 | pio_write_pin(port, s0_pin, 0); 45 | pio_write_pin(port, s1_pin, 0); 46 | pio_write_pin(port, s2_pin, 0); 47 | } 48 | 49 | void l74hc4051_set_channel(struct l74hc4051 *self, uint8_t channel) { 50 | //bit 1 51 | if((channel & (1 << 0)) >> 0) 52 | pio_write_pin(self->port, self->s0_pin, 1); 53 | else 54 | pio_write_pin(self->port, self->s0_pin, 0); 55 | //bit 2 56 | if((channel & (1 << 1)) >> 1) 57 | pio_write_pin(self->port, self->s1_pin, 1); 58 | else 59 | pio_write_pin(self->port, self->s1_pin, 0); 60 | //bit 3 61 | if((channel & (1 << 2)) >> 2) 62 | pio_write_pin(self->port, self->s2_pin, 1); 63 | else 64 | pio_write_pin(self->port, self->s2_pin, 0); 65 | } 66 | -------------------------------------------------------------------------------- /src/io/l74hc595.c: -------------------------------------------------------------------------------- 1 | /** 2 | output shift register driver for generic parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #include 26 | 27 | #include 28 | 29 | #include "l74hc595.h" 30 | 31 | #ifndef CONFIG_L74HC595_STC_PIN 32 | #define CONFIG_L74HC595_STC_PIN GPIO_NONE 33 | #endif 34 | 35 | #define spi_writereadbyte(b) (serial_putc(self->spi, b), serial_getc(self->spi)) 36 | 37 | #define L74HC595_CELo pio_write_pin(self->gpio, self->ce_pin, 0) 38 | #define L74HC595_CEHi pio_write_pin(self->gpio, self->ce_pin, 1) 39 | 40 | #define L74HC595_STCLo pio_write_pin(self->gpio, self->stc_pin, 0) 41 | #define L74HC595_STCHi pio_write_pin(self->gpio, self->stc_pin, 1) 42 | /* 43 | * init the shift register 44 | */ 45 | void l74hc595_init(struct l74hc595 *self, serial_dev_t spi, pio_dev_t gpio, gpio_pin_t ce_pin, gpio_pin_t stc_pin) { 46 | self->spi = spi; 47 | self->gpio = gpio; 48 | self->stc_pin = stc_pin; 49 | self->ce_pin = ce_pin; 50 | 51 | pio_configure_pin(gpio, ce_pin, GP_OUTPUT); 52 | pio_configure_pin(gpio, stc_pin, GP_OUTPUT); 53 | 54 | L74HC595_STCLo; 55 | } 56 | 57 | void l74hc595_write(struct l74hc595 *self, uint8_t data) { 58 | L74HC595_CEHi; 59 | spi_writereadbyte(data); 60 | L74HC595_STCHi; 61 | delay_us(1); // not needed but still for safety (16ns is minimum high period) 62 | L74HC595_STCLo; 63 | L74HC595_CELo; 64 | } 65 | -------------------------------------------------------------------------------- /src/disp/ledmatrix88.c: -------------------------------------------------------------------------------- 1 | /** 2 | 8x8 led matrix display driver for 8 bit parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include "ledmatrix88.h" 29 | 30 | //define led matrix columns and rows 31 | #define LEDMATRIX88_COLS 8 32 | #define LEDMATRIX88_ROWS 8 33 | 34 | volatile uint8_t ledmatrix88_col = 0; //contains column data 35 | volatile uint8_t ledmatrix88_row = 0; //contains row data 36 | 37 | // clear the display 38 | void ledmatrix88_clear(struct ledmatrix88 *self) { 39 | memset(self->data, 0, sizeof(self->data)); 40 | } 41 | 42 | void ledmatrix88_init(struct ledmatrix88 *self, pio_dev_t port, uint8_t x_bank, uint8_t y_bank) { 43 | self->port = port; 44 | self->x_bank = x_bank; 45 | self->y_bank = y_bank; 46 | self->cur_x = self->cur_y = 0; 47 | memset(self->data, 0, sizeof(self->data)); 48 | } 49 | 50 | void ledmatrix88_write_row(struct ledmatrix88 *self, uint8_t row, uint8_t data){ 51 | self->data[row & 0x07] = data; 52 | } 53 | 54 | uint8_t ledmatrix88_read_row(struct ledmatrix88 *self, uint8_t row){ 55 | return self->data[row & 0x07]; 56 | } 57 | 58 | void ledmatrix88_update(struct ledmatrix88 *self) { 59 | //emit column data 60 | for(int row = 0; row < 8; row++){ 61 | pio_write_word(self->port, self->x_bank, self->data[row]); 62 | pio_write_word(self->port, self->y_bank, (1 << row)); 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/test_spiffs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * test_spiffs.h 3 | * 4 | * Created on: Jun 19, 2013 5 | * Author: petera 6 | */ 7 | 8 | #ifndef TEST_SPIFFS_H_ 9 | #define TEST_SPIFFS_H_ 10 | 11 | #include "spiffs.h" 12 | 13 | #define FS &__fs 14 | 15 | extern spiffs __fs; 16 | 17 | 18 | #define CHECK(r) if (!(r)) return -1; 19 | #define CHECK_RES(r) if (r < 0) return -1; 20 | #define FS_PURE_DATA_PAGES(fs) \ 21 | ((fs)->cfg.phys_size / (fs)->cfg.log_page_size - (fs)->block_count * SPIFFS_OBJ_LOOKUP_PAGES(fs)) 22 | #define FS_PURE_DATA_SIZE(fs) \ 23 | FS_PURE_DATA_PAGES(fs) * SPIFFS_DATA_PAGE_SIZE(fs) 24 | 25 | typedef enum { 26 | EMPTY, 27 | SMALL, 28 | MEDIUM, 29 | LARGE, 30 | } tfile_size; 31 | 32 | typedef enum { 33 | UNTAMPERED, 34 | APPENDED, 35 | MODIFIED, 36 | REWRITTEN, 37 | } tfile_type; 38 | 39 | typedef enum { 40 | SHORT = 4, 41 | NORMAL = 20, 42 | LONG = 100, 43 | } tfile_life; 44 | 45 | typedef struct { 46 | tfile_size tsize; 47 | tfile_type ttype; 48 | tfile_life tlife; 49 | } tfile_conf; 50 | 51 | typedef struct { 52 | int state; 53 | spiffs_file fd; 54 | tfile_conf cfg; 55 | char name[32]; 56 | } tfile; 57 | 58 | 59 | void fs_reset(); 60 | int read_and_verify(char *name); 61 | int read_and_verify_fd(spiffs_file fd, char *name); 62 | void dump_page(spiffs *fs, spiffs_page_ix p); 63 | void hexdump(u32_t addr, u32_t len); 64 | char *make_test_fname(const char *name); 65 | void clear_test_path(); 66 | void area_write(u32_t addr, u8_t *buf, u32_t size); 67 | void area_read(u32_t addr, u8_t *buf, u32_t size); 68 | void dump_erase_counts(spiffs *fs); 69 | void dump_flash_access_stats(); 70 | void set_flash_ops_log(int enable); 71 | void clear_flash_ops_log(); 72 | u32_t get_flash_ops_log_read_bytes(); 73 | u32_t get_flash_ops_log_write_bytes(); 74 | void invoke_error_after_read_bytes(u32_t b, char once_only); 75 | void invoke_error_after_write_bytes(u32_t b, char once_only); 76 | 77 | void memrand(u8_t *b, int len); 78 | int test_create_file(char *name); 79 | int test_create_and_write_file(char *name, int size, int chunk_size); 80 | void _setup(); 81 | void _teardown(); 82 | u32_t tfile_get_size(tfile_size s); 83 | int run_file_config(int cfg_count, tfile_conf* cfgs, int max_runs, int max_concurrent_files, int dbg); 84 | 85 | 86 | #endif /* TEST_SPIFFS_H_ */ 87 | -------------------------------------------------------------------------------- /src/temperature/ds18b20.h: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | 22 | References: 23 | + Using DS18B20 digital temperature sensor on AVR microcontrollers 24 | by Gerard Marull Paretas, 2007 25 | http://teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf 26 | */ 27 | 28 | #ifndef DS18B20_H_ 29 | #define DS18B20_H_ 30 | 31 | //setup connection 32 | #define DS18B20_PORT PORTC 33 | #define DS18B20_DDR DDRC 34 | #define DS18B20_PIN PINC 35 | #define DS18B20_DQ PC0 36 | 37 | //commands 38 | #define DS18B20_CMD_CONVERTTEMP 0x44 39 | #define DS18B20_CMD_RSCRATCHPAD 0xbe 40 | #define DS18B20_CMD_WSCRATCHPAD 0x4e 41 | #define DS18B20_CMD_CPYSCRATCHPAD 0x48 42 | #define DS18B20_CMD_RECEEPROM 0xb8 43 | #define DS18B20_CMD_RPWRSUPPLY 0xb4 44 | #define DS18B20_CMD_SEARCHROM 0xf0 45 | #define DS18B20_CMD_READROM 0x33 46 | #define DS18B20_CMD_MATCHROM 0x55 47 | #define DS18B20_CMD_SKIPROM 0xcc 48 | #define DS18B20_CMD_ALARMSEARCH 0xec 49 | 50 | //decimal conversion table 51 | #define DS18B20_DECIMALSTEPS_9BIT 5000 //0.5 52 | #define DS18B20_DECIMALSTEPS_10BIT 2500 //0.25 53 | #define DS18B20_DECIMALSTEPS_11BIT 1250 //0.125 54 | #define DS18B20_DECIMALSTEPS_12BIT 625 //0.0625 55 | #define DS18B20_DECIMALSTEPS DS18B20_DECIMALSTEPS_12BIT 56 | 57 | struct ds18b20 { 58 | pio_dev_t gpio; 59 | gpio_pin_t data_pin; 60 | }; 61 | 62 | void ds18b20_init(struct ds18b20 *self, 63 | pio_dev_t gpio, gpio_pin_t data_pin); 64 | double ds18b20_read_temperature(struct ds18b20 *self); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/testrunner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * testrunner.h 3 | * 4 | * Created on: Jun 19, 2013 5 | * Author: petera 6 | */ 7 | 8 | /* 9 | 10 | SUITE(mysuite) 11 | 12 | void setup(test *t) {} 13 | 14 | void teardown(test *t) {} 15 | 16 | TEST(mytest) { 17 | printf("mytest runs now..\n"); 18 | return 0; 19 | } TEST_END(mytest) 20 | 21 | SUITE_END(mysuite) 22 | 23 | 24 | 25 | SUITE(mysuite2) 26 | 27 | void setup(test *t) {} 28 | 29 | void teardown(test *t) {} 30 | 31 | TEST(mytest2a) { 32 | printf("mytest2a runs now..\n"); 33 | return 0; 34 | } TEST_END(mytest2a) 35 | 36 | TEST(mytest2b) { 37 | printf("mytest2b runs now..\n"); 38 | return 0; 39 | } TEST_END(mytest2b) 40 | 41 | SUITE_END(mysuite2) 42 | 43 | 44 | 45 | void add_suites() { 46 | ADD_SUITE(mysuite); 47 | ADD_SUITE(mysuite2); 48 | } 49 | */ 50 | 51 | #ifndef TESTS_H_ 52 | #define TESTS_H_ 53 | 54 | #define TEST_RES_OK 0 55 | #define TEST_RES_FAIL -1 56 | #define TEST_RES_ASSERT -2 57 | 58 | struct test_s; 59 | 60 | typedef int (*test_f)(struct test_s *t); 61 | 62 | typedef struct test_s { 63 | test_f f; 64 | char name[256]; 65 | void *data; 66 | void (*setup)(struct test_s *t); 67 | void (*teardown)(struct test_s *t); 68 | struct test_s *_next; 69 | } test; 70 | 71 | typedef struct test_res_s { 72 | char name[256]; 73 | struct test_res_s *_next; 74 | } test_res; 75 | 76 | #define TEST_CHECK(x) if (!(x)) { \ 77 | printf(" TEST FAIL %s:%i\n", __FILE__, __LINE__); \ 78 | goto __fail_stop; \ 79 | } 80 | #define TEST_ASSERT(x) if (!(x)) { \ 81 | printf(" TEST ASSERT %s:%i\n", __FILE__, __LINE__); \ 82 | goto __fail_assert; \ 83 | } 84 | 85 | #define DBGT(...) printf(__VA_ARGS__) 86 | 87 | #define str(s) #s 88 | 89 | #define SUITE(sui) \ 90 | extern void __suite_##sui() { 91 | #define SUITE_END(sui) \ 92 | } 93 | #define ADD_SUITE(sui) \ 94 | __suite_##sui(); 95 | #define TEST(tf) \ 96 | int tf(struct test_s *t) { do 97 | #define TEST_END(tf) \ 98 | while(0); \ 99 | __fail_stop: return TEST_RES_FAIL; \ 100 | __fail_assert: return TEST_RES_ASSERT; \ 101 | } \ 102 | add_test(tf, str(tf), setup, teardown); 103 | 104 | 105 | void add_suites(); 106 | void test_init(void (*on_stop)(test *t)); 107 | void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t)); 108 | void run_tests(int argc, char **args); 109 | 110 | #endif /* TESTS_H_ */ 111 | -------------------------------------------------------------------------------- /src/io/l74hc165.c: -------------------------------------------------------------------------------- 1 | /** 2 | input shift register driver for generic parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "l74hc165.h" 31 | 32 | /* 33 | * init the shift register 34 | */ 35 | void l74hc165_init(struct l74hc165 *self, pio_dev_t port, 36 | gpio_pin_t clock_pin, gpio_pin_t load_pin, gpio_pin_t data_pin) { 37 | self->port = port; 38 | self->clock_pin = clock_pin; 39 | self->load_pin = load_pin; 40 | self->data_pin = data_pin; 41 | 42 | pio_configure_pin(port, clock_pin, GP_OUTPUT); 43 | pio_configure_pin(port, load_pin, GP_OUTPUT); 44 | pio_configure_pin(port, data_pin, GP_INPUT | GP_PULLUP); 45 | pio_write_pin(port, clock_pin, 0); 46 | pio_write_pin(port, load_pin, 0); 47 | } 48 | 49 | /* 50 | * shift in data 51 | */ 52 | void l74hc165_read(struct l74hc165 *self, uint8_t *bytearray, uint8_t count) { 53 | //parallel load to freeze the state of the data lines 54 | pio_write_pin(self->port, self->load_pin, 0); 55 | delay_us(5); 56 | pio_write_pin(self->port, self->load_pin, 1); 57 | for(uint8_t i = 0; i < count; i++){ 58 | //iterate through the bits in each registers 59 | uint8_t currentbyte = 0; 60 | for(uint8_t j = 0; j < 8; j++){ 61 | uint8_t data = (pio_read_pin(self->port, self->data_pin))?1:0; 62 | currentbyte |= (data << (7-j)); 63 | //get next 64 | pio_write_pin(self->port, self->clock_pin, 0); 65 | delay_us(5); 66 | pio_write_pin(self->port, self->clock_pin, 1); 67 | } 68 | memcpy(&bytearray[i], ¤tbyte, 1); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/waterflow/fs300a.c: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | 22 | References: 23 | * http://www.seeedstudio.com/wiki/G3/4_Water_Flow_sensor 24 | */ 25 | 26 | #ifdef FS300A 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "fs300a.h" 33 | 34 | /* 35 | * TODO: figure out how to read it without using timers directly 36 | * 37 | 38 | volatile uint16_t fs300a_flowpulsecount = 0; 39 | volatile uint16_t fs300a_timer0counter = 0; 40 | 41 | ISR(TIMER0_OVF_vect) { 42 | //we are here every TIMER0_MSREPEATMS 43 | static uint8_t input_state; 44 | static uint16_t tflowpulsecount; 45 | uint8_t i; 46 | uint8_t current_state; 47 | fs300a_timer0counter++; 48 | //every 1sec get the pulse for seconds, hertz 49 | if(fs300a_timer0counter>=TIMER0_FS300ARESET) { 50 | fs300a_timer0counter = 0; 51 | fs300a_flowpulsecount = tflowpulsecount/2; //get the rise edge only 52 | tflowpulsecount = 0; 53 | } 54 | current_state = (FS300A_PIN & (1<>FS300A_INPUT1; //get current state 55 | i = input_state ^ ~current_state; //is it changed? (using xor) 56 | input_state = ~current_state; //set last input state as current state 57 | tflowpulsecount += i; //increment count if state is changed 58 | } 59 | 60 | void fs300a_init(void) { 61 | //set timer0 62 | TCCR0B = TIMER0_PRESCALER; 63 | TIMSK0 = 1<. 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | #include 26 | 27 | #include "pcf8574.h" 28 | 29 | #define PCF8574_ADDRBASE (0x20) //device base address 30 | 31 | #define PCF8574_MAXDEVICES 8 //max devices, depends on address (3 bit) 32 | #define PCF8574_MAXPINS 8 //max pin per device 33 | 34 | //#define PCF8574_LCD_DEVICEID 7 35 | 36 | void pcf8574_init(struct pcf8574 *self, i2c_dev_t i2c, uint8_t device_id) { 37 | self->i2c = i2c; 38 | self->device_id = device_id; 39 | self->in_reg = self->out_reg = 0xff; 40 | } 41 | 42 | static void _pcf8574_flush(struct pcf8574 *self){ 43 | i2c_start_write(self->i2c, 44 | ((PCF8574_ADDRBASE+self->device_id)<<1), &self->out_reg, 1); 45 | i2c_stop(self->i2c); 46 | } 47 | 48 | static void _pcf8574_read(struct pcf8574 *self){ 49 | i2c_start_read(self->i2c, 50 | ((PCF8574_ADDRBASE+self->device_id)<<1), &self->in_reg, 1); 51 | i2c_stop(self->i2c); 52 | } 53 | 54 | uint8_t pcf8574_write_word(struct pcf8574 *self, uint8_t data) { 55 | self->out_reg = data; 56 | _pcf8574_flush(self); 57 | return 0; 58 | } 59 | 60 | uint8_t pcf8574_write_pin(struct pcf8574 *self, uint8_t pin, uint8_t value) { 61 | pin &= 0x07; // this is an 8 bit device 62 | self->out_reg = (value)?(self->out_reg | (1 << pin)):(self->out_reg & ~(1 << pin)); 63 | _pcf8574_flush(self); 64 | return 0; 65 | } 66 | 67 | uint8_t pcf8574_read_word(struct pcf8574 *self) { 68 | _pcf8574_read(self); 69 | return self->in_reg; 70 | } 71 | 72 | uint8_t pcf8574_read_pin(struct pcf8574 *self, uint8_t pin) { 73 | _pcf8574_read(self); 74 | return (self->in_reg & (1 << (pin & 0x07)))?1:0; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/disp/ks0713.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ARTaylor.co.uk 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 3 as 6 | * published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * Author: Richard Taylor (richard@artaylor.co.uk) 14 | */ 15 | 16 | #ifndef _LCD_H 17 | #define _LCD_H 18 | 19 | #include 20 | 21 | #include "interface.h" 22 | 23 | #define KS0713_WIDTH 128 24 | #define KS0713_HEIGHT 64 25 | 26 | // pin positions as they are outputted by the driver 27 | #define KS0713_PIN_MASK (0x1FFF) 28 | 29 | #define KS0713_DATA (0xFF) // D0-D7 30 | #define KS0713_RD (1 << 8) // RD / E 31 | #define KS0713_WR (1 << 9) // RD / #WR 32 | #define KS0713_A0 (1 << 10) // A0 / RS / Data / #CMD 33 | #define KS0713_RES (1 << 11) // Reset 34 | #define KS0713_CS1 (1 << 12) // Chip Select 1 35 | 36 | #define KS0713_BACKLIGHT (1 << 13) 37 | 38 | #define KS0713_COMMAND_BUFFER_SIZE (KS0713_WIDTH / 8 * 2) 39 | 40 | struct ks0713 { 41 | uint16_t port_state; 42 | uint8_t contrast; 43 | uint8_t lcd_buffer[KS0713_WIDTH * KS0713_HEIGHT / 8]; 44 | uint16_t cursor_x, cursor_y; 45 | 46 | void (*putn)(struct ks0713 *self, uint16_t *data, size_t size); 47 | 48 | struct tty_device *tty; 49 | }; 50 | 51 | typedef enum { 52 | KS0713_OP_NONE, 53 | KS0713_OP_SET, 54 | KS0713_OP_CLR, 55 | KS0713_OP_XOR 56 | } ks0713_pixel_op_t; 57 | 58 | void ks0713_init(struct ks0713 *self, void (*putn)(struct ks0713 *self, uint16_t *data, size_t size)); 59 | void ks0713_set_backlight(struct ks0713 *self, uint8_t on); 60 | void ks0713_set_contrast(struct ks0713 *self, uint8_t val); 61 | void ks0713_clear(struct ks0713 *self); 62 | void ks0713_commit(struct ks0713 *self); 63 | void ks0713_move_cursor(struct ks0713 *self, uint8_t x, uint8_t y); 64 | void ks0713_write_pixel(struct ks0713 *self, uint8_t x, uint8_t y, ks0713_pixel_op_t op); 65 | //void ks0713_putc(struct ks0713 *self, uint8_t ch, uint16_t flags); 66 | //void ks0713_puts(const char *s, LCD_OP op, uint16_t flags); 67 | void ks0713_draw_line(struct ks0713 *self, int8_t x1, int8_t y1, int8_t x2, int8_t y2, ks0713_pixel_op_t op); 68 | void ks0713_draw_rect(struct ks0713 *self, int8_t x1, int8_t y1, int8_t x2, int8_t y2, ks0713_pixel_op_t op); 69 | 70 | tty_dev_t ks0713_get_tty_interface(struct ks0713 *self); 71 | 72 | #endif // _LCD_H 73 | -------------------------------------------------------------------------------- /src/range/hcsr04.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Github: https://github.com/mkschreder 18 | 19 | Contributors: 20 | * Martin K. Schröder - original driver 21 | */ 22 | 23 | /** 24 | * Device driver for HC-SR04 ultrasound module 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include "hcsr04.h" 33 | 34 | //values for state 35 | #define ST_IDLE 0 36 | #define ST_PULSE_SENT 1 37 | #define HCSR04_PULSE_TIMEOUT 1000000UL 38 | 39 | static uint8_t hcsr04_send_pulse(struct hcsr04 *self) 40 | { 41 | pio_write_pin(self->gpio, self->trigger_pin, 1); 42 | delay_us(10); 43 | pio_write_pin(self->gpio, self->trigger_pin, 0); 44 | 45 | self->state = ST_PULSE_SENT; 46 | self->pulse_timeout = timestamp_from_now_us(HCSR04_PULSE_TIMEOUT); 47 | 48 | return 1; 49 | } 50 | 51 | void hcsr04_init(struct hcsr04 *self, pio_dev_t gpio, 52 | gpio_pin_t trigger_pin, gpio_pin_t echo_pin){ 53 | self->gpio = gpio; 54 | self->trigger_pin = trigger_pin; 55 | self->echo_pin = echo_pin; 56 | 57 | pio_configure_pin(self->gpio, self->trigger_pin, GP_OUTPUT | GP_PULLUP); 58 | pio_configure_pin(self->gpio, self->echo_pin, 59 | GP_INPUT | GP_PCINT); 60 | 61 | self->state = ST_IDLE; 62 | self->distance = -1; 63 | 64 | hcsr04_send_pulse(self); 65 | } 66 | 67 | static uint8_t hcsr04_check_response(struct hcsr04 *self){ 68 | timestamp_t t_up, t_down; 69 | uint8_t status = pio_get_pin_status(self->gpio, self->echo_pin, &t_up, &t_down); 70 | if(status == GP_WENT_LOW){ 71 | timestamp_t us = timestamp_ticks_to_us(t_down - t_up); 72 | // convert to cm 73 | self->distance = (uint16_t)(us * 0.000001 * 34029.0f); 74 | self->state = ST_IDLE; 75 | return 1; 76 | } 77 | return 0; 78 | } 79 | 80 | int16_t hcsr04_read_distance_in_cm(struct hcsr04 *self) 81 | { 82 | if(hcsr04_check_response(self) || self->state == ST_IDLE || timestamp_expired(self->pulse_timeout)){ 83 | hcsr04_send_pulse(self); 84 | } 85 | return self->distance; 86 | } 87 | -------------------------------------------------------------------------------- /src/mem/at24.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | //#define AT24_PAGE_SIZE 32 16 | 17 | #define AT24_TIMEOUT 1000 18 | 19 | struct at24 { 20 | i2c_device_t i2c; 21 | uint8_t addr; 22 | struct memory_device dev; 23 | }; 24 | 25 | static int _at24_read(memory_device_t dev, size_t offset, void *data, size_t size){ 26 | if(!dev) return -EINVAL; 27 | struct at24 *self = container_of(dev, struct at24, dev.ops); 28 | uint8_t tx_data[1] = { (uint8_t)offset }; 29 | return i2c_transfer(self->i2c, self->addr, tx_data, 1, data, size, AT24_TIMEOUT); 30 | } 31 | 32 | static int _at24_write(memory_device_t dev, size_t offset, const void *data, size_t _size){ 33 | if(!dev) return -EINVAL; 34 | struct at24 *self = container_of(dev, struct at24, dev.ops); 35 | size_t size = _size; 36 | uint8_t *buf = (uint8_t*)data; 37 | // write one byte at a time (guaranteed support on all devices) 38 | while(size--){ 39 | //if(i2c_write16_reg8(self->i2c, self->addr, (uint16_t)offset, *buf++) < 0){ 40 | uint8_t dat[2] = {(uint8_t)offset, *buf++}; 41 | if(i2c_transfer(self->i2c, self->addr, dat, 2, NULL, 0, AT24_TIMEOUT) < 0){ 42 | return -EFAULT; 43 | } 44 | // twr is at least 10ms 45 | thread_sleep_ms(10); 46 | offset++; 47 | } 48 | return (int)(_size - size); 49 | } 50 | 51 | static struct memory_device_ops _at24_memory_ops = { 52 | .read = _at24_read, 53 | .write = _at24_write 54 | }; 55 | 56 | static int _at24_probe(void *fdt, int fdt_node) { 57 | i2c_device_t i2c = i2c_find_by_ref(fdt, fdt_node, "i2c"); 58 | uint8_t addr = (uint8_t)fdt_get_int_or_default(fdt, fdt_node, "reg", 0x32); 59 | 60 | if(!i2c){ 61 | printk("at24: no i2c\n"); 62 | return -1; 63 | } 64 | 65 | struct at24 *self = kzmalloc(sizeof(struct at24)); 66 | if(!self){ 67 | printk("at24: nomem\n"); 68 | return -1; 69 | } 70 | 71 | self->addr = addr; 72 | self->i2c = i2c; 73 | 74 | memory_device_init(&self->dev, fdt, fdt_node, &_at24_memory_ops); 75 | memory_device_register(&self->dev); 76 | 77 | printk("at24: ready (addr %02x)\n", addr); 78 | 79 | return 0; 80 | } 81 | 82 | static int _at24_remove(void *fdt, int fdt_node) { 83 | memory_device_t mem = memory_find_by_node(fdt, fdt_node); 84 | if(!mem) return -1; 85 | struct at24 *self = container_of(mem, struct at24, dev.ops); 86 | kfree(self); 87 | return 0; 88 | } 89 | 90 | DEVICE_DRIVER(at24, "fw,at24", _at24_probe, _at24_remove) 91 | 92 | -------------------------------------------------------------------------------- /src/tty/vt100.h: -------------------------------------------------------------------------------- 1 | /** 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | */ 21 | 22 | #pragma once 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #include 29 | 30 | #define VT100_CHAR_WIDTH 6 31 | #define VT100_CHAR_HEIGHT 8 32 | 33 | #define VT100_MAX_COMMAND_ARGS 4 34 | 35 | 36 | struct vt100 { 37 | union flags { 38 | uint8_t val; 39 | struct { 40 | // 0 = cursor remains on last column when it gets there 41 | // 1 = lines wrap after last column to next line 42 | uint8_t cursor_wrap : 1; 43 | uint8_t scroll_mode : 1; 44 | uint8_t origin_mode : 1; 45 | }; 46 | } flags; 47 | 48 | tty_dev_t display; 49 | 50 | //uint16_t screen_width, screen_height; 51 | // cursor position on the screen (0, 0) = top left corner. 52 | uint16_t cursor_x, cursor_y; 53 | uint16_t saved_cursor_x, saved_cursor_y; // used for cursor save restore 54 | uint16_t scroll_start_row, scroll_end_row; 55 | // character width and height 56 | //uint8_t char_width, char_height; 57 | // colors used for rendering current characters 58 | uint16_t back_color, front_color; 59 | // the starting y-position of the screen scroll 60 | uint16_t scroll_value; 61 | // command arguments that get parsed as they appear in the terminal 62 | uint8_t narg; uint16_t args[VT100_MAX_COMMAND_ARGS]; 63 | // current arg pointer (we use it for parsing) 64 | uint8_t carg; 65 | uint16_t screen_height, screen_width; 66 | 67 | void (*state)(struct vt100 *term, uint8_t ev, uint16_t arg); 68 | //void (*send_response)(char *str); 69 | void (*ret_state)(struct vt100 *term, uint8_t ev, uint16_t arg); 70 | 71 | struct serial_if *serial; 72 | }; 73 | 74 | #include "../arch/interface.h" 75 | 76 | //void vt100_init(void (*send_response)(char *str)); 77 | void vt100_init(struct vt100 *self, tty_dev_t display); 78 | void vt100_putc(struct vt100 *self, uint8_t ch); 79 | void vt100_puts(struct vt100 *self, const char *str); 80 | 81 | serial_dev_t vt100_get_serial_interface(struct vt100 *self); 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | -------------------------------------------------------------------------------- /src/disp/interface.h: -------------------------------------------------------------------------------- 1 | /** 2 | A graphical LCD framebuffer interface 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | */ 21 | 22 | #pragma once 23 | 24 | typedef enum { 25 | FB_PIXEL_FORMAT_1BIT, 26 | FB_PIXEL_FORMAT_RGB8, 27 | FB_PIXEL_FORMAT_RGB16 28 | } fb_pixel_type_t; 29 | 30 | typedef struct fb_image { 31 | uint16_t w; 32 | uint16_t h; 33 | uint8_t *data; 34 | fb_pixel_type_t format; 35 | } fb_image_t; 36 | 37 | typedef struct { 38 | uint8_t r, g, b, a; 39 | } fb_color_t; 40 | 41 | #define RGBA(r, g, b, a) (fb_color_t){r, g, b, a} 42 | 43 | typedef void (*fb_fill)(fb_color_t color, size_t count); 44 | typedef void (*fb_set_region)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); 45 | typedef size_t (*fb_write)(const uint8_t *data, size_t sz, fb_pixel_type_t type_of_supplied_data); 46 | typedef size_t (*fb_read)(uint8_t *data, size_t sz, fb_pixel_type_t encode_in_format); 47 | typedef void (*fb_get_size)(uint16_t *width, uint16_t *height); 48 | 49 | struct fb_device { 50 | fb_fill fill; 51 | fb_set_region set_region; 52 | fb_write write; 53 | fb_read read; 54 | fb_get_size get_size; 55 | }; 56 | 57 | typedef struct tty_device **tty_dev_t; 58 | typedef uint16_t color_t; 59 | 60 | struct tty_device { 61 | void (*put)(tty_dev_t self, uint8_t ch, color_t fg, color_t bg); 62 | void (*move_cursor)(tty_dev_t self, uint16_t x, uint16_t y); 63 | 64 | //void (*draw_fill_rect)(tty_dev_t *disp, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, color_t color); 65 | 66 | void (*get_size)(tty_dev_t self, uint16_t *w, uint16_t *h); 67 | //void (*set_scroll_region)(tty_dev_t *disp, uint16_t start, uint16_t end); 68 | //void (*set_top_line)(tty_dev_t *disp, uint16_t idx); 69 | void (*clear)(tty_dev_t self); 70 | }; 71 | 72 | static inline void tty_put(tty_dev_t self, uint8_t ch, color_t fg, color_t bg){ 73 | (*self)->put(self, ch, fg, bg); 74 | } 75 | 76 | static inline void tty_move_cursor(tty_dev_t self, uint16_t x, uint16_t y){ 77 | (*self)->move_cursor(self, x, y); 78 | } 79 | 80 | static inline void tty_get_size(tty_dev_t self, uint16_t *w, uint16_t *h){ 81 | (*self)->get_size(self, w, h); 82 | } 83 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/test_dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test_dev.c 3 | * 4 | * Created on: Jul 14, 2013 5 | * Author: petera 6 | */ 7 | 8 | 9 | #include "testrunner.h" 10 | #include "test_spiffs.h" 11 | #include "spiffs_nucleus.h" 12 | #include "spiffs.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | SUITE(dev_tests) 21 | void setup() { 22 | _setup(); 23 | } 24 | void teardown() { 25 | _teardown(); 26 | } 27 | 28 | TEST(interrupted_write) { 29 | const char *name = "interrupt"; 30 | const char *name2 = "interrupt2"; 31 | int res; 32 | spiffs_file fd; 33 | 34 | const u32_t sz = SPIFFS_CFG_LOG_PAGE_SZ(FS)*8; 35 | u8_t *buf = malloc(sz); 36 | memrand(buf, sz); 37 | 38 | printf(" create reference file\n"); 39 | fd = SPIFFS_open(FS, name, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); 40 | TEST_CHECK(fd > 0); 41 | clear_flash_ops_log(); 42 | res = SPIFFS_write(FS, fd, buf, sz); 43 | TEST_CHECK(res >= 0); 44 | SPIFFS_close(FS, fd); 45 | 46 | u32_t written = get_flash_ops_log_write_bytes(); 47 | printf(" written bytes: %i\n", written); 48 | 49 | 50 | printf(" create error file\n"); 51 | fd = SPIFFS_open(FS, name2, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); 52 | TEST_CHECK(fd > 0); 53 | clear_flash_ops_log(); 54 | invoke_error_after_write_bytes(written/2, 0); 55 | res = SPIFFS_write(FS, fd, buf, sz); 56 | SPIFFS_close(FS, fd); 57 | TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_TEST); 58 | 59 | clear_flash_ops_log(); 60 | 61 | #if SPIFFS_CACHE 62 | // delete all cache 63 | spiffs_cache *cache = spiffs_get_cache(FS); 64 | cache->cpage_use_map = 0; 65 | #endif 66 | 67 | 68 | printf(" read error file\n"); 69 | fd = SPIFFS_open(FS, name2, SPIFFS_RDONLY, 0); 70 | TEST_CHECK(fd > 0); 71 | 72 | spiffs_stat s; 73 | res = SPIFFS_fstat(FS, fd, &s); 74 | TEST_CHECK(res >= 0); 75 | printf(" file size: %i\n", s.size); 76 | 77 | if (s.size > 0) { 78 | u8_t *buf2 = malloc(s.size); 79 | res = SPIFFS_read(FS, fd, buf2, s.size); 80 | TEST_CHECK(res >= 0); 81 | 82 | u32_t ix = 0; 83 | for (ix = 0; ix < s.size; ix += 16) { 84 | int i; 85 | printf(" "); 86 | for (i = 0; i < 16; i++) { 87 | printf("%02x", buf[ix+i]); 88 | } 89 | printf(" "); 90 | for (i = 0; i < 16; i++) { 91 | printf("%02x", buf2[ix+i]); 92 | } 93 | printf("\n"); 94 | } 95 | free(buf2); 96 | } 97 | SPIFFS_close(FS, fd); 98 | 99 | 100 | printf(" FS check\n"); 101 | SPIFFS_check(FS); 102 | 103 | printf(" read error file again\n"); 104 | fd = SPIFFS_open(FS, name2, SPIFFS_APPEND | SPIFFS_RDWR, 0); 105 | TEST_CHECK(fd > 0); 106 | res = SPIFFS_fstat(FS, fd, &s); 107 | TEST_CHECK(res >= 0); 108 | printf(" file size: %i\n", s.size); 109 | printf(" write file\n"); 110 | res = SPIFFS_write(FS, fd, buf, sz); 111 | TEST_CHECK(res >= 0); 112 | SPIFFS_close(FS, fd); 113 | 114 | free(buf); 115 | 116 | return TEST_RES_OK; 117 | 118 | } TEST_END(interrupted_write) 119 | 120 | SUITE_END(dev_tests) 121 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-posix-dir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | * Author: Adam Dunkels 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #include "cfs/cfs.h" 40 | 41 | struct cfs_posix_dir { 42 | DIR *dirp; 43 | }; 44 | 45 | /*---------------------------------------------------------------------------*/ 46 | int 47 | cfs_opendir(struct cfs_dir *p, const char *n) 48 | { 49 | struct cfs_posix_dir *dir = (struct cfs_posix_dir *)p; 50 | 51 | dir->dirp = opendir(n); 52 | return dir->dirp == NULL; 53 | } 54 | /*---------------------------------------------------------------------------*/ 55 | int 56 | cfs_readdir(struct cfs_dir *p, struct cfs_dirent *e) 57 | { 58 | struct cfs_posix_dir *dir = (struct cfs_posix_dir *)p; 59 | struct dirent *res; 60 | 61 | if(dir->dirp == NULL) { 62 | return -1; 63 | } 64 | res = readdir(dir->dirp); 65 | if(res == NULL) { 66 | return -1; 67 | } 68 | strncpy(e->name, res->d_name, sizeof(e->name)); 69 | #if defined(__APPLE2__) || defined(__APPLE2ENH__) || defined(__CBM__) 70 | e->size = res->d_blocks; 71 | #else /* __APPLE2__ || __APPLE2ENH__ || __CBM__ */ 72 | e->size = 0; 73 | #endif /* __APPLE2__ || __APPLE2ENH__ || __CBM__ */ 74 | return 0; 75 | } 76 | /*---------------------------------------------------------------------------*/ 77 | void 78 | cfs_closedir(struct cfs_dir *p) 79 | { 80 | struct cfs_posix_dir *dir = (struct cfs_posix_dir *)p; 81 | 82 | if(dir->dirp != NULL) { 83 | closedir(dir->dirp); 84 | } 85 | } 86 | /*---------------------------------------------------------------------------*/ 87 | -------------------------------------------------------------------------------- /.config: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated make config: don't edit 3 | # version: 4 | # Mon Feb 9 13:46:26 2015 5 | # 6 | 7 | # 8 | # Hardware 9 | # 10 | # CONFIG_HAVE_ADC is not set 11 | CONFIG_HAVE_UART=y 12 | CONFIG_HAVE_UART0=y 13 | # CONFIG_HAVE_UART1 is not set 14 | # CONFIG_HAVE_SPI is not set 15 | # CONFIG_HAVE_SPI0 is not set 16 | # CONFIG_HAVE_SPI1 is not set 17 | # CONFIG_HAVE_TWI is not set 18 | # CONFIG_HAVE_TWI0 is not set 19 | # CONFIG_HAVE_TWI1 is not set 20 | # CONFIG_HAVE_TWI2 is not set 21 | # CONFIG_HAVE_TIMER0 is not set 22 | # CONFIG_HAVE_TIMER1 is not set 23 | # CONFIG_HAVE_TIMER2 is not set 24 | # CONFIG_HAVE_PWM0 is not set 25 | # CONFIG_HAVE_PWM1 is not set 26 | # CONFIG_HAVE_PWM2 is not set 27 | # CONFIG_AVR is not set 28 | CONFIG_ARM=y 29 | # CONFIG_NATIVE is not set 30 | 31 | # 32 | # Processor type 33 | # 34 | # CONFIG_AVRMEGA is not set 35 | # CONFIG_ATMEGA328P is not set 36 | # CONFIG_ATMEGA103 is not set 37 | # CONFIG_ATMEGA88 is not set 38 | # CONFIG_ATMEGA128 is not set 39 | # CONFIG_ATMEGA168 is not set 40 | # CONFIG_ATMEGA2560 is not set 41 | # CONFIG_ATMEGA644 is not set 42 | # CONFIG_ATMEGA48 is not set 43 | # CONFIG_TIMESTAMP_COUNTER is not set 44 | # CONFIG_ADC_MODE_AUTOMATIC is not set 45 | # CONFIG_GPIO_PIN_STATES is not set 46 | # CONFIG_BUFFERED_UART is not set 47 | CONFIG_UART0_TX_BUF_SIZE=0 48 | CONFIG_UART0_RX_BUF_SIZE=0 49 | CONFIG_UART0_NAME="" 50 | CONFIG_UART1_NAME="" 51 | CONFIG_UART2_NAME="" 52 | CONFIG_SPI0_NAME="" 53 | CONFIG_SPI1_NAME="" 54 | CONFIG_SPI2_NAME="" 55 | CONFIG_TWI0_NAME="" 56 | CONFIG_TWI1_NAME="" 57 | # CONFIG_STM32 is not set 58 | # CONFIG_SAM3 is not set 59 | # CONFIG_STM32F103 is not set 60 | CONFIG_STM32F100MDVL=y 61 | # CONFIG_AT91SAM3 is not set 62 | # CONFIG_STM32F10X is not set 63 | 64 | # 65 | # Board support 66 | # 67 | # CONFIG_BOARD_MULTIWII is not set 68 | # CONFIG_BOARD_PROMINI is not set 69 | # CONFIG_BOARD_STM32F103 is not set 70 | # CONFIG_BOARD_ARDUINO_DUE is not set 71 | # CONFIG_BOARD_ARDURADIO is not set 72 | # CONFIG_BOARD_VIRTUAL is not set 73 | CONFIG_MULTIWII_ACC="" 74 | 75 | # 76 | # Device driver support 77 | # 78 | 79 | # 80 | # Cryptographic support 81 | # 82 | CONFIG_CRYPTO=y 83 | CONFIG_CRYPTO_AES=y 84 | 85 | # 86 | # Display support 87 | # 88 | CONFIG_ILI9340=y 89 | CONFIG_LCDPAR=y 90 | CONFIG_LEDMATRIX88=y 91 | CONFIG_SSD1306=y 92 | CONFIG_SEVSEG=y 93 | 94 | # 95 | # HID support 96 | # 97 | CONFIG_WIINUNCHUK=y 98 | 99 | # 100 | # IO logic support 101 | # 102 | # CONFIG_L74HC165 is not set 103 | # CONFIG_L74HC4051 is not set 104 | # CONFIG_L74HC595 is not set 105 | CONFIG_PCF8574=y 106 | 107 | # 108 | # Network support 109 | # 110 | CONFIG_ENC28J60=y 111 | CONFIG_DHCP=y 112 | CONFIG_DNS=y 113 | # CONFIG_RFNET is not set 114 | CONFIG_TCPIP=y 115 | 116 | # 117 | # Radio modem support 118 | # 119 | # CONFIG_NRF24L01 is not set 120 | 121 | # 122 | # RFID readers support 123 | # 124 | CONFIG_MFRC522=y 125 | 126 | # 127 | # Sensor drivers 128 | # 129 | CONFIG_ACS712=y 130 | CONFIG_ADXL345=y 131 | CONFIG_AMT1001=y 132 | CONFIG_BH1750=y 133 | CONFIG_BMP085=y 134 | CONFIG_DHT=y 135 | CONFIG_DS18B20=y 136 | CONFIG_FS300A=y 137 | CONFIG_HCSR04=y 138 | CONFIG_HMC5883L=y 139 | CONFIG_IMU10DOF01=y 140 | CONFIG_L3G4200D=y 141 | CONFIG_MMA7455=y 142 | CONFIG_MPU6050=y 143 | CONFIG_TEMT6000=y 144 | CONFIG_TSL235=y 145 | CONFIG_VT100=y 146 | 147 | # 148 | # Application Configuration 149 | # 150 | # CONFIG_SIMULATOR is not set 151 | CONFIG_HARDWARE=y 152 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-posix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | * Author: Adam Dunkels 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #ifdef _MSC_VER 38 | #include 39 | #else 40 | #include 41 | #endif 42 | 43 | #include "cfs/cfs.h" 44 | 45 | /*---------------------------------------------------------------------------*/ 46 | int 47 | cfs_open(const char *n, int f) 48 | { 49 | int s = 0; 50 | if(f == CFS_READ) { 51 | return open(n, O_RDONLY); 52 | } else if(f & CFS_WRITE) { 53 | s = O_CREAT; 54 | if(f & CFS_READ) { 55 | s |= O_RDWR; 56 | } else { 57 | s |= O_WRONLY; 58 | } 59 | if(f & CFS_APPEND) { 60 | s |= O_APPEND; 61 | } else { 62 | s |= O_TRUNC; 63 | } 64 | return open(n, s, 0600); 65 | } 66 | return -1; 67 | } 68 | /*---------------------------------------------------------------------------*/ 69 | void 70 | cfs_close(int f) 71 | { 72 | close(f); 73 | } 74 | /*---------------------------------------------------------------------------*/ 75 | int 76 | cfs_read(int f, void *b, unsigned int l) 77 | { 78 | return read(f, b, l); 79 | } 80 | /*---------------------------------------------------------------------------*/ 81 | int 82 | cfs_write(int f, const void *b, unsigned int l) 83 | { 84 | return write(f, b, l); 85 | } 86 | /*---------------------------------------------------------------------------*/ 87 | cfs_offset_t 88 | cfs_seek(int f, cfs_offset_t o, int w) 89 | { 90 | if(w == CFS_SEEK_SET) { 91 | w = SEEK_SET; 92 | } else if(w == CFS_SEEK_CUR) { 93 | w = SEEK_CUR; 94 | } else if(w == CFS_SEEK_END) { 95 | w = SEEK_END; 96 | } else { 97 | return (cfs_offset_t)-1; 98 | } 99 | return lseek(f, o, w); 100 | } 101 | /*---------------------------------------------------------------------------*/ 102 | int 103 | cfs_remove(const char *name) 104 | { 105 | return remove(name); 106 | } 107 | /*---------------------------------------------------------------------------*/ 108 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: 0 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Right 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: false 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | AfterExternBlock: false 33 | BeforeCatch: false 34 | BeforeElse: false 35 | IndentBraces: false 36 | SplitEmptyFunction: true 37 | SplitEmptyRecord: true 38 | SplitEmptyNamespace: true 39 | BreakBeforeBinaryOperators: None 40 | BreakBeforeBraces: Attach 41 | BreakBeforeInheritanceComma: false 42 | BreakBeforeTernaryOperators: true 43 | BreakConstructorInitializersBeforeComma: false 44 | BreakConstructorInitializers: BeforeColon 45 | BreakAfterJavaFieldAnnotations: false 46 | BreakStringLiterals: true 47 | ColumnLimit: 85 48 | CommentPragmas: '^ IWYU pragma:' 49 | CompactNamespaces: false 50 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 51 | ConstructorInitializerIndentWidth: 4 52 | ContinuationIndentWidth: 4 53 | Cpp11BracedListStyle: true 54 | DerivePointerAlignment: false 55 | DisableFormat: false 56 | ExperimentalAutoDetectBinPacking: false 57 | FixNamespaceComments: true 58 | ForEachMacros: 59 | - foreach 60 | - Q_FOREACH 61 | - BOOST_FOREACH 62 | IncludeBlocks: Preserve 63 | IncludeCategories: 64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 65 | Priority: 2 66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 67 | Priority: 3 68 | - Regex: '.*' 69 | Priority: 1 70 | IncludeIsMainRegex: '(Test)?$' 71 | IndentCaseLabels: true 72 | IndentPPDirectives: None 73 | IndentWidth: 2 74 | IndentWrappedFunctionNames: false 75 | JavaScriptQuotes: Leave 76 | JavaScriptWrapImports: true 77 | KeepEmptyLinesAtTheStartOfBlocks: true 78 | MacroBlockBegin: '' 79 | MacroBlockEnd: '' 80 | MaxEmptyLinesToKeep: 1 81 | NamespaceIndentation: None 82 | ObjCBlockIndentWidth: 2 83 | ObjCSpaceAfterProperty: false 84 | ObjCSpaceBeforeProtocolList: true 85 | PenaltyBreakAssignment: 2 86 | PenaltyBreakBeforeFirstCallParameter: 19 87 | PenaltyBreakComment: 300 88 | PenaltyBreakFirstLessLess: 120 89 | PenaltyBreakString: 1000 90 | PenaltyExcessCharacter: 1000000 91 | PenaltyReturnTypeOnItsOwnLine: 60 92 | PointerAlignment: Right 93 | RawStringFormats: 94 | - Delimiter: pb 95 | Language: TextProto 96 | BasedOnStyle: google 97 | ReflowComments: true 98 | SortIncludes: true 99 | SortUsingDeclarations: true 100 | SpaceAfterCStyleCast: false 101 | SpaceAfterTemplateKeyword: true 102 | SpaceBeforeAssignmentOperators: true 103 | SpaceBeforeParens: Never 104 | SpaceInEmptyParentheses: false 105 | SpacesBeforeTrailingComments: 1 106 | SpacesInAngles: false 107 | SpacesInContainerLiterals: true 108 | SpacesInCStyleCastParentheses: false 109 | SpacesInParentheses: false 110 | SpacesInSquareBrackets: false 111 | Standard: Cpp11 112 | TabWidth: 2 113 | UseTab: ForIndentation 114 | ... 115 | 116 | -------------------------------------------------------------------------------- /src/sensors/dht.c: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #include "dht.h" 29 | 30 | void dht_init(struct dht *self, pio_dev_t gpio, gpio_pin_t signal_pin, uint8_t sensor_type){ 31 | self->gpio = gpio; 32 | self->signal_pin = signal_pin; 33 | 34 | if(sensor_type != DHT_DHT11 && sensor_type != DHT_DHT22) 35 | sensor_type = DHT_DHT11; 36 | 37 | self->sensor_type = sensor_type; 38 | } 39 | 40 | static int8_t dht_read_data(struct dht *self, int8_t *temperature, int8_t *humidity) { 41 | uint8_t bits[5]; 42 | 43 | memset(bits, 0, sizeof(bits)); 44 | 45 | //reset port 46 | 47 | pio_configure_pin(self->gpio, self->signal_pin, GP_OUTPUT); 48 | pio_write_pin(self->gpio, self->signal_pin, 1); 49 | delay_us(100000L); 50 | 51 | // send request 52 | pio_write_pin(self->gpio, self->signal_pin, 0); 53 | if(self->sensor_type == DHT_DHT11) 54 | delay_us(18000L); 55 | else 56 | delay_us(500); 57 | 58 | pio_configure_pin(self->gpio, self->signal_pin, GP_INPUT | GP_PULLUP); 59 | delay_us(40); 60 | 61 | #define read_pin() pio_read_pin(self->gpio, self->signal_pin) 62 | // start condition 1 63 | if(read_pin()) 64 | return -1; 65 | delay_us(80); 66 | // start condition 2 67 | if(!read_pin()) 68 | return -1; 69 | delay_us(80); 70 | 71 | //read the data 72 | uint16_t timeoutcounter = 0; 73 | for (int j=0; j<5; j++) { //read 5 byte 74 | uint8_t result=0; 75 | for(int i=0; i<8; i++) {//read every bit 76 | timeoutcounter = 0; 77 | while(!read_pin()) { //wait for an high input (non blocking) 78 | timeoutcounter++; 79 | if(timeoutcounter > DHT_TIMEOUT) { 80 | return -1; //timeout 81 | } 82 | } 83 | delay_us(30); 84 | if(read_pin()) //if input is high after 30 us, get result 85 | result |= (1<<(7-i)); 86 | timeoutcounter = 0; 87 | while(read_pin()) { //wait until input get low (blocking) 88 | timeoutcounter++; 89 | if(timeoutcounter > DHT_TIMEOUT) { 90 | return -1; //timeout 91 | } 92 | } 93 | } 94 | bits[j] = result; 95 | } 96 | 97 | //reset port 98 | pio_configure_pin(self->gpio, self->signal_pin, GP_OUTPUT); 99 | pio_write_pin(self->gpio, self->signal_pin, 0); 100 | 101 | //check checksum 102 | if ((uint8_t)(bits[0] + bits[1] + bits[2] + bits[3]) == bits[4]) { 103 | //return temperature and humidity 104 | if(self->sensor_type == DHT_DHT11){ 105 | *temperature = bits[2]; 106 | *humidity = bits[0]; 107 | } else if(self->sensor_type == DHT_DHT22){ 108 | uint16_t rawhumidity = bits[0]<<8 | bits[1]; 109 | uint16_t rawtemperature = bits[2]<<8 | bits[3]; 110 | if(rawtemperature & 0x8000) { 111 | *temperature = (float)((rawtemperature & 0x7FFF) / 10.0) * -1.0; 112 | } else { 113 | *temperature = (float)(rawtemperature)/10.0; 114 | } 115 | *humidity = (float)(rawhumidity)/10.0; 116 | } 117 | return 0; 118 | } 119 | 120 | return -1; 121 | } 122 | 123 | int8_t dht_read(struct dht *self, int8_t *temperature, int8_t *humidity) { 124 | return dht_read_data(self, temperature, humidity); 125 | } 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/radio/nrf24l01.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPI 2.4Ghz radio driver 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Contributions: 22 | * Davide Gironi - developing original driver 23 | * This library is based upon nRF24L01 avr lib by Stefan Engelke 24 | http://www.tinkerer.eu/AVRLib/nRF24L01 25 | * and arduino library 2011 by J. Coliz 26 | http://maniacbug.github.com/RF24 27 | */ 28 | #ifndef _NRF24L01_H_ 29 | #define _NRF24L01_H_ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | struct nrf24l01 { 36 | serial_dev_t spi; 37 | gpio_pin_t cs_pin; 38 | gpio_pin_t ce_pin; 39 | }; 40 | 41 | #define NRF24L01_MAX_CHANNEL 128 42 | 43 | //power setup 44 | #define NRF24L01_RF24_PA_MIN 1 45 | #define NRF24L01_RF24_PA_LOW 2 46 | #define NRF24L01_RF24_PA_HIGH 3 47 | #define NRF24L01_RF24_PA_MAX 4 48 | #define NRF24L01_RF24_PA NRF24L01_RF24_PA_MAX 49 | 50 | //speed setup 51 | #define NRF24L01_RF24_SPEED_250KBPS 1 52 | #define NRF24L01_RF24_SPEED_1MBPS 2 53 | #define NRF24L01_RF24_SPEED_2MBPS 3 54 | #define NRF24L01_RF24_SPEED NRF24L01_RF24_SPEED_1MBPS 55 | 56 | //crc setup 57 | #define NRF24L01_RF24_CRC_DISABLED 1 58 | #define NRF24L01_RF24_CRC_8 2 59 | #define NRF24L01_RF24_CRC_16 3 60 | #define NRF24L01_RF24_CRC NRF24L01_RF24_CRC_16 61 | 62 | //transmission channel 63 | #define NRF24L01_CH 54 64 | 65 | //payload lenght 66 | #define NRF24L01_PAYLOAD 32 67 | 68 | //auto ack enabled 69 | #define NRF24L01_ACK 0 70 | 71 | //auto retransmit delay and count 72 | #define NRF24L01_RETR 0xff //1500uS, 15 times 73 | 74 | //enable / disable pipe 75 | #define NRF24L01_ENABLEDP0 1 //pipe 0 76 | #define NRF24L01_ENABLEDP1 1 //pipe 1 77 | #define NRF24L01_ENABLEDP2 0 //pipe 2 78 | #define NRF24L01_ENABLEDP3 0 //pipe 3 79 | #define NRF24L01_ENABLEDP4 0 //pipe 4 80 | #define NRF24L01_ENABLEDP5 0 //pipe 5 81 | 82 | //address size 83 | #define NRF24L01_ADDRSIZE 5 84 | 85 | //pipe address 86 | /* 87 | #define NRF24L01_ADDRP0 {0xE8, 0xE8, 0xF0, 0xF0, 0xE2} //pipe 0, 5 byte address 88 | #define NRF24L01_ADDRP1 {0xC1, 0xC2, 0xC2, 0xC2, 0xC2} //pipe 1, 5 byte address 89 | #define NRF24L01_ADDRP2 {0xC1, 0xC2, 0xC2, 0xC2, 0xC3} //pipe 2, 5 byte address 90 | #define NRF24L01_ADDRP3 {0xC1, 0xC2, 0xC2, 0xC2, 0xC4} //pipe 3, 5 byte address 91 | #define NRF24L01_ADDRP4 {0xC1, 0xC2, 0xC2, 0xC2, 0xC5} //pipe 4, 5 byte address 92 | #define NRF24L01_ADDRP5 {0xC1, 0xC2, 0xC2, 0xC2, 0xC6} //pipe 5, 5 byte address 93 | #define NRF24L01_ADDRTX {0xE8, 0xE8, 0xF0, 0xF0, 0xE2} //tx default address 94 | */ 95 | //enable print info function 96 | #define NRF24L01_PRINTENABLE 0 97 | 98 | extern void nrf24l01_init(struct nrf24l01 *nrf, serial_dev_t spi, gpio_pin_t cs, gpio_pin_t ce); 99 | extern uint8_t nrf24l01_getstatus(struct nrf24l01 *nrf); 100 | extern uint8_t nrf24l01_readready(struct nrf24l01 *nrf, uint8_t* pipe); 101 | extern void nrf24l01_read(struct nrf24l01 *nrf, uint8_t *data); 102 | extern uint8_t nrf24l01_write(struct nrf24l01 *nrf, uint8_t *data); 103 | extern void nrf24l01_setrxaddr(struct nrf24l01 *nrf, uint8_t channel, uint8_t *addr); 104 | extern void nrf24l01_settxaddr(struct nrf24l01 *nrf, uint8_t *addr); 105 | void nrf24l01_powerdown(struct nrf24l01 *nrf); 106 | void nrf24l01_scan(struct nrf24l01 *nrf, uint8_t iterations, uint8_t result[NRF24L01_MAX_CHANNEL]); 107 | 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /src/sensors/amt1001.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of martink project. 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Github: https://github.com/mkschreder 18 | 19 | Contributors: 20 | * Davide Gironi - developing original driver 21 | * Martin K. Schröder - maintenance since Oct 2014 22 | */ 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "amt1001.h" 29 | 30 | //define min and max valid voltage to measure humidity 31 | #define AMT1001_HUMIDITYVMIN 0.0 32 | #define AMT1001_HUMIDITYVMAX 3.0 33 | 34 | //slope factor to calculate humidity 35 | #define AMT1001_HUMIDITYSLOPE 33.33 36 | 37 | //define min and max valid adc to measure temperature 38 | #define AMT1001_TEMPERATUREVMIN 0.0 39 | #define AMT1001_TEMPERATUREVMAX 0.8 40 | 41 | //slope factor to calculate temperature 42 | #define AMT1001_TEMPERATURESLOPE 100.0 43 | 44 | 45 | //define min and max valid voltage to measure humidity 46 | #define AMT1001_HUMIDITYVMIN 0.0 47 | #define AMT1001_HUMIDITYVMAX 3.0 48 | 49 | //slope factor to calculate humidity 50 | #define AMT1001_HUMIDITYSLOPE 33.33 51 | 52 | //define lookup method variables for temperature 53 | #define amt1001_lookupadcfirst 1 //adc first value of lookup table 54 | #define amt1001_lookupadcstep 10 //step between every table point 55 | #define amt1001_lookuptablesize 103 //size of the lookup table 56 | const float PROGMEM amt1001_lookuptable[amt1001_lookuptablesize] = { 57 | -86.99 , -59.05 , -49.91 , -43.96 , -39.45 , -35.76 , -32.61 , -29.84 , -27.37 , -25.11 , -23.03 , -21.1 , -19.29 , -17.58 , -15.95 , -14.41 , -12.92 , -11.5 , -10.12 , -8.79 , -7.5 , -6.25 , -5.03 , -3.83 , -2.66 , -1.52 , -0.4 , 0.71 , 1.8 , 2.87 , 3.93 , 4.97 , 6.01 , 7.03 , 8.05 , 9.05 , 10.06 , 11.05 , 12.04 , 13.03 , 14.02 , 15 , 15.98 , 16.96 , 17.95 , 18.93 , 19.92 , 20.9 , 21.9 , 22.89 , 23.89 , 24.9 , 25.91 , 26.93 , 27.96 , 29 , 30.05 , 31.11 , 32.19 , 33.27 , 34.37 , 35.49 , 36.63 , 37.78 , 38.95 , 40.14 , 41.36 , 42.6 , 43.87 , 45.17 , 46.5 , 47.86 , 49.26 , 50.7 , 52.18 , 53.71 , 55.29 , 56.92 , 58.62 , 60.38 , 62.22 , 64.14 , 66.15 , 68.26 , 70.49 , 72.84 , 75.34 , 78.01 , 80.87 , 83.95 , 87.3 , 90.96 , 95 , 99.52 , 104.62 , 110.48 , 117.36 , 125.67 , 136.09 , 149.94 , 170.2 , 206.11 , 330.42 58 | }; 59 | 60 | /* 61 | * get humidity based on read voltage 62 | */ 63 | int16_t amt1001_gethumidity(double voltage) { 64 | if(voltage > AMT1001_HUMIDITYVMIN && voltage < AMT1001_HUMIDITYVMAX) 65 | return (int16_t)(AMT1001_HUMIDITYSLOPE*voltage); 66 | else 67 | return -1; 68 | } 69 | 70 | /* 71 | * get temperature based on read voltage 72 | */ 73 | int16_t amt1001_gettemperature(uint16_t adcvalue) { 74 | float t = 0.0; 75 | float mint = 0; 76 | float maxt = 0; 77 | 78 | //return error for invalid adcvalues 79 | if(adcvalueamt1001_lookupadcfirst+amt1001_lookupadcstep*(amt1001_lookuptablesize-1)) { 80 | return -1; 81 | } 82 | 83 | uint8_t i = 0; 84 | uint16_t a = amt1001_lookupadcfirst; 85 | for(i=0; i. 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Contributions: 22 | * Davide Gironi - developing original driver 23 | */ 24 | 25 | /* Memory Map */ 26 | #define NRF24L01_REG_CONFIG 0x00 27 | #define NRF24L01_REG_EN_AA 0x01 28 | #define NRF24L01_REG_EN_RXADDR 0x02 29 | #define NRF24L01_REG_SETUP_AW 0x03 30 | #define NRF24L01_REG_SETUP_RETR 0x04 31 | #define NRF24L01_REG_RF_CH 0x05 32 | #define NRF24L01_REG_RF_SETUP 0x06 33 | #define NRF24L01_REG_STATUS 0x07 34 | #define NRF24L01_REG_OBSERVE_TX 0x08 35 | #define NRF24L01_REG_CD 0x09 36 | #define NRF24L01_REG_RX_ADDR_P0 0x0A 37 | #define NRF24L01_REG_RX_ADDR_P1 0x0B 38 | #define NRF24L01_REG_RX_ADDR_P2 0x0C 39 | #define NRF24L01_REG_RX_ADDR_P3 0x0D 40 | #define NRF24L01_REG_RX_ADDR_P4 0x0E 41 | #define NRF24L01_REG_RX_ADDR_P5 0x0F 42 | #define NRF24L01_REG_TX_ADDR 0x10 43 | #define NRF24L01_REG_RX_PW_P0 0x11 44 | #define NRF24L01_REG_RX_PW_P1 0x12 45 | #define NRF24L01_REG_RX_PW_P2 0x13 46 | #define NRF24L01_REG_RX_PW_P3 0x14 47 | #define NRF24L01_REG_RX_PW_P4 0x15 48 | #define NRF24L01_REG_RX_PW_P5 0x16 49 | #define NRF24L01_REG_FIFO_STATUS 0x17 50 | #define NRF24L01_REG_FEATURE 0x1D 51 | #define NRF24L01_REG_DYNPD 0x1C 52 | 53 | /* Bit Mnemonics */ 54 | #define NRF24L01_REG_MASK_RX_DR 6 55 | #define NRF24L01_REG_MASK_TX_DS 5 56 | #define NRF24L01_REG_MASK_MAX_RT 4 57 | #define NRF24L01_REG_EN_CRC 3 58 | #define NRF24L01_REG_CRCO 2 59 | #define NRF24L01_REG_PWR_UP 1 60 | #define NRF24L01_REG_PRIM_RX 0 61 | #define NRF24L01_REG_ENAA_P5 5 62 | #define NRF24L01_REG_ENAA_P4 4 63 | #define NRF24L01_REG_ENAA_P3 3 64 | #define NRF24L01_REG_ENAA_P2 2 65 | #define NRF24L01_REG_ENAA_P1 1 66 | #define NRF24L01_REG_ENAA_P0 0 67 | #define NRF24L01_REG_ERX_P5 5 68 | #define NRF24L01_REG_ERX_P4 4 69 | #define NRF24L01_REG_ERX_P3 3 70 | #define NRF24L01_REG_ERX_P2 2 71 | #define NRF24L01_REG_ERX_P1 1 72 | #define NRF24L01_REG_ERX_P0 0 73 | #define NRF24L01_REG_AW 0 74 | #define NRF24L01_REG_ARD 4 75 | #define NRF24L01_REG_ARC 0 76 | #define NRF24L01_REG_PLL_LOCK 4 77 | #define NRF24L01_REG_RF_DR 3 78 | #define NRF24L01_REG_RF_PWR 1 79 | #define NRF24L01_REG_LNA_HCURR 0 80 | #define NRF24L01_REG_RX_DR 6 81 | #define NRF24L01_REG_TX_DS 5 82 | #define NRF24L01_REG_MAX_RT 4 83 | #define NRF24L01_REG_RX_P_NO 1 84 | #define NRF24L01_REG_TX_FULL 0 85 | #define NRF24L01_REG_PLOS_CNT 4 86 | #define NRF24L01_REG_ARC_CNT 0 87 | #define NRF24L01_REG_TX_REUSE 6 88 | #define NRF24L01_REG_FIFO_FULL 5 89 | #define NRF24L01_REG_TX_EMPTY 4 90 | #define NRF24L01_REG_RX_FULL 1 91 | #define NRF24L01_REG_RX_EMPTY 0 92 | #define NRF24L01_REG_RPD 0x09 93 | #define NRF24L01_REG_RF_DR_LOW 5 94 | #define NRF24L01_REG_RF_DR_HIGH 3 95 | #define NRF24L01_REG_RF_PWR_LOW 1 96 | #define NRF24L01_REG_RF_PWR_HIGH 2 97 | 98 | /* Instruction Mnemonics */ 99 | #define NRF24L01_CMD_R_REGISTER 0x00 100 | #define NRF24L01_CMD_W_REGISTER 0x20 101 | #define NRF24L01_CMD_REGISTER_MASK 0x1F 102 | #define NRF24L01_CMD_R_RX_PAYLOAD 0x61 103 | #define NRF24L01_CMD_W_TX_PAYLOAD 0xA0 104 | #define NRF24L01_CMD_FLUSH_TX 0xE1 105 | #define NRF24L01_CMD_FLUSH_RX 0xE2 106 | #define NRF24L01_CMD_REUSE_TX_PL 0xE3 107 | #define NRF24L01_CMD_NOP 0xFF 108 | -------------------------------------------------------------------------------- /src/temperature/ds18b20.c: -------------------------------------------------------------------------------- 1 | /* 2 | martink firmware project is free software: you can redistribute it and/or modify 3 | it under the terms of the GNU General Public License as published by 4 | the Free Software Foundation, either version 3 of the License, or 5 | (at your option) any later version. 6 | 7 | martink firmware is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with martink firmware. If not, see . 14 | 15 | Author: Martin K. Schröder 16 | Email: info@fortmax.se 17 | Github: https://github.com/mkschreder 18 | 19 | Special thanks to: 20 | * Davide Gironi, original implementation 21 | */ 22 | 23 | #include 24 | 25 | #include "ds18b20.h" 26 | 27 | #define pin_write(value) pio_write_pin(self->gpio, self->data_pin, value) 28 | #define pin_dir(dir) pio_configure_pin(self->gpio, self->data_pin, dir) 29 | #define pin_read() pio_read_pin(self->gpio, self->data_pin) 30 | 31 | static uint8_t ds18b20_reset(struct ds18b20 *self) { 32 | uint8_t i; 33 | 34 | pin_write(0); 35 | pin_dir(GP_OUTPUT); 36 | delay_us(480); 37 | 38 | //release line and wait for 60uS 39 | pin_dir(GP_INPUT); 40 | delay_us(60); 41 | 42 | //get value and wait 420us 43 | i = pin_read(); 44 | delay_us(420); 45 | 46 | return i; 47 | } 48 | 49 | /* 50 | * write one bit 51 | */ 52 | static void ds18b20_writebit(struct ds18b20 *self, uint8_t bit){ 53 | // low for 1us 54 | pin_write(0); 55 | pin_dir(GP_OUTPUT); 56 | delay_us(1); 57 | 58 | //if we want to write 1, release the line (if not will keep low) 59 | if(bit) 60 | pin_dir(GP_INPUT); 61 | 62 | //wait 60uS and release the line 63 | delay_us(60); 64 | pin_dir(GP_INPUT); 65 | } 66 | 67 | /* 68 | * read one bit 69 | */ 70 | static uint8_t ds18b20_readbit(struct ds18b20 *self){ 71 | uint8_t bit=0; 72 | //low for 1uS 73 | pin_write(0); 74 | pin_dir(GP_OUTPUT); 75 | delay_us(1); 76 | 77 | //release line and wait for 14uS 78 | pin_dir(GP_INPUT); 79 | delay_us(14); 80 | 81 | //read the value 82 | if(pin_read()) 83 | bit=1; 84 | 85 | //wait 45uS and return read value 86 | delay_us(45); 87 | 88 | return bit; 89 | } 90 | 91 | /* 92 | * write one byte 93 | */ 94 | static void ds18b20_writebyte(struct ds18b20 *self, uint8_t byte){ 95 | uint8_t i=8; 96 | while(i--){ 97 | ds18b20_writebit(self, byte&1); 98 | byte >>= 1; 99 | } 100 | } 101 | 102 | /* 103 | * read one byte 104 | */ 105 | static uint8_t ds18b20_readbyte(struct ds18b20 *self){ 106 | uint8_t i=8, n=0; 107 | while(i--){ 108 | n >>= 1; 109 | n |= (ds18b20_readbit(self)<<7); 110 | } 111 | return n; 112 | } 113 | 114 | 115 | void ds18b20_init(struct ds18b20 *self, 116 | pio_dev_t gpio, gpio_pin_t data_pin){ 117 | self->gpio = gpio; 118 | self->data_pin = data_pin; 119 | } 120 | 121 | /* 122 | * get temperature 123 | */ 124 | double ds18b20_read_temperature(struct ds18b20 *self) { 125 | uint8_t temperature[2]; 126 | int8_t digit; 127 | uint16_t decimal; 128 | double retd = 0; 129 | 130 | ds18b20_reset(self); //reset 131 | ds18b20_writebyte(self, DS18B20_CMD_SKIPROM); //skip ROM 132 | ds18b20_writebyte(self, DS18B20_CMD_CONVERTTEMP); //start temperature conversion 133 | 134 | while(!ds18b20_readbit(self)); //wait until conversion is complete 135 | 136 | ds18b20_reset(self); //reset 137 | ds18b20_writebyte(self, DS18B20_CMD_SKIPROM); //skip ROM 138 | ds18b20_writebyte(self, DS18B20_CMD_RSCRATCHPAD); //read scratchpad 139 | 140 | //read 2 byte from scratchpad 141 | temperature[0] = ds18b20_readbyte(self); 142 | temperature[1] = ds18b20_readbyte(self); 143 | 144 | ds18b20_reset(self); //reset 145 | 146 | //store temperature integer digits 147 | digit = temperature[0]>>4; 148 | digit |= (temperature[1]&0x7)<<4; 149 | 150 | //store temperature decimal digits 151 | decimal = temperature[0]&0xf; 152 | decimal *= DS18B20_DECIMALSTEPS; 153 | 154 | //compose the double temperature value and return it 155 | retd = digit + decimal * 0.0001; 156 | 157 | return retd; 158 | } 159 | 160 | -------------------------------------------------------------------------------- /src/gpio/max14890.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains a lot of code from Ninjaflight. 3 | * 4 | * Authors: Martin Schröder & Cleanflight project 5 | * 6 | * Ninjaflight is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Ninjaflight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Ninjaflight. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include 35 | 36 | #define MAX14890_CMD_WRITE_CONFIG (5 << 13) 37 | #define MAX14890_CMD_FAULT_STATUS (2 << 13) 38 | 39 | #define MAX14890_HITH_LOW (0) 40 | #define MAX14890_HITH_HIGH ((1 << 12)) 41 | 42 | #define MAX14890_MODEA_DHTL (0) 43 | #define MAX14890_MODEA_RS422 ((1 << 10)) 44 | #define MAX14890_MODEA_SEHTL ((2 << 10)) 45 | #define MAX14890_MODEA_TTL ((3 << 10)) 46 | 47 | #define MAX14890_MODEB_DHTL (0) 48 | #define MAX14890_MODEB_RS422 ((1 << 8)) 49 | #define MAX14890_MODEB_SEHTL ((2 << 8)) 50 | #define MAX14890_MODEB_TTL ((3 << 8)) 51 | 52 | #define MAX14890_MODEZ_DHTL ((0)) 53 | #define MAX14890_MODEZ_RS422 ((4 << 5)) 54 | #define MAX14890_MODEZ_SEHTL ((2 << 5)) 55 | #define MAX14890_MODEZ_TTL ((6 << 5)) 56 | #define MAX14890_MODEZ_DI ((1 << 5)) 57 | 58 | #define MAX14890_MODEY_RS422 (0) 59 | #define MAX14890_MODEY_TTL ((3 << 3)) 60 | #define MAX14890_MODEY_DI ((1 << 3)) 61 | 62 | #define MAX14890_MODED2_DI ((1 << 2)) 63 | #define MAX14890_MODED2_TTL 0 64 | #define MAX14890_MODED3_DI ((1 << 1)) 65 | #define MAX14890_MODED3_TTL 0 66 | 67 | #define MAX14890_FILTER_OFF 0 68 | #define MAX14890_FILTER_ON ((1 << 0)) 69 | 70 | #define MAX14890_TIMEOUT 10 71 | 72 | struct max14890 { 73 | gpio_device_t gpio; 74 | spi_device_t spi; 75 | uint32_t cs_pin; 76 | }; 77 | 78 | static int _max14890_cmd(struct max14890 *self, uint32_t txdata, uint16_t *rxdata){ 79 | uint8_t tx[2] = {(uint8_t)(txdata >> 8), (uint8_t)txdata}; 80 | uint8_t rx[2] = {0}; 81 | 82 | thread_sleep_us(50); 83 | 84 | spi_transfer(self->spi, self->gpio, self->cs_pin, tx, rx, sizeof(tx), MAX14890_TIMEOUT); 85 | 86 | thread_sleep_us(50); 87 | 88 | // read status 89 | spi_transfer(self->spi, self->gpio, self->cs_pin, tx, rx, sizeof(tx), MAX14890_TIMEOUT); 90 | 91 | *rxdata = (uint16_t)(((int)rx[0] << 8) | rx[1]); 92 | 93 | return 0; 94 | } 95 | 96 | static int _max14890_probe(void *fdt, int fdt_node){ 97 | spi_device_t spi = spi_find_by_ref(fdt, fdt_node, "spi"); 98 | if(!spi){ 99 | printk("max14890: spi error\n"); 100 | return -1; 101 | } 102 | gpio_device_t gpio = gpio_find_by_ref(fdt, fdt_node, "gpio"); 103 | if(!gpio){ 104 | printk("max14890: gpio error\n"); 105 | return -1; 106 | } 107 | uint32_t cs_pin = (uint32_t)fdt_get_int_or_default(fdt, fdt_node, "cs_pin", 0); 108 | 109 | struct max14890 *self = kzmalloc(sizeof(struct max14890)); 110 | self->gpio = gpio; 111 | self->cs_pin = cs_pin; 112 | self->spi = spi; 113 | 114 | gpio_set(self->gpio, self->cs_pin); 115 | 116 | // configure mode for pins 117 | uint16_t status = 0; 118 | _max14890_cmd(self, 119 | MAX14890_CMD_WRITE_CONFIG | 120 | MAX14890_MODEA_TTL | 121 | MAX14890_MODEB_TTL | 122 | MAX14890_MODEZ_TTL | 123 | MAX14890_MODEY_TTL | 124 | MAX14890_MODED2_TTL | 125 | MAX14890_MODED3_TTL 126 | , &status); 127 | 128 | _max14890_cmd(self, 129 | MAX14890_CMD_FAULT_STATUS, &status); 130 | 131 | if((status & 0xe000) != 0x4000){ 132 | printk(PRINT_ERROR "max14890: fault status (%04x) invalid. Chip unreachable!\n", status); 133 | } else { 134 | printk(PRINT_SUCCESS "max14890: ready (%04x)\n", status); 135 | } 136 | 137 | return 0; 138 | } 139 | 140 | static int _max14890_remove(void *fdt, int fdt_node){ 141 | return -1; 142 | } 143 | 144 | DEVICE_DRIVER(max14890, "fw,max14890", _max14890_probe, _max14890_remove) 145 | 146 | -------------------------------------------------------------------------------- /src/fpga/ice40.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "ice40-fw.c" 17 | 18 | struct ice40 { 19 | memory_device_t flash; 20 | gpio_device_t gpio; 21 | spi_device_t spi; 22 | uint32_t creset_pin, cdone_pin, cs_pin; 23 | }; 24 | 25 | int _ice40_probe(void *fdt, int fdt_node){ 26 | memory_device_t flash = memory_find_by_ref(fdt, fdt_node, "flash"); 27 | gpio_device_t gpio = gpio_find_by_ref(fdt, fdt_node, "gpio"); 28 | spi_device_t spi = spi_find_by_ref(fdt, fdt_node, "spi"); 29 | int creset_pin = fdt_get_int_or_default(fdt, fdt_node, "creset_pin", -1); 30 | int cdone_pin = fdt_get_int_or_default(fdt, fdt_node, "cdone_pin", -1); 31 | int cs_pin = fdt_get_int_or_default(fdt, fdt_node, "cs_pin", -1); 32 | int pwr_pin = fdt_get_int_or_default(fdt, fdt_node, "pwr_pin", -1); 33 | 34 | if(!flash){ 35 | printk("ice40: missing flash device!\n"); 36 | return -1; 37 | } 38 | 39 | if(!gpio){ 40 | printk("ice40: missing gpio device!\n"); 41 | return -1; 42 | } 43 | 44 | if(creset_pin < 0){ 45 | printk("ice40: missing creset_pin!\n"); 46 | return -1; 47 | } 48 | 49 | if(cdone_pin < 0){ 50 | printk("ice40: missing cdone_pin!\n"); 51 | return -1; 52 | } 53 | 54 | if(cs_pin < 0){ 55 | printk("ice40: missing cs_pin!\n"); 56 | return -1; 57 | } 58 | 59 | struct ice40 *self = kzmalloc(sizeof(struct ice40)); 60 | self->flash = flash; 61 | self->gpio = gpio; 62 | self->spi = spi; 63 | self->creset_pin = (uint32_t)creset_pin; 64 | self->cdone_pin = (uint32_t)cdone_pin; 65 | self->cs_pin = (uint32_t)cs_pin; 66 | 67 | // to enter spi slave mode we set the SS low and then toggle power 68 | if(spi){ 69 | int r = 0; 70 | uint8_t dummy[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 71 | 72 | // reset the chip into slave mode 73 | gpio_reset(self->gpio, self->cs_pin); 74 | gpio_reset(self->gpio, self->creset_pin); 75 | thread_sleep_ms(1); 76 | 77 | // power cycle 78 | if(pwr_pin >= 0){ 79 | gpio_reset(self->gpio, (uint32_t)pwr_pin); 80 | thread_sleep_ms(50); 81 | gpio_set(self->gpio, (uint32_t)pwr_pin); 82 | thread_sleep_ms(50); 83 | } 84 | 85 | gpio_set(self->gpio, self->creset_pin); 86 | // chip needs 1200us to boot into slave mode 87 | thread_sleep_ms(2); 88 | 89 | // pull cs high and output a byte 90 | gpio_set(self->gpio, self->cs_pin); 91 | spi_transfer(self->spi, NULL, 0, dummy, NULL, 1, 1000); 92 | thread_sleep_ms(1); 93 | 94 | // now pull it low and send the whole image! 95 | gpio_reset(self->gpio, self->cs_pin); 96 | r = spi_transfer(self->spi, NULL, 0, example_bin, NULL, example_bin_len, 1000); 97 | gpio_set(self->gpio, self->cs_pin); 98 | 99 | if(r < 0){ 100 | printk("ice40: failed to write configuration image!\n"); 101 | } else { 102 | printk("ice40: written %d bytes to FPGA!\n", r); 103 | } 104 | // we are not done yet so CDONE should be low! 105 | if(gpio_read(self->gpio, self->cdone_pin)){ 106 | printk("ice40: WARNING: CDONE is high when it shouldn't!\n"); 107 | } 108 | spi_transfer(self->spi, NULL, 0, dummy, NULL, sizeof(dummy), 1000); 109 | if(gpio_read(self->gpio, self->cdone_pin)){ 110 | printk("ice40: FPGA configured!\n", r); 111 | } else { 112 | printk("ice40: FAILED to start FPGA! (timeout waiting for CDONE)\n", r); 113 | } 114 | spi_transfer(self->spi, NULL, 0, dummy, NULL, sizeof(dummy), 1000); 115 | } else { 116 | // chip is going to be spi master so we write the firmware here to flash while chip is in reset 117 | gpio_reset(self->gpio, self->creset_pin); 118 | gpio_set(self->gpio, self->cs_pin); 119 | thread_sleep_ms(1); 120 | 121 | // power cycle 122 | if(pwr_pin >= 0){ 123 | gpio_reset(self->gpio, (uint32_t)pwr_pin); 124 | thread_sleep_ms(50); 125 | gpio_set(self->gpio, (uint32_t)pwr_pin); 126 | thread_sleep_ms(50); 127 | } 128 | 129 | int r = memory_write(self->flash, 0, example_bin, example_bin_len); 130 | if(r < 0){ 131 | printk("ice40: failed to write flash!\n"); 132 | } else { 133 | printk("ice40: written %d bytes\n", r); 134 | } 135 | 136 | gpio_set(self->gpio, self->creset_pin); 137 | } 138 | 139 | return 0; 140 | } 141 | 142 | int _ice40_remove(void *fdt, int fdt_node){ 143 | return 0; 144 | } 145 | 146 | DEVICE_DRIVER(ice40, "fw,ice40", _ice40_probe, _ice40_remove) 147 | -------------------------------------------------------------------------------- /src/disp/lcd7seg.c: -------------------------------------------------------------------------------- 1 | /** 2 | 7 segment led display driver for 8 bit parallel port 3 | 4 | martink firmware project is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | martink firmware is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with martink firmware. If not, see . 16 | 17 | Author: Martin K. Schröder 18 | Email: info@fortmax.se 19 | Github: https://github.com/mkschreder 20 | 21 | Special thanks to: 22 | * Davide Gironi, original implementation 23 | */ 24 | 25 | 26 | #include 27 | #include "lcd7seg.h" 28 | 29 | #include 30 | 31 | #define SEVSEG_PINA 0 32 | #define SEVSEG_PINB 1 33 | #define SEVSEG_PINC 2 34 | #define SEVSEG_PIND 3 35 | #define SEVSEG_PINE 4 36 | #define SEVSEG_PINF 5 37 | #define SEVSEG_PING 6 38 | #define SEVSEG_PINDOT 7 39 | 40 | //set minimum power on display time (us) 41 | #define SEVSEG_USONTIME 1000 42 | 43 | //lookup table ascii char to 7 segment 44 | #define SEGN 0xFF 45 | #define SEGU 0xF7 //unknown way of display this character 46 | static const uint8_t PROGMEM sevsegascii_table[] = { 47 | SEGN, SEGN, SEGN, SEGN, 48 | SEGN, SEGN, SEGN, SEGN, 49 | SEGN, SEGN, SEGN, SEGN, 50 | SEGN, SEGN, SEGN, SEGN, 51 | SEGN, SEGN, SEGN, SEGN, 52 | SEGN, SEGN, SEGN, SEGN, 53 | SEGN, SEGN, SEGN, SEGN, 54 | SEGN, SEGN, SEGN, SEGN, 55 | SEGN, SEGN, SEGN, SEGN, 56 | SEGN, SEGN, SEGN, SEGN, 57 | SEGN, SEGN, SEGN, SEGN, 58 | SEGN, SEGN, SEGN, SEGN, 59 | 0xc0, 0xf9, 0xa4, 0xb0, // 0 1 2 3 60 | 0x99, 0x92, 0x82, 0xf8, // 4 5 6 7 61 | 0x80, 0x90, SEGN, SEGN, // 8 9 62 | SEGN, SEGN, SEGN, SEGN, 63 | SEGN, 0x88, 0x83, 0xc6, // A B C 64 | 0xa1, 0x86, 0x8e, 0xc2, // D E F G 65 | 0x8b, 0xcf, 0xe1, SEGU, // H I J _ 66 | 0xc7, 0xc8, 0xab, 0xc0, // L M N O 67 | 0x8c, 0x98, 0xaf, 0x92, // P Q R S 68 | 0x87, 0xc1, 0xe3, SEGU, // T U V _ 69 | SEGU, 0x91, 0xa4, SEGN, // _ Y Z 70 | SEGN, SEGN, SEGN, SEGN, 71 | SEGN, 0x88, 0x83, 0xc6, // A B C 72 | 0xa1, 0x86, 0x8e, 0xc2, // D E F G 73 | 0x8b, 0xcf, 0xe1, SEGU, // H I J _ 74 | 0xc7, 0xc8, 0xab, 0xc0, // L M N O 75 | 0x8c, 0x98, 0xaf, 0x92, // P Q R S 76 | 0x87, 0xc1, 0xe3, SEGU, // T U V _ 77 | SEGU, 0x91, 0xa4, SEGN, // _ Y Z 78 | SEGN, SEGN, SEGN, SEGN 79 | }; 80 | 81 | #define set_data(data) (pio_write_word(self->port, self->data_port, data)) 82 | #define set_cs_pin() (pio_write_pin(self->port, self->cs_pin, 1)) 83 | #define clear_cs_pin() (pio_write_pin(self->port, self->cs_pin, 0)) 84 | 85 | void led7seg_off(struct led7seg *self){ 86 | if(self->type == SEVSEG_TYPECC || self->type == SEVSEG_TYPECAT) 87 | set_data(0x00); 88 | else if(self->type == SEVSEG_TYPECA || self->type == SEVSEG_TYPECCT) 89 | set_data(0xFF); 90 | 91 | if(self->type == SEVSEG_TYPECA || self->type == SEVSEG_TYPECAT) 92 | set_cs_pin(); 93 | else if(self->type == SEVSEG_TYPECC || self->type == SEVSEG_TYPECCT) 94 | clear_cs_pin(); 95 | } 96 | 97 | void led7seg_on(struct led7seg *self){ 98 | set_data(self->data); 99 | 100 | if(self->type == SEVSEG_TYPECA || self->type == SEVSEG_TYPECAT) 101 | set_cs_pin(); 102 | else if(self->type == SEVSEG_TYPECC || self->type == SEVSEG_TYPECCT) 103 | clear_cs_pin(); 104 | } 105 | 106 | void led7seg_init(struct led7seg *self, pio_dev_t port, uint8_t data_port, gpio_pin_t cs_pin, lcd7seg_type type) { 107 | self->port = port; 108 | self->data_port = data_port; 109 | self->cs_pin = cs_pin; 110 | self->type = type; 111 | 112 | //off 113 | 114 | if(self->type == SEVSEG_TYPECC || self->type == SEVSEG_TYPECAT) 115 | self->data = 0x00; 116 | else if(self->type == SEVSEG_TYPECA || self->type == SEVSEG_TYPECCT) 117 | self->data = 0xFF; 118 | 119 | led7seg_off(self); 120 | } 121 | /* 122 | void sevseg_putc(struct led7seg *self, uint8_t c, uint8_t dot) { 123 | uint8_t cdisp = pgm_read_byte(&sevsegascii_table[c]); 124 | if(dot) 125 | cdisp &= ~(1<<7); 126 | if(self->type == SEVSEG_TYPECC|| self->type == SEVSEG_TYPECAT) 127 | self->data = 0XFF ^ cdisp; 128 | else if(self->type == SEVSEG_TYPECA || self->type == SEVSEG_TYPECCT) 129 | self->data = cdisp; 130 | }*/ 131 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-eeprom.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | * Author: Adam Dunkels 32 | * 33 | */ 34 | 35 | #include "cfs/cfs.h" 36 | #include "dev/eeprom.h" 37 | 38 | struct filestate { 39 | int flag; 40 | #define FLAG_FILE_CLOSED 0 41 | #define FLAG_FILE_OPEN 1 42 | eeprom_addr_t fileptr; 43 | eeprom_addr_t filesize; 44 | }; 45 | 46 | static struct filestate file; 47 | 48 | #ifdef CFS_EEPROM_CONF_OFFSET 49 | #define CFS_EEPROM_OFFSET CFS_EEPROM_CONF_OFFSET 50 | #else 51 | #define CFS_EEPROM_OFFSET 0 52 | #endif 53 | 54 | /*---------------------------------------------------------------------------*/ 55 | int 56 | cfs_open(const char *n, int f) 57 | { 58 | if(file.flag == FLAG_FILE_CLOSED) { 59 | file.flag = FLAG_FILE_OPEN; 60 | if(f & CFS_READ) { 61 | file.fileptr = 0; 62 | } 63 | if(f & CFS_WRITE){ 64 | if(f & CFS_APPEND) { 65 | file.fileptr = file.filesize; 66 | } else { 67 | file.fileptr = 0; 68 | file.filesize = 0; 69 | } 70 | } 71 | return 1; 72 | } else { 73 | return -1; 74 | } 75 | } 76 | /*---------------------------------------------------------------------------*/ 77 | void 78 | cfs_close(int f) 79 | { 80 | file.flag = FLAG_FILE_CLOSED; 81 | } 82 | /*---------------------------------------------------------------------------*/ 83 | int 84 | cfs_read(int f, void *buf, unsigned int len) 85 | { 86 | if(f == 1) { 87 | eeprom_read(CFS_EEPROM_OFFSET + file.fileptr, buf, len); 88 | file.fileptr += len; 89 | return len; 90 | } else { 91 | return -1; 92 | } 93 | } 94 | /*---------------------------------------------------------------------------*/ 95 | int 96 | cfs_write(int f, const void *buf, unsigned int len) 97 | { 98 | if(f == 1) { 99 | eeprom_write(CFS_EEPROM_OFFSET + file.fileptr, (unsigned char *)buf, len); 100 | file.fileptr += len; 101 | return len; 102 | } else { 103 | return -1; 104 | } 105 | } 106 | /*---------------------------------------------------------------------------*/ 107 | cfs_offset_t 108 | cfs_seek(int f, cfs_offset_t o, int w) 109 | { 110 | if(w == CFS_SEEK_SET && f == 1) { 111 | file.fileptr = o; 112 | return o; 113 | } else { 114 | return -1; 115 | } 116 | } 117 | /*---------------------------------------------------------------------------*/ 118 | int 119 | cfs_remove(const char *name) 120 | { 121 | return -1; 122 | } 123 | /*---------------------------------------------------------------------------*/ 124 | int 125 | cfs_opendir(struct cfs_dir *p, const char *n) 126 | { 127 | return -1; 128 | } 129 | /*---------------------------------------------------------------------------*/ 130 | int 131 | cfs_readdir(struct cfs_dir *p, struct cfs_dirent *e) 132 | { 133 | return -1; 134 | } 135 | /*---------------------------------------------------------------------------*/ 136 | void 137 | cfs_closedir(struct cfs_dir *p) 138 | { 139 | } 140 | /*---------------------------------------------------------------------------*/ 141 | -------------------------------------------------------------------------------- /m4/ltsugar.m4: -------------------------------------------------------------------------------- 1 | # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software 4 | # Foundation, Inc. 5 | # Written by Gary V. Vaughan, 2004 6 | # 7 | # This file is free software; the Free Software Foundation gives 8 | # unlimited permission to copy and/or distribute it, with or without 9 | # modifications, as long as this notice is preserved. 10 | 11 | # serial 6 ltsugar.m4 12 | 13 | # This is to help aclocal find these macros, as it can't see m4_define. 14 | AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) 15 | 16 | 17 | # lt_join(SEP, ARG1, [ARG2...]) 18 | # ----------------------------- 19 | # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their 20 | # associated separator. 21 | # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier 22 | # versions in m4sugar had bugs. 23 | m4_define([lt_join], 24 | [m4_if([$#], [1], [], 25 | [$#], [2], [[$2]], 26 | [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) 27 | m4_define([_lt_join], 28 | [m4_if([$#$2], [2], [], 29 | [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) 30 | 31 | 32 | # lt_car(LIST) 33 | # lt_cdr(LIST) 34 | # ------------ 35 | # Manipulate m4 lists. 36 | # These macros are necessary as long as will still need to support 37 | # Autoconf-2.59, which quotes differently. 38 | m4_define([lt_car], [[$1]]) 39 | m4_define([lt_cdr], 40 | [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], 41 | [$#], 1, [], 42 | [m4_dquote(m4_shift($@))])]) 43 | m4_define([lt_unquote], $1) 44 | 45 | 46 | # lt_append(MACRO-NAME, STRING, [SEPARATOR]) 47 | # ------------------------------------------ 48 | # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. 49 | # Note that neither SEPARATOR nor STRING are expanded; they are appended 50 | # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). 51 | # No SEPARATOR is output if MACRO-NAME was previously undefined (different 52 | # than defined and empty). 53 | # 54 | # This macro is needed until we can rely on Autoconf 2.62, since earlier 55 | # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. 56 | m4_define([lt_append], 57 | [m4_define([$1], 58 | m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) 59 | 60 | 61 | 62 | # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) 63 | # ---------------------------------------------------------- 64 | # Produce a SEP delimited list of all paired combinations of elements of 65 | # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list 66 | # has the form PREFIXmINFIXSUFFIXn. 67 | # Needed until we can rely on m4_combine added in Autoconf 2.62. 68 | m4_define([lt_combine], 69 | [m4_if(m4_eval([$# > 3]), [1], 70 | [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl 71 | [[m4_foreach([_Lt_prefix], [$2], 72 | [m4_foreach([_Lt_suffix], 73 | ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, 74 | [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) 75 | 76 | 77 | # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) 78 | # ----------------------------------------------------------------------- 79 | # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited 80 | # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. 81 | m4_define([lt_if_append_uniq], 82 | [m4_ifdef([$1], 83 | [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], 84 | [lt_append([$1], [$2], [$3])$4], 85 | [$5])], 86 | [lt_append([$1], [$2], [$3])$4])]) 87 | 88 | 89 | # lt_dict_add(DICT, KEY, VALUE) 90 | # ----------------------------- 91 | m4_define([lt_dict_add], 92 | [m4_define([$1($2)], [$3])]) 93 | 94 | 95 | # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) 96 | # -------------------------------------------- 97 | m4_define([lt_dict_add_subkey], 98 | [m4_define([$1($2:$3)], [$4])]) 99 | 100 | 101 | # lt_dict_fetch(DICT, KEY, [SUBKEY]) 102 | # ---------------------------------- 103 | m4_define([lt_dict_fetch], 104 | [m4_ifval([$3], 105 | m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), 106 | m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) 107 | 108 | 109 | # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) 110 | # ----------------------------------------------------------------- 111 | m4_define([lt_if_dict_fetch], 112 | [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], 113 | [$5], 114 | [$6])]) 115 | 116 | 117 | # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) 118 | # -------------------------------------------------------------- 119 | m4_define([lt_dict_filter], 120 | [m4_if([$5], [], [], 121 | [lt_join(m4_quote(m4_default([$4], [[, ]])), 122 | lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), 123 | [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl 124 | ]) 125 | -------------------------------------------------------------------------------- /src/fs/spiffs/test/testrunner.c: -------------------------------------------------------------------------------- 1 | /* 2 | * testrunner.c 3 | * 4 | * Created on: Jun 18, 2013 5 | * Author: petera 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "testrunner.h" 20 | 21 | static struct { 22 | test *tests; 23 | test *_last_test; 24 | int test_count; 25 | void (*on_stop)(test *t); 26 | test_res *failed; 27 | test_res *failed_last; 28 | test_res *stopped; 29 | test_res *stopped_last; 30 | FILE *spec; 31 | } test_main; 32 | 33 | void test_init(void (*on_stop)(test *t)) { 34 | test_main.on_stop = on_stop; 35 | } 36 | 37 | static char check_spec(char *name) { 38 | if (test_main.spec) { 39 | fseek(test_main.spec, 0, SEEK_SET); 40 | char *line = NULL; 41 | size_t sz; 42 | ssize_t read; 43 | while ((read = getline(&line, &sz, test_main.spec)) != -1) { 44 | if (strncmp(line, name, strlen(name)) == 0) { 45 | free(line); 46 | return 1; 47 | } 48 | } 49 | free(line); 50 | return 0; 51 | } else { 52 | return 1; 53 | } 54 | } 55 | 56 | void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t)) { 57 | if (f == 0) return; 58 | if (!check_spec(name)) return; 59 | DBGT("adding test %s\n", name); 60 | test *t = malloc(sizeof(test)); 61 | memset(t, 0, sizeof(test)); 62 | t->f = f; 63 | strcpy(t->name, name); 64 | t->setup = setup; 65 | t->teardown = teardown; 66 | if (test_main.tests == 0) { 67 | test_main.tests = t; 68 | } else { 69 | test_main._last_test->_next = t; 70 | } 71 | test_main._last_test = t; 72 | test_main.test_count++; 73 | } 74 | 75 | static void add_res(test *t, test_res **head, test_res **last) { 76 | test_res *tr = malloc(sizeof(test_res)); 77 | memset(tr,0,sizeof(test_res)); 78 | strcpy(tr->name, t->name); 79 | if (*head == 0) { 80 | *head = tr; 81 | } else { 82 | (*last)->_next = tr; 83 | } 84 | *last = tr; 85 | } 86 | 87 | static void dump_res(test_res **head) { 88 | test_res *tr = (*head); 89 | while (tr) { 90 | test_res *next_tr = tr->_next; 91 | printf(" %s\n", tr->name); 92 | free(tr); 93 | tr = next_tr; 94 | } 95 | } 96 | 97 | void run_tests(int argc, char **args) { 98 | memset(&test_main, 0, sizeof(test_main)); 99 | if (argc > 1) { 100 | printf("running tests from %s\n", args[1]); 101 | FILE *fd = fopen(args[1], "r"); 102 | if (fd == NULL) { 103 | printf("%s not found\n", args[1]); 104 | exit(EXIT_FAILURE); 105 | } 106 | test_main.spec = fd; 107 | } 108 | 109 | DBGT("adding suites...\n"); 110 | add_suites(); 111 | DBGT("%i tests added\n", test_main.test_count); 112 | if (test_main.spec) { 113 | fclose(test_main.spec); 114 | } 115 | 116 | if (test_main.test_count == 0) { 117 | printf("No tests to run\n"); 118 | return; 119 | } 120 | 121 | int fd_success = open("_tests_ok", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); 122 | int fd_bad = open("_tests_fail", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); 123 | 124 | DBGT("running tests...\n"); 125 | int ok = 0; 126 | int failed = 0; 127 | int stopped = 0; 128 | test *cur_t = test_main.tests; 129 | int i = 1; 130 | while (cur_t) { 131 | cur_t->setup(cur_t); 132 | test *next_test = cur_t->_next; 133 | DBGT("TEST %i/%i : running test %s\n", i, test_main.test_count, cur_t->name); 134 | i++; 135 | int res = cur_t->f(cur_t); 136 | cur_t->teardown(cur_t); 137 | int fd = res == TEST_RES_OK ? fd_success : fd_bad; 138 | write(fd, cur_t->name, strlen(cur_t->name)); 139 | write(fd, "\n", 1); 140 | switch (res) { 141 | case TEST_RES_OK: 142 | ok++; 143 | printf(" .. ok\n"); 144 | break; 145 | case TEST_RES_FAIL: 146 | failed++; 147 | printf(" .. FAILED\n"); 148 | if (test_main.on_stop) test_main.on_stop(cur_t); 149 | add_res(cur_t, &test_main.failed, &test_main.failed_last); 150 | break; 151 | case TEST_RES_ASSERT: 152 | stopped++; 153 | printf(" .. ABORTED\n"); 154 | if (test_main.on_stop) test_main.on_stop(cur_t); 155 | add_res(cur_t, &test_main.stopped, &test_main.stopped_last); 156 | break; 157 | } 158 | free(cur_t); 159 | cur_t = next_test; 160 | } 161 | close(fd_success); 162 | close(fd_bad); 163 | DBGT("ran %i tests\n", test_main.test_count); 164 | printf("Test report, %i tests\n", test_main.test_count); 165 | printf("%i succeeded\n", ok); 166 | printf("%i failed\n", failed); 167 | dump_res(&test_main.failed); 168 | printf("%i stopped\n", stopped); 169 | dump_res(&test_main.stopped); 170 | if (ok < test_main.test_count) { 171 | printf("\nFAILED\n"); 172 | } else { 173 | printf("\nALL TESTS OK\n"); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/vardir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Martin K. Schröder 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | struct vardir_driver { 29 | struct vardir_device dev; 30 | 31 | struct vardir dir; 32 | struct mutex lock; 33 | }; 34 | 35 | int _vardir_add_static(vardir_device_t dev, uint32_t id, const char *name, vardir_value_type_t type, const void *init_value){ 36 | struct vardir_driver *self = container_of(dev, struct vardir_driver, dev.ops); 37 | thread_mutex_lock(&self->lock); 38 | 39 | int ret = vardir_add_field(&self->dir, id, name, type, 123); 40 | 41 | thread_mutex_unlock(&self->lock); 42 | 43 | return ret; 44 | } 45 | 46 | int _vardir_add_dynamic(vardir_device_t dev, uint32_t id, const char *name, vardir_value_type_t type, struct vardir_entry_ops **ops){ 47 | struct vardir_driver *self = container_of(dev, struct vardir_driver, dev.ops); 48 | thread_mutex_lock(&self->lock); 49 | 50 | int ret = vardir_add_entry(&self->dir, id, name, type, ops); 51 | 52 | thread_mutex_unlock(&self->lock); 53 | 54 | return ret; 55 | } 56 | 57 | int _vardir_get(vardir_device_t dev, uint32_t id, const char *name, vardir_value_type_t type, void *value, size_t size){ 58 | struct vardir_driver *self = container_of(dev, struct vardir_driver, dev.ops); 59 | 60 | thread_mutex_lock(&self->lock); 61 | struct vardir_entry *e = NULL; 62 | if(name){ 63 | if((e = vardir_find_entry_by_name(&self->dir, name))) id = e->id; 64 | else { 65 | thread_mutex_unlock(&self->lock); 66 | return -ENOENT; 67 | } 68 | } 69 | 70 | struct vardir_entry *ent = vardir_find_entry_by_id(&self->dir, id); 71 | 72 | int ret = 0; 73 | 74 | uint32_t val = 0; 75 | vardir_entry_get_u32(ent, &val); 76 | 77 | switch(type){ 78 | case VAR_INT32: 79 | case VAR_UINT32: 80 | if(size != sizeof(uint32_t)) return -1; 81 | *((uint32_t*)value) = val; 82 | ret = sizeof(uint32_t); 83 | break; 84 | case VAR_INT16: 85 | case VAR_UINT16: 86 | if(size != sizeof(uint16_t)) return -1; 87 | *((uint16_t*)value) = (uint16_t)val; 88 | ret = sizeof(uint16_t); 89 | break; 90 | case VAR_INT8: 91 | case VAR_UINT8: 92 | if(size != sizeof(uint8_t)) return -1; 93 | *((uint8_t*)value) = (uint8_t)val; 94 | ret = sizeof(uint8_t); 95 | break; 96 | case VAR_STRING: { 97 | break; 98 | } 99 | default: 100 | printk("vardir: unsupported type\n"); 101 | } 102 | 103 | thread_mutex_unlock(&self->lock); 104 | return ret; 105 | } 106 | 107 | int _vardir_set(vardir_device_t dev, uint32_t id, const char *name, vardir_value_type_t type, const void *value){ 108 | struct vardir_driver *self = container_of(dev, struct vardir_driver, dev.ops); 109 | struct vardir_entry *e = NULL; 110 | if(name) e = vardir_find_entry_by_name(&self->dir, name); 111 | else e = vardir_find_entry_by_id(&self->dir, id); 112 | if(!e) return -ENOENT; 113 | 114 | thread_mutex_lock(&self->lock); 115 | switch (e->type & VARDIR_VALUE_TYPE_MASK) { 116 | case VAR_UINT8: 117 | case VAR_INT8: 118 | case VAR_UINT16: 119 | case VAR_INT16: 120 | case VAR_INT32: 121 | case VAR_UINT32: 122 | if(name && vardir_set_int_by_name(&self->dir, name, *((uint32_t*)value))){ 123 | vardir_set_int(&self->dir, id, *((uint32_t*)value)); 124 | } 125 | break; 126 | case VAR_FLOAT: 127 | if(name && vardir_set_float_by_name(&self->dir, name, *((float*)value))){ 128 | vardir_set_float(&self->dir, id, *((float*)value)); 129 | } 130 | break; 131 | case VAR_STRING: 132 | 133 | break; 134 | }; 135 | thread_mutex_unlock(&self->lock); 136 | return 0; 137 | } 138 | 139 | 140 | static struct vardir_device_ops _vardir_ops = { 141 | .add_static = _vardir_add_static, 142 | .add_dynamic = _vardir_add_dynamic, 143 | .get = _vardir_get, 144 | .set = _vardir_set, 145 | }; 146 | 147 | static int _vardir_probe(void *fdt, int fdt_node){ 148 | struct vardir_driver *self = kzmalloc(sizeof(struct vardir_driver)); 149 | thread_mutex_init(&self->lock); 150 | vardir_init(&self->dir); 151 | 152 | vardir_device_init(&self->dev, fdt, fdt_node, &_vardir_ops); 153 | vardir_device_register(&self->dev); 154 | 155 | return 0; 156 | } 157 | 158 | static int _vardir_remove(void *fdt, int fdt_node){ 159 | return -1; 160 | } 161 | 162 | DEVICE_DRIVER(vardir, "fw,vardir", _vardir_probe, _vardir_remove) 163 | -------------------------------------------------------------------------------- /src/usb/usbd_cdc.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This driver implements CDC functionality on top of a usb interface driver. 3 | * It requires usb interface reference to be passed in "interface" string or 4 | * for the device tree node to be defined as a child of a usb interface node 5 | * (it will search for that node by node id within available usb devices). 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #define USB_CDC_DEFAULT_VENDOR_ID 0x25AE 18 | #define USB_CDC_DEFAULT_PRODUCT_ID 0x24AB 19 | #define USB_CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */ 20 | #define USB_CDC_DATA_FS_CMD_PACKET_SIZE 16 /* Endpoint IN & OUT Packet size */ 21 | #define USB_CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ 22 | 23 | // endpoint indices 24 | #define USB_CDC_DATA_IN_ENDP 2 25 | #define USB_CDC_DATA_OUT_ENDP 3 26 | #if 0 27 | static const struct usb_device_descriptor _default_device_desc = { 28 | .bLength = 18, // bLength 29 | .bDescriptorType = USB_DESC_TYPE_DEVICE, // bDescriptorType 30 | .bcdUSBL = 0x10, // bcdUSB 31 | .bcdUSBH = 0x01, // bcdUSB 32 | .bDeviceClass = 0, // bDeviceClass 33 | .bDeviceSubClass = 0, // bDeviceSubClass 34 | .bDeviceProtocol = 0, // bDeviceProtocol 35 | .bMaxPacketSize0 = USB_CDC_CMD_PACKET_SIZE, // bMaxPacketSize0 36 | .idVendorL = USB_LOBYTE(USB_CDC_DEFAULT_VENDOR_ID), // idVendor 37 | .idVendorH = USB_HIBYTE(USB_CDC_DEFAULT_VENDOR_ID), // idVendor 38 | .idProductL = USB_LOBYTE(USB_CDC_DEFAULT_PRODUCT_ID), // idProduct 39 | .idProductH = USB_HIBYTE(USB_CDC_DEFAULT_PRODUCT_ID), // idProduct 40 | .bcdDeviceL = 0x00, // bcdDevice 41 | .bcdDeviceH = 0x01, // bcdDevice 42 | .iManufacturer = 1, // iManufacturer 43 | .iProduct = 2, // iProduct 44 | .iSerialNumber = 3, // iSerialNumbert 45 | .bNumConfigurations = 1 // bNumConfigurations 46 | }; 47 | #endif 48 | const uint8_t USB_DEVICE_QR_DESC[] = { 49 | (uint8_t)10, // bLength 50 | (uint8_t)0x06, // bDescriptorType 51 | (uint8_t)0x00, // bcdUSB 52 | (uint8_t)0x02, // bcdUSB 53 | (uint8_t)USB_DEV_CLASS_COMM, // bDeviceClass 54 | (uint8_t)0, // bDeviceSubClass 55 | (uint8_t)0, // bDeviceProtocol 56 | (uint8_t)8, // bMaxPacketSize0 57 | (uint8_t)1, // bNumConfigurations 58 | (uint8_t)0 // reserved 59 | }; 60 | 61 | struct usb_cdc { 62 | struct serial_device dev; 63 | usbd_device_t usbd; 64 | }; 65 | 66 | #if 0 67 | static int _usb_cdc_command_isr(struct usbd_device *dev, struct usb_setup_packet *packet) { 68 | switch (packet->wRequestAndType) { 69 | case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING: 70 | //usbd_write(self->usbd, 0, 0, 0); 71 | break; 72 | case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE: 73 | //usbd_write(self->usbd, 0, 0, 0); 74 | break; 75 | default: 76 | return -EINVAL; 77 | } 78 | return 0; 79 | } 80 | #endif 81 | static int _serial_write(serial_port_t dev, const void *data, size_t size, uint32_t timeout){ 82 | struct usb_cdc *self = container_of(dev, struct usb_cdc, dev.ops); 83 | if(!self) return -1; 84 | 85 | // send data to the host 86 | //return usbd_write(self->usbd, USB_CDC_IN_EP, data, size, timeout); 87 | return 0; 88 | } 89 | 90 | static int _serial_read(serial_port_t dev, void *data, size_t size, uint32_t timeout){ 91 | struct usb_cdc *self = container_of(dev, struct usb_cdc, dev.ops); 92 | if(!self) return -1; 93 | 94 | // receive data in full if possible or timeout at 1 or more received bites 95 | //return usbd_read(self->usbd, USB_CDC_OUT_EP, data, size, timeout); 96 | return 0; 97 | } 98 | 99 | static const struct serial_device_ops _serial_ops = { 100 | .read = _serial_read, 101 | .write = _serial_write 102 | }; 103 | 104 | static int _usb_cdc_probe(void *fdt, int fdt_node){ 105 | int usb_node = fdt_find_node_by_ref(fdt, fdt_node, "usb"); 106 | if(usb_node < 0){ 107 | dbg_printk("USBCDC: no usb node!\n"); 108 | return -1; 109 | } 110 | 111 | usbd_device_t usbd = usbd_find_by_node(usb_node); 112 | if(!usbd){ 113 | dbg_printk("USBCDC: nousb\n"); 114 | return -1; 115 | } 116 | 117 | struct usb_cdc *self = kzmalloc(sizeof(struct usb_cdc)); 118 | self->usbd = usbd; 119 | 120 | serial_device_init(&self->dev, fdt, fdt_node, &_serial_ops); 121 | serial_device_register(&self->dev); 122 | 123 | return 0; 124 | } 125 | 126 | static int _usb_cdc_remove(void *fdt, int fdt_node){ 127 | return 0; 128 | } 129 | 130 | DEVICE_DRIVER(usbd_serial,"fw,usbd_cdc", _usb_cdc_probe,_usb_cdc_remove) 131 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-ram.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | * Author: Adam Dunkels 32 | * 33 | */ 34 | 35 | #include 36 | 37 | #include "cfs/cfs.h" 38 | 39 | struct filestate { 40 | int flag; 41 | #define FLAG_FILE_CLOSED 0 42 | #define FLAG_FILE_OPEN 1 43 | int fileptr; 44 | int filesize; 45 | }; 46 | 47 | #ifdef CFS_RAM_CONF_SIZE 48 | #define CFS_RAM_SIZE CFS_RAM_CONF_SIZE 49 | #else 50 | #define CFS_RAM_SIZE 4096 51 | #endif 52 | 53 | static struct filestate file; 54 | static char filemem[CFS_RAM_SIZE]; 55 | 56 | /*---------------------------------------------------------------------------*/ 57 | int 58 | cfs_open(const char *n, int f) 59 | { 60 | if(file.flag == FLAG_FILE_CLOSED) { 61 | file.flag = FLAG_FILE_OPEN; 62 | if(f & CFS_READ) { 63 | file.fileptr = 0; 64 | } 65 | if(f & CFS_WRITE){ 66 | if(f & CFS_APPEND) { 67 | file.fileptr = file.filesize; 68 | } else { 69 | file.fileptr = 0; 70 | file.filesize = 0; 71 | } 72 | } 73 | return 1; 74 | } else { 75 | return -1; 76 | } 77 | } 78 | /*---------------------------------------------------------------------------*/ 79 | void 80 | cfs_close(int f) 81 | { 82 | file.flag = FLAG_FILE_CLOSED; 83 | } 84 | /*---------------------------------------------------------------------------*/ 85 | int 86 | cfs_read(int f, void *buf, unsigned int len) 87 | { 88 | if(file.fileptr + len > sizeof(filemem)) { 89 | len = sizeof(filemem) - file.fileptr; 90 | } 91 | 92 | if(file.fileptr + len > file.filesize) { 93 | len = file.filesize - file.fileptr; 94 | } 95 | 96 | if(f == 1) { 97 | memcpy(buf, &filemem[file.fileptr], len); 98 | file.fileptr += len; 99 | return len; 100 | } else { 101 | return -1; 102 | } 103 | } 104 | /*---------------------------------------------------------------------------*/ 105 | int 106 | cfs_write(int f, const void *buf, unsigned int len) 107 | { 108 | if(file.fileptr >= sizeof(filemem)) { 109 | return 0; 110 | } 111 | if(file.fileptr + len > sizeof(filemem)) { 112 | len = sizeof(filemem) - file.fileptr; 113 | } 114 | 115 | if(file.fileptr + len > file.filesize) { 116 | /* Extend the size of the file. */ 117 | file.filesize = file.fileptr + len; 118 | } 119 | 120 | if(f == 1) { 121 | memcpy(&filemem[file.fileptr], buf, len); 122 | file.fileptr += len; 123 | return len; 124 | } else { 125 | return -1; 126 | } 127 | } 128 | /*---------------------------------------------------------------------------*/ 129 | cfs_offset_t 130 | cfs_seek(int f, cfs_offset_t o, int w) 131 | { 132 | if(w == CFS_SEEK_SET && f == 1) { 133 | if(o > file.filesize) { 134 | o = file.filesize; 135 | } 136 | file.fileptr = o; 137 | return o; 138 | } 139 | return (cfs_offset_t)-1; 140 | } 141 | /*---------------------------------------------------------------------------*/ 142 | int 143 | cfs_remove(const char *name) 144 | { 145 | return -1; 146 | } 147 | /*---------------------------------------------------------------------------*/ 148 | int 149 | cfs_opendir(struct cfs_dir *p, const char *n) 150 | { 151 | return -1; 152 | } 153 | /*---------------------------------------------------------------------------*/ 154 | int 155 | cfs_readdir(struct cfs_dir *p, struct cfs_dirent *e) 156 | { 157 | return -1; 158 | } 159 | /*---------------------------------------------------------------------------*/ 160 | void 161 | cfs_closedir(struct cfs_dir *p) 162 | { 163 | } 164 | /*---------------------------------------------------------------------------*/ 165 | -------------------------------------------------------------------------------- /config/test-driver: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # test-driver - basic testsuite driver script. 3 | 4 | scriptversion=2013-07-13.22; # UTC 5 | 6 | # Copyright (C) 2011-2014 Free Software Foundation, Inc. 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2, or (at your option) 11 | # any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | # As a special exception to the GNU General Public License, if you 22 | # distribute this file as part of a program that contains a 23 | # configuration script generated by Autoconf, you may include it under 24 | # the same distribution terms that you use for the rest of that program. 25 | 26 | # This file is maintained in Automake, please report 27 | # bugs to or send patches to 28 | # . 29 | 30 | # Make unconditional expansion of undefined variables an error. This 31 | # helps a lot in preventing typo-related bugs. 32 | set -u 33 | 34 | usage_error () 35 | { 36 | echo "$0: $*" >&2 37 | print_usage >&2 38 | exit 2 39 | } 40 | 41 | print_usage () 42 | { 43 | cat <$log_file 2>&1 108 | estatus=$? 109 | 110 | if test $enable_hard_errors = no && test $estatus -eq 99; then 111 | tweaked_estatus=1 112 | else 113 | tweaked_estatus=$estatus 114 | fi 115 | 116 | case $tweaked_estatus:$expect_failure in 117 | 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 118 | 0:*) col=$grn res=PASS recheck=no gcopy=no;; 119 | 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 120 | 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; 121 | *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; 122 | *:*) col=$red res=FAIL recheck=yes gcopy=yes;; 123 | esac 124 | 125 | # Report the test outcome and exit status in the logs, so that one can 126 | # know whether the test passed or failed simply by looking at the '.log' 127 | # file, without the need of also peaking into the corresponding '.trs' 128 | # file (automake bug#11814). 129 | echo "$res $test_name (exit status: $estatus)" >>$log_file 130 | 131 | # Report outcome to console. 132 | echo "${col}${res}${std}: $test_name" 133 | 134 | # Register the test result, and other relevant metadata. 135 | echo ":test-result: $res" > $trs_file 136 | echo ":global-test-result: $res" >> $trs_file 137 | echo ":recheck: $recheck" >> $trs_file 138 | echo ":copy-in-global-log: $gcopy" >> $trs_file 139 | 140 | # Local Variables: 141 | # mode: shell-script 142 | # sh-indentation: 2 143 | # eval: (add-hook 'write-file-hooks 'time-stamp) 144 | # time-stamp-start: "scriptversion=" 145 | # time-stamp-format: "%:y-%02m-%02d.%02H" 146 | # time-stamp-time-zone: "UTC" 147 | # time-stamp-end: "; # UTC" 148 | # End: 149 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-coffee-arch.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \addtogroup mbxxx-platform 3 | * 4 | * @{ 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2010, STMicroelectronics. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of the Institute nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | * 35 | */ 36 | 37 | /** 38 | * \file 39 | * Coffee architecture-dependent header for the STM32W108-based mb851 40 | * platform. STM32W108 has 128KB of program flash. 41 | * \author 42 | * Salvatore Pitrulli 43 | */ 44 | 45 | #ifndef CFS_COFFEE_ARCH_H 46 | #define CFS_COFFEE_ARCH_H 47 | 48 | 49 | #define CCIF 50 | //typedef int coffee_page_t; 51 | #define COFFEE_ADDRESS 0 52 | 53 | /* 54 | * STM32W108 has 128KB of program flash in 128 pages of 1024 bytes each = 128KB. 55 | * The smallest erasable unit is one page and the smallest writable 56 | * unit is an aligned 16-bit half-word. 57 | */ 58 | /* Byte page size, starting address on page boundary, and size of file system */ 59 | #define FLASH_START 0 60 | /* Minimum erasable unit. */ 61 | #define FLASH_PAGE_SIZE 256UL 62 | /* Last 3 pages reserved for NVM. */ 63 | #define FLASH_PAGES 8192UL 64 | 65 | /* Minimum reservation unit for Coffee. It can be changed by the user. */ 66 | #define COFFEE_PAGE_SIZE (FLASH_PAGE_SIZE/4) 67 | 68 | /* 69 | * If using IAR, COFFEE_ADDRESS reflects the static value in the linker script 70 | * iar-cfg-coffee.icf, so it can't be passed as a parameter for Make. 71 | */ 72 | #ifdef __ICCARM__ 73 | #define COFFEE_ADDRESS 0 74 | #endif 75 | #if (COFFEE_ADDRESS & 0x3FF) != 0 76 | #error "COFFEE_ADDRESS not aligned to a 1024-bytes page boundary." 77 | #endif 78 | 79 | #define COFFEE_PAGES ((FLASH_PAGES*FLASH_PAGE_SIZE- \ 80 | (COFFEE_ADDRESS-FLASH_START))/COFFEE_PAGE_SIZE) 81 | #define COFFEE_START (COFFEE_ADDRESS & ~(COFFEE_PAGE_SIZE-1)) 82 | #define COFFEE_SIZE (COFFEE_PAGES*COFFEE_PAGE_SIZE) 83 | 84 | /* These must agree with the parameters passed to makefsdata */ 85 | #define COFFEE_SECTOR_SIZE FLASH_PAGE_SIZE 86 | #define COFFEE_NAME_LENGTH 20 87 | 88 | /* These are used internally by the AVR flash read routines */ 89 | /* Word reads are faster but take 130 bytes more PROGMEM */ 90 | /* #define FLASH_WORD_READS 1 */ 91 | /* 92 | * 1 = Slower reads, but no page writes after erase and 18 bytes less PROGMEM. 93 | * Best for dynamic file system 94 | */ 95 | /* #define FLASH_COMPLEMENT_DATA 0 */ 96 | 97 | /* These are used internally by the coffee file system */ 98 | #define COFFEE_MAX_OPEN_FILES 4UL 99 | #define COFFEE_FD_SET_SIZE 8UL 100 | #define COFFEE_DYN_SIZE (COFFEE_PAGE_SIZE*1) 101 | /* Micro logs are not needed for single page sectors */ 102 | #define COFFEE_MICRO_LOGS 1 103 | #define COFFEE_LOG_TABLE_LIMIT 16UL /* It doesnt' matter as */ 104 | #define COFFEE_LOG_SIZE 128UL /* COFFEE_MICRO_LOGS is 0. */ 105 | 106 | #if COFFEE_PAGES <= 127 107 | #define coffee_page_t int8_t 108 | #elif COFFEE_PAGES <= 0x7FFFUL 109 | #define coffee_page_t int16_t 110 | #else 111 | #define coffee_page_t int32_t 112 | #endif 113 | 114 | #define COFFEE_WRITE(buf, size, offset) \ 115 | stm32w_flash_write(COFFEE_START + offset, buf, size) 116 | 117 | #define COFFEE_READ(buf, size, offset) \ 118 | stm32w_flash_read(COFFEE_START + offset, buf, size) 119 | 120 | #define COFFEE_ERASE(sector) \ 121 | stm32w_flash_erase(sector) 122 | 123 | 124 | void stm32w_flash_read(uint32_t address, void *data, uint32_t length); 125 | 126 | void stm32w_flash_write(uint32_t address, const void *data, uint32_t length); 127 | 128 | void stm32w_flash_erase(uint8_t sector); 129 | 130 | int coffee_file_test(void); 131 | 132 | #endif /* !COFFEE_ARCH_H */ 133 | /** @} */ 134 | -------------------------------------------------------------------------------- /src/analog/mcp4461.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of libdriver 3 | * 4 | * Copyright (c) 2019 Martin Schröder 5 | * 6 | * Ninjaflight is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Ninjaflight is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Ninjaflight. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #define MCP4XXX_REG_WIPER0 0x00 38 | #define MCP4XXX_REG_WIPER1 0x10 39 | #define MCP4XXX_REG_NV_WIPER0 0x20 40 | #define MCP4XXX_REG_NV_WIPER1 0x30 41 | #define MCP4XXX_REG_TCON0 0x40 42 | #define MCP4XXX_REG_STATUS 0x50 43 | #define MCP4XXX_REG_WIPER2 0x60 44 | #define MCP4XXX_REG_WIPER3 0x70 45 | #define MCP4XXX_REG_NV_WIPER2 0x80 46 | #define MCP4XXX_REG_NV_WIPER3 0x90 47 | #define MCP4XXX_REG_TCON1 0xa0 48 | 49 | #define MCP4XXX_OP_READ 0x0C 50 | #define MCP4XXX_OP_WRITE 0x00 51 | 52 | #define MCP4461_TIMEOUT 1000 53 | 54 | struct mcp4461 { 55 | i2c_device_t i2c; 56 | gpio_device_t gpio; 57 | uint8_t addr; 58 | uint32_t reset_pin, wp_pin; 59 | struct analog_device dev; 60 | }; 61 | 62 | static int _mcp4461_write_reg(struct mcp4461 *self, uint8_t reg, uint8_t val){ 63 | int ret = 0; 64 | uint8_t data[] = {reg | MCP4XXX_OP_WRITE | (uint8_t)(val >> 8), (uint8_t)(val & 0xff)}; 65 | if((ret = i2c_transfer(self->i2c, self->addr, data, 2, NULL, 0, MCP4461_TIMEOUT)) < 0) return ret; 66 | return 0; 67 | } 68 | 69 | static int _mcp4461_read_reg(struct mcp4461 *self, uint8_t reg, uint16_t *val){ 70 | int ret = 0; 71 | reg |= MCP4XXX_OP_READ; 72 | 73 | if((ret = i2c_transfer(self->i2c, self->addr, ®, 1, val, 2, MCP4461_TIMEOUT)) < 0){ 74 | return ret; 75 | } 76 | 77 | return 0; 78 | } 79 | 80 | static int _mcp4461_analog_write(analog_device_t dev, unsigned int chan, float value){ 81 | struct mcp4461 *self = container_of(dev, struct mcp4461, dev.ops); 82 | 83 | if(chan > 7) return -EINVAL; 84 | 85 | value = constrain_float(value, 0, 1.0f); 86 | uint16_t val = (uint16_t)((float)((uint16_t)0xff)*value) & 0xff; 87 | 88 | static const uint8_t regs[8] = { 89 | MCP4XXX_REG_WIPER0, 90 | MCP4XXX_REG_WIPER1, 91 | MCP4XXX_REG_WIPER2, 92 | MCP4XXX_REG_WIPER3, 93 | MCP4XXX_REG_NV_WIPER0, 94 | MCP4XXX_REG_NV_WIPER1, 95 | MCP4XXX_REG_NV_WIPER2, 96 | MCP4XXX_REG_NV_WIPER3 97 | }; 98 | 99 | return _mcp4461_write_reg(self, regs[chan & 7] | (uint8_t)(val >> 8), (uint8_t)(val & 0xff)); 100 | } 101 | 102 | static int _mcp4461_analog_read(analog_device_t dev, unsigned int chan, float *value){ 103 | return -1; 104 | } 105 | 106 | static struct analog_device_ops _mcp4461_analog_ops = { 107 | .write = _mcp4461_analog_write, 108 | .read = _mcp4461_analog_read 109 | }; 110 | 111 | static int _mcp4461_probe(void *fdt, int fdt_node){ 112 | i2c_device_t i2c = i2c_find_by_ref(fdt, fdt_node, "i2c"); 113 | gpio_device_t gpio = gpio_find_by_ref(fdt, fdt_node, "gpio"); 114 | uint8_t addr = (uint8_t)fdt_get_int_or_default(fdt, fdt_node, "reg", 0x2d); 115 | int reset_pin = fdt_get_int_or_default(fdt, fdt_node, "reset_pin", -1); 116 | int wp_pin = fdt_get_int_or_default(fdt, fdt_node, "wp_pin", -1); 117 | 118 | if(!i2c){ 119 | printk("mcp4461: invalid i2c\n"); 120 | return -EINVAL; 121 | } 122 | 123 | struct mcp4461 *self = kzmalloc(sizeof(struct mcp4461)); 124 | self->i2c = i2c; 125 | self->gpio = gpio; 126 | self->addr = addr; 127 | 128 | if(self->gpio && wp_pin >= 0){ 129 | self->wp_pin = (uint32_t)wp_pin; 130 | gpio_set(self->gpio, self->wp_pin); 131 | } 132 | 133 | if(self->gpio && reset_pin >= 0){ 134 | self->reset_pin = (uint32_t)reset_pin; 135 | 136 | gpio_set(self->gpio, self->reset_pin); 137 | thread_sleep_ms(1); 138 | gpio_reset(self->gpio, self->reset_pin); 139 | thread_sleep_ms(1); 140 | gpio_set(self->gpio, self->reset_pin); 141 | thread_sleep_ms(1); 142 | } 143 | 144 | uint16_t status = 0; 145 | if(_mcp4461_read_reg(self, MCP4XXX_REG_STATUS, &status) != 0){ 146 | printk(PRINT_ERROR "mcp4461: could not read status\n"); 147 | return -EIO; 148 | } 149 | 150 | if(((status >> 8) & 0xff) != 0x82 || (status & 0xff) != 0x01){ 151 | printk("mcp4461: invalid status (%02x)\n", status); 152 | return -1; 153 | } 154 | 155 | analog_device_init(&self->dev, fdt, fdt_node, &_mcp4461_analog_ops); 156 | analog_device_register(&self->dev); 157 | 158 | printk("mcp4461: ready (addr %02x)\n", addr); 159 | 160 | return 0; 161 | } 162 | 163 | static int _mcp4461_remove(void *fdt, int fdt_node){ 164 | return 0; 165 | } 166 | 167 | DEVICE_DRIVER(mcp4461, "fw,mcp4461", _mcp4461_probe, _mcp4461_remove) 168 | 169 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-coffee.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \addtogroup cfs 3 | * @{ 4 | */ 5 | 6 | /* 7 | * Copyright (c) 2008, Swedish Institute of Computer Science 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the Institute nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | * 34 | * This file is part of the Contiki operating system. 35 | * 36 | */ 37 | 38 | #ifndef CFS_COFFEE_H 39 | #define CFS_COFFEE_H 40 | 41 | #include "cfs.h" 42 | 43 | /** 44 | * Instruct Coffee that the access pattern to this file is adapted to 45 | * flash I/O semantics by design, and Coffee should therefore not 46 | * invoke its own micro logs when file modifications occur. 47 | * 48 | * This semantical I/O setting is useful when implementing flash storage 49 | * algorithms on top of Coffee. 50 | * 51 | * \sa cfs_coffee_set_io_semantics() 52 | */ 53 | #define CFS_COFFEE_IO_FLASH_AWARE 0x1 54 | 55 | /** 56 | * Instruct Coffee not to attempt to extend the file when there is 57 | * an attempt to write past the reserved file size. 58 | * 59 | * A case when this is necessary is when the file has a firm size limit, 60 | * and a safeguard is needed to protect against writes beyond this limit. 61 | * 62 | * \sa cfs_coffee_set_io_semantics() 63 | */ 64 | #define CFS_COFFEE_IO_FIRM_SIZE 0x2 65 | 66 | /** 67 | * \file 68 | * Header for the Coffee file system. 69 | * \author 70 | * Nicolas Tsiftes 71 | * 72 | * \name Functions called from application programs 73 | * @{ 74 | */ 75 | 76 | /** 77 | * \brief Reserve space for a file. 78 | * \param name The filename. 79 | * \param size The size of the file. 80 | * \return 0 on success, -1 on failure. 81 | * 82 | * Coffee uses sequential page structures for files. The sequential 83 | * structure can be reserved with a certain size. If a file has not 84 | * been reserved when it is opened for the first time, it will be 85 | * allocated with a default size. 86 | */ 87 | int cfs_coffee_reserve(const char *name, cfs_offset_t size); 88 | 89 | /** 90 | * \brief Configure the on-demand log file. 91 | * \param file The filename. 92 | * \param log_size The total log size. 93 | * \param log_entry_size The log entry size. 94 | * \return 0 on success, -1 on failure. 95 | * 96 | * When file data is first modified, Coffee creates a micro log for the 97 | * file. The micro log stores a table of modifications whose 98 | * parameters--the log size and the log entry size--can be modified 99 | * through the cfs_coffee_configure_log function. 100 | */ 101 | int cfs_coffee_configure_log(const char *file, unsigned log_size, 102 | unsigned log_entry_size); 103 | 104 | /** 105 | * \brief Set the I/O semantics for accessing a file. 106 | * 107 | * \param fd The file descriptor through which the file is accessed. 108 | * \param flags A bit vector of flags. 109 | * 110 | * Coffee is used on a wide range of storage types, and the default 111 | * I/O file semantics may not be optimal for the access pattern 112 | * of a certain file. Hence, this functions allows programmers to 113 | * switch the /O semantics on a file that is accessed through a 114 | * particular file descriptor. 115 | * 116 | */ 117 | int cfs_coffee_set_io_semantics(int fd, unsigned flags); 118 | 119 | /** 120 | * \brief Format the storage area assigned to Coffee. 121 | * \return 0 on success, -1 on failure. 122 | * 123 | * Coffee formats the underlying storage by setting all bits to zero. 124 | * Formatting must be done before using Coffee for the first time in 125 | * a mote. 126 | */ 127 | int cfs_coffee_format(void); 128 | 129 | /** 130 | * \brief Points out a memory region that may not be altered during 131 | * checkpointing operations that use the file system. 132 | * \param size 133 | * \return A pointer to the protected memory. 134 | * 135 | * This function returns the protected memory pointer and writes its size 136 | * to the given parameter. Mainly used by sensornet checkpointing to protect 137 | * the coffee state during CFS-based checkpointing operations. 138 | */ 139 | void *cfs_coffee_get_protected_mem(unsigned *size); 140 | 141 | /** @} */ 142 | /** @} */ 143 | 144 | #endif /* !COFFEE_H */ 145 | -------------------------------------------------------------------------------- /src/fs/cfs/cfs-xmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004, Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the Institute nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * This file is part of the Contiki operating system. 30 | * 31 | * Author: Adam Dunkels 32 | * 33 | */ 34 | 35 | #include "cfs/cfs.h" 36 | #include "dev/xmem.h" 37 | 38 | struct filestate { 39 | int flag; 40 | #define FLAG_FILE_CLOSED 0 41 | #define FLAG_FILE_OPEN 1 42 | unsigned int fileptr; 43 | unsigned int filesize; 44 | }; 45 | 46 | #ifdef CFS_XMEM_CONF_OFFSET 47 | #define CFS_XMEM_OFFSET CFS_XMEM_CONF_OFFSET 48 | #else 49 | #define CFS_XMEM_OFFSET 0 50 | #endif 51 | 52 | /* Note the CFS_XMEM_CONF_SIZE must be a tuple of XMEM_ERASE_UNIT_SIZE */ 53 | #ifdef CFS_XMEM_CONF_SIZE 54 | #define CFS_XMEM_SIZE CFS_XMEM_CONF_SIZE 55 | #else 56 | #define CFS_XMEM_SIZE XMEM_ERASE_UNIT_SIZE 57 | #endif 58 | 59 | static struct filestate file; 60 | 61 | /*---------------------------------------------------------------------------*/ 62 | int 63 | cfs_open(const char *n, int f) 64 | { 65 | if(file.flag == FLAG_FILE_CLOSED) { 66 | file.flag = FLAG_FILE_OPEN; 67 | if(f & CFS_READ) { 68 | file.fileptr = 0; 69 | } 70 | if(f & CFS_WRITE){ 71 | if(f & CFS_APPEND) { 72 | file.fileptr = file.filesize; 73 | } else { 74 | file.fileptr = 0; 75 | file.filesize = 0; 76 | xmem_erase(CFS_XMEM_SIZE, CFS_XMEM_OFFSET); 77 | } 78 | } 79 | return 1; 80 | } else { 81 | return -1; 82 | } 83 | } 84 | /*---------------------------------------------------------------------------*/ 85 | void 86 | cfs_close(int f) 87 | { 88 | file.flag = FLAG_FILE_CLOSED; 89 | } 90 | /*---------------------------------------------------------------------------*/ 91 | int 92 | cfs_read(int f, void *buf, unsigned int len) 93 | { 94 | if(file.fileptr + len > CFS_XMEM_SIZE) { 95 | len = CFS_XMEM_SIZE - file.fileptr; 96 | } 97 | 98 | if(file.fileptr + len > file.filesize) { 99 | len = file.filesize - file.fileptr; 100 | } 101 | 102 | if(f == 1) { 103 | xmem_pread(buf, len, CFS_XMEM_OFFSET + file.fileptr); 104 | file.fileptr += len; 105 | return len; 106 | } else { 107 | return -1; 108 | } 109 | } 110 | /*---------------------------------------------------------------------------*/ 111 | int 112 | cfs_write(int f, const void *buf, unsigned int len) 113 | { 114 | if(file.fileptr >= CFS_XMEM_SIZE) { 115 | return 0; 116 | } 117 | if(file.fileptr + len > CFS_XMEM_SIZE) { 118 | len = CFS_XMEM_SIZE - file.fileptr; 119 | } 120 | 121 | if(file.fileptr + len > file.filesize) { 122 | /* Extend the size of the file. */ 123 | file.filesize = file.fileptr + len; 124 | } 125 | 126 | if(f == 1) { 127 | xmem_pwrite(buf, len, CFS_XMEM_OFFSET + file.fileptr); 128 | file.fileptr += len; 129 | return len; 130 | } else { 131 | return -1; 132 | } 133 | } 134 | /*---------------------------------------------------------------------------*/ 135 | cfs_offset_t 136 | cfs_seek(int f, cfs_offset_t o, int w) 137 | { 138 | if(w == CFS_SEEK_SET && f == 1) { 139 | if(o > file.filesize) { 140 | o = file.filesize; 141 | } 142 | file.fileptr = o; 143 | return o; 144 | } 145 | return -1; 146 | } 147 | /*---------------------------------------------------------------------------*/ 148 | int 149 | cfs_remove(const char *name) 150 | { 151 | file.flag = FLAG_FILE_CLOSED; 152 | file.fileptr = 0; 153 | file.filesize = 0; 154 | xmem_erase(CFS_XMEM_SIZE, CFS_XMEM_OFFSET); 155 | return 0; 156 | } 157 | /*---------------------------------------------------------------------------*/ 158 | int 159 | cfs_opendir(struct cfs_dir *p, const char *n) 160 | { 161 | return -1; 162 | } 163 | /*---------------------------------------------------------------------------*/ 164 | int 165 | cfs_readdir(struct cfs_dir *p, struct cfs_dirent *e) 166 | { 167 | return -1; 168 | } 169 | /*---------------------------------------------------------------------------*/ 170 | void 171 | cfs_closedir(struct cfs_dir *p) 172 | { 173 | } 174 | /*---------------------------------------------------------------------------*/ 175 | -------------------------------------------------------------------------------- /tests/m25.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "mock/printk.hpp" 3 | #include "mock/thread.hpp" 4 | #include "mock/driver.hpp" 5 | #include "mock/memory.hpp" 6 | 7 | #define M25_CMD_WREN 0x06 /* Write Enable */ 8 | #define M25_CMD_WRDI 0x04 /* Write Disable */ 9 | #define M25_CMD_RDID 0x9F /* Read Identification */ 10 | #define M25_CMD_RDSR 0x05 /* Read Status Register */ 11 | #define M25_CMD_WRSR 0x01 /* Write Status Register */ 12 | #define M25_CMD_READ 0x03 /* Read Data Bytes */ 13 | #define M25_CMD_FAST_READ 0x0B /* Read Data Bytes at Higher Speed */ 14 | #define M25_CMD_PAGE_PROGRAM 0x02 /* Page Program */ 15 | #define M25_CMD_SECTOR_ERASE 0x20 16 | #define M25_CMD_BLOCK_ERASE_32K 0x52 /* Sector Erase */ 17 | #define M25_CMD_BLOCK_ERASE_64K 0xD8 /* Sector Erase */ 18 | #define M25_CMD_BULK_ERASE 0xC7 /* Bulk Erase */ 19 | #define M25_CMD_DP 0xB9 /* Deep Power-down */ 20 | #define M25_CMD_RES 0xAB /* Release from Deep Power-down */ 21 | 22 | extern "C" { 23 | #include 24 | #include 25 | #include "m25-dtb.h" 26 | 27 | struct mock_spi { 28 | struct spi_device dev; 29 | }; 30 | 31 | static uint8_t _flash[1024 * 1024]; 32 | 33 | static int _mock_spi_transfer(spi_device_t dev, gpio_device_t gpio, uint32_t cs_pin, const void *tx_data, void *rx_data, size_t size, msec_t timeout){ 34 | struct mock_spi *self = container_of(dev, struct mock_spi, dev.ops); 35 | uint8_t *rx = (uint8_t*)rx_data; 36 | const uint8_t *tx = (const uint8_t*)tx_data; 37 | switch(tx[0]){ 38 | case M25_CMD_WREN: { 39 | printf("mock m25: write enable\n"); 40 | } break; 41 | case M25_CMD_WRDI: { 42 | printf("mock m25: write disable\n"); 43 | } break; 44 | case M25_CMD_RDSR: { 45 | printf("mock m25: read status\n"); 46 | EXPECT_EQ(size, 2); 47 | rx[1] = 0x00; 48 | } break; 49 | case M25_CMD_RDID: { 50 | printf("mock m25: read id\n"); 51 | EXPECT_EQ(size, 4); 52 | EXPECT_NE(tx_data, nullptr); 53 | EXPECT_NE(rx_data, nullptr); 54 | rx[1] = 0x4f; 55 | rx[2] = 0x20; 56 | rx[3] = 0x15; 57 | } break; 58 | case M25_CMD_READ: { 59 | uint32_t addr = rx[1] << 16 | rx[2] << 8 | rx[3]; 60 | printf("mock m25: read %u, size: %lu\n", addr, size - 4); 61 | EXPECT_LE(addr, sizeof(_flash)); 62 | EXPECT_GE(size, 5); 63 | memcpy(rx + 4, _flash + addr, size - 4); 64 | } break; 65 | case M25_CMD_PAGE_PROGRAM: { 66 | uint32_t addr = rx[1] << 16 | rx[2] << 8 | rx[3]; 67 | printf("mock m25: write %u, size: %lu\n", addr, size - 4); 68 | EXPECT_LE(addr, sizeof(_flash)); 69 | EXPECT_GE(size, 5); 70 | memcpy(_flash + addr, tx + 4, size - 4); 71 | } break; 72 | case M25_CMD_SECTOR_ERASE: { 73 | uint32_t addr = rx[1] << 16 | rx[2] << 8 | rx[3]; 74 | printf("mock m25: sector erase %u, size: %lu\n", addr, size - 4); 75 | } break; 76 | default: 77 | printf("mock m25: unknown transfer %lu bytes\n", size); 78 | }; 79 | return size; 80 | } 81 | 82 | static const struct spi_device_ops _mock_spi_ops = { 83 | .transfer = _mock_spi_transfer 84 | }; 85 | 86 | static int _mock_spi_probe(void *fdt, int fdt_node){ 87 | struct mock_spi *self = (struct mock_spi*)kzmalloc(sizeof(struct mock_spi)); 88 | spi_device_init(&self->dev, fdt, fdt_node, &_mock_spi_ops); 89 | spi_device_register(&self->dev); 90 | memset(_flash, 0xff, sizeof(_flash)); 91 | return 0; 92 | } 93 | 94 | static int _mock_spi_remove(void *fdt, int fdt_node){ 95 | return 0; 96 | } 97 | 98 | DEVICE_DRIVER(spi, "mock,spi", _mock_spi_probe, _mock_spi_remove) 99 | 100 | struct mock_gpio { 101 | struct gpio_device dev; 102 | }; 103 | 104 | static int _mock_gpio_write_pin(gpio_device_t dev, uint32_t pin, bool value){ 105 | printf("gpio write: %d, %d\n", pin, value); 106 | return 0; 107 | } 108 | 109 | static int _mock_gpio_read_pin(gpio_device_t dev, uint32_t pin, bool *value){ 110 | printf("gpio read: %d\n", pin); 111 | return 0; 112 | } 113 | 114 | static const struct gpio_device_ops _mock_gpio_ops = { 115 | .write_pin = _mock_gpio_write_pin, 116 | .read_pin = _mock_gpio_read_pin 117 | }; 118 | 119 | static int _mock_gpio_probe(void *fdt, int fdt_node){ 120 | struct mock_gpio *self = (struct mock_gpio*)kzmalloc(sizeof(struct mock_gpio)); 121 | gpio_device_init(&self->dev, fdt, fdt_node, &_mock_gpio_ops); 122 | gpio_device_register(&self->dev); 123 | return 0; 124 | } 125 | 126 | static int _mock_gpio_remove(void *fdt, int fdt_node){ 127 | return 0; 128 | } 129 | 130 | DEVICE_DRIVER(gpio, "mock,gpio", _mock_gpio_probe, _mock_gpio_remove) 131 | } 132 | 133 | class M25Test : public ::testing::Test { 134 | protected: 135 | memory_device_t mem; 136 | void SetUp() { 137 | probe_device_drivers(m25_dtb); 138 | mem = memory_find(m25_dtb, "/m25"); 139 | } 140 | void TearDown() { 141 | //remove_device_drivers(m25_dtb); 142 | } 143 | void clock(unsigned cycles) { 144 | 145 | } 146 | }; 147 | 148 | TEST_F(M25Test, check_init) { 149 | EXPECT_NE(memory_find(m25_dtb, "/m25"), nullptr); 150 | } 151 | 152 | TEST_F(M25Test, check_write) { 153 | uint8_t data[4096 + 10]; 154 | memset(data, 0xFE, sizeof(data)); 155 | memset(_flash, 0x00, sizeof(_flash)); 156 | EXPECT_EQ(memory_write(mem, 4090, data, 12), 12); 157 | EXPECT_EQ(_flash[4090], 0xFE); 158 | EXPECT_EQ(_flash[4090 + 11], 0xFE); 159 | } 160 | 161 | TEST_F(M25Test, check_read) { 162 | uint8_t data[32]; 163 | memset(data, 0, sizeof(data)); 164 | EXPECT_EQ(memory_read(mem, 0, data, 32), 32); 165 | EXPECT_EQ(data[0], 0xff); 166 | _flash[0] = 0x10; 167 | _flash[1] = 0x11; 168 | _flash[2] = 0x12; 169 | _flash[3] = 0x13; 170 | EXPECT_EQ(memory_read(mem, 0, data, 4), 4); 171 | EXPECT_EQ(data[0], 0x10); 172 | EXPECT_EQ(data[1], 0x11); 173 | EXPECT_EQ(data[2], 0x12); 174 | EXPECT_EQ(data[3], 0x13); 175 | } 176 | 177 | int main(int argc, char **argv) { 178 | ::testing::InitGoogleMock(&argc, argv); 179 | return RUN_ALL_TESTS(); 180 | } 181 | -------------------------------------------------------------------------------- /src/disp/ledpanel.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "font_16x16.h" 9 | #include "font_5x7.h" 10 | #include "font_8x8.h" 11 | 12 | enum { 13 | LEDPANEL_PIN_A, 14 | LEDPANEL_PIN_B, 15 | LEDPANEL_PIN_C, 16 | LEDPANEL_PIN_D, 17 | LEDPANEL_PIN_GREEN, 18 | LEDPANEL_PIN_RED, 19 | LEDPANEL_PIN_LAT, 20 | LEDPANEL_PIN_CLK, 21 | LEDPANEL_PIN_OE, 22 | }; 23 | 24 | struct ledpanel { 25 | struct display_device dev; 26 | gpio_device_t gpio; 27 | uint8_t *framebuffer; 28 | uint16_t width, height; 29 | uint8_t bpp; 30 | uint16_t fb_width; 31 | }; 32 | 33 | void _ledpanel_task(void *data) { 34 | struct ledpanel *self = (struct ledpanel *)data; 35 | int scroll = 0, scroll_cnt = 0; 36 | while(1) { 37 | for(int line = 0; line < self->height; line++) { 38 | if(line & 0x01) 39 | gpio_set(self->gpio, LEDPANEL_PIN_A); 40 | else 41 | gpio_reset(self->gpio, LEDPANEL_PIN_A); 42 | if(line & 0x02) 43 | gpio_set(self->gpio, LEDPANEL_PIN_B); 44 | else 45 | gpio_reset(self->gpio, LEDPANEL_PIN_B); 46 | if(line & 0x04) 47 | gpio_set(self->gpio, LEDPANEL_PIN_C); 48 | else 49 | gpio_reset(self->gpio, LEDPANEL_PIN_C); 50 | if(line & 0x08) 51 | gpio_set(self->gpio, LEDPANEL_PIN_D); 52 | else 53 | gpio_reset(self->gpio, LEDPANEL_PIN_D); 54 | 55 | for(int c = scroll; c < self->width + scroll; c++) { 56 | int x = c % self->fb_width; 57 | int base = line * (self->fb_width * self->bpp) + x * self->bpp; 58 | int byte = base / 8; 59 | int bit = base & 0x07; 60 | bool r = self->framebuffer[byte] & (1 << bit); 61 | base++; 62 | byte = base / 8; 63 | bit = base & 0x07; 64 | bool g = self->framebuffer[byte] & (1 << bit); 65 | if(r) 66 | gpio_reset(self->gpio, LEDPANEL_PIN_RED); 67 | else 68 | gpio_set(self->gpio, LEDPANEL_PIN_RED); 69 | 70 | if(g) 71 | gpio_reset(self->gpio, LEDPANEL_PIN_GREEN); 72 | else 73 | gpio_set(self->gpio, LEDPANEL_PIN_GREEN); 74 | 75 | gpio_set(self->gpio, LEDPANEL_PIN_CLK); 76 | gpio_reset(self->gpio, LEDPANEL_PIN_CLK); 77 | } 78 | 79 | gpio_set(self->gpio, LEDPANEL_PIN_LAT); 80 | gpio_reset(self->gpio, LEDPANEL_PIN_LAT); 81 | 82 | gpio_reset(self->gpio, LEDPANEL_PIN_OE); 83 | int time = 500; 84 | while(--time) 85 | asm volatile("nop"); 86 | gpio_set(self->gpio, LEDPANEL_PIN_OE); 87 | 88 | // latch output 89 | // thread_sleeP_Ms(1); 90 | } 91 | scroll_cnt = (scroll_cnt + 1); 92 | if(scroll_cnt % 5 == 0) 93 | scroll = (scroll + 1) % self->fb_width; 94 | } 95 | thread_sleep_ms(10); 96 | } 97 | 98 | int _ledpanel_write_pixel(display_device_t dev, int x, int y, color_t color) { 99 | struct ledpanel *self = container_of(dev, struct ledpanel, dev.ops); 100 | 101 | if(x < 0 || x >= self->fb_width || y < 0 || y >= self->height) 102 | return -1; 103 | 104 | for(int c = 0; c < 2; c++) { 105 | int base = y * (self->fb_width * self->bpp) + x * self->bpp + c; 106 | int byte = base / 8; 107 | int bit = base & 0x7; 108 | if(color & (uint32_t)(1 << c)) { 109 | self->framebuffer[byte] = (uint8_t)(self->framebuffer[byte] | (1 << bit)); 110 | } else { 111 | self->framebuffer[byte] = (uint8_t)(self->framebuffer[byte] & ~(1 << bit)); 112 | } 113 | } 114 | return 0; 115 | } 116 | 117 | static const struct display_device_ops _display_ops = {.write_pixel = 118 | _ledpanel_write_pixel}; 119 | 120 | int _ledpanel_probe(void *fdt, int fdt_node) { 121 | // find the gpio device for pins 122 | int node = fdt_find_node_by_ref(fdt, fdt_node, "pins"); 123 | if(node < 0) { 124 | dbg_printk("ledpanel: nopins!\n"); 125 | return -EINVAL; 126 | } 127 | 128 | gpio_device_t gpio = gpio_find_by_node(fdt, node); 129 | if(!gpio) { 130 | dbg_printk("ledpanel: nogpio!\n"); 131 | return -EINVAL; 132 | } 133 | 134 | int width = fdt_get_int_or_default(fdt, fdt_node, "width", 64); 135 | int height = fdt_get_int_or_default(fdt, fdt_node, "height", 8); 136 | int bpp = fdt_get_int_or_default(fdt, fdt_node, "bpp", 3); 137 | int fb_width = fdt_get_int_or_default(fdt, fdt_node, "fb_width", width); 138 | 139 | // reset communication lines 140 | gpio_reset(gpio, LEDPANEL_PIN_A); 141 | gpio_reset(gpio, LEDPANEL_PIN_B); 142 | gpio_reset(gpio, LEDPANEL_PIN_C); 143 | gpio_reset(gpio, LEDPANEL_PIN_D); 144 | gpio_reset(gpio, LEDPANEL_PIN_GREEN); 145 | gpio_reset(gpio, LEDPANEL_PIN_RED); 146 | gpio_reset(gpio, LEDPANEL_PIN_LAT); 147 | gpio_reset(gpio, LEDPANEL_PIN_CLK); 148 | gpio_reset(gpio, LEDPANEL_PIN_OE); 149 | 150 | struct ledpanel *self = kzmalloc(sizeof(struct ledpanel)); 151 | if(!self) 152 | return -ENOMEM; 153 | 154 | display_device_init(&self->dev, fdt_node, &_display_ops); 155 | display_device_register(&self->dev); 156 | 157 | self->framebuffer = kzmalloc((size_t)((fb_width * height * bpp) / 8)); 158 | self->gpio = gpio; 159 | self->width = (uint16_t)width; 160 | self->height = (uint16_t)height; 161 | self->bpp = (uint8_t)bpp; 162 | self->fb_width = (uint16_t)fb_width; 163 | 164 | if(!self->framebuffer) { 165 | dbg_printk("ledpanel: fbfail\n"); 166 | kfree(self); 167 | return -1; 168 | } 169 | /* 170 | const char *str = ">>> Need an engineer? Call now! <<<"; 171 | _ledpanel_write(self, 0, str, (int)strlen(str), 1); 172 | const char *str2 = "0733387694 | Martin | 0733387694 "; 173 | _ledpanel_write(self, 1, str2, (int)strlen(str), 3); 174 | //_ledpanel_write_bitmap(self, 256, 0, _smiley, 16, 16); 175 | */ 176 | if(thread_create(_ledpanel_task, "lp", 180, self, 1, NULL) < 0) 177 | dbg_printk("ledpanel: taskfail\n"); 178 | else 179 | dbg_printk("ledpanel: ok\n"); 180 | return 0; 181 | } 182 | 183 | int _ledpanel_remove(void *fdt, int node) { 184 | return -1; 185 | } 186 | 187 | DEVICE_DRIVER(ledpanel, "mk,ledpanel", _ledpanel_probe, _ledpanel_remove) 188 | --------------------------------------------------------------------------------