Skip to content

Commit

Permalink
Add edge counters for pin 0 on both ports
Browse files Browse the repository at this point in the history
  • Loading branch information
photron committed Aug 28, 2013
1 parent 2d96ab6 commit 7a3e84f
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 5 deletions.
2 changes: 1 addition & 1 deletion software/CMakeLists.txt
Expand Up @@ -8,7 +8,7 @@ PROJECT(${PROJECT_NAME})

# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
SET(OPTIMIZATION_LEVEL 1)
SET(OPTIMIZATION_LEVEL s)
SET(DEBUG "")

SET(CMAKE_BUILD_TYPE None)
Expand Down
1 change: 1 addition & 0 deletions software/changelog
Expand Up @@ -6,3 +6,4 @@
2.0.0: Support for protocol 2.0
2.0.1: Add missing invocation for set_selected_values function
2.0.2: Apply debounce period on port b again
2.0.3: Add edge counters for pin 0 on both ports
14 changes: 13 additions & 1 deletion software/src/config.h
Expand Up @@ -32,7 +32,7 @@

#define BRICKLET_FIRMWARE_VERSION_MAJOR 2
#define BRICKLET_FIRMWARE_VERSION_MINOR 0
#define BRICKLET_FIRMWARE_VERSION_REVISION 2
#define BRICKLET_FIRMWARE_VERSION_REVISION 3

#define BRICKLET_HARDWARE_VERSION_MAJOR 1
#define BRICKLET_HARDWARE_VERSION_MINOR 1
Expand Down Expand Up @@ -62,6 +62,18 @@ typedef struct {
uint32_t port_b_time_remaining[NUM_PINS_PER_PORT];
uint8_t port_a_monoflop_callback_mask;
uint8_t port_b_monoflop_callback_mask;

uint32_t port_a_pin_0_edge_count;
uint8_t port_a_pin_0_edge_type;
uint8_t port_a_pin_0_edge_debounce;
uint8_t port_a_pin_0_edge_debounce_counter;
uint8_t port_a_pin_0_edge_last_state;

uint32_t port_b_pin_0_edge_count;
uint8_t port_b_pin_0_edge_type;
uint8_t port_b_pin_0_edge_debounce;
uint8_t port_b_pin_0_edge_debounce_counter;
uint8_t port_b_pin_0_edge_last_state;
} BrickContext;

#endif
157 changes: 155 additions & 2 deletions software/src/io.c
Expand Up @@ -86,6 +86,21 @@ void invocation(const ComType com, const uint8_t *data) {
break;
}

case FID_GET_EDGE_COUNT: {
get_edge_count(com, (GetEdgeCount*)data);
break;
}

case FID_SET_EDGE_COUNT_CONFIG: {
set_edge_count_config(com, (SetEdgeCountConfig*)data);
break;
}

case FID_GET_EDGE_COUNT_CONFIG: {
get_edge_count_config(com, (GetEdgeCountConfig*)data);
break;
}

default: {
BA->com_return_error(data, sizeof(MessageHeader), MESSAGE_ERROR_CODE_NOT_SUPPORTED, com);
break;
Expand Down Expand Up @@ -130,12 +145,24 @@ void constructor(void) {

BC->port_a_monoflop_callback_mask = 0;
BC->port_b_monoflop_callback_mask = 0;

BC->port_a_pin_0_edge_count = 0;
BC->port_a_pin_0_edge_type = EDGE_TYPE_RISING;
BC->port_a_pin_0_edge_debounce = 100;
BC->port_a_pin_0_edge_debounce_counter = 0;
BC->port_a_pin_0_edge_last_state = 1;

BC->port_b_pin_0_edge_count = 0;
BC->port_b_pin_0_edge_type = EDGE_TYPE_RISING;
BC->port_b_pin_0_edge_debounce = 100;
BC->port_b_pin_0_edge_debounce_counter = 0;
BC->port_b_pin_0_edge_last_state = 1;
}

void destructor(void) {
PIN_RESET.type = PIO_INPUT;
/*PIN_RESET.type = PIO_INPUT;
PIN_RESET.attribute = PIO_PULLUP;
BA->PIO_Configure(&PIN_RESET, 1);
BA->PIO_Configure(&PIN_RESET, 1);*/
}

void send_interrupt_callback(const char port,
Expand Down Expand Up @@ -230,6 +257,43 @@ void send_monoflop_callback(const char port,
*monoflop_callback_mask = 0;
}

void update_edge_counter(const uint8_t internal_address_iodir,
const uint8_t internal_address_gpio,
uint8_t *edge_debounce_counter,
const uint8_t edge_debounce,
uint8_t *edge_last_state,
const uint8_t edge_type,
uint32_t *edge_count) {
if (*edge_debounce_counter != 0) {
return;
}

uint8_t direction_mask = io_read(internal_address_iodir);

if ((direction_mask & (1 << 0)) == 0) {
return;
}

uint8_t state = (io_read(internal_address_gpio) & (1 << 0)) ? 1 : 0;

if(state == *edge_last_state) {
return;
}

*edge_last_state = state;
*edge_debounce_counter = edge_debounce;

if(state) {
if(edge_type == EDGE_TYPE_RISING || edge_type == EDGE_TYPE_BOTH) {
++*edge_count;
}
} else {
if(edge_type == EDGE_TYPE_FALLING || edge_type == EDGE_TYPE_BOTH) {
++*edge_count;
}
}
}

void tick(const uint8_t tick_type) {
if(tick_type & TICK_TASK_TYPE_CALCULATION) {
if(BC->port_a_counter != 0) {
Expand All @@ -248,6 +312,29 @@ void tick(const uint8_t tick_type) {
update_monoflop_time(I2C_INTERNAL_ADDRESS_OLAT_B,
&BC->port_b_monoflop_callback_mask,
&b);

// edge counter
if(BC->port_a_pin_0_edge_debounce_counter != 0) {
BC->port_a_pin_0_edge_debounce_counter--;
}
if(BC->port_b_pin_0_edge_debounce_counter != 0) {
BC->port_b_pin_0_edge_debounce_counter--;
}

update_edge_counter(I2C_INTERNAL_ADDRESS_IODIR_A,
I2C_INTERNAL_ADDRESS_GPIO_A,
&BC->port_a_pin_0_edge_debounce_counter,
BC->port_a_pin_0_edge_debounce,
&BC->port_a_pin_0_edge_last_state,
BC->port_a_pin_0_edge_type,
&BC->port_a_pin_0_edge_count);
update_edge_counter(I2C_INTERNAL_ADDRESS_IODIR_B,
I2C_INTERNAL_ADDRESS_GPIO_B,
&BC->port_b_pin_0_edge_debounce_counter,
BC->port_b_pin_0_edge_debounce,
&BC->port_b_pin_0_edge_last_state,
BC->port_b_pin_0_edge_type,
&BC->port_b_pin_0_edge_count);
}

if(tick_type & TICK_TASK_TYPE_MESSAGE) {
Expand Down Expand Up @@ -632,3 +719,69 @@ void set_selected_values(const ComType com, const SetSelectedValues *data) {

BA->com_return_setter(com, data);
}

void get_edge_count(const ComType com, const GetEdgeCount *data) {
uint32_t *edge_count;

if(data->port == 'a' || data->port == 'A') {
edge_count = &BC->port_a_pin_0_edge_count;
} else if(data->port == 'b' || data->port == 'B') {
edge_count = &BC->port_b_pin_0_edge_count;
} else {
BA->com_return_error(data, sizeof(MessageHeader), MESSAGE_ERROR_CODE_INVALID_PARAMETER, com);
return;
}

GetEdgeCountReturn gecr;

gecr.header = data->header;
gecr.header.length = sizeof(GetEdgeCountReturn);
gecr.count = *edge_count;

BA->send_blocking_with_timeout(&gecr,
sizeof(GetEdgeCountReturn),
com);

if(data->reset_counter) {
*edge_count = 0;
}
}

void set_edge_count_config(const ComType com, const SetEdgeCountConfig *data) {
if(data->port == 'a' || data->port == 'A') {
BC->port_a_pin_0_edge_type = data->edge_type;
BC->port_a_pin_0_edge_debounce = data->debounce;
BC->port_a_pin_0_edge_count = 0;
} else if(data->port == 'b' || data->port == 'B') {
BC->port_b_pin_0_edge_type = data->edge_type;
BC->port_b_pin_0_edge_debounce = data->debounce;
BC->port_b_pin_0_edge_count = 0;
} else {
BA->com_return_error(data, sizeof(MessageHeader), MESSAGE_ERROR_CODE_INVALID_PARAMETER, com);
return;
}

BA->com_return_setter(com, data);
}

void get_edge_count_config(const ComType com, const GetEdgeCountConfig *data) {
GetEdgeCountConfigReturn geccr;

geccr.header = data->header;
geccr.header.length = sizeof(GetEdgeCountConfigReturn);

if(data->port == 'a' || data->port == 'A') {
geccr.edge_type = BC->port_a_pin_0_edge_type;
geccr.debounce = BC->port_a_pin_0_edge_debounce;
} else if(data->port == 'b' || data->port == 'B') {
geccr.edge_type = BC->port_b_pin_0_edge_type;
geccr.debounce = BC->port_b_pin_0_edge_debounce;
} else {
BA->com_return_error(data, sizeof(GetEdgeCountConfigReturn), MESSAGE_ERROR_CODE_INVALID_PARAMETER, com);
return;
}

BA->send_blocking_with_timeout(&geccr,
sizeof(GetEdgeCountConfigReturn),
com);
}
41 changes: 40 additions & 1 deletion software/src/io.h
@@ -1,5 +1,5 @@
/* io16-bricklet
* Copyright (C) 2012 Matthias Bolte <matthias@tinkerforge.com>
* Copyright (C) 2012-2013 Matthias Bolte <matthias@tinkerforge.com>
* Copyright (C) 2010-2013 Olaf Lüke <olaf@tinkerforge.com>
*
* io.h: Implementation of IO-16 Bricklet messages
Expand Down Expand Up @@ -56,6 +56,10 @@

#define IOCON_ODR (1 << 2)

#define EDGE_TYPE_RISING 0
#define EDGE_TYPE_FALLING 1
#define EDGE_TYPE_BOTH 2

#define FID_SET_PORT 1
#define FID_GET_PORT 2
#define FID_SET_PORT_CONFIGURATION 3
Expand All @@ -69,6 +73,9 @@
#define FID_GET_PORT_MONOFLOP 11
#define FID_MONOFLOP_DONE 12
#define FID_SET_SELECTED_VALUES 13
#define FID_GET_EDGE_COUNT 14
#define FID_SET_EDGE_COUNT_CONFIG 15
#define FID_GET_EDGE_COUNT_CONFIG 16

typedef struct {
MessageHeader header;
Expand Down Expand Up @@ -177,6 +184,35 @@ typedef struct {
uint8_t value_mask;
} __attribute__((__packed__)) MonoflopDone;

typedef struct {
MessageHeader header;
char port;
bool reset_counter;
} __attribute__((__packed__)) GetEdgeCount;

typedef struct {
MessageHeader header;
uint32_t count;
} __attribute__((__packed__)) GetEdgeCountReturn;

typedef struct {
MessageHeader header;
char port;
uint8_t edge_type;
uint8_t debounce;
} __attribute__((__packed__)) SetEdgeCountConfig;

typedef struct {
MessageHeader header;
char port;
} __attribute__((__packed__)) GetEdgeCountConfig;

typedef struct {
MessageHeader header;
uint8_t edge_type;
uint8_t debounce;
} __attribute__((__packed__)) GetEdgeCountConfigReturn;

typedef struct {
MessageHeader header;
} __attribute__((__packed__)) StandardMessage;
Expand All @@ -192,6 +228,9 @@ void get_port_interrupt(const ComType com, const GetPortInterrupt *data);
void set_port_monoflop(const ComType com, const SetPortMonoflop *data);
void get_port_monoflop(const ComType com, const GetPortMonoflop *data);
void set_selected_values(const ComType com, const SetSelectedValues *data);
void get_edge_count(const ComType com, const GetEdgeCount *data);
void set_edge_count_config(const ComType com, const SetEdgeCountConfig *data);
void get_edge_count_config(const ComType com, const GetEdgeCountConfig *data);

void invocation(const ComType com, const uint8_t *data);
void constructor(void);
Expand Down

0 comments on commit 7a3e84f

Please sign in to comment.