macb_example.c File Reference


Detailed Description

MACB example driver for EVK1100 board.

This file provides a useful example for the MACB interface on AVR32 devices.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

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 Documentation

#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().


Function Documentation

unsigned short in_cksum ( unsigned short *  addr,
int  len 
)

Checksum routine for Internet Protocol family headers.

Parameters:
addr address of data to compute checksum
len length of data to compute checksum
Returns:
unsigned short checksum computed

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

Parameters:
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

Parameters:
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 }


Variable Documentation

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
}
define the ARP global frame

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().


Generated on Fri Feb 19 02:25:23 2010 for AVR32 - MACB Driver by  doxygen 1.5.5