tdc stuff again
This commit is contained in:
parent
9b703ef0a9
commit
bd2c9b8f68
@ -14,17 +14,18 @@ struct fifo {
|
|||||||
char buf[0];
|
char buf[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t fifo_put(struct fifo *fifo, const char *buf, uint32_t len);
|
uint32_t fifo_put(struct fifo *fifo, char *buf, uint32_t len);
|
||||||
uint32_t fifo_get(struct fifo *fifo, char *buf, uint32_t len);
|
uint32_t fifo_get(struct fifo *fifo, char *buf, uint32_t len);
|
||||||
|
|
||||||
|
uint32_t fifo_peek(struct fifo *fifo, char *buf, uint32_t len);
|
||||||
|
uint32_t fifo_remove(struct fifo *fifo, uint32_t len);
|
||||||
|
|
||||||
uint32_t fifo_rxpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize);
|
uint32_t fifo_rxpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize);
|
||||||
uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize);
|
uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize);
|
||||||
|
|
||||||
uint32_t fifo_putbyte(struct fifo *fifo, char c);
|
uint32_t fifo_putbyte(struct fifo *fifo, char c);
|
||||||
uint32_t fifo_getbyte(struct fifo *fifo, char *p);
|
uint32_t fifo_getbyte(struct fifo *fifo, char *p);
|
||||||
|
|
||||||
char * fifo_peek(struct fifo *fifo, uint32_t len);
|
|
||||||
|
|
||||||
struct fifo * fifo_alloc(uint32_t size);
|
struct fifo * fifo_alloc(uint32_t size);
|
||||||
|
|
||||||
#endif /*FIFO_H_*/
|
#endif /*FIFO_H_*/
|
||||||
|
@ -86,6 +86,24 @@ struct tdc_reqvalues_reply {
|
|||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct comm_device {
|
||||||
|
struct fifo *rxfifo;
|
||||||
|
struct fifo *txfifo;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tdc_register_device(uint32_t addr, struct comm_device *device);
|
||||||
|
|
||||||
|
int32_t tdc_transmit(uint32_t addr, struct tdc_pkt_header *head);
|
||||||
|
|
||||||
|
void tdc_receive(struct comm_device *device);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct tdc_value {
|
struct tdc_value {
|
||||||
void *data;
|
void *data;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -114,5 +132,4 @@ struct tdc_value {
|
|||||||
#define TDC_FLOAT(var, desc) TDC_VALUE(var, desc, float, TDC_FP)
|
#define TDC_FLOAT(var, desc) TDC_VALUE(var, desc, float, TDC_FP)
|
||||||
#define TDC_DOUBLE(var, desc) TDC_VALUE(var, desc, double, TDC_FP)
|
#define TDC_DOUBLE(var, desc) TDC_VALUE(var, desc, double, TDC_FP)
|
||||||
|
|
||||||
|
|
||||||
#endif /*TELEMETRIE_H_*/
|
#endif /*TELEMETRIE_H_*/
|
||||||
|
@ -76,14 +76,14 @@ void at91_dbgu_putc(char c)
|
|||||||
|
|
||||||
void at91_dbgu_puts(const char *p)
|
void at91_dbgu_puts(const char *p)
|
||||||
{
|
{
|
||||||
fifo_put(txfifo, p, strlen(p));
|
fifo_put(txfifo, (char *)p, strlen(p));
|
||||||
// *AT91C_DBGU_IER = AT91C_US_TXEMPTY;
|
// *AT91C_DBGU_IER = AT91C_US_TXEMPTY;
|
||||||
*AT91C_DBGU_IER = AT91C_US_TXBUFE;
|
*AT91C_DBGU_IER = AT91C_US_TXBUFE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int at91_dbgu_write(void *base, const char *buf, size_t len)
|
int at91_dbgu_write(void *base, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
int retval = fifo_put(txfifo, buf, len);
|
int retval = fifo_put(txfifo, (char *)buf, len);
|
||||||
// *AT91C_DBGU_IER = AT91C_US_TXEMPTY;
|
// *AT91C_DBGU_IER = AT91C_US_TXEMPTY;
|
||||||
*AT91C_DBGU_IER = AT91C_US_TXBUFE;
|
*AT91C_DBGU_IER = AT91C_US_TXBUFE;
|
||||||
return retval;
|
return retval;
|
||||||
|
30
src/fifo.c
30
src/fifo.c
@ -43,12 +43,11 @@ static uint32_t fifo_used(struct fifo *fifo)
|
|||||||
* append data to fifo
|
* append data to fifo
|
||||||
* returns number of bytes copied
|
* returns number of bytes copied
|
||||||
*/
|
*/
|
||||||
uint32_t fifo_put(struct fifo *fifo, const char *buf, uint32_t len)
|
uint32_t fifo_put(struct fifo *fifo, char *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
uint32_t left = fifo->size - fifo_used(fifo);
|
uint32_t left = fifo->size - fifo_used(fifo);
|
||||||
// TODO: check semantic
|
|
||||||
if (len > left)
|
if (len > left)
|
||||||
len = left;
|
return 0;
|
||||||
|
|
||||||
uint32_t count = len;
|
uint32_t count = len;
|
||||||
while (count--)
|
while (count--)
|
||||||
@ -75,16 +74,31 @@ uint32_t fifo_get(struct fifo *fifo, char *buf, uint32_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns a pointer to the data in the fifo
|
* get data from fifo, without changing the internal state
|
||||||
* (without changing internal state)
|
|
||||||
*/
|
*/
|
||||||
char * fifo_peek(struct fifo *fifo, uint32_t len)
|
uint32_t fifo_peek(struct fifo *fifo, char *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
uint32_t used = fifo_used(fifo);
|
uint32_t used = fifo_used(fifo);
|
||||||
if (len > used)
|
if (len > used)
|
||||||
return NULL;
|
len = used;
|
||||||
|
|
||||||
return fifo->buf + (fifo->out & FIFO_MASK(fifo));
|
uint32_t count = len;
|
||||||
|
uint32_t out = fifo->out;
|
||||||
|
while (count--)
|
||||||
|
*buf++ = fifo->buf[out++ & FIFO_MASK(fifo)];
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* removes data without reading it (eg. after a peek) */
|
||||||
|
uint32_t fifo_remove(struct fifo *fifo, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t used = fifo_used(fifo);
|
||||||
|
if (len > used)
|
||||||
|
len = used;
|
||||||
|
|
||||||
|
fifo->out += len;
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
251
src/telemetrie.c
251
src/telemetrie.c
@ -20,62 +20,40 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "board.h" // ARRAY_SIZE()
|
#include "board.h" // ARRAY_SIZE()
|
||||||
|
#include "at91_pitc.h"
|
||||||
#include "telemetrie.h"
|
#include "telemetrie.h"
|
||||||
#include "memalloc.h"
|
#include "memalloc.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
/* extern symbols, defined in ldscript */
|
/* extern symbols, defined in ldscript */
|
||||||
extern struct tdc_value _tdc_value_table;
|
extern struct tdc_value _tdc_value_table;
|
||||||
extern struct tdc_value _tdc_value_table_end;
|
extern struct tdc_value _tdc_value_table_end;
|
||||||
|
|
||||||
|
/* max. 8x 32 = 256 variables */
|
||||||
|
static uint32_t tdc_varmap[8];
|
||||||
|
|
||||||
|
static struct comm_device *routing_table[8];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* transmit function
|
|
||||||
* returns:
|
* returns:
|
||||||
* -1 : could not sent data (e.g. fifo full)
|
* -1: on routing error
|
||||||
* >= 0 : bytes sent
|
* 0: no space left in txfifo (caller should retry)
|
||||||
|
* >0: success
|
||||||
*/
|
*/
|
||||||
typedef uint32_t (txfunc_t)(struct tdc_pkt_header *head);
|
|
||||||
|
|
||||||
/* just eat the packet */
|
|
||||||
static uint32_t txdummy(struct tdc_pkt_header *head)
|
|
||||||
{
|
|
||||||
return head->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* table of txfuncs for routing/forwarding */
|
|
||||||
static txfunc_t *transmit_table[8] = {
|
|
||||||
&txdummy, &txdummy, &txdummy, &txdummy,
|
|
||||||
&txdummy, &txdummy, &txdummy, &txdummy,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct tdc_hello_reply hello_reply = {
|
|
||||||
.cmd = TDC_REPLY | TDC_ADDR1 | TDC_HELLO,
|
|
||||||
.size = sizeof(struct tdc_hello_reply),
|
|
||||||
.name = "sam7fc-v0.01",
|
|
||||||
};
|
|
||||||
|
|
||||||
void tdc_register_txfunc(uint32_t addr, txfunc_t *txfunc)
|
|
||||||
{
|
|
||||||
if (addr <= ARRAY_SIZE(transmit_table))
|
|
||||||
transmit_table[addr] = txfunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tdc_transmit(uint32_t addr, struct tdc_pkt_header *head)
|
int32_t tdc_transmit(uint32_t addr, struct tdc_pkt_header *head)
|
||||||
{
|
{
|
||||||
if (addr <= ARRAY_SIZE(transmit_table))
|
if (addr >= ARRAY_SIZE(routing_table) || !routing_table[addr])
|
||||||
return transmit_table[addr](head);
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
return fifo_put(routing_table[addr]->txfifo, (char *)head, head->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int32_t tdc_get_vars(void)
|
||||||
* send all variable names & flags
|
|
||||||
* returns:
|
|
||||||
* 0 - success (*id = 0)
|
|
||||||
* -1 - not all data was sent, restart request later (*id has restart-point)
|
|
||||||
*/
|
|
||||||
int32_t tdc_get_vars(uint32_t *id)
|
|
||||||
{
|
{
|
||||||
struct tdc_value *value = &_tdc_value_table + *id;
|
/* restart point */
|
||||||
|
static uint32_t id;
|
||||||
|
|
||||||
|
struct tdc_value *value = &_tdc_value_table + id;
|
||||||
|
|
||||||
while (value < &_tdc_value_table_end) {
|
while (value < &_tdc_value_table_end) {
|
||||||
uint32_t datalen = strlen(value->name);
|
uint32_t datalen = strlen(value->name);
|
||||||
@ -83,27 +61,32 @@ int32_t tdc_get_vars(uint32_t *id)
|
|||||||
struct tdc_getvars_reply *reply = alloc(sizeof(struct tdc_getvars_reply) + datalen);
|
struct tdc_getvars_reply *reply = alloc(sizeof(struct tdc_getvars_reply) + datalen);
|
||||||
reply->cmd = TDC_REPLY | TDC_ADDR1 | TDC_GETVARS;
|
reply->cmd = TDC_REPLY | TDC_ADDR1 | TDC_GETVARS;
|
||||||
reply->size = sizeof(struct tdc_getvars_reply) + datalen;
|
reply->size = sizeof(struct tdc_getvars_reply) + datalen;
|
||||||
reply->id = *id;
|
reply->id = id;
|
||||||
reply->flags = value->flags;
|
reply->flags = value->flags;
|
||||||
memcpy(reply->name, value->name, datalen);
|
memcpy(reply->name, value->name, datalen);
|
||||||
|
|
||||||
uint32_t txerror = (tdc_transmit(TDC_ADDR0, ((struct tdc_pkt_header *)reply)) != reply->size);
|
uint32_t ret = tdc_transmit(TDC_ADDR0, ((struct tdc_pkt_header *)reply));
|
||||||
free(reply);
|
free(reply);
|
||||||
|
|
||||||
/* transmit fifo is full, remember position (*id) and restart */
|
/* push routing error(-1) and retry(0) */
|
||||||
if (txerror)
|
if (ret <= 0)
|
||||||
return -1;
|
return ret;
|
||||||
|
|
||||||
(*id)++;
|
id++;
|
||||||
value++;
|
value++;
|
||||||
}
|
}
|
||||||
*id = 0;
|
|
||||||
return 0;
|
/* dump complete, reset restart point */
|
||||||
|
id = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tdc_get_value(uint32_t id)
|
static int32_t tdc_get_value(uint32_t id)
|
||||||
{
|
{
|
||||||
struct tdc_value *value = &_tdc_value_table + id;
|
struct tdc_value *value = &_tdc_value_table + id;
|
||||||
|
if (value >= &_tdc_value_table_end)
|
||||||
|
return -1;
|
||||||
|
|
||||||
uint32_t datalen = value->flags & TDC_SIZEMASK;
|
uint32_t datalen = value->flags & TDC_SIZEMASK;
|
||||||
|
|
||||||
struct tdc_getvalue_reply *reply = alloc(sizeof(struct tdc_getvalue_reply) + datalen);
|
struct tdc_getvalue_reply *reply = alloc(sizeof(struct tdc_getvalue_reply) + datalen);
|
||||||
@ -112,96 +95,160 @@ int32_t tdc_get_value(uint32_t id)
|
|||||||
reply->id = id;
|
reply->id = id;
|
||||||
memcpy(reply->data, value->data, datalen);
|
memcpy(reply->data, value->data, datalen);
|
||||||
|
|
||||||
int32_t txerror = (tdc_transmit(TDC_ADDR0, ((struct tdc_pkt_header *)reply)) != reply->size);
|
int32_t ret = tdc_transmit(TDC_ADDR0, ((struct tdc_pkt_header *)reply));
|
||||||
free(reply);
|
free(reply);
|
||||||
|
|
||||||
return (txerror) ? -1 : 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdc_set_value(uint32_t id, uint8_t *data)
|
static int32_t tdc_set_value(uint32_t id, uint8_t *data)
|
||||||
{
|
{
|
||||||
struct tdc_value *value = &_tdc_value_table + id;
|
struct tdc_value *value = &_tdc_value_table + id;
|
||||||
|
if (value >= &_tdc_value_table_end)
|
||||||
|
return -1;
|
||||||
|
|
||||||
uint32_t datalen = value->flags & TDC_SIZEMASK;
|
uint32_t datalen = value->flags & TDC_SIZEMASK;
|
||||||
|
|
||||||
// TODO: atomic?
|
// TODO: atomic?
|
||||||
memcpy(value->data, data, datalen);
|
memcpy(value->data, data, datalen);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static uint32_t tdc_timer_cb(struct pitc_timer *timer)
|
||||||
* parses tdc data
|
|
||||||
* returns:
|
|
||||||
* -1 : data too short / error
|
|
||||||
* >= 0 : data read, come back if there is more
|
|
||||||
*/
|
|
||||||
int32_t tdc_parse_pkt(txfunc_t *txfunc, const uint8_t *data, uint32_t size)
|
|
||||||
{
|
{
|
||||||
// TODO: use a fifo, with a peek function?
|
uint32_t i, j;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tdc_varmap); i++) {
|
||||||
|
uint32_t tmp = tdc_varmap[i];
|
||||||
|
|
||||||
struct tdc_pkt_header *head = (struct tdc_pkt_header *)data;
|
for (j = 0; j < 32; j++) {
|
||||||
|
if (!tmp)
|
||||||
|
break;
|
||||||
|
|
||||||
if (size < sizeof(struct tdc_pkt_header))
|
if (tmp & 0x01) {
|
||||||
return -1;
|
if (tdc_get_value(i * 32 + j) <= 0)
|
||||||
|
return PITC_REMOVE_TIMER;
|
||||||
/* if it's a hello-request, remember the txfunc as path to the host */
|
|
||||||
if ((head->cmd & (TDC_OPCODEMASK & TDC_DIR)) == TDC_HELLO)
|
|
||||||
tdc_register_txfunc(TDC_ADDR0, txfunc);
|
|
||||||
|
|
||||||
/* all replys go to the HOST */
|
|
||||||
if (head->cmd & TDC_REPLY) {
|
|
||||||
// TODO: wrong returncode
|
|
||||||
return tdc_transmit(TDC_ADDR0, head);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PITC_RESTART_TIMER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pitc_timer tdc_timer = {
|
||||||
|
.func = tdc_timer_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32_t tdc_setup_timer(uint32_t interval, uint32_t *varmap)
|
||||||
|
{
|
||||||
|
memcpy(tdc_varmap, varmap, sizeof(tdc_varmap));
|
||||||
|
|
||||||
|
if (interval > 0) {
|
||||||
|
tdc_timer.interval = interval;
|
||||||
|
// TODO: timer already running
|
||||||
|
pitc_schedule_timer(&tdc_timer);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// TODO: timer stop
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct tdc_hello_reply hello_reply = {
|
||||||
|
.cmd = TDC_REPLY | TDC_ADDR1 | TDC_HELLO,
|
||||||
|
.size = sizeof(struct tdc_hello_reply),
|
||||||
|
.name = "sam7fc-v0.01",
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns:
|
||||||
|
* -1: on routing error
|
||||||
|
* 0: no space left in txfifo (caller should retry)
|
||||||
|
* >0: success
|
||||||
|
*/
|
||||||
|
static int32_t tdc_parse_packet(struct tdc_pkt_header *head)
|
||||||
|
{
|
||||||
|
/* all replys go to the HOST */
|
||||||
|
if (head->cmd & TDC_REPLY)
|
||||||
|
return tdc_transmit(TDC_ADDR0, head);
|
||||||
|
|
||||||
/* forward this packet? */
|
/* forward this packet? */
|
||||||
if ((head->cmd & TDC_ADDRMASK) != TDC_ADDR1) {
|
if ((head->cmd & TDC_ADDRMASK) != TDC_ADDR1) {
|
||||||
uint32_t addr = (head->cmd & TDC_ADDRMASK) >> 4;
|
uint32_t addr = (head->cmd & TDC_ADDRMASK) >> 4;
|
||||||
// TODO: wrong returncode
|
|
||||||
return tdc_transmit(addr, head);
|
return tdc_transmit(addr, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t ret = -1;
|
||||||
|
|
||||||
/* parse the packet */
|
/* parse the packet */
|
||||||
switch (head->cmd & TDC_OPCODEMASK) {
|
switch (head->cmd & TDC_OPCODEMASK) {
|
||||||
/* HELLO from HOST */
|
|
||||||
case TDC_HELLO:
|
case TDC_HELLO:
|
||||||
tdc_transmit(TDC_ADDR0, (struct tdc_pkt_header *)&hello_reply);
|
/* answer the hello */
|
||||||
|
ret = tdc_transmit(TDC_ADDR0, (struct tdc_pkt_header *)&hello_reply);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TDC_GETVARS: {
|
case TDC_GETVARS:
|
||||||
static uint32_t i;
|
ret = tdc_get_vars();
|
||||||
|
break;
|
||||||
/* tx-fifo is full, complete request later */
|
|
||||||
if (tdc_get_vars(&i) == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TDC_GETVALUE: {
|
case TDC_GETVALUE: {
|
||||||
struct tdc_getvalue_request *pkt = (struct tdc_getvalue_request *)data;
|
struct tdc_getvalue_request *pkt = (struct tdc_getvalue_request *)head;
|
||||||
|
ret = tdc_get_value(pkt->id);
|
||||||
/* tx-fifo is full, retry request later */
|
|
||||||
if (tdc_get_value(pkt->id) == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TDC_SETVALUE: {
|
case TDC_SETVALUE: {
|
||||||
struct tdc_setvalue_request *pkt = (struct tdc_setvalue_request *)data;
|
struct tdc_setvalue_request *pkt = (struct tdc_setvalue_request *)head;
|
||||||
tdc_set_value(pkt->id, pkt->data);
|
ret = tdc_set_value(pkt->id, pkt->data);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TDC_REQVALUES: {
|
case TDC_REQVALUES: {
|
||||||
struct tdc_reqvalues_request *pkt = (struct tdc_reqvalues_request *)data;
|
struct tdc_reqvalues_request *pkt = (struct tdc_reqvalues_request *)head;
|
||||||
|
ret = tdc_setup_timer(pkt->interval, pkt->varmap);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case TDC_TERMINAL:
|
|
||||||
// TODO: not possible?
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TDC_USERDATA:
|
|
||||||
// TODO: currently not used
|
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return head->size;
|
/*
|
||||||
|
* on succes(>0) return size of request,
|
||||||
|
* and push retry(0) and routing error(-1) up
|
||||||
|
*/
|
||||||
|
return (ret > 0) ? head->size : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdc_register_device(uint32_t addr, struct comm_device *device)
|
||||||
|
{
|
||||||
|
if (addr < ARRAY_SIZE(routing_table))
|
||||||
|
routing_table[addr] = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdc_receive(struct comm_device *device)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
/* peek the header */
|
||||||
|
struct tdc_pkt_header tmp_head;
|
||||||
|
uint32_t len = fifo_peek(device->rxfifo, (char *)&tmp_head, sizeof(tmp_head));
|
||||||
|
if (len != sizeof(tmp_head))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* peek the whole packet */
|
||||||
|
struct tdc_pkt_header *head = alloc(tmp_head.size);
|
||||||
|
len = fifo_peek(device->rxfifo, (char *)head, tmp_head.size);
|
||||||
|
if (len != tmp_head.size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* if it's a hello-request, remember the device as path to the host */
|
||||||
|
if ((head->cmd & (TDC_OPCODEMASK & TDC_DIR)) == TDC_HELLO)
|
||||||
|
tdc_register_device(TDC_ADDR0, device);
|
||||||
|
|
||||||
|
/* parse packet, remove data if no restart is needed */
|
||||||
|
int32_t ret = tdc_parse_packet(head);
|
||||||
|
free(head);
|
||||||
|
|
||||||
|
/* some tx-fifo was full(0), return to caller and let it retry */
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* success(>0) or routing error(-1) -> remove the packet */
|
||||||
|
fifo_remove(device->rxfifo, tmp_head.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user