This file provides a useful example for the MACB interface on AVR32 devices.
Definition in file macb_example.c.
#include <stdio.h>
#include <string.h>
#include <avr32/io.h>
#include "print_funcs.h"
#include "usart.h"
#include "board.h"
#include "macb.h"
#include "gpio.h"
#include "compiler.h"
#include "conf_eth.h"
#include "flashc.h"
#include "pm.h"
#include "intc.h"
Go to the source code of this file.
Defines | |
#define | SEQ_NUM_START 0x2546 |
Functions | |
unsigned short | in_cksum (unsigned short *addr, int len) |
Checksum routine for Internet Protocol family headers. | |
void | local_start_pll (void) |
start a PLL @ 48Mhz to run with | |
void | macb_example_receive_packet (macb_packet_t *pkt) |
callback to manage packets reception | |
static void | macb_example_send_ARP_request (void) |
Send an ARP request to host. | |
void | macb_example_send_ping_response (macb_packet_t *pkt) |
function to send PING response to pkt->data->host | |
int | main (void) |
main function : do init and loop (poll if configured so) | |
Variables | |
const unsigned char | ARP_FRAME [42] |
unsigned char | data [ETHERNET_CONF_TX_BUFFER_SIZE] |
unsigned char | hwaddr [6] = { ETHERNET_CONF_ETHADDR0,ETHERNET_CONF_ETHADDR1,ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,ETHERNET_CONF_ETHADDR4,ETHERNET_CONF_ETHADDR5 } |
const unsigned char | local_ipaddr [4] = {ETHERNET_CONF_IPADDR0,ETHERNET_CONF_IPADDR1,ETHERNET_CONF_IPADDR2,ETHERNET_CONF_IPADDR3} |
unsigned short | seqnum = SEQ_NUM_START |
#define SEQ_NUM_START 0x2546 |
initial sequence number for ICMP request and reply
Definition at line 99 of file macb_example.c.
Referenced by macb_example_send_ping_response().
unsigned short in_cksum | ( | unsigned short * | addr, | |
int | len | |||
) |
Checksum routine for Internet Protocol family headers.
addr | address of data to compute checksum | |
len | length of data to compute checksum |
Definition at line 132 of file macb_example.c.
Referenced by macb_example_send_ping_response().
00133 { 00134 int nleft, sum; 00135 unsigned short *w; 00136 union { 00137 unsigned short us; 00138 unsigned char uc[2]; 00139 } last; 00140 unsigned short answer; 00141 00142 nleft = len; 00143 sum = 0; 00144 w = addr; 00145 00146 /* 00147 * Algorithm is simple, using a 32 bit accumulator (sum) : 00148 * add sequential 16 bit words to it, and at the end, fold back all the 00149 * carry bits from the top 16 bits into the lower 16 bits. 00150 */ 00151 while (nleft > 1) 00152 { 00153 sum += *w++; 00154 nleft -= 2; 00155 } 00156 00157 // mop up an odd byte, if necessary 00158 if (nleft == 1) 00159 { 00160 last.uc[0] = *(unsigned char *)w; 00161 last.uc[1] = 0; 00162 sum += last.us; 00163 } 00164 00165 // add back carry outs from top 16 bits to low 16 bits 00166 sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16 00167 sum += (sum >> 16); // add carry 00168 answer = ~sum; // truncate to 16 bits 00169 return(answer); 00170 }
void local_start_pll | ( | void | ) |
start a PLL @ 48Mhz to run with
Definition at line 305 of file macb_example.c.
Referenced by main().
00306 { 00307 volatile avr32_pm_t *pm = &AVR32_PM; 00308 00309 // Switch the main clock to OSC0 00310 pm_switch_to_osc0(pm, FOSC0, OSC0_STARTUP); 00311 // Setup PLL0 on OSC0, mul=15 ,no divisor, lockcount=16, ie. 12Mhzx16 = 192MHz output 00312 pm_pll_setup(pm, // volatile avr32_pm_t *pm 00313 0, // unsigned int pll 00314 15, // unsigned int mul 00315 1, // unsigned int div, Sel Osc0/PLL0 or Osc1/Pll1 00316 0, // unsigned int osc 00317 16); // unsigned int lockcount 00318 // set PLL options to run @ 96 Mhz 00319 pm_pll_set_option(pm, // volatile avr32_pm_t *pm 00320 0, // unsigned int pll 00321 0, // unsigned int pll_freq 00322 1, // unsigned int pll_div2 00323 0); // unsigned int pll_wbwdisable 00324 // Enable PLL0 00325 pm_pll_enable(pm,0); 00326 // Wait for PLL0 locked 00327 pm_wait_for_pll0_locked(pm) ; 00328 // Setup generic clock number 0 on PLL, with OSC0/PLL0, no divisor 00329 pm_gc_setup(pm, 00330 0, 00331 1, // Use Osc (=0) or PLL (=1) 00332 0, // Sel Osc0/PLL0 or Osc1/Pll1 00333 0, 00334 0); 00335 // Enable Generic clock 0*/ 00336 pm_gc_enable(pm, 0); 00337 // set divider to 8 for PBA bus and 2 for PBB 00338 pm_cksel(pm,1,2,1,0,1,0); 00339 // one wait state at 48 Mhz 00340 flashc_set_wait_state(1); 00341 /* Output the clock to a gpio(PA7) */ 00342 gpio_enable_module_pin(AVR32_PM_GCLK_0_0_PIN, AVR32_PM_GCLK_0_0_FUNCTION); 00343 // switch to clock 00344 pm_switch_to_clock(pm, AVR32_PM_MCCTRL_MCSEL_PLL0); 00345 }
void macb_example_receive_packet | ( | macb_packet_t * | pkt | ) |
callback to manage packets reception
pkt | packet to manage |
Definition at line 219 of file macb_example.c.
References macb_packet_t::data, hwaddr, macb_packet_t::len, lMACBSend(), local_ipaddr, and macb_example_send_ping_response().
Referenced by main().
00220 { 00221 unsigned char ipaddr[4]; 00222 00223 // if it is a ARP frame, answer it 00224 if ((pkt->data[12] == 0x08) && (pkt->data[13] == 0x06)) 00225 { 00226 // ARP request 00227 if ((pkt->data[20] == 0x00) && (pkt->data[21] == 0x01)) 00228 { 00229 print_dbg("ARP Request received...\r\n"); 00230 // Reply only if the ARP request is destined to our IP address. 00231 if(memcmp(pkt->data+38, local_ipaddr, 4)) 00232 { 00233 print_dbg("...Ignored...\r\n"); 00234 return; 00235 } 00236 00237 // swap sender & receiver address 00238 memmove(pkt->data, pkt->data+6, 6); 00239 memcpy(pkt->data+6, hwaddr, 6); 00240 // ARP Response 00241 pkt->data[21] = 0x02; 00242 // swap sender & receiver parameters 00243 memcpy(ipaddr, pkt->data+38, 4); 00244 memmove(pkt->data+32, pkt->data+22, 10); 00245 memcpy(pkt->data+22, hwaddr, 6); 00246 memcpy(pkt->data+28, ipaddr, 4); 00247 // send response, nothing else to send 00248 lMACBSend(&AVR32_MACB, pkt->data, pkt->len, TRUE); 00249 } 00250 // ARP response 00251 else if ((pkt->data[20] == 0x00) && (pkt->data[21] == 0x02)) 00252 { 00253 print_dbg("ARP Response received...\r\n"); 00254 } 00255 // unknown frame, loop it back 00256 else 00257 { 00258 print_dbg("Unimplemented ARP packet...\r\n"); 00259 } 00260 } 00261 // ICMP protocol 00262 else if (pkt->data[23] == 0x01) 00263 { 00264 // if it is our IP address 00265 if (!memcmp(&pkt->data[30], local_ipaddr, 4)) 00266 { 00267 if (pkt->data[34] == 0x08) // PING Request 00268 { 00269 print_dbg("PING Request received...\r\n"); 00270 macb_example_send_ping_response(pkt); 00271 } 00272 else 00273 { 00274 print_dbg("Unimplemented ICMP packet...\r\n"); 00275 } 00276 } 00277 } 00278 else 00279 { 00280 print_dbg("Unknown packet...\r\n"); 00281 } 00282 }
static void macb_example_send_ARP_request | ( | void | ) | [static] |
Send an ARP request to host.
Definition at line 287 of file macb_example.c.
References ARP_FRAME, data, macb_packet_t::data, macb_packet_t::len, and lMACBSend().
Referenced by main().
00288 { 00289 macb_packet_t request_pkt; 00290 00291 request_pkt.data = data; 00292 // Prepare ARP frame for host 00293 memcpy(request_pkt.data, ARP_FRAME, 42); 00294 request_pkt.len = 42; 00295 #if CONF_MACB_VERBOSE 00296 print_dbg("Sending ARP Request...\r\n"); 00297 #endif 00298 // send response, nothing else to send 00299 lMACBSend(&AVR32_MACB, request_pkt.data, request_pkt.len, TRUE); 00300 }
void macb_example_send_ping_response | ( | macb_packet_t * | pkt | ) |
function to send PING response to pkt->data->host
pkt | packet to manage |
Definition at line 177 of file macb_example.c.
References macb_packet_t::data, hwaddr, in_cksum(), macb_packet_t::len, lMACBSend(), SEQ_NUM_START, and seqnum.
Referenced by macb_example_receive_packet().
00178 { 00179 unsigned char ipaddr[4]; 00180 unsigned short chksum; 00181 00182 // swap sender & receiver HW address 00183 memmove(pkt->data, pkt->data+6, 6); 00184 memcpy(pkt->data+6, hwaddr, 6); 00185 // swap sender & receiver IP address 00186 memcpy(ipaddr, pkt->data+26, 4); 00187 memmove(pkt->data+26, pkt->data+30, 4); 00188 memcpy(pkt->data+30, ipaddr, 4); 00189 // set seq num 00190 pkt->data[18] = MSB(seqnum); 00191 pkt->data[19] = LSB(seqnum); 00192 if (++seqnum >= 0xFF00) seqnum = SEQ_NUM_START; 00193 // reset checksum before computation 00194 pkt->data[24] = 0; 00195 pkt->data[25] = 0; 00196 // compute IP checksum 00197 chksum = in_cksum((unsigned short *)&pkt->data[14], 20); 00198 // set IP checksum 00199 pkt->data[24] = MSB(chksum); 00200 pkt->data[25] = LSB(chksum); 00201 // set reply bit 00202 pkt->data[34] = 0; 00203 // reset checksum before computation 00204 pkt->data[36] = 0; 00205 pkt->data[37] = 0; 00206 // compute ICMP checksum 00207 chksum = in_cksum((unsigned short *)&pkt->data[34], (pkt->len - 34)); 00208 // set ICMP checksum 00209 pkt->data[36] = MSB(chksum); 00210 pkt->data[37] = LSB(chksum); 00211 // send request, nothing else to send 00212 lMACBSend(&AVR32_MACB, pkt->data, pkt->len, TRUE); 00213 }
int main | ( | void | ) |
main function : do init and loop (poll if configured so)
Definition at line 350 of file macb_example.c.
References macb_packet_t::data, data, macb_packet_t::len, local_start_pll(), macb_example_receive_packet(), macb_example_send_ARP_request(), ulMACBInputLength(), vMACBRead(), vMACBWaitForInput(), and xMACBInit().
00351 { 00352 unsigned long len, i = 0; 00353 macb_packet_t recvd_pkt; 00354 static const gpio_map_t MACB_GPIO_MAP = 00355 { 00356 {AVR32_MACB_MDC_0_PIN, AVR32_MACB_MDC_0_FUNCTION }, 00357 {AVR32_MACB_MDIO_0_PIN, AVR32_MACB_MDIO_0_FUNCTION }, 00358 {AVR32_MACB_RXD_0_PIN, AVR32_MACB_RXD_0_FUNCTION }, 00359 {AVR32_MACB_TXD_0_PIN, AVR32_MACB_TXD_0_FUNCTION }, 00360 {AVR32_MACB_RXD_1_PIN, AVR32_MACB_RXD_1_FUNCTION }, 00361 {AVR32_MACB_TXD_1_PIN, AVR32_MACB_TXD_1_FUNCTION }, 00362 {AVR32_MACB_TX_EN_0_PIN, AVR32_MACB_TX_EN_0_FUNCTION }, 00363 {AVR32_MACB_RX_ER_0_PIN, AVR32_MACB_RX_ER_0_FUNCTION }, 00364 {AVR32_MACB_RX_DV_0_PIN, AVR32_MACB_RX_DV_0_FUNCTION }, 00365 {AVR32_MACB_TX_CLK_0_PIN, AVR32_MACB_TX_CLK_0_FUNCTION} 00366 }; 00367 00368 // start a PLL 00369 local_start_pll(); 00370 00371 // init the system interrupts 00372 INTC_init_interrupts(); 00373 00374 // init debug serial line 00375 init_dbg_rs232(FOSC0); 00376 00377 // display welcome 00378 print_dbg("\x1B[2J\x1B[H\r\n MACB Example\r\n"); 00379 00380 // Assign GPIO to MACB 00381 gpio_enable_module(MACB_GPIO_MAP, sizeof(MACB_GPIO_MAP) / sizeof(MACB_GPIO_MAP[0])); 00382 00383 // initialize MACB & Phy Layers 00384 if (xMACBInit(&AVR32_MACB) == FALSE ) 00385 { 00386 gpio_clr_gpio_pin(LED0_GPIO); 00387 while(1); 00388 } 00389 00390 gpio_clr_gpio_pin(LED1_GPIO); 00391 00392 // do a loop, and display stats or quit 00393 while (1) 00394 { 00395 // Loop while no data are pending. 00396 vMACBWaitForInput(100); 00397 // Obtain the size of the packet. 00398 len = ulMACBInputLength(); 00399 if( len != 0) 00400 { 00401 // Let the driver know we are going to read a new packet. 00402 vMACBRead( NULL, 0, 0 ); 00403 // Read enough bytes to fill this buf. 00404 vMACBRead( data, 128, len ); 00405 recvd_pkt.data = data; 00406 recvd_pkt.len = len; 00407 macb_example_receive_packet(&recvd_pkt); 00408 } 00409 if (++i >= 400) 00410 { 00411 i = 0; 00412 // send ARP request to host 00413 macb_example_send_ARP_request(); 00414 } 00415 } 00416 }
const unsigned char ARP_FRAME[42] |
Initial value:
{ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, ETHERNET_CONF_ETHADDR0,ETHERNET_CONF_ETHADDR1,ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,ETHERNET_CONF_ETHADDR4,ETHERNET_CONF_ETHADDR5, 0x08,0x06,0x00,0x01,0x08,0x00,0x06,0x04,0x00,0x01, ETHERNET_CONF_ETHADDR0,ETHERNET_CONF_ETHADDR1,ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,ETHERNET_CONF_ETHADDR4,ETHERNET_CONF_ETHADDR5, ETHERNET_CONF_IPADDR0,ETHERNET_CONF_IPADDR1,ETHERNET_CONF_IPADDR2,ETHERNET_CONF_IPADDR3, 0x00,0x00,0x00,0x00,0x00,0x00, ETHERNET_CONF_GATEWAY_ADDR0,ETHERNET_CONF_GATEWAY_ADDR1,ETHERNET_CONF_GATEWAY_ADDR2,ETHERNET_CONF_GATEWAY_ADDR3 }
Definition at line 108 of file macb_example.c.
Referenced by macb_example_send_ARP_request().
unsigned char data[ETHERNET_CONF_TX_BUFFER_SIZE] |
buffer for sending packets
Definition at line 119 of file macb_example.c.
Referenced by macb_example_send_ARP_request(), and main().
unsigned char hwaddr[6] = { ETHERNET_CONF_ETHADDR0,ETHERNET_CONF_ETHADDR1,ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,ETHERNET_CONF_ETHADDR4,ETHERNET_CONF_ETHADDR5 } |
Definition at line 121 of file macb_example.c.
Referenced by macb_example_receive_packet(), and macb_example_send_ping_response().
const unsigned char local_ipaddr[4] = {ETHERNET_CONF_IPADDR0,ETHERNET_CONF_IPADDR1,ETHERNET_CONF_IPADDR2,ETHERNET_CONF_IPADDR3} |
buffer for sending packets
Definition at line 105 of file macb_example.c.
Referenced by macb_example_receive_packet().
unsigned short seqnum = SEQ_NUM_START |
sequence number for ICMP request and reply
Definition at line 102 of file macb_example.c.
Referenced by macb_example_send_ping_response().