?? cs8900a.c
字號:
PP_IA + 2, UIP_ETHADDR2 + (UIP_ETHADDR3 << 8),
PP_IA + 4, UIP_ETHADDR4 + (UIP_ETHADDR5 << 8),
PP_LineCTL, SERIAL_RX_ON | SERIAL_TX_ON, // configure the Physical Interface
PP_RxCTL, RX_OK_ACCEPT | RX_IA_ACCEPT | RX_BROADCAST_ACCEPT
};
// Writes a word in little-endian byte order to a specified port-address
void
cs8900a_write(unsigned addr, unsigned int data)
{
IODIR |= 0xff << 16; // Data port to output
IOCLR = 0xf << 4; // Put address on bus
IOSET = addr << 4;
IOCLR = 0xff << 16; // Write low order byte to data bus
IOSET = data << 16;
IOCLR = IOW; // Toggle IOW-signal
IOSET = IOW;
IOCLR = 0xf << 4;
IOSET = ((addr | 1) << 4); // And put next address on bus
IOCLR = 0xff << 16; // Write high order byte to data bus
IOSET = data >> 8 << 16;
IOCLR = IOW; // Toggle IOW-signal
IOSET = IOW;
}
// Reads a word in little-endian byte order from a specified port-address
unsigned
cs8900a_read(unsigned addr)
{
unsigned int value;
IODIR &= ~(0xff << 16); // Data port to input
IOCLR = 0xf << 4; // Put address on bus
IOSET = addr << 4;
IOCLR = IOR; // IOR-signal low
value = (IOPIN >> 16) & 0xff; // get low order byte from data bus
IOSET = IOR;
IOSET = 1 << 4; // IOR high and put next address on bus
IOCLR = IOR; // IOR-signal low
value |= ((IOPIN >> 8) & 0xff00); // get high order byte from data bus
IOSET = IOR; // IOR-signal low
return value;
}
// Reads a word in little-endian byte order from a specified port-address
unsigned
cs8900a_read_addr_high_first(unsigned addr)
{
unsigned int value;
IODIR &= ~(0xff << 16); // Data port to input
IOCLR = 0xf << 4; // Put address on bus
IOSET = (addr+1) << 4;
IOCLR = IOR; // IOR-signal low
value = ((IOPIN >> 8) & 0xff00); // get high order byte from data bus
IOSET = IOR; // IOR-signal high
IOCLR = 1 << 4; // Put low address on bus
IOCLR = IOR; // IOR-signal low
value |= (IOPIN >> 16) & 0xff; // get low order byte from data bus
IOSET = IOR;
return value;
}
void
cs8900a_init(void)
{
int i;
// Reset outputs, control lines high
IOSET = IOR | IOW;
// No LEDs on.
IOSET = LED_RED | LED_YELLOW | LED_GREEN;
// Port 3 as output (all pins but RS232)
IODIR = ~0U; // everything to output.
// Reset outputs
IOCLR = 0xff << 16; // clear data outputs
// Reset the CS8900A
cs8900a_write(ADD_PORT, PP_SelfCTL);
cs8900a_write(DATA_PORT, POWER_ON_RESET);
// Wait until chip-reset is done
cs8900a_write(ADD_PORT, PP_SelfST);
while ((cs8900a_read(DATA_PORT) & INIT_DONE) == 0)
;
// Configure the CS8900A
for (i = 0; i < sizeof InitSeq / sizeof (TInitSeq); ++i)
{
cs8900a_write(ADD_PORT, InitSeq[i].Addr);
cs8900a_write(DATA_PORT, InitSeq[i].Data);
}
}
void
cs8900a_send(void)
{
unsigned u;
IOCLR = LED_RED; // Light RED LED when frame starting
// Transmit command
cs8900a_write(TX_CMD_PORT, TX_START_ALL_BYTES);
cs8900a_write(TX_LEN_PORT, uip_len);
// Maximum number of retries
u = 8;
for (;;)
{
// Check for avaliable buffer space
cs8900a_write(ADD_PORT, PP_BusST);
if (cs8900a_read(DATA_PORT) & READY_FOR_TX_NOW)
break;
if (u -- == 0)
{
IOSET = LED_RED; // Extinguish RED LED on end of frame
return;
}
// No space avaliable, skip a received frame and try again
skip_frame();
}
IODIR |= 0xff << 16; // Data port to output
// Send 40+14=54 bytes of header
for (u = 0; u < 54; u += 2)
{
IOCLR = 0xf << 4; // Put address on bus
IOSET = TX_FRAME_PORT << 4;
IOCLR = 0xff << 16; // Write low order byte to data bus
IOSET = uip_buf[u] << 16; // write low order byte to data bus
IOCLR = IOW; // Toggle IOW-signal
IOSET = IOW;
IOCLR = 0xf << 4; // Put address on bus
IOSET = (TX_FRAME_PORT | 1) << 4; // and put next address on bus
IOCLR = 0xff << 16; // Write low order byte to data bus
IOSET = uip_buf[u+1] << 16; // write low order byte to data bus
IOCLR = IOW; // Toggle IOW-signal
IOSET = IOW;
}
if (uip_len <= 54)
{
IOSET = LED_RED; // Extinguish RED LED on end of frame
return;
}
// Send remainder of packet, the application data
uip_len -= 54;
for (u = 0; u < uip_len; u += 2)
{
IOCLR = 0xf << 4; // Put address on bus
IOSET = TX_FRAME_PORT << 4;
IOCLR = 0xff << 16; // Write low order byte to data bus
IOSET = uip_appdata[u] << 16; // write low order byte to data bus
IOCLR = IOW; // Toggle IOW-signal
IOSET = IOW;
IOCLR = 0xf << 4; // Put address on bus
IOSET = (TX_FRAME_PORT | 1) << 4; // and put next address on bus
IOCLR = 0xff << 16; // Write low order byte to data bus
IOSET = uip_appdata[u+1] << 16; // write low order byte to data bus
IOCLR = IOW; // Toggle IOW-signal
IOSET = IOW;
}
IOSET = LED_RED; // Extinguish RED LED on end of frame
}
static void
skip_frame(void)
{
// No space avaliable, skip a received frame and try again
cs8900a_write(ADD_PORT, PP_RxCFG);
cs8900a_write(DATA_PORT, cs8900a_read(DATA_PORT) | SKIP_1);
}
u8_t
cs8900a_poll(void)
{
u16_t len, u;
// Check receiver event register to see if there are any valid frames avaliable
cs8900a_write(ADD_PORT, PP_RxEvent);
if ((cs8900a_read(DATA_PORT) & 0xd00) == 0)
return 0;
IOCLR = LED_GREEN; // Light GREED LED when frame coming in.
// Read receiver status and discard it.
cs8900a_read_addr_high_first(RX_FRAME_PORT);
// Read frame length
len = cs8900a_read_addr_high_first(RX_FRAME_PORT);
// If the frame is too big to handle, throw it away
if (len > UIP_BUFSIZE)
{
skip_frame();
return 0;
}
// Data port to input
IODIR &= ~(0xff << 16);
IOCLR = 0xf << 4; // put address on bus
IOSET = RX_FRAME_PORT << 4;
// Read bytes into uip_buf
u = 0;
while (u < len)
{
IOCLR = 1 << 4; // put address on bus
IOCLR = IOR; // IOR-signal low
uip_buf[u] = IOPIN >> 16; // get high order byte from data bus
IOSET = IOR; // IOR-signal high
IOSET = 1 << 4; // put address on bus
IOCLR = IOR; // IOR-signal low
uip_buf[u+1] = IOPIN >> 16; // get high order byte from data bus
IOSET = IOR; // IOR-signal high
u += 2;
}
IOSET = LED_GREEN; // Extinguish GREED LED when frame finished.
return len;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -