1 | #include <avr/io.h>
|
2 | #include <string.h>
|
3 | #include <stdio.h>
|
4 | #include <util/delay.h>
|
5 |
|
6 |
|
7 | #define BAUD_RATE 115200
|
8 | #define F_CPU 14745600
|
9 | #define SPI_PORT PORTB
|
10 | #define SPI_DDR DDRB
|
11 | #define SPI_CS PB4
|
12 |
|
13 | // Wiznet W5100 Op Code
|
14 |
|
15 | #define WIZNET_WRITE_OPCODE 0xF0
|
16 | #define WIZNET_READ_OPCODE 0x0F
|
17 |
|
18 | // Wiznet W5100 Register Addresses
|
19 | #define MR 0x0000 // Mode Register
|
20 | #define GAR 0x0001 // Gateway Address: 0x0001 to 0x0004
|
21 | #define SUBR 0x0005 // Subnet mask Address: 0x0005 to 0x0008
|
22 | #define SAR 0x0009 // Source Hardware Address (MAC): 0x0009 to 0x000E
|
23 | #define SIPR 0x000F // Source IP Address: 0x000F to 0x0012
|
24 | #define RMSR 0x001A // RX Memory Size Register
|
25 | #define TMSR 0x001B // TX Memory Size Register
|
26 |
|
27 | void uart_init(void)
|
28 | {
|
29 | UCSRA = 0x00;
|
30 | UCSRB = (1<<RXEN) | (1<<TXEN);
|
31 | UCSRC = (1<<UCSZ1) | (1<<UCSZ0) | (1<<URSEL);
|
32 | UBRRL = 7;
|
33 | UBRRH = 0;
|
34 | }
|
35 |
|
36 | void uart_flush(void)
|
37 | {
|
38 | unsigned char dummy;
|
39 |
|
40 | while (UCSRA & (1<<RXC)) dummy = UDR;
|
41 | }
|
42 |
|
43 | int uart_putch(char ch,FILE *stream)
|
44 | {
|
45 | if (ch == '\n')
|
46 | uart_putch('\r', stream);
|
47 |
|
48 | while (!(UCSRA & (1<<UDRE)));
|
49 | UDR=ch;
|
50 |
|
51 | return 0;
|
52 | }
|
53 |
|
54 | int uart_getch(FILE *stream)
|
55 | {
|
56 | unsigned char ch;
|
57 |
|
58 | while (!(UCSRA & (1<<RXC)));
|
59 | ch=UDR;
|
60 |
|
61 | /* Echo the Output Back to terminal */
|
62 | uart_putch(ch,stream);
|
63 |
|
64 | return ch;
|
65 | }
|
66 |
|
67 | void ansi_cl(void)
|
68 | {
|
69 | // ANSI clear screen: cl=\E[H\E[J
|
70 | putchar(27);
|
71 | putchar('[');
|
72 | putchar('H');
|
73 | putchar(27);
|
74 | putchar('[');
|
75 | putchar('J');
|
76 | }
|
77 |
|
78 | void ansi_me(void)
|
79 | {
|
80 | // ANSI turn off all attribute: me=\E[0m
|
81 | putchar(27);
|
82 | putchar('[');
|
83 | putchar('0');
|
84 | putchar('m');
|
85 | }
|
86 |
|
87 | void SPI_Write(unsigned int addr,unsigned char data)
|
88 | {
|
89 | // Activate the CS pin
|
90 | SPI_PORT &= ~(1<<SPI_CS);
|
91 |
|
92 | // Start Wiznet W5100 Write OpCode transmission
|
93 | SPDR = WIZNET_WRITE_OPCODE;
|
94 |
|
95 | // Wait for transmission complete
|
96 | while(!(SPSR & (1<<SPIF)));
|
97 |
|
98 | // Start Wiznet W5100 Address High Bytes transmission
|
99 | SPDR = (addr & 0xFF00) >> 8;
|
100 |
|
101 | // Wait for transmission complete
|
102 | while(!(SPSR & (1<<SPIF)));
|
103 |
|
104 | // Start Wiznet W5100 Address Low Bytes transmission
|
105 | SPDR = addr & 0x00FF;
|
106 |
|
107 | // Wait for transmission complete
|
108 | while(!(SPSR & (1<<SPIF)));
|
109 |
|
110 | // Start Data transmission
|
111 | SPDR = data;
|
112 |
|
113 | // Wait for transmission complete
|
114 | while(!(SPSR & (1<<SPIF)));
|
115 |
|
116 | // CS pin is not active
|
117 | SPI_PORT |= (1<<SPI_CS);
|
118 | }
|
119 |
|
120 | unsigned char SPI_Read(unsigned int addr)
|
121 | {
|
122 | // Activate the CS pin
|
123 | SPI_PORT &= ~(1<<SPI_CS);
|
124 |
|
125 | // Start Wiznet W5100 Read OpCode transmission
|
126 | SPDR = WIZNET_READ_OPCODE;
|
127 |
|
128 | // Wait for transmission complete
|
129 | while(!(SPSR & (1<<SPIF)));
|
130 |
|
131 | // Start Wiznet W5100 Address High Bytes transmission
|
132 | SPDR = (addr & 0xFF00) >> 8;
|
133 |
|
134 | // Wait for transmission complete
|
135 | while(!(SPSR & (1<<SPIF)));
|
136 |
|
137 | // Start Wiznet W5100 Address Low Bytes transmission
|
138 | SPDR = addr & 0x00FF;
|
139 |
|
140 | // Wait for transmission complete
|
141 | while(!(SPSR & (1<<SPIF)));
|
142 |
|
143 | // Send Dummy transmission for reading the data
|
144 | SPDR = 0x00;
|
145 |
|
146 | // Wait for transmission complete
|
147 | while(!(SPSR & (1<<SPIF)));
|
148 |
|
149 | // CS pin is not active
|
150 | SPI_PORT |= (1<<SPI_CS);
|
151 |
|
152 | return(SPDR);
|
153 | }
|
154 |
|
155 | void W5100_Init(void)
|
156 | {
|
157 | printf("start\n\r");
|
158 | // Ethernet Setup
|
159 | unsigned char mac_addr[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
|
160 | unsigned char ip_addr[] = {192,168,2,10};
|
161 | unsigned char sub_mask[] = {255,255,255,0};
|
162 | unsigned char gtw_addr[] = {192,168,2,1};
|
163 |
|
164 | // Setting the Wiznet W5100 Mode Register: 0x0000
|
165 | SPI_Write(MR,0x80); // MR = 0b10000000;
|
166 | _delay_ms(1000);
|
167 | printf("Reading MR: %d\n\n",SPI_Read(MR));
|
168 |
|
169 | // Setting the Wiznet W5100 Gateway Address (GAR): 0x0001 to 0x0004
|
170 | printf("Setting Gateway Address %d.%d.%d.%d\n",gtw_addr[0],gtw_addr[1],\
|
171 | gtw_addr[2],gtw_addr[3]);
|
172 | SPI_Write(GAR + 0,gtw_addr[0]);
|
173 | SPI_Write(GAR + 1,gtw_addr[1]);
|
174 | SPI_Write(GAR + 2,gtw_addr[2]);
|
175 | SPI_Write(GAR + 3,gtw_addr[3]);
|
176 | _delay_ms(1000);
|
177 |
|
178 | printf("Reading GAR: %d.%d.%d.%d\n\n",SPI_Read(GAR + 0),SPI_Read(GAR + 1),\
|
179 | SPI_Read(GAR + 2),SPI_Read(GAR + 3));
|
180 |
|
181 | // Setting the Wiznet W5100 Source Address Register (SAR): 0x0009 to 0x000E
|
182 | printf("Setting Source Address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",mac_addr[0],mac_addr[1],\
|
183 | mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
|
184 | SPI_Write(SAR + 0,mac_addr[0]);
|
185 | SPI_Write(SAR + 1,mac_addr[1]);
|
186 | SPI_Write(SAR + 2,mac_addr[2]);
|
187 | SPI_Write(SAR + 3,mac_addr[3]);
|
188 | SPI_Write(SAR + 4,mac_addr[4]);
|
189 | SPI_Write(SAR + 5,mac_addr[5]);
|
190 | _delay_ms(1000);
|
191 |
|
192 | printf("Reading SAR: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n\n",SPI_Read(SAR + 0),SPI_Read(SAR + 1),\
|
193 | SPI_Read(SAR + 2),SPI_Read(SAR + 3),SPI_Read(SAR + 4),SPI_Read(SAR + 5));
|
194 |
|
195 | // Setting the Wiznet W5100 Sub Mask Address (SUBR): 0x0005 to 0x0008
|
196 | printf("Setting Sub Mask Address %d.%d.%d.%d\n",sub_mask[0],sub_mask[1],\
|
197 | sub_mask[2],sub_mask[3]);
|
198 | SPI_Write(SUBR + 0,sub_mask[0]);
|
199 | SPI_Write(SUBR + 1,sub_mask[1]);
|
200 | SPI_Write(SUBR + 2,sub_mask[2]);
|
201 | SPI_Write(SUBR + 3,sub_mask[3]);
|
202 | _delay_ms(1000);
|
203 |
|
204 | printf("Reading SUBR: %d.%d.%d.%d\n\n",SPI_Read(SUBR + 0),SPI_Read(SUBR + 1),\
|
205 | SPI_Read(SUBR + 2),SPI_Read(SUBR + 3));
|
206 |
|
207 | // Setting the Wiznet W5100 IP Address (SIPR): 0x000F to 0x0012
|
208 | printf("Setting IP Address %d.%d.%d.%d\n",ip_addr[0],ip_addr[1],\
|
209 | ip_addr[2],ip_addr[3]);
|
210 | SPI_Write(SIPR + 0,ip_addr[0]);
|
211 | SPI_Write(SIPR + 1,ip_addr[1]);
|
212 | SPI_Write(SIPR + 2,ip_addr[2]);
|
213 | SPI_Write(SIPR + 3,ip_addr[3]);
|
214 | _delay_ms(1000);
|
215 |
|
216 | printf("Reading SIPR: %d.%d.%d.%d\n\n",SPI_Read(SIPR + 0),SPI_Read(SIPR + 1),\
|
217 | SPI_Read(SIPR + 2),SPI_Read(SIPR + 3));
|
218 |
|
219 | // Setting the Wiznet W5100 RX and TX Memory Size, we use 2KB for Rx/Tx 4 channels
|
220 | printf("Setting Wiznet RMSR and TMSR\n\n");
|
221 | SPI_Write(RMSR,0x55);
|
222 | SPI_Write(TMSR,0x55);
|
223 |
|
224 | printf("Done Wiznet W5100 Initialized!\n");
|
225 | }
|
226 |
|
227 | // Assign I/O stream to UART
|
228 | FILE uart_str = FDEV_SETUP_STREAM(uart_putch, uart_getch, _FDEV_SETUP_RW);
|
229 |
|
230 | int main(void){
|
231 | // Set the PORTD as Output:
|
232 |
|
233 | // Define Output/Input Stream
|
234 | stdout = stdin = &uart_str;
|
235 |
|
236 | // Initial UART Peripheral
|
237 | uart_init();
|
238 |
|
239 | // Clear Screen
|
240 | ansi_me();
|
241 | ansi_cl();
|
242 | ansi_me();
|
243 | ansi_cl();
|
244 | uart_flush();
|
245 |
|
246 | // Initial the AVR ATMega168/328 SPI Peripheral
|
247 | // Set MOSI (PORTB3),SCK (PORTB5) and PORTB2 (SS) as output, others as input
|
248 | SPI_DDR = (1<<PB5)|(1<<PB4)|(1<<PB7);
|
249 |
|
250 | // CS pin is not active
|
251 | SPI_PORT |= (1<<SPI_CS);
|
252 |
|
253 | // Enable SPI, Master Mode 0, set the clock rate fck/128
|
254 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
|
255 | SPSR = 0;
|
256 |
|
257 | // Initial the Wiznet W5100
|
258 | _delay_ms(10000);
|
259 | printf("Wiznet W5100 Init\n\n");
|
260 | W5100_Init();
|
261 |
|
262 | // Loop forever
|
263 | for(;;){
|
264 | }
|
265 | return 0;
|
266 | }
|