1 #include "avr-handler.h"
11 #define DEBUG(...) printf(__VA_ARGS__)
16 PROCESS(avr_process,
"AVR Process");
21 #define AVR_EVENT_GET_DATA 1
26 #define AVR_EVENT_GOT_DATA 2
31 #define AVR_TIMEOUT 10
42 #define AVR_OPCODE_ECHO 0x00
43 #define AVR_OPCODE_LIST 0x01
44 #define AVR_OPCODE_GET_DATA 0x02
45 #define AVR_OPCODE_SET_GAIN 0x03
46 #define AVR_OPCODE_RESPONSE 0xFF
47 #define AVR_MASTER_ADDR 0x00
52 static uint8_t incm_dest;
57 static uint8_t incm_type;
64 static uint16_t incm_num;
69 static uint8_t incm_crc[2];
79 static volatile bool isReceiving;
86 static void (*serial_write)(uint8_t *buf,
int len);
93 static void (*callback)(
bool isSuccess);
105 static uint16_t crc16(uint16_t crc, uint8_t a);
114 static uint16_t crc16_all(uint16_t crc, uint8_t *buf, uint8_t
len);
125 static bool check_message(uint8_t
addr, uint8_t opcode, uint8_t *payload, uint8_t payload_length, uint8_t crc[2]);
135 static bool send_message(uint8_t
addr, uint8_t opcode, uint8_t *payload, uint8_t payload_length);
137 int avr_input_byte(uint8_t byte) {
141 DEBUG(
"Not receiving! Discarding data\n");
146 if (*incm_data->
len >= incm_data->
size) {
147 DEBUG(
"Incm Buffer full, len %d size %d! Discarding data\n", *incm_data->
len, incm_data->
size);
177 incm_data->
data[(*incm_data->
len)++] = incm_crc[0];
178 incm_crc[0] = incm_crc[1];
184 if (check_message(incm_dest, incm_type, incm_data->
data, *incm_data->
len, incm_crc)) {
192 static struct etimer avr_timeout_timer;
193 static uint8_t attempt;
194 static uint8_t num_required;
195 static uint8_t success_num;
202 DEBUG(
"Got event %d\n", ev);
204 if (ev == AVR_EVENT_GET_DATA) {
206 incm_data = data_ptr;
212 if (incm_data->
id < 0x10) {
216 for (attempt = 0; attempt < AVR_RETRY * num_required; attempt++) {
218 DEBUG(
"Getting data from avr %x, attempt %d, success_num %d\n", incm_data->
id, attempt, success_num);
229 send_message(incm_data->
id, AVR_OPCODE_GET_DATA,
NULL, (
int)
NULL);
237 success_num += (ev == AVR_EVENT_GOT_DATA);
239 DEBUG(
"Received %d bytes. Success_num %d ADDR %u TYPE %u CRC %u: ", incm_num, success_num, incm_dest, incm_type, *((uint16_t *) incm_crc));
242 for (i = 0; i < *incm_data->
len; i++) {
243 printf(
"%02x,", incm_data->
data[i]);
249 if (success_num >= num_required) {
254 DEBUG(
"Done after %d retries\n", attempt);
256 callback(success_num >= num_required);
263 uint16_t crc16(uint16_t crc, uint8_t a) {
269 for (i = 0; i < 8; ++i) {
271 crc = (crc >> 1) ^ 0xA001;
281 uint16_t crc16_all(uint16_t crc, uint8_t *buf, uint8_t len) {
283 for (i = 0; i < len; i++) {
284 crc = crc16(crc, buf[i]);
289 bool send_message(uint8_t
addr, uint8_t opcode, uint8_t *payload, uint8_t payload_length) {
294 if (serial_write ==
NULL) {
295 DEBUG(
"No writebyte specified\n");
300 uint16_t crc = crc16(0xFFFF, addr);
301 crc = crc16(crc, opcode);
304 crc = crc16_all(crc, payload, payload_length);
306 DEBUG(
"CRC is %u High: %x Low: %x High2: %x Low2: %x\n", crc, (crc >> 8) & 0xFF, crc & 0xFF, *(((uint8_t *) &crc) + 1), *((uint8_t *) &crc));
308 serial_write(&addr, 1);
309 serial_write(&opcode, 1);
310 serial_write(payload, payload_length);
314 serial_write(((uint8_t *) &crc), 2);
319 bool check_message(uint8_t addr, uint8_t opcode, uint8_t *payload, uint8_t payload_length, uint8_t crc[2]) {
320 if (addr != AVR_MASTER_ADDR) {
325 if (opcode != AVR_OPCODE_RESPONSE) {
331 uint16_t rcv_crc = *((uint16_t *) crc);
334 uint16_t cal_crc = crc16(0xFFFF, addr);
335 cal_crc = crc16(cal_crc, opcode);
336 cal_crc = crc16_all(cal_crc, payload, payload_length);
340 if (rcv_crc != cal_crc) {
350 void avr_set_callback(
void (*cb)(
bool isSuccess)) {
354 bool avr_get_data(
struct avr_data *data) {
356 if (callback ==
NULL) {
357 DEBUG(
"Callback not set!\n");
363 DEBUG(
"Already receiving!\n");
367 DEBUG(
"Sending event for avr %x, size %d\n", data->
id, data->
size);
372 void avr_set_output(
void (*wb)(uint8_t *buf,
int len)) {
uint8_t id
The ID of the AVR to sample from.
static uip_ds6_addr_t * addr
Pointer to a router list entry.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
uint8_t * len
The length of data.
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
void etimer_stop(struct etimer *et)
Stop a pending event timer.
#define NULL
The null pointer.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
#define PROCESS_ERR_OK
Return value indicating that an operation was successful.
#define CLOCK_SECOND
A second, measured in system clock time.
uint8_t size
The size of data.
A struct used to request data from an AVR.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define PROCESS_BEGIN()
Define the beginning of a process.