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:
mb 2009-02-21 19:37:52 +00:00
parent 0d2ac176e0
commit ceec7e5bec
3 changed files with 60 additions and 23 deletions

View File

@ -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>

View File

@ -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"

View File

@ -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)