264 lines
6.1 KiB
C
264 lines
6.1 KiB
C
|
/*
|
||
|
* 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 <stdint.h>
|
||
|
#include <unistd.h>
|
||
|
#include <wiringPi.h>
|
||
|
|
||
|
#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);
|
||
|
}
|
||
|
}
|