blob: 47d7b8e463838c01871635b8d518b09a5d295843 [file] [log] [blame]
adamdunkelscd499282003-07-30 22:40:36 +00001/*
2 * Copyright (c) 2001, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Adam Dunkels.
16 * 4. The name of the author may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * This file is part of the uIP TCP/IP stack.
33 *
adamdunkels7cde6092003-08-24 22:35:22 +000034 * $Id: rrnet-drv.c,v 1.5 2003/08/24 22:35:23 adamdunkels Exp $
adamdunkelscd499282003-07-30 22:40:36 +000035 *
36 */
37
adamdunkelscd499282003-07-30 22:40:36 +000038
39#include "uip.h"
40#include "uip_arp.h"
41#include "uip-signal.h"
42#include "loader.h"
43#include "cs8900a.h"
44
45#include "dispatcher.h"
46#include "ek.h"
47
48#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
49
50static u8_t i, arptimer;
51static u16_t start, current;
52
53static void rrnet_drv_idle(void);
54static DISPATCHER_SIGHANDLER(rrnet_drv_sighandler, s, data);
55static struct dispatcher_proc p =
56 {DISPATCHER_PROC("TCP/IP/RR-Net driver", rrnet_drv_idle,
57 rrnet_drv_sighandler, NULL)};
58static ek_id_t id;
59
adamdunkelscd499282003-07-30 22:40:36 +000060/*-----------------------------------------------------------------------------------*/
61static void
adamdunkels7cde6092003-08-24 22:35:22 +000062send(void)
63{
64 if(uip_len > 0) {
65 uip_arp_out();
66 cs8900a_send();
67 }
68}
69/*-----------------------------------------------------------------------------------*/
70static void
adamdunkelscd499282003-07-30 22:40:36 +000071timer(void)
72{
73 for(i = 0; i < UIP_CONNS; ++i) {
74 uip_periodic(i);
adamdunkels7cde6092003-08-24 22:35:22 +000075 send();
adamdunkelscd499282003-07-30 22:40:36 +000076 }
77
78 for(i = 0; i < UIP_UDP_CONNS; i++) {
79 uip_udp_periodic(i);
80 /* If the above function invocation resulted in data that
81 should be sent out on the network, the global variable
82 uip_len is set to a value > 0. */
adamdunkels7cde6092003-08-24 22:35:22 +000083 send();
adamdunkelscd499282003-07-30 22:40:36 +000084 }
85}
86/*-----------------------------------------------------------------------------------*/
87static void
88rrnet_drv_idle(void)
89{
90 /* Poll Ethernet device to see if there is a frame avaliable. */
91 uip_len = cs8900a_poll();
92 if(uip_len > 0) {
93 /* A frame was avaliable (and is now read into the uip_buf), so
94 we process it. */
adamdunkelse4f18322003-08-20 20:35:33 +000095 if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
adamdunkelscd499282003-07-30 22:40:36 +000096 uip_arp_ipin();
97 uip_len -= sizeof(struct uip_eth_hdr);
98 uip_input();
99 /* If the above function invocation resulted in data that
100 should be sent out on the network, the global variable
101 uip_len is set to a value > 0. */
adamdunkels7cde6092003-08-24 22:35:22 +0000102 send();
adamdunkelse4f18322003-08-20 20:35:33 +0000103 } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
adamdunkelscd499282003-07-30 22:40:36 +0000104 uip_arp_arpin();
105 /* If the above function invocation resulted in data that
106 should be sent out on the network, the global variable
107 uip_len is set to a value > 0. */
108 if(uip_len > 0) {
109 cs8900a_send();
110 }
111 }
112 }
113 /* Check the clock so see if we should call the periodic uIP
114 processing. */
115 current = ek_clock();
116
117 if((current - start) >= CLK_TCK/2) {
118 timer();
119 start = current;
120 }
121}
122/*-----------------------------------------------------------------------------------*/
adamdunkels7cde6092003-08-24 22:35:22 +0000123LOADER_INIT_FUNC(rrnet_drv_init, arg)
adamdunkelscd499282003-07-30 22:40:36 +0000124{
adamdunkels7cde6092003-08-24 22:35:22 +0000125 arg_free(arg);
126
adamdunkelscd499282003-07-30 22:40:36 +0000127 if(id == EK_ID_NONE) {
128 id = dispatcher_start(&p);
129
130 arptimer = 0;
131 start = ek_clock();
132
133 asm("lda #1");
134 asm("ora $de01");
135 asm("sta $de01");
136 cs8900a_init();
137
adamdunkelse4f18322003-08-20 20:35:33 +0000138 dispatcher_listen(uip_signal_poll);
139 dispatcher_listen(uip_signal_poll_udp);
adamdunkelsc1316ec2003-08-06 23:01:07 +0000140 dispatcher_listen(uip_signal_uninstall);
adamdunkelscd499282003-07-30 22:40:36 +0000141 }
142}
143/*-----------------------------------------------------------------------------------*/
144static
145DISPATCHER_SIGHANDLER(rrnet_drv_sighandler, s, data)
146{
147 DISPATCHER_SIGHANDLER_ARGS(s, data);
148
adamdunkelse4f18322003-08-20 20:35:33 +0000149 if(s == uip_signal_poll) {
150 uip_periodic_conn(data);
adamdunkels7cde6092003-08-24 22:35:22 +0000151 send();
adamdunkelse4f18322003-08-20 20:35:33 +0000152 } else if(s == uip_signal_poll_udp) {
153 uip_udp_periodic_conn(data);
adamdunkels7cde6092003-08-24 22:35:22 +0000154 send();
adamdunkelse4f18322003-08-20 20:35:33 +0000155 } else if(s == dispatcher_signal_quit ||
156 s == uip_signal_uninstall) {
adamdunkelscd499282003-07-30 22:40:36 +0000157 dispatcher_exit(&p);
158 id = EK_ID_NONE;
159 LOADER_UNLOAD();
160 }
161}
162/*-----------------------------------------------------------------------------------*/