work work

This commit is contained in:
Olaf Rempel 2017-11-27 19:22:55 +01:00
parent 7bd831d169
commit 4e9a4a246d
9 changed files with 280 additions and 137 deletions

View File

@ -23,7 +23,6 @@
/* *********************************************************************** */
#define EVENT_COUNT 16
#define TIMER_COUNT 8
static struct event_entry events[EVENT_COUNT];
static volatile uint8_t event_in_idx;

12
event.h
View File

@ -12,11 +12,13 @@ struct event_entry
#define EVENT_TYPE_EMPTY 0x00
#define EVENT_TYPE_GENERIC 0x01
#define EVENT_TYPE_INPUT 0x02
#define EVENT_TYPE_PWM_COMMAND 0x03
#define EVENT_TYPE_PWM_VALUE 0x04
#define EVENT_TYPE_TIMER_SET 0x05
#define EVENT_TYPE_TIMER_ELAPSED 0x06
#define EVENT_TYPE_INPUT_SWITCH 0x10
#define EVENT_TYPE_INPUT_BUTTON 0x11
#define EVENT_TYPE_INPUT_INCDEC 0x12
#define EVENT_TYPE_PWM_COMMAND 0x18
#define EVENT_TYPE_PWM_VALUE 0x19
#define EVENT_TYPE_TIMER_SET 0xF0
#define EVENT_TYPE_TIMER_ELAPSED 0xF1
/* *********************************************************************** */

View File

@ -1,6 +1,8 @@
#ifndef __FUNK_PROTO_H__
#define __FUNK_PROTO_H__
#include <stdint.h>
/* *********************************************************************** */
/*
@ -12,8 +14,6 @@
* - initiator increases seqnum and sends request again
* - commands have 2bit req/resp/ind/conf encoding
* - single window
* - multi master should be supported (for lights talking to each other)
*
*
* - firmware has modules, that communicate through "events"
* - INPUT modules (button/quadencoder) send events to all other (!INPUT) modules
@ -22,9 +22,6 @@
* - communication receives all events and can send to anyone
* - configuration in eeprom(?) to enable which events shall be send (and to who)
*
* - or is there a register service?
* - need to detect if device is restarted and register again
*
* - support to switch to bootloader
* - support forward to mpm/twi
*
@ -48,6 +45,8 @@
#define MSG_CMD_DESCRIPTION_RESPONSE (MSG_TYPE_RESPONSE | 0x02) /* 0xC2 */
#define MSG_CMD_CONTROL_REQUEST (MSG_TYPE_REQUEST | 0x03) /* 0x03 */
#define MSG_CMD_CONTROL_RESPONSE (MSG_TYPE_RESPONSE | 0x03) /* 0xC3 */
#define MSG_CMD_REGISTER_REQUEST (MSG_TYPE_REQUEST | 0x04) /* 0x04 */
#define MSG_CMD_REGISTER_RESPONSE (MSG_TYPE_RESPONSE | 0x04) /* 0xC4 */
#define MSG_CMD_EVENT_INDICATION (MSG_TYPE_INDICATION | 0x03) /* 0x83 */
#define MSG_CMD_EVENT_CONFIRMATION (MSG_TYPE_CONFIRMATION | 0x03) /* 0x43 */
@ -67,6 +66,9 @@
#define CAUSE_INVALID_PARAMETER 0xF1
#define CAUSE_UNSPECIFIED_ERROR 0xFF
#define DESCRIPTION_TYPE_CONTROL 0x01
#define DESCRIPTION_TYPE_EVENT 0x02
#define BOOTMODE_BOOTLOADER 0x00
#define BOOTMODE_APPLICATION 0x80
@ -75,92 +77,151 @@
/* *********************************************************************** */
struct rfm12_msg
/*
* Send a Description Request to a Light
* - type is "Control" or "Event"
* - num is number of controls or events
*/
struct _description_request
{
uint8_t command; /* MSG_CMD_* */
uint8_t seqnum;
uint8_t cause; /* CAUSE_* */
union {
/*
* Send a Description Request to a Light
* - type is "Control" or "Event"
* - num is 1-based number of controls or events
*/
struct { /* MSG_CMD_DESCRIPTION_REQUEST */
uint8_t type;
uint8_t num;
} desc_req;
} __attribute__ ((__packed__));
/*
* Send a Description Response to the master
* - type is Control or Event
* - num is 1-based number of controls or event
* - max_num is the max number of controls or events
* - data_type is used in Control_req / Event_ind
* - data_num is used in Control_req / Event_ind
* - data_desc is short ASCII name of that control/event
*/
struct { /* MSG_CMD_DESCRIPTION_RESPONSE */
/*
* Send a Description Response to the master
* - type is Control or Event
* - num is number of controls or event
* - max_num is the max number of controls or events
* - data_type is used in Control_req / Event_ind
* - data_num is used in Control_req / Event_ind
* - data_desc is short ASCII name of that control/event
*/
struct _description_response
{
uint8_t type;
uint8_t num;
uint8_t max_num;
uint8_t data_type;
uint8_t data_num;
uint8_t data_desc[16];
} desc_rsp;
} __attribute__ ((__packed__));
/*
* Send a Control Request to a Light
* - data_type is "button_press", "abs_dim_value", "step_up/down"
* - data_num is button_numer or channel ID of light
* - data is for abs values, width is encoded in ctrl_type
*/
struct { /* MSG_CMD_CONTROL_REQUEST */
/*
* Send a Control Request to a Light
* - data_type is "button_press", "abs_dim_value", "step_up/down"
* - data_num is button_numer or channel ID of light
* - data is for abs values, width is encoded in ctrl_type
*/
struct _control_request
{
uint8_t data_type;
uint8_t data_num;
union {
uint8_t u8[4];
uint16_t u16[2];
uint32_t u32;
} data;
} ctrl_req;
uint16_t data_value;
} __attribute__ ((__packed__));
/*
* Response for Control Response
* just repeat the type & num
* cause is in header
*/
struct { /* MSG_CMD_CONTROL_RESPONSE */
/*
* Response for Control Request
* just repeat the type & num
* cause is in header
*/
struct _control_response
{
uint8_t data_type;
uint8_t data_num;
} ctrl_rsp;
} __attribute__ ((__packed__));
/*
/*
* Register a Event
* - data_type is "button_press", "movement detected", "step up/down"
* - data_num is button number or channel ID
* - enable is true/false
*/
struct _register_request
{
uint8_t data_type;
uint8_t data_num;
uint8_t enable;
} __attribute__ ((__packed__));
/*
* Response for Register Request
* - data_type is "button_press", "movement detected", "step up/down"
* - data_num is button number or channel ID
* - data_value is last known value
*/
struct _register_response
{
uint8_t data_type;
uint8_t data_num;
uint16_t data_value;
} __attribute__ ((__packed__));
/*
* Send a Event to Master
* - data_type is "button_press", "movement detected", "step up/down"
* - data_num is button number or channel ID
* - data is for abs values, width is encoded in ctrl_type
*/
struct { /* MSG_CMD_EVENT_INDICATION */
struct _event_indication
{
uint8_t data_type;
uint8_t data_num;
union {
uint8_t u8[4];
uint16_t u16[2];
uint32_t u32;
} data;
} evt_ind;
uint16_t data_value;
} __attribute__ ((__packed__));
/*
* Confirmation of event indication
* just repeat the type & num
* cause is in header
*/
struct { /* MSG_CMD_EVENT_CONFIRMATION */
/*
* Confirmation of event indication
* just repeat the type & num
* cause is in header
*/
struct _event_confirmation
{
uint8_t data_type;
uint8_t data_num;
} evt_cnf;
} __attribute__ ((__packed__));
struct rfm12_msg
{
uint8_t command; /* MSG_CMD_* */
uint8_t seqnum;
uint8_t cause; /* CAUSE_* */
union
{
/* application messages */
/* MSG_CMD_DESCRIPTION_REQUEST */
struct _description_request desc_req;
/* MSG_CMD_DESCRIPTION_RESPONSE */
struct _description_response desc_rsp;
/* MSG_CMD_CONTROL_REQUEST */
struct _control_request ctrl_req;
/* MSG_CMD_CONTROL_RESPONSE */
struct _control_response ctrl_rsp;
/* MSG_CMD_REGISTER_REQUEST */
struct _register_request reg_req;
/* MSG_CMD_REGISTER_RESPONSE */
struct _register_response reg_rsp;
/* MSG_CMD_EVENT_INDICATION */
struct _event_indication evt_ind;
/* MSG_CMD_EVENT_CONFIRMATION */
struct _event_confirmation evt_cnf;
/* bootloader messages */
@ -193,7 +254,7 @@ struct rfm12_msg
uint8_t data[32];
} write_req;
} p;
};
} __attribute__ ((__packed__));
/* *********************************************************************** */

View File

@ -33,6 +33,22 @@
#include "funk_proto.h"
#include "target.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
/* *********************************************************************** */
static const struct _description_response control_desc[] PROGMEM = {
{ DESCRIPTION_TYPE_CONTROL, 0xFF, 0xFF, EVENT_TYPE_PWM_COMMAND, EVENT_NUM_PWM_CH0, "Door Light Cmd" },
{ DESCRIPTION_TYPE_CONTROL, 0xFF, 0xFF, EVENT_TYPE_PWM_COMMAND, EVENT_NUM_PWM_CH1, "Wall Light Cmd" },
{ DESCRIPTION_TYPE_CONTROL, 0xFF, 0xFF, EVENT_TYPE_PWM_VALUE, EVENT_NUM_PWM_CH0, "Door Light Val" },
{ DESCRIPTION_TYPE_CONTROL, 0xFF, 0xFF, EVENT_TYPE_PWM_VALUE, EVENT_NUM_PWM_CH1, "Wall Light Val" },
};
static const struct _description_response event_desc[] PROGMEM = {
{ DESCRIPTION_TYPE_EVENT, 0xFF, 0xFF, EVENT_TYPE_INPUT_BUTTON, EVENT_NUM_INPUT_BUTTON, "Wall Button" },
{ DESCRIPTION_TYPE_EVENT, 0xFF, 0xFF, EVENT_TYPE_INPUT_SWITCH, EVENT_NUM_INPUT_DOOR, "Door Switch" },
};
/* *********************************************************************** */
#define LED_RX 0
@ -73,19 +89,6 @@ static void led_tick(void)
}
} /* led_tick */
static void uart_event_handler(struct event_entry *event)
{
/* output all events on UART */
uart_putstr_p(PSTR("evt: "));
uart_put_hex(event->type);
uart_putc(' ');
uart_put_hex(event->num);
uart_putc(' ');
uart_put_hex(event->value >> 8);
uart_put_hex(event->value & 0xFF);
uart_putstr("\r\n");
} /* uart_event_handler */
/*
* For newer devices the watchdog timer remains active even after a
@ -136,8 +139,17 @@ int main(void)
struct event_entry *event = event_get();
if (event->type != EVENT_TYPE_EMPTY)
{
uart_event_handler(event);
#if 0
/* output all events on UART */
uart_putstr_p(PSTR("evt: "));
uart_put_hex(event->type);
uart_putc(' ');
uart_put_hex(event->num);
uart_putc(' ');
uart_put_hex(event->value >> 8);
uart_put_hex(event->value & 0xFF);
uart_putstr("\r\n");
#endif
switch (event->type)
{
case EVENT_TYPE_PWM_COMMAND:
@ -145,7 +157,7 @@ int main(void)
pwm_event_handler(event);
break;
case EVENT_TYPE_INPUT:
case EVENT_TYPE_INPUT_INCDEC:
if (event->num == EVENT_NUM_INPUT_QUAD)
{
if (event->value == EVENT_VALUE_INPUT_QUAD_DEC)
@ -163,7 +175,10 @@ int main(void)
);
}
}
else if (event->num == EVENT_NUM_INPUT_BUTTON)
break;
case EVENT_TYPE_INPUT_BUTTON:
if (event->num == EVENT_NUM_INPUT_BUTTON)
{
if (event->value == EVENT_VALUE_INPUT_BUTTON_PRESSED)
{
@ -173,7 +188,10 @@ int main(void)
);
}
}
else if (event->num == EVENT_NUM_INPUT_DOOR)
break;
case EVENT_TYPE_INPUT_SWITCH:
if (event->num == EVENT_NUM_INPUT_DOOR)
{
if (event->value == EVENT_VALUE_INPUT_DOOR_CLOSED)
{
@ -238,6 +256,7 @@ int main(void)
struct rfm12_msg *req_msg = (struct rfm12_msg *)req_pkt->data;
struct rfm12_msg *rsp_msg = (struct rfm12_msg *)rsp_pkt->data;
#if 0
/* retransmitted request -> retransmit response */
if ((req_pkt->source_address == rsp_pkt->dest_address) &&
((req_msg->command & MSG_CMD_MASK) == (rsp_msg->command & MSG_CMD_MASK)) &&
@ -255,6 +274,7 @@ int main(void)
continue;
}
#endif
rsp_pkt->dest_address = req_pkt->source_address;
rsp_pkt->data_length = 3;
@ -262,6 +282,7 @@ int main(void)
rsp_msg->seqnum = req_msg->seqnum;
rsp_msg->cause = CAUSE_SUCCESS;
uint8_t i;
switch (req_msg->command)
{
case MSG_CMD_SWITCHAPP_REQUEST:
@ -275,6 +296,59 @@ int main(void)
}
break;
case MSG_CMD_DESCRIPTION_REQUEST:
if ((req_msg->p.desc_req.type == DESCRIPTION_TYPE_CONTROL) &&
(req_msg->p.desc_req.num < ARRAY_SIZE(control_desc))
)
{
memcpy_P(&rsp_msg->p.desc_rsp,
&control_desc[req_msg->p.desc_req.num],
sizeof(struct _description_response));
rsp_msg->p.desc_rsp.num = req_msg->p.desc_req.num;
rsp_msg->p.desc_rsp.max_num = ARRAY_SIZE(control_desc) -1;
rsp_pkt->data_length += sizeof(struct _description_response);
}
else if ((req_msg->p.desc_req.type == DESCRIPTION_TYPE_EVENT) &&
(req_msg->p.desc_req.num < ARRAY_SIZE(event_desc))
)
{
memcpy_P(&rsp_msg->p.desc_rsp,
&event_desc[req_msg->p.desc_req.num],
sizeof(struct _description_response));
rsp_msg->p.desc_rsp.num = req_msg->p.desc_req.num;
rsp_msg->p.desc_rsp.max_num = ARRAY_SIZE(event_desc) -1;
rsp_pkt->data_length += sizeof(struct _description_response);
}
else
{
rsp_msg->cause = CAUSE_INVALID_PARAMETER;
}
break;
case MSG_CMD_CONTROL_REQUEST:
rsp_msg->cause = CAUSE_INVALID_PARAMETER;
for (i = 0; i < ARRAY_SIZE(control_desc); i++)
{
if ((pgm_read_byte(&control_desc[i].data_type) == req_msg->p.ctrl_req.data_type) &&
(pgm_read_byte(&control_desc[i].data_num) == req_msg->p.ctrl_req.data_num)
)
{
event_queue(req_msg->p.ctrl_req.data_type,
req_msg->p.ctrl_req.data_num,
req_msg->p.ctrl_req.data_value);
rsp_msg->cause = CAUSE_SUCCESS;
rsp_msg->p.ctrl_rsp.data_type = req_msg->p.ctrl_req.data_type;
rsp_msg->p.ctrl_rsp.data_num = req_msg->p.ctrl_req.data_num;
rsp_pkt->data_length += sizeof(struct _control_response);
break;
}
}
break;
default:
rsp_msg->cause = CAUSE_NOT_SUPPORTED;
break;

55
input.c
View File

@ -36,19 +36,14 @@ static uint8_t input_old_state[2];
/* *********************************************************************** */
static void input_send_event(uint8_t channel, uint8_t state)
static void input_send_event(uint8_t type, uint8_t num, uint8_t state)
{
if ((channel != EVENT_NUM_INPUT_BUTTON) && (channel != EVENT_NUM_INPUT_DOOR))
if ((debounce_timer[num] == 0) && (state != input_old_state[num]))
{
return;
}
event_queue(type, num, state);
if ((debounce_timer[channel -2] == 0) && (state != input_old_state[channel -2]))
{
event_queue(EVENT_TYPE_INPUT, channel, state);
debounce_timer[channel -2] = INPUT_DEBOUNCE_TIMER;
input_old_state[channel -2] = state;
debounce_timer[num] = INPUT_DEBOUNCE_TIMER;
input_old_state[num] = state;
}
} /* input_send_event */
@ -102,12 +97,16 @@ ISR(PCINT1_vect)
/* quadruple decoder switch changed */
else if (pcint & (1<<PINC2))
{
input_send_event(EVENT_NUM_INPUT_BUTTON, !!(pcint_new & (1<<PINC2)));
input_send_event(EVENT_TYPE_INPUT_BUTTON,
EVENT_NUM_INPUT_BUTTON,
!!(pcint_new & (1<<PINC2)));
}
/* door switch changed */
else if (pcint & (1<<PINC3))
{
input_send_event(EVENT_NUM_INPUT_DOOR, !!(pcint_new & (1<<PINC3)));
input_send_event(EVENT_TYPE_INPUT_SWITCH,
EVENT_NUM_INPUT_DOOR,
!(pcint_new & (1<<PINC3)));
}
/* one revolution completed? */
@ -116,7 +115,7 @@ ISR(PCINT1_vect)
/* counter clock wise */
if (quad_state == 1)
{
event_queue(EVENT_TYPE_INPUT,
event_queue(EVENT_TYPE_INPUT_INCDEC,
EVENT_NUM_INPUT_QUAD,
EVENT_VALUE_INPUT_QUAD_DEC
);
@ -124,7 +123,7 @@ ISR(PCINT1_vect)
/* clock wise */
else if (quad_state == 2)
{
event_queue(EVENT_TYPE_INPUT,
event_queue(EVENT_TYPE_INPUT_INCDEC,
EVENT_NUM_INPUT_QUAD,
EVENT_VALUE_INPUT_QUAD_INC
);
@ -145,21 +144,25 @@ ISR(PCINT1_vect)
void input_tick(void)
{
if (debounce_timer[0] > 0)
if (debounce_timer[EVENT_NUM_INPUT_BUTTON] > 0)
{
debounce_timer[0]--;
if (debounce_timer[0] == 0)
debounce_timer[EVENT_NUM_INPUT_BUTTON]--;
if (debounce_timer[EVENT_NUM_INPUT_BUTTON] == 0)
{
input_send_event(EVENT_NUM_INPUT_BUTTON, !!(PINC & (1<<PINC2)));
input_send_event(EVENT_TYPE_INPUT_BUTTON,
EVENT_NUM_INPUT_BUTTON,
!!(PINC & (1<<PINC2)));
}
}
if (debounce_timer[1] > 0)
if (debounce_timer[EVENT_NUM_INPUT_DOOR] > 0)
{
debounce_timer[1]--;
if (debounce_timer[1] == 0)
debounce_timer[EVENT_NUM_INPUT_DOOR]--;
if (debounce_timer[EVENT_NUM_INPUT_DOOR] == 0)
{
input_send_event(EVENT_NUM_INPUT_DOOR, !!(PINC & (1<<PINC3)));
input_send_event(EVENT_TYPE_INPUT_SWITCH,
EVENT_NUM_INPUT_DOOR,
!(PINC & (1<<PINC3)));
}
}
} /* input_tick */
@ -182,8 +185,12 @@ void input_init(void)
quad_state = PINC & ((1<<PINC0) | (1<<PINC1));
/* send button state */
input_send_event(EVENT_NUM_INPUT_BUTTON, !!(PINC & (1<<PINC2)));
input_send_event(EVENT_TYPE_INPUT_BUTTON,
EVENT_NUM_INPUT_BUTTON,
!!(PINC & (1<<PINC2)));
/* send door state */
input_send_event(EVENT_NUM_INPUT_DOOR, !!(PINC & (1<<PINC3)));
input_send_event(EVENT_TYPE_INPUT_SWITCH,
EVENT_NUM_INPUT_DOOR,
!(PINC & (1<<PINC3)));
} /* input_init */

10
input.h
View File

@ -3,16 +3,16 @@
/* *********************************************************************** */
#define EVENT_NUM_INPUT_QUAD 0x01
#define EVENT_NUM_INPUT_BUTTON 0x02
#define EVENT_NUM_INPUT_DOOR 0x03
#define EVENT_NUM_INPUT_BUTTON 0x00
#define EVENT_NUM_INPUT_DOOR 0x01
#define EVENT_NUM_INPUT_QUAD 0x02
#define EVENT_VALUE_INPUT_QUAD_DEC 0x01
#define EVENT_VALUE_INPUT_QUAD_INC 0x02
#define EVENT_VALUE_INPUT_BUTTON_RELEASED 0x00
#define EVENT_VALUE_INPUT_BUTTON_PRESSED 0x01
#define EVENT_VALUE_INPUT_DOOR_OPEN 0x00
#define EVENT_VALUE_INPUT_DOOR_CLOSED 0x01
#define EVENT_VALUE_INPUT_DOOR_CLOSED 0x00
#define EVENT_VALUE_INPUT_DOOR_OPEN 0x01
/* *********************************************************************** */

View File

@ -28,7 +28,7 @@
/* *********************************************************************** */
#define UART_RXBUF_SIZE 128
#define UART_RXBUF_SIZE 16
#define UART_TXBUF_SIZE 128
/* *********************************************************************** */

View File

@ -19,11 +19,10 @@
#include <avr/io.h>
#include "event.h"
#include "timer.h"
/* *********************************************************************** */
#define TIMER_COUNT 2
static uint16_t timers[TIMER_COUNT];
/* *********************************************************************** */

View File

@ -4,6 +4,7 @@
/* *********************************************************************** */
#define TIMER_DOOR_CLOSE_DELAY 0
#define TIMER_COUNT 2
/* *********************************************************************** */