|
From: | Konrad, Guido |
Subject: | Re: [lwip-users] Odd byte packets in LWIP |
Date: | Tue, 11 Nov 2003 14:19:42 +0100 |
I also
faced this problem with the c6900.c driver code from Leon. Our HW
interface
allows
only 16 bit writes. I implemented a quick and dirty
solution which makes copies
if
there is an odd number of characters in one buffer. (lwip 0.5.3).
Attached you will
find
my output function. Perhaps it is in some kind usefull even if it
kills performance.
If there is a better solution please let
me know.
--
Guido
static
err_t cs8900_output(struct cs8900if *cs8900if, struct pbuf
*p)
{ struct pbuf *q; u32_t i; u16_t *ptr, val; u8_t *ptr8, buf[TCP_MSS]; u32_t len; int tries = 0, valHasValue = 0; INT8U ucErr; OSMutexPend( pDeviceMut, 0, &ucErr ); // exit if link has failed PACKETPP = CS_PP_LINESTATUS; if ((PPDATA & 0x0080U/*LinkOK*/) == 0) { (void)OSMutexPost( pDeviceMut ); return ERR_MEM; // TODO: find a correct error code } /* transmit command */ TXCMD = 0x00C9U; TXLENGTH = p->tot_len; PACKETPP = CS_PP_BUSSTATUS; // not ready for transmission and still within 100 retries? while(((PPDATA & 0x0100U/*Rdy4TxNOW*/) == 0) && (tries++ < 100)) { // throw away the last committed received frame PACKETPP = CS_PP_RXCFG; PPDATA = (0x0003U | 0x0040U/*Skip_1*/ | 0x0100U/*RxOKiE*/); PACKETPP = CS_PP_BUSSTATUS; /* cs8900if->dropped++; CHECK: we do not know if we actually will drop a frame here */ } // ready to transmit? if((PPDATA & 0x0100U/*Rdy4TxNOW*/) != 0) { for(q = p; q != NULL; q = q->next) { DEBUGF(ETH_DEBUG, ("cs8900_output: pbuf @%p len %d\n", q, q->len)); /* Send the data from the pbuf to the interface, one pbuf at a time. The size of the data in each pbuf is kept in the ->len variable. */ /* Check alignement */ if( (((int)q->payload) & 0x01 ) == 0x01 ) { DEBUGF(ETH_DEBUG, ("cs8900_output: buffer not aligned\n")); } if( !q->len ) continue; if( valHasValue ) { ptr8 = (u8_t *)q->payload; val |= (*ptr8)<<8; len = --(q->len); for( i = 1; i <= len; i++ ) { buf[i-1] = ptr8[i]; } ptr = (u16_t *)buf; len &= (u32_t)0xFFFFFFFE; valHasValue = 2; /* Transmit value */ RXTXREG = val; } else { ptr = (u16_t *)q->payload; len = q->len; len &= (u32_t)0xFFFFFFFE; } for(i = 0; i < len; i += 2) { RXTXREG = *ptr++; } if( len != q->len ) { val = (u16_t)(*(u8_t*)ptr); if( valHasValue == 2 ) { ++(q->len); } valHasValue = 1; } else { if( valHasValue == 2 ) { ++(q->len); valHasValue = 0; } } } if( valHasValue ) { RXTXREG = val; } } else { DEBUGF(ETH_DEBUG, ("cs8900_output: device not ready to send pbuf @%p len %d\n", q, q->len)); } (void)OSMutexPost( pDeviceMut ); return ERR_OK; }
|
[Prev in Thread] | Current Thread | [Next in Thread] |