From 6f70008a42d75df78490a1e5087ee4bf5b64f21c Mon Sep 17 00:00:00 2001 From: Jonas Widen Date: Sat, 25 Apr 2020 19:55:38 +0200 Subject: [PATCH] Import of the real code --- .gitignore | 2 + LICENSE | 2 +- Makefile | 34 +++++++ main.c | 66 ++++++++++++++ nexa_new.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++ nexa_new.h | 80 ++++++++++++++++ 6 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 main.c create mode 100644 nexa_new.c create mode 100644 nexa_new.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a623f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +nexa diff --git a/LICENSE b/LICENSE index 2d2bab1..7a36b15 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) . All rights reserved. +Copyright (c) 2012, Jonas Widén (jonas.widen@widens.eu). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b4ca391 --- /dev/null +++ b/Makefile @@ -0,0 +1,34 @@ +BUILD_DIR = build + +CFLAGS += -std=gnu99 -W -Wall -pedantic +CFLAGS += -Wstrict-prototypes -Wundef -Werror +CFLAGS += -ffunction-sections +CFLAGS += -Os -g +CFLAGS += -DNEXA_PIN=29 + +LDFLAGS += -lwiringPi + +srcs += main.c +srcs += nexa_new.c + +objs = $(srcs:%.c=${BUILD_DIR}/%.o) + +target = nexa + +${BUILD_DIR}/%.o: %.c + @echo "[CC] $< -> $@" + @$(CC) -c $(CFLAGS) -o $@ $< + +$(target): $(BUILD_DIR) $(objs) + @echo "[LINK] $@" + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(objs) + +${BUILD_DIR}: + @mkdir -p $@ + +clean: + @rm -rf $(objs) $(asm_objs) $(target) $(target.elf) ${BUILD_DIR} + +.PHONY: clean + +-include $(srcs:%.c=%.d) diff --git a/main.c b/main.c new file mode 100644 index 0000000..1761252 --- /dev/null +++ b/main.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, Jonas Widén (jonas.widen@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "nexa_new.h" + +#include +#include +#include + +int main(int argc, char **argv) +{ + int opt; + uint8_t channel = 0; + uint8_t button = 0; + nexa_activation_t status = NEXA_ACTIVATION_ON; + + while ((opt = getopt(argc, argv, "c:b:s:")) != -1) { + switch (opt) { + case 'c': + channel = atoi(optarg); + break; + case 'b': + button = atoi(optarg); + break; + case 's': + status = atoi(optarg) ? NEXA_ACTIVATION_ON : NEXA_ACTIVATION_OFF; + break; + default: /* '?' */ + fprintf(stderr, "Usage: %s [-c channel] [-b button] [-s status]\n", + argv[0]); + exit(EXIT_FAILURE); + } + } + + nexa_new_init(); + + nexa_new_transmit(channel, + button, + status, + NEXA_DIM_LEVEL_1, + false); + return 0; +} diff --git a/nexa_new.c b/nexa_new.c new file mode 100644 index 0000000..67436ab --- /dev/null +++ b/nexa_new.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2012, Jonas Widén (jonas.widen@widens.eu) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "nexa_new.h" + +#include +#include +#include + +#define NEXA_DELAY_HIGH 250 +#define NEXA_DELAY_ZERO 1250 +#define NEXA_DELAY_ONE 250 +#define NEXA_DELAY_SYNC 2500 + +#define NEXA_RESENDS 6 + +#define NEXA_CLASS_1 (0x5) +#define NEXA_CLASS_2 (0x6) +#define NEXA_CLASS_3 (0x9) +#define NEXA_CLASS_4 (0xa) + +static void send_zero(void) +{ + digitalWrite(NEXA_PIN, HIGH); + usleep(NEXA_DELAY_HIGH); + digitalWrite(NEXA_PIN, LOW); + usleep(NEXA_DELAY_ZERO); +} + +static void send_one(void) +{ + digitalWrite(NEXA_PIN, HIGH); + usleep(NEXA_DELAY_HIGH); + digitalWrite(NEXA_PIN, LOW); + usleep(NEXA_DELAY_ONE); +} + +static void send_sync(void) +{ + digitalWrite(NEXA_PIN, HIGH); + usleep(NEXA_DELAY_HIGH); + digitalWrite(NEXA_PIN, LOW); + usleep(NEXA_DELAY_SYNC); +} + +static void send_nibble(uint8_t nibble) +{ + if (nibble & 0x08) send_one(); else send_zero(); + if (nibble & 0x04) send_one(); else send_zero(); + if (nibble & 0x02) send_one(); else send_zero(); + if (nibble & 0x01) send_one(); else send_zero(); +} + +static void send_id(void) +{ + uint8_t i; + uint8_t id[7] = {0x96, 0xa5, 0x55, 0xa5, 0x55, 0x55, 0x6}; + for (i = 0; i < 7; ++i) { + if (i < 6) { + send_nibble((id[i] >> 4) & 0x0f); + } + send_nibble(id[i] & 0x0f); + } +} + +static void send_group(bool group_mode) +{ + if (group_mode) { + send_zero(); + send_one(); + } + else { + send_one(); + send_zero(); + } +} + +static void send_activation(nexa_activation_t mode) +{ + switch(mode) { + case NEXA_ACTIVATION_OFF: + send_one(); + send_zero(); + break; + case NEXA_ACTIVATION_ON: + send_zero(); + send_one(); + break; + case NEXA_ACTIVATION_DIM: + send_one(); + send_one(); + break; + default: + send_one(); + send_zero(); + break; + } +} + +static void send_dim_level(nexa_dim_level_t level) +{ + switch(level) { + case NEXA_DIM_LEVEL_1: + send_nibble(NEXA_CLASS_1); + send_nibble(NEXA_CLASS_2); + break; + case NEXA_DIM_LEVEL_2: + send_nibble(NEXA_CLASS_3); + send_nibble(NEXA_CLASS_2); + break; + case NEXA_DIM_LEVEL_3: + send_nibble(NEXA_CLASS_2); + send_nibble(NEXA_CLASS_2); + break; + case NEXA_DIM_LEVEL_4: + send_nibble(NEXA_CLASS_4); + send_nibble(NEXA_CLASS_2); + break; + case NEXA_DIM_LEVEL_5: + send_nibble(NEXA_CLASS_1); + send_nibble(NEXA_CLASS_4); + break; + case NEXA_DIM_LEVEL_6: + send_nibble(NEXA_CLASS_3); + send_nibble(NEXA_CLASS_4); + break; + case NEXA_DIM_LEVEL_7: + send_nibble(NEXA_CLASS_2); + send_nibble(NEXA_CLASS_4); + break; + case NEXA_DIM_LEVEL_8: + send_nibble(NEXA_CLASS_4); + send_nibble(NEXA_CLASS_4); + break; + case NEXA_DIM_LEVEL_9: + send_nibble(NEXA_CLASS_1); + send_nibble(NEXA_CLASS_3); + break; + case NEXA_DIM_LEVEL_10: + send_nibble(NEXA_CLASS_3); + send_nibble(NEXA_CLASS_3); + break; + case NEXA_DIM_LEVEL_11: + send_nibble(NEXA_CLASS_2); + send_nibble(NEXA_CLASS_3); + break; + case NEXA_DIM_LEVEL_12: + send_nibble(NEXA_CLASS_4); + send_nibble(NEXA_CLASS_3); + break; + case NEXA_DIM_LEVEL_13: + send_nibble(NEXA_CLASS_2); + send_nibble(NEXA_CLASS_1); + break; + case NEXA_DIM_LEVEL_14: + send_nibble(NEXA_CLASS_4); + send_nibble(NEXA_CLASS_1); + break; + case NEXA_DIM_LEVEL_15: + send_nibble(NEXA_CLASS_3); + send_nibble(NEXA_CLASS_1); + break; + case NEXA_DIM_LEVEL_16: + send_nibble(NEXA_CLASS_1); + send_nibble(NEXA_CLASS_1); + break; + } +} + +static void send_channel(nexa_channel_t channel) +{ + switch(channel) { + case NEXA_CHANNEL_1: + send_nibble(NEXA_CLASS_1); + break; + case NEXA_CHANNEL_2: + send_nibble(NEXA_CLASS_2); + break; + case NEXA_CHANNEL_3: + send_nibble(NEXA_CLASS_3); + break; + case NEXA_CHANNEL_4: + send_nibble(NEXA_CLASS_4); + break; + default: + send_nibble(NEXA_CLASS_1); + break; + } +} + +static void send_button(nexa_button_t channel) +{ + switch(channel) { + case NEXA_BUTTON_1: + send_nibble(NEXA_CLASS_1); + break; + case NEXA_BUTTON_2: + send_nibble(NEXA_CLASS_2); + break; + case NEXA_BUTTON_3: + send_nibble(NEXA_CLASS_3); + break; + case NEXA_BUTTON_4: + send_nibble(NEXA_CLASS_4); + break; + default: + send_nibble(NEXA_CLASS_1); + break; + } +} + +void nexa_new_init(void) +{ + wiringPiSetup(); + pinMode(NEXA_PIN, OUTPUT); + digitalWrite(NEXA_PIN, LOW); +} + +void nexa_new_transmit(nexa_channel_t channel, + nexa_button_t button, + nexa_activation_t activation, + nexa_dim_level_t level, + bool group_mode) +{ + uint8_t i; + for (i = 0; i < NEXA_RESENDS; ++i) { + send_sync(); + send_id(); + send_group(group_mode); + send_activation(activation); + send_channel(channel); + send_button(button); + if (activation == NEXA_ACTIVATION_DIM) { + send_dim_level(level); + } + send_zero(); + usleep(10); + } +} diff --git a/nexa_new.h b/nexa_new.h new file mode 100644 index 0000000..79dd4cc --- /dev/null +++ b/nexa_new.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012, Jonas Widén (jonas.widen@widens.eu) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NEXA_NEW_H_ +#define NEXA_NEW_H_ + +#include +#include + +typedef enum { + NEXA_ACTIVATION_OFF, + NEXA_ACTIVATION_ON, + NEXA_ACTIVATION_DIM +} nexa_activation_t; + +typedef enum { + NEXA_DIM_LEVEL_1, + NEXA_DIM_LEVEL_2, + NEXA_DIM_LEVEL_3, + NEXA_DIM_LEVEL_4, + NEXA_DIM_LEVEL_5, + NEXA_DIM_LEVEL_6, + NEXA_DIM_LEVEL_7, + NEXA_DIM_LEVEL_8, + NEXA_DIM_LEVEL_9, + NEXA_DIM_LEVEL_10, + NEXA_DIM_LEVEL_11, + NEXA_DIM_LEVEL_12, + NEXA_DIM_LEVEL_13, + NEXA_DIM_LEVEL_14, + NEXA_DIM_LEVEL_15, + NEXA_DIM_LEVEL_16 +} nexa_dim_level_t; + +typedef enum { + NEXA_CHANNEL_1, + NEXA_CHANNEL_2, + NEXA_CHANNEL_3, + NEXA_CHANNEL_4 +} nexa_channel_t; + +typedef enum { + NEXA_BUTTON_1, + NEXA_BUTTON_2, + NEXA_BUTTON_3, + NEXA_BUTTON_4 +} nexa_button_t; + +void nexa_new_init(void); +void nexa_new_transmit(nexa_channel_t channel, + nexa_button_t button, + nexa_activation_t activation, + nexa_dim_level_t level, + bool group_mode); + +#endif /* NEXA_NEW_H_ */