BOOTLOADER
Main Page
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
bootloader
external drivers
cs8900.c
Go to the documentation of this file.
1
//==========
2
// Project name: MyArm920t
3
// Author: Book Chen
4
// Start time: 2007.06.04
5
// Function: Driver of ethernet controller CS8900
6
//==========
7
#include "
includes.h
"
8
9
#define Cs8900IdleState 0
10
#define Cs8900InitialState0 1
11
#define Cs8900InitialState1 2
12
#define Cs8900InitialState2 3
13
#define Cs8900InitialState3 4
14
#define Cs8900InitialState4 5
15
16
#define MAX_COUNT 0x00100000
17
18
CS8900_CONTROL
Cs8900Ctrl
;
19
20
#define F_Cs8900IoRead(Offset) ((INT16U)*((volatile INT16U*)(Cs8900Ctrl.IoBase+(Offset))))
21
#define F_Cs8900IoWrite(Offset,Data) *((volatile INT16U*)(Cs8900Ctrl.IoBase+(Offset)))=(INT16U)(Data)
22
#define F_Cs8900MemryRead(Offset) ((INT16U)*((volatile INT16U*)(Cs8900Ctrl.MemBase+(Offset))))
23
#define F_Cs8900MemoryWrite(Offset,Data) *((volatile INT16U*)(Cs8900Ctrl.MemBase+(Offset)))=(INT16U)(Data)
24
#define CS8900_MEMORY_MODE 0
25
#if(CS8900_MEMORY_MODE==1)
26
#define F_Cs8900RegisterRead1 F_Cs8900RegisterRead
27
#define F_Cs8900RegisterRead2 F_Cs8900MemryRead
28
#define F_Cs8900RegisterWrite1 F_Cs8900RegisterWrite
29
#define F_Cs8900RegisterWrite2 F_Cs8900MemoryWrite
30
#else
31
#define F_Cs8900RegisterRead1 F_Cs8900RegisterRead
32
#define F_Cs8900RegisterRead2 F_Cs8900RegisterRead
33
#define F_Cs8900RegisterWrite1 F_Cs8900RegisterWrite
34
#define F_Cs8900RegisterWrite2 F_Cs8900RegisterWrite
35
#endif
36
void
F_Cs8900Init
(
void
);
37
void
F_Cs8900Svc
(
void
);
38
INT8U
F_Cs8900InUseCheck
(
void
);
39
INT8U
F_Cs8900Allocate
(
INT16U
UserId);
40
INT8U
F_Cs8900Release
(
INT16U
UserId);
41
INT8U
F_Cs8900InitialStart
(
INT16U
UserId);
42
INT8U
F_Cs8900MacAddressSet
(
INT16U
UserId,
INT8U
*pMacAddress);
43
INT8U
F_Cs8900IpAddressSet
(
INT16U
UserId,
INT8U
*pIpAddress);
44
INT8U
F_Cs8900InitialPassCheck
(
void
);
45
INT16U
F_Cs8900RegisterRead
(
INT16U
Offset);
46
void
F_Cs8900RegisterWrite
(
INT16U
Offset,
INT16U
Data);
47
void
F_Cs8900IrqEnable
(
void
);
48
INT32U
F_Cs8900PacketReceive
(
INT8U
*pPacketData,
INT32U
PacketLength);
49
INT8U
F_Cs8900PacketTransmit
(
INT8U
*pPacketData,
INT16U
PacketLength);
50
INT8U
F_Cs8900PacketReceiveCheck
(
void
);
51
INT8U
F_Cs8900Link
(
void
);
52
53
void
F_Cs8900Init
(
void
){
54
Cs8900Ctrl.
InitialPass
=
FALSE
;
55
Cs8900Ctrl.
IoBase
=
CS8900_ADDRESS
;
56
Cs8900Ctrl.
MemBase
=0;
57
Cs8900Ctrl.
Id
=
ID_CS8900
;
58
Cs8900Ctrl.
InUse
=
FALSE
;
59
Cs8900Ctrl.
State
=
Cs8900IdleState
;
60
}
61
void
F_Cs8900Svc
(
void
){
62
INT16U
i;
63
INT16U
*pMac;
64
65
switch
(Cs8900Ctrl.
State
){
66
case
Cs8900IdleState
:
67
break
;
68
case
Cs8900InitialState0
:
69
Cs8900Ctrl.
InitialPass
=
FALSE
;
70
// SPEC. 3.3.3 bus reset consideration
71
// IO_PACKET_PAGE_POINTER has sigunature 3000h.
72
i=
F_Cs8900IoRead
(
IO_PACKET_PAGE_POINTER
);
73
#if(DEBUG_CS8900==1)
74
printf
(
"\n sigunature %8x"
,i);
75
#endif
76
if
((i&
CS8900_SIGNATURE_MASK
)!=CS8900_SIGNATURE_MASK){
77
#if(DEBUG_CS8900==1)
78
printf
(
"\n sigunature error"
);
79
#endif
80
Cs8900Ctrl.
State
=
Cs8900IdleState
;
81
return
;
82
}
83
// SPEC. 4.3.1 bus interface register EISA number
84
// EISA NUMBER 0x630E
85
i=
F_Cs8900RegisterRead1
(
PKTPG_EISA_NUMBER
);
86
#if(DEBUG_CS8900==1)
87
printf
(
"\n EISA number %8x"
,i);
88
#endif
89
if
(i!=
CS8900_EISA_NUMBER
){
90
#if(DEBUG_CS8900==1)
91
printf
(
"\n EISA number error"
);
92
#endif
93
Cs8900Ctrl.
State
=
Cs8900IdleState
;
94
return
;
95
}
96
// SPEC. 4.3.1 bus interface register ID code's 0s
97
i=
F_Cs8900RegisterRead1
(
PKTPG_PRDCT_ID_CODE
);
98
#if(DEBUG_CS8900==1)
99
printf
(
"\n CS8900_PRDCT_ID %8x"
,i);
100
#endif
101
if
((i&
CS8900_PRDCT_ID_MASK
)!=
CS8900_PRDCT_ID
){
102
#if(DEBUG_CS8900==1)
103
printf
(
"\n product ID error"
);
104
#endif
105
Cs8900Ctrl.
State
=
Cs8900IdleState
;
106
return
;
107
}
108
i=
F_Cs8900RegisterRead1
(
PKTPG_IO_BASE_ADDR
);
109
#if(DEBUG_CS8900==1)
110
printf
(
"\n PKTPG_IO_BASE_ADDR %8x"
,i);
111
printf
(
"\n CS8900 detected"
);
112
#endif
113
F_Cs8900RegisterWrite1
(
PKTPG_SELF_CTL
,(
SELF_CTL_RESET
|
SELF_CTL_LOW_BITS
));
114
Cs8900Ctrl.
State
=
Cs8900InitialState1
;
115
break
;
116
case
Cs8900InitialState1
:
117
if
((
F_Cs8900RegisterRead1
(
PKTPG_SELF_ST
)&
SELF_ST_INITD
)==0)
return
;
// wait cs8900 goes ready
118
#if(DEBUG_CS8900==1)
119
printf
(
"\n initial ok "
);
120
#endif
121
Cs8900Ctrl.
State
=
Cs8900InitialState2
;
122
break
;
123
case
Cs8900InitialState2
:
124
if
((
F_Cs8900RegisterRead1
(
PKTPG_SELF_ST
)&
SELF_ST_SIBUSY
)!=0)
return
;
// wait cs8900 goes ready
125
#if(DEBUG_CS8900==1)
126
printf
(
"\n initial done "
);
127
#endif
128
Cs8900Ctrl.
State
=
Cs8900InitialState3
;
129
break
;
130
case
Cs8900InitialState3
:
131
// set 10 base T and mode back off
132
i=
F_Cs8900RegisterRead2
(
PKTPG_LINE_CTL
)|
LINE_CTL_10_BASE_T
|
LINE_CTL_MOD_BACKOFF
;
133
F_Cs8900RegisterWrite2
(
PKTPG_LINE_CTL
,i);
134
// set frame receive interrupt enable
135
F_Cs8900RegisterWrite2
(
PKTPG_RX_CFG
,
RX_CFG_RX_OK_I_E
|
RX_CFG_LOW_BITS
);
136
// set frame rx enable,
137
// set destination address match enable
138
// set broadcast address match enable
139
F_Cs8900RegisterWrite2
(
PKTPG_RX_CTL
,
RX_CTL_RX_OK_A
|
RX_CTL_IND_ADDR_A
|
RX_CTL_BROADCAST_A
|
RX_CTL_LOW_BITS
);
140
// {0x00,0x80,0x48,0x12,0x34,0x56}
141
pMac=(
INT16U
*)Cs8900Ctrl.
MacAddress
;
142
#
if
(
DEBUG_CS8900
==1)
143
printf
(
"\n pMAC %4x "
,*pMac);
144
#endif
145
F_Cs8900RegisterWrite2
(
PKTPG_INDIVISUAL_ADDR
+0,*pMac++);
// 158,159
146
#if(DEBUG_CS8900==1)
147
printf
(
"\n pMAC %4x "
,*pMac);
148
#endif
149
F_Cs8900RegisterWrite2
(
PKTPG_INDIVISUAL_ADDR
+2,*pMac++);
// 15a,15b
150
#if(DEBUG_CS8900==1)
151
printf
(
"\n pMAC %4x "
,*pMac);
152
#endif
153
F_Cs8900RegisterWrite2
(
PKTPG_INDIVISUAL_ADDR
+4,*pMac );
// 15c,15d
154
// disable interrupts for frame tx
155
F_Cs8900RegisterWrite2
(
PKTPG_TX_CFG
,
TX_CFG_LOW_BITS
);
156
Cs8900Ctrl.
State
=
Cs8900InitialState4
;
157
break
;
158
case
Cs8900InitialState4
:
159
// disable intrq 0,1,2,3 ...like interrupts(et0,et1,es0,ex0,ex1) in 8051
160
F_Cs8900RegisterWrite2
(
PKTPG_INTERRUPT_NUMBER
,
INTERRUPT_NUMBER
);
161
// enable interrupt generation...like "ea" in 8051
162
i=
F_Cs8900RegisterRead2
(
PKTPG_BUS_CTL
)|
BUS_CTL_ENABLE_IRQ
;
163
F_Cs8900RegisterWrite2
(
PKTPG_BUS_CTL
,i);
164
// enable packet rx,tx
165
i=
F_Cs8900RegisterRead2
(
PKTPG_LINE_CTL
)|
LINE_CTL_RX_ON
|
LINE_CTL_TX_ON
;
166
F_Cs8900RegisterWrite2
(
PKTPG_LINE_CTL
,i);
167
168
printf
(
"\n CS8900 MAC initial ok"
);
169
Cs8900Ctrl.
InitialPass
=
TRUE
;
170
Cs8900Ctrl.
State
=
Cs8900IdleState
;
171
break
;
172
}
173
}
174
INT8U
F_Cs8900InUseCheck
(
void
){
175
if
(Cs8900Ctrl.
InUse
==
TRUE
)
return
TRUE
;
176
else
return
FALSE
;
177
}
178
INT8U
F_Cs8900Allocate
(
INT16U
UserId){
179
if
(Cs8900Ctrl.
InUse
==
FALSE
){
180
Cs8900Ctrl.
InUse
=
TRUE
;
181
Cs8900Ctrl.
UserId
=UserId;
182
return
TRUE
;
183
}
184
else
return
FALSE
;
185
}
186
INT8U
F_Cs8900Release
(
INT16U
UserId){
187
if
((Cs8900Ctrl.
InUse
==
TRUE
)&&(Cs8900Ctrl.
UserId
==UserId)){
188
Cs8900Ctrl.
InUse
=
FALSE
;
189
return
TRUE
;
190
}
191
else
return
FALSE
;
192
}
193
INT8U
F_Cs8900InitialStart
(
INT16U
UserId){
194
if
((Cs8900Ctrl.
InUse
==
TRUE
)&&(Cs8900Ctrl.
UserId
==UserId)){
195
Cs8900Ctrl.
State
=
Cs8900InitialState0
;
196
return
TRUE
;
197
}
198
else
return
FALSE
;
199
}
200
INT8U
F_Cs8900MacAddressSet
(
INT16U
UserId,
INT8U
*pMacAddress){
201
if
((Cs8900Ctrl.
InUse
==
TRUE
)&&(Cs8900Ctrl.
UserId
==UserId)){
202
Cs8900Ctrl.
MacAddress
[0]=pMacAddress[0];
203
Cs8900Ctrl.
MacAddress
[1]=pMacAddress[1];
204
Cs8900Ctrl.
MacAddress
[2]=pMacAddress[2];
205
Cs8900Ctrl.
MacAddress
[3]=pMacAddress[3];
206
Cs8900Ctrl.
MacAddress
[4]=pMacAddress[4];
207
Cs8900Ctrl.
MacAddress
[5]=pMacAddress[5];
208
return
TRUE
;
209
}
210
else
return
FALSE
;
211
}
212
INT8U
F_Cs8900IpAddressSet
(
INT16U
UserId,
INT8U
*pIpAddress){
213
if
((Cs8900Ctrl.
InUse
==
TRUE
)&&(Cs8900Ctrl.
UserId
==UserId)){
214
Cs8900Ctrl.
IpAddress
[0]=pIpAddress[0];
215
Cs8900Ctrl.
IpAddress
[1]=pIpAddress[1];
216
Cs8900Ctrl.
IpAddress
[2]=pIpAddress[2];
217
Cs8900Ctrl.
IpAddress
[3]=pIpAddress[3];
218
return
TRUE
;
219
}
220
else
return
FALSE
;
221
}
222
INT8U
F_Cs8900InitialPassCheck
(
void
){
223
if
(Cs8900Ctrl.
InitialPass
==
TRUE
)
return
TRUE
;
224
else
return
FALSE
;
225
}
226
INT8U
F_Cs8900ReadyCheck
(
void
){
227
if
(Cs8900Ctrl.
State
==
Cs8900IdleState
)
return
TRUE
;
228
else
return
FALSE
;
229
}
230
INT16U
F_Cs8900IoRegisterRead
(
INT16U
Offset){
231
return
F_Cs8900IoRead
(Offset);
232
}
233
INT16U
F_Cs8900RegisterRead
(
INT16U
Offset){
234
F_Cs8900IoWrite
(
IO_PACKET_PAGE_POINTER
,Offset);
235
return
F_Cs8900IoRead
(
IO_PACKET_PAGE_DATA_0
);
236
}
237
void
F_Cs8900RegisterWrite
(
INT16U
Offset,
INT16U
Data){
238
F_Cs8900IoWrite
(
IO_PACKET_PAGE_POINTER
,Offset);
239
F_Cs8900IoWrite
(
IO_PACKET_PAGE_DATA_0
,Data);
240
}
241
void
F_Cs8900IrqEnable
(
void
){
242
INT16U
i;
243
244
// disable intrq 0,1,2,3 ...like interrupts(et0,et1,es0,ex0,ex1) in 8051
245
F_Cs8900RegisterWrite2
(
PKTPG_INTERRUPT_NUMBER
,
INTERRUPT_NUMBER
);
246
// enable interrupt generation...like "ea" in 8051
247
i=
F_Cs8900RegisterRead2
(
PKTPG_BUS_CTL
)|
BUS_CTL_ENABLE_IRQ
;
248
F_Cs8900RegisterWrite2
(
PKTPG_BUS_CTL
,i);
249
// enable packet rx,tx
250
i=
F_Cs8900RegisterRead2
(
PKTPG_LINE_CTL
)|
LINE_CTL_RX_ON
|
LINE_CTL_TX_ON
;
251
F_Cs8900RegisterWrite2
(
PKTPG_LINE_CTL
,i);
252
}
253
INT32U
F_Cs8900PacketReceive
(
INT8U
*pPacketData,
INT32U
PacketLength){
254
INT32U
Length;
255
INT32U
ReceiveLength=0;
256
INT16U
*pData;
257
INT16U
Data;
258
259
Data=
F_Cs8900IoRead
(
IO_RX_TX_DATA_0
);
// ignore first byte??
260
Length=
F_Cs8900IoRead
(
IO_RX_TX_DATA_0
);
// read frame length
261
if
(Length>PacketLength) Length=0;
// frame length to large
262
pData=(
INT16U
*)pPacketData;
// convert INT8U pointer to INT16U pointer
263
ReceiveLength=Length;
264
while
(ReceiveLength!=0){
265
Data=
F_Cs8900IoRead
(
IO_RX_TX_DATA_0
);
// host read frame data stored in cs8900 (in 16bits)
266
if
(ReceiveLength==1){
267
*((
INT8U
*)pData)=(
INT8U
)Data;
// last byte if odd frame length
268
ReceiveLength=0;
269
}
270
else
{
271
*pData++=Data;
// 16 bit
272
ReceiveLength-=2;
// 2*8bit
273
}
274
}
275
return
Length;
276
}
277
INT8U
F_Cs8900PacketTransmit
(
INT8U
*pPacketData,
INT16U
PacketLength){
278
INT16U
*pData;
279
INT16U
BusStatus;
280
INT32U
i;
281
282
// SPEC. 4.5.1
283
// set start transmission after entire frame is in cs8900
284
F_Cs8900IoWrite
(
IO_TX_CMD
,(
TX_CMD_START_ALL
|
TX_CMD_LOW_BITS
));
285
// SPEC. 4.5.2
286
// set tansmission packet length(in bytes)
287
F_Cs8900IoWrite
(
IO_TX_LENGTH
,PacketLength);
288
for
(i=0;i<
MAX_COUNT
;i++){
// polling time counter
289
BusStatus=
F_Cs8900RegisterRead2
(
PKTPG_BUS_ST
);
// polling cs8900 ready
290
if
(BusStatus&
BUS_ST_RDY_4_TX_NOW
)
break
;
// polling status ready
291
}
292
if
(i>=MAX_COUNT)
return
FALSE
;
// polling time out, return
293
pData=(
INT16U
*)pPacketData;
// convert INT8U pointer to INT16U pointer
294
while
(PacketLength!=0){
295
F_Cs8900IoWrite
(
IO_RX_TX_DATA_0
, *pData++);
// transmit data from host to cs8900(in 16bits)
296
if
(PacketLength==1) PacketLength=0;
// last byte if odd frame length
297
else
PacketLength-=2;
298
}
299
return
TRUE
;
300
}
301
INT8U
F_Cs8900PacketReceiveCheck
(
void
){
302
INT16U
Event;
303
304
// read INT_STATUS_QUEUE
305
// then check if REG_NUM_RX_EVENT is in
306
// then check if RX_EVENT_RX_OK is ok
307
// then check if RX_EVENT_IND_ADDR or RX_CTL_BROADCAST_A
308
// then return TRUE <-- there is a packet received
309
Event=
F_Cs8900IoRead
(
IO_INT_STATSU_QUEUE
);
310
if
(((Event&
ISQ_REG_NUM
)==
REG_NUM_RX_EVENT
)&&
// check 000100
311
((Event&
RX_EVENT_RX_OK
)==RX_EVENT_RX_OK)&&
// has rx a frame
312
((Event&
RX_EVENT_IND_ADDR
)|(Event&
RX_CTL_BROADCAST_A
))){
313
Cs8900Ctrl.
RxEvent
=Event;
314
//if(Event&RX_EVENT_IND_ADDR) Cs8900Ctrl.IsIndividual=TRUE;
315
//else Cs8900Ctrl.IsIndividual=FALSE;
316
//if(Event&RX_CTL_BROADCAST_A) Cs8900Ctrl.IsBroadcast=TRUE;
317
//else Cs8900Ctrl.IsBroadcast=FALSE;
318
return
TRUE
;
319
}
320
else
return
FALSE
;
321
}
322
INT8U
F_Cs8900Link
(
void
){
323
return
TRUE
;
324
}
Generated on Wed Jun 13 2012 00:03:09 for BOOTLOADER by
1.8.1.1