ucmb: Update AVR sample implementation and update license headers.
git-svn-id: svn://svn.openwrt.org/openwrt/packages@14604 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
0d2ac176e0
commit
ceec7e5bec
@ -1,10 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Microcontroller Message Bus
|
* Microcontroller Message Bus
|
||||||
* Userspace commandline utility
|
* Userspace commandline utility
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
|
* Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
|
||||||
*
|
*
|
||||||
* Licensed under the GNU/GPL. See COPYING for details.
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Microcontroller Message Bus
|
* Microcontroller Message Bus
|
||||||
|
* Linux kernel driver
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
|
* Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
|
||||||
*
|
*
|
||||||
* Licensed under the GNU/GPL. See COPYING for details.
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ucmb.h"
|
#include "ucmb.h"
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
struct ucmb_message_hdr {
|
struct ucmb_message_hdr {
|
||||||
uint16_t magic; /* UCMB_MAGIC */
|
uint16_t magic; /* UCMB_MAGIC */
|
||||||
uint16_t len; /* Payload length (excluding header) */
|
uint16_t len; /* Payload length (excluding header and footer) */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ucmb_message_footer {
|
struct ucmb_message_footer {
|
||||||
@ -62,9 +62,10 @@ static uint16_t ucmb_send_message_len;
|
|||||||
/* Statemachine */
|
/* Statemachine */
|
||||||
static uint8_t ucmb_state;
|
static uint8_t ucmb_state;
|
||||||
enum {
|
enum {
|
||||||
UCMB_ST_LISTEN,
|
UCMB_ST_LISTEN, /* Listen for incoming messages. */
|
||||||
UCMB_ST_SENDSTATUS,
|
UCMB_ST_SENDSTATUS, /* Send the status report. */
|
||||||
UCMB_ST_SENDMESSAGE,
|
UCMB_ST_SENDMESSAGE, /* Send the message. */
|
||||||
|
UCMB_ST_RETRSTATUS, /* Retrieve the status report. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TRAILING 1
|
#define TRAILING 1
|
||||||
@ -100,7 +101,7 @@ static void ucmb_send_next_byte(void)
|
|||||||
if (ucmb_buf_ptr == full_length + TRAILING) {
|
if (ucmb_buf_ptr == full_length + TRAILING) {
|
||||||
ucmb_send_message_len = 0;
|
ucmb_send_message_len = 0;
|
||||||
ucmb_buf_ptr = 0;
|
ucmb_buf_ptr = 0;
|
||||||
ucmb_state = UCMB_ST_LISTEN;//FIXME retr status
|
ucmb_state = UCMB_ST_RETRSTATUS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} }
|
} }
|
||||||
@ -138,13 +139,16 @@ ISR(SPI_STC_vect)
|
|||||||
uint8_t data;
|
uint8_t data;
|
||||||
|
|
||||||
data = SPDR;
|
data = SPDR;
|
||||||
|
SPDR = 0;
|
||||||
|
|
||||||
switch (ucmb_state) {
|
switch (ucmb_state) {
|
||||||
case UCMB_ST_LISTEN: {
|
case UCMB_ST_LISTEN: {
|
||||||
struct ucmb_message_hdr *hdr;
|
struct ucmb_message_hdr *hdr;
|
||||||
struct ucmb_message_footer *footer;
|
struct ucmb_message_footer *footer;
|
||||||
|
|
||||||
ucmb_buf[ucmb_buf_ptr++] = data;
|
if (ucmb_buf_ptr < sizeof(ucmb_buf))
|
||||||
|
ucmb_buf[ucmb_buf_ptr] = data;
|
||||||
|
ucmb_buf_ptr++;
|
||||||
if (ucmb_buf_ptr < sizeof(struct ucmb_message_hdr))
|
if (ucmb_buf_ptr < sizeof(struct ucmb_message_hdr))
|
||||||
return; /* Header RX not complete. */
|
return; /* Header RX not complete. */
|
||||||
hdr = (struct ucmb_message_hdr *)ucmb_buf;
|
hdr = (struct ucmb_message_hdr *)ucmb_buf;
|
||||||
@ -154,10 +158,8 @@ ISR(SPI_STC_vect)
|
|||||||
ucmb_buf_ptr = 0;
|
ucmb_buf_ptr = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (hdr->len > UCMB_MAX_MSG_LEN) {
|
if (hdr->len > 0x8000) {
|
||||||
/* Invalid length. */
|
/* Completely bogus length! Reset. */
|
||||||
//FIXME don't interrupt, but poll len bytes and
|
|
||||||
// send an immediate failure report
|
|
||||||
ucmb_buf_ptr = 0;
|
ucmb_buf_ptr = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -167,17 +169,25 @@ ISR(SPI_STC_vect)
|
|||||||
if (ucmb_buf_ptr == sizeof(struct ucmb_message_hdr) +
|
if (ucmb_buf_ptr == sizeof(struct ucmb_message_hdr) +
|
||||||
sizeof(struct ucmb_message_footer) +
|
sizeof(struct ucmb_message_footer) +
|
||||||
hdr->len) {
|
hdr->len) {
|
||||||
footer = (struct ucmb_message_footer *)(
|
|
||||||
ucmb_buf + sizeof(struct ucmb_message_hdr) +
|
|
||||||
hdr->len);
|
|
||||||
status_buf.magic = UCMB_MAGIC;
|
status_buf.magic = UCMB_MAGIC;
|
||||||
status_buf.code = UCMB_STAT_OK;
|
status_buf.code = UCMB_STAT_OK;
|
||||||
if (ucmb_calc_msg_buffer_crc() != footer->crc)
|
if (ucmb_buf_ptr > sizeof(ucmb_buf)) {
|
||||||
status_buf.code = UCMB_STAT_ECRC;
|
/* Message is way too big and was truncated. */
|
||||||
|
status_buf.code = UCMB_STAT_E2BIG;
|
||||||
|
} else {
|
||||||
|
footer = (struct ucmb_message_footer *)(
|
||||||
|
ucmb_buf + sizeof(struct ucmb_message_hdr) +
|
||||||
|
hdr->len);
|
||||||
|
if (ucmb_calc_msg_buffer_crc() != footer->crc)
|
||||||
|
status_buf.code = UCMB_STAT_ECRC;
|
||||||
|
}
|
||||||
ucmb_state = UCMB_ST_SENDSTATUS;
|
ucmb_state = UCMB_ST_SENDSTATUS;
|
||||||
ucmb_buf_ptr = 0;
|
ucmb_buf_ptr = 0;
|
||||||
ucmb_send_next_byte();
|
ucmb_send_next_byte();
|
||||||
|
|
||||||
|
if (status_buf.code != UCMB_STAT_OK)
|
||||||
|
return; /* Corrupt message. Don't pass it to user code. */
|
||||||
|
|
||||||
ucmb_send_message_len = ucmb_rx_message(
|
ucmb_send_message_len = ucmb_rx_message(
|
||||||
ucmb_buf + sizeof(struct ucmb_message_hdr),
|
ucmb_buf + sizeof(struct ucmb_message_hdr),
|
||||||
hdr->len);
|
hdr->len);
|
||||||
@ -197,7 +207,17 @@ ISR(SPI_STC_vect)
|
|||||||
case UCMB_ST_SENDMESSAGE:
|
case UCMB_ST_SENDMESSAGE:
|
||||||
ucmb_send_next_byte();
|
ucmb_send_next_byte();
|
||||||
break;
|
break;
|
||||||
}
|
case UCMB_ST_RETRSTATUS: {
|
||||||
|
uint8_t *st = (uint8_t *)&status_buf;
|
||||||
|
|
||||||
|
st[ucmb_buf_ptr++] = data;
|
||||||
|
if (ucmb_buf_ptr == sizeof(struct ucmb_status)) {
|
||||||
|
/* We could possibly handle the status report here... */
|
||||||
|
ucmb_buf_ptr = 0;
|
||||||
|
ucmb_state = UCMB_ST_LISTEN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ucmb_init(void)
|
void ucmb_init(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user