|
Предлагаю считывать в обратном порядке, т.е. младший, а затем - старший байты слова:
Если я правильно воспользуюсь тегами, то ниже - мой работающий исходник для at89s8252
/*
driver for CS8900A
pin
*/#include
#include
#include
#include
#include/* This is the address table for CS8900 I/O regesters.
* They all have 0xF000 offset because of circuit diagram
* (74HC139 used as address decoder)
*/#define RxTxData 0xF000 // Receive/Transmit data (port 0)
#define RxTxDatap1 0xF001 // Receive/Transmit data (port 0)
#define RxTxData1 0xF002 // Receive/Transmit data (port 1)
#define TxCmd 0xF004 // Transmit Command
#define TxLength 0xF006 // Transmit Length
#define ISQ 0xF008 // Interrupt status queue
#define PPPtr 0xF00a // PacketPage pointer
#define PPPtrp1 0xF00b // PacketPage pointer
#define PPData 0xF00c // PacketPage data (port 0)
#define PPDatap1 0xF00d // PacketPage data (port 0)
#define PPData1 0xF00e // PacketPage data (port 1)
/* Macro to access external data memory area, where CS8900A is connected */
#define CS(i) (*((volatile UINT8 xdata *)(i)))/* Structures moved here from ethernet.c, defined in ethernet.h */
struct ethernet_frame received_frame;
struct ethernet_frame send_frame;/* Buffers to store input and output packets */
UINT8 RxBuf1[ETH_MTU];
UINT8 TxBuf1[ETH_MTU];/* Pointers to these buffers */
UINT8 * RxPtr;
UINT8 * TxPtr;/* The length of received frame */
UINT16 RxLength;data UINT8 bid_cntr = 0;
#define BID_CNT_LIMIT 5
/*
* Init CS8900A chip before use it: reset and set config. REGs
*/
void CSInit (UINT8* mac)
{
/* UINT8 chip_id[4]; */
/* HW Reset of the CS8900, _|--|_____ */
P1_3 = 1;
wait(0xFFFF);
P1_3 = 0;
wait(0xFFFF);CS(PPPtr) = 0x58;
CS(PPPtrp1) = 0x01;CS(PPData) = *(mac+5); /* Set MAC Address */
CS(PPDatap1) = *(mac+4);CS(PPPtr) = 0x5A;
CS(PPPtrp1) = 0x01;CS(PPData) = *(mac+3); /* Set MAC Address */
CS(PPDatap1) = *(mac+2);CS(PPPtr) = 0x5C;
CS(PPPtrp1) = 0x01;CS(PPData) = *(mac+1); /* Set MAC Address */
CS(PPDatap1) = *(mac);// Configure RxCTL
CS(PPPtr) = 0x04;
CS(PPPtrp1) = 0x01;
CS(PPData) = 0x00;
CS(PPDatap1) = 0x0D;// Set 10BaseT, SerRxOn, SerTxOn in LineCTL
CS(PPPtr) = 0x12;
CS(PPPtrp1) = 0x01;
CS(PPData) = 0xc0;
CS(PPDatap1) = 0x00;/* Next code lines are useful, when MONITOR is supported or DEBUG messages are enabled.
* Read the CS8900 chip ID, that should be like 0x0E63xxxx. If wrong ID received,
* check target hardware ;)
*/
/* CS(PPPtr)=0x00;
CS(PPPtrp1)=0x00;chip_id[0]=CS(PPData);
chip_id[1]=CS(PPDatap1);CS(PPPtr)=0x02;
CS(PPPtrp1)=0x00;chip_id[2]=CS(PPData);
chip_id[3]=CS(PPDatap1);*/
ETH_DEBUGOUT("Ethernet chip initialized\r\n");
}
UINT8 CSReceiveFrame (void)
{
UINT8 temp, tmp1,lenh, lenl;
UINT16 i;CS(PPPtr) = 0x24;
CS(PPPtrp1) = 0x01;
temp = CS(PPDatap1);
tmp1 = CS(PPData); //dummy readif (temp == FALSE) /* Do we have a new frame? */
return(FALSE); /* no */RxPtr = &RxBuf1[0];
temp=CS(RxTxDatap1);
temp=CS(RxTxData);
lenh=CS(RxTxDatap1);
lenl=CS(RxTxData);
RxLength=(UINT16)((lenh<<8)+lenl);
for (i=0;i<(RxLength>>1);i++)
{
*RxPtr++=CS(RxTxData);
*RxPtr++=CS(RxTxDatap1);
}
if((RxLength&0x0001)==1)
{
*RxPtr++=CS(RxTxData);
}
RxPtr = &RxBuf1[0];
/* Record Frame Size */
received_frame.frame_size = lenl;
received_frame.frame_size |= ((UINT16)lenh) << 8;
/* Remove chip specific bytes here, if they are existing */
/* Record destination Ethernet Address */
received_frame.destination[5] = *RxPtr++;
received_frame.destination[4] = *RxPtr++;
received_frame.destination[3] = *RxPtr++;
received_frame.destination[2] = *RxPtr++;
received_frame.destination[1] = *RxPtr++;
received_frame.destination[0] = *RxPtr++;
/* Record senders Ethernet address */
received_frame.source[5] = *RxPtr++;
received_frame.source[4] = *RxPtr++;
received_frame.source[3] = *RxPtr++;
received_frame.source[2] = *RxPtr++;
received_frame.source[1] = *RxPtr++;
received_frame.source[0] = *RxPtr++;
/* Record Protocol */
received_frame.protocol = *RxPtr++;
received_frame.protocol <<= 8;
received_frame.protocol |= *RxPtr++;
/* Give the next layer data start buffer index from the start */
received_frame.buf_index = ETH_HEADER_LEN;
ETH_DEBUGOUT("Ethernet Frame Received\r\n");
return(TRUE); /* Indicate we got packet */
}
void CSSendFrame (UINT16 len) //NETWORK_COMPLETE_SEND()
{
UINT8 BusST;
UINT16 i = 0;
TxPtr = &TxBuf1[0];
bid_cntr = 0;
do
{
if (bid_cntr)
{
bid_cntr = 0;
CS(TxCmd)= 0xc0;
CS(TxCmd + 1) = 0x01; //force
}
else
{
CS(TxCmd)= 0xc0;
CS(TxCmd + 1) = 0x00;
}
CS(TxLength) = (UINT8) (len & 0x00FF);
CS(TxLength + 1) = (UINT8) (len >> 8);CS(PPPtr) = 0x38;
CS(PPPtr + 1) = 0x01;
do
{
bid_cntr++;
BusST = CS(PPData);
BusST = CS(PPDatap1);
BusST &= 0x01;
} while (!BusST & (bid_cntr < BID_CNT_LIMIT));
} while(!BusST);while (i<(len>>1))
{
CS(RxTxData) = *(TxPtr++);
CS(RxTxDatap1) = *(TxPtr++);
i++;
}
if((len&0x0001)==1)
{
CS(RxTxData) = *(TxPtr);
}
ETH_DEBUGOUT("Ethernet Frame Sent\r\n");
}
/* Invoke this function (through NETWORK_RECEIVE_INITIALIZE() macro)
* to prepare NIC for reading from the specified position. */void CSInitRx_position (UINT16 pos)
{
RxPtr = &RxBuf1[0] + pos;
/* Now just read by inBUF() */
}/* Invoke this function (through NETWORK_SEND_INITIALIZE() macro)
* to prepare NIC for reading from the specified position. */void CSInitTx_position (UINT16 pos)
{
TxPtr = &TxBuf1[0] + pos;
/* Now just write by outBUF() */
}void CSDumpRxFrame (void)
{
;
}void outBUF (UINT8 dat)
{
*TxPtr++ = dat;
}
UINT8 inBUF (void)
{
return(*RxPtr++);
}
void CSWriteEthernetHeader (struct ethernet_frame* frame)
{
INT8 i;
/* Write destination Ethernet Address */
TxPtr = &TxBuf1[0];
for(i=ETH_ADDRESS_LEN-1; i >= 0; i--) {
*TxPtr++ = frame->destination[i];
}/* Write sender (our) Ethernet address */
for(i=ETH_ADDRESS_LEN-1; i >= 0; i--) {
*TxPtr++ = frame->source[i];
}
/* Write protocol */
*TxPtr++ = (UINT8)(frame->protocol >> 8);
*TxPtr++ = (UINT8)frame->protocol;
}
void outCS8900againbuf (UINT8* buf, UINT16 len)
{
while(len--)
{
*TxPtr++ = *buf++;
}
}
void inCS8900againbuf (UINT8* buf, UINT16 len)
{
while(len--)
{
*buf++ = *RxPtr++;
}
}
E-mail: info@telesys.ru