Add AVR32 port and demo files.

This commit is contained in:
Richard Barry 2007-04-01 19:37:01 +00:00
parent b727359f1b
commit bf2b676eaa
52 changed files with 12194 additions and 0 deletions

View file

@ -0,0 +1,252 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Basic SMTP Host for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Implements a simplistic SMTP client.
*/
#if (SMTP_USED == 1)
#include <string.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "BasicSMTP.h"
/* Demo includes. */
#include "AVR32_EMAC.h"
#include "portmacro.h"
#include "partest.h"
/* lwIP includes. */
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/arch.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "netif/loopif.h"
/*! SMTP default port */
#define SMTP_PORT 25
/*! SMTP EHLO code answer */
#define SMTP_EHLO_STRING "220"
/*! SMTP end of transmission code answer */
#define SMTP_END_OF_TRANSMISSION_STRING "221"
/*! SMTP OK code answer */
#define SMTP_OK_STRING "250"
/*! SMTP start of transmission code answer */
#define SMTP_START_OF_TRANSMISSION_STRING "354"
/*! SMTP DATA<CRLF> */
#define SMTP_DATA_STRING "DATA\r\n"
/*! SMTP <CRLF>.<CRLF> */
#define SMTP_MAIL_END_STRING "\r\n.\r\n"
/*! SMTP QUIT<CRLFCRLF> */
#define SMTP_QUIT_STRING "QUIT\r\n\r\n"
/*! Server address */
portCHAR cServer[] = "192.168.0.1";
/*! Fill here the ehlo with your SMTP server name */
#error configure SMTP server
char ehlo[] = "EHLO smtp.domain.com\r\n";
/*! Fill here the mailfrom with your mail address */
#error configure mail sender
char mailfrom[] = "MAIL FROM: <sender@domain.com>\r\n";
/*! Fill here the mailto with your contact mail address */
#error configure mail receiver
char mailto[] = "RCPT TO: <receiver@domain.com>\r\n";
/*! Fill here the mailcontent with the mail you want to send */
#error configure mail content
char mailcontent[] ="Subject: *** SPAM ***\r\nFROM: \"Your Name here\" <sender@domain.com>\r\nTO: \"Your Contact here\" <receiver@domain.com>\r\n\r\nSay what you want here.";
Bool bSendMail = pdTRUE;
portCHAR cTempBuffer[200];
/*! Basic SMTP Host task definition */
portTASK_FUNCTION( vBasicSMTPHost, pvParameters )
{
struct sockaddr_in stServeurSockAddr;
portLONG lRetval;
portLONG lSocket = -1;
for (;;)
{
// wait for a signal to send a mail
while (bSendMail != pdTRUE) vTaskDelay(200);
// Set up port
memset(&stServeurSockAddr, 0, sizeof(stServeurSockAddr));
stServeurSockAddr.sin_len = sizeof(stServeurSockAddr);
stServeurSockAddr.sin_addr.s_addr = inet_addr(cServer);
stServeurSockAddr.sin_port = htons(SMTP_PORT);
stServeurSockAddr.sin_family = AF_INET;
// clear the flag
bSendMail = pdFALSE;
// socket as a stream
if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
// socket failed, blink a LED and stay here
for (;;) {
vParTestToggleLED( 0 );
vTaskDelay( 200 );
}
}
// connect to the server
if(connect(lSocket,(struct sockaddr *)&stServeurSockAddr, sizeof(stServeurSockAddr)) < 0)
{
// connect failed, blink a LED and stay here
for (;;) {
vParTestToggleLED( 1 );
vTaskDelay( 200 );
}
}
else
{
//Server: 220 SMTP Ready
/* wait for SMTP Server answer */
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_EHLO_STRING, sizeof(cTempBuffer)) >= 0)
{
//Client: EHLO smtp.domain.com
/* send ehlo */
send(lSocket, cEhlo, strlen(cEhlo), 0);
//Server: 250
/* wait for SMTP Server answer */
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)
{
//Server: 250 HELP
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
//Client: MAIL FROM:<sender@domain.com>
/* send MAIL FROM */
send(lSocket, cMailfrom, strlen(cMailfrom), 0);
//Server: 250 OK
/* wait for SMTP Server answer */
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)
{
//Client: RCPT TO:<receiver@domain.com>
/* send RCPT TO */
send(lSocket, cMailto, strlen(cMailto), 0);
//Server: 250 OK
/* wait for SMTP Server answer */
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)
{
//Client: DATA<CRLF>
/* send DATA */
send(lSocket, SMTP_DATA_STRING, 6, 0);
//Server: 354 Start mail input; end with <CRLF>.<CRLF>
/* wait for SMTP Server answer */
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_START_OF_TRANSMISSION_STRING, sizeof(cTempBuffer)) >= 0)
{
/* send content */
send(lSocket, cMailcontent, strlen(cMailcontent), 0);
//Client: <CRLF>.<CRLF>
/* send "<CRLF>.<CRLF>" */
send(lSocket, SMTP_MAIL_END_STRING, 5, 0);
//Server: 250 OK
/* wait for SMTP Server answer */
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_OK_STRING, sizeof(cTempBuffer)) >= 0)
{
//Client: QUIT<CRLFCRLF>
/* send QUIT */
send(lSocket, SMTP_QUIT_STRING, 8, 0);
//Server: 221 smtp.domain.com closing transmission
do
{
lRetval = recv(lSocket, cTempBuffer, sizeof(cTempBuffer), 0);
}while (lRetval <= 0);
if (strncmp(cTempBuffer, SMTP_END_OF_TRANSMISSION_STRING, sizeof(cTempBuffer)) >= 0)
{
vParTestSetLED( 3 , pdTRUE );
}
}
}
}
}
}
/* close socket */
close(lSocket);
}
}
}
}
#endif

View file

@ -0,0 +1,57 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Basic SMTP Host for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASIC_SMTP_SERVER_H
#define BASIC_SMTP_SERVER_H
#include "portmacro.h"
/* The function that implements the SMTP host task. */
portTASK_FUNCTION_PROTO( vBasicSMTPHost, pvParameters );
#endif

View file

@ -0,0 +1,473 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Basic TFTP Server for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Implements a simplistic TFTP server.
In order to put data on the TFTP server (not over 2048 bytes)
tftp 192.168.0.2 PUT <src_filename>
this will copy file from your hard drive to the RAM buffer of the application
tftp 192.168.0.2 GET <dst_filename>
this will copy file from the RAM buffer of the application to your hard drive
You can then check that src_filename and dst_filename are identical
*/
#if (TFTP_USED == 1)
#include <string.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "partest.h"
#include "BasicTFTP.h"
/* Demo includes. */
#include "AVR32_EMAC.h"
#include "portmacro.h"
/* lwIP includes. */
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/arch.h"
#include "lwip/sys.h"
#include "netif/loopif.h"
#include "lwip/sockets.h"
#define O_WRONLY 1
#define O_RDONLY 2
/* The port on which we listen. */
#define TFTP_PORT ( 69 )
/* Delay on close error. */
#define TFTP_DELAY ( 10 )
/* Delay on bind error. */
#define TFTP_ERROR_DELAY ( 40 )
#define TFTP_LED ( 4 )
char data_out[SEGSIZE+sizeof(struct tftphdr)];
char data_in[SEGSIZE+sizeof(struct tftphdr)];
//struct tftp_server *server;
/*------------------------------------------------------------*/
static char * errmsg[] = {
"Undefined error code", // 0 nothing defined
"File not found", // 1 TFTP_ENOTFOUND
"Access violation", // 2 TFTP_EACCESS
"Disk full or allocation exceeded", // 3 TFTP_ENOSPACE
"Illegal TFTP operation", // 4 TFTP_EBADOP
"Unknown transfer ID", // 5 TFTP_EBADID
"File already exists", // 6 TFTP_EEXISTS
"No such user", // 7 TFTP_ENOUSER
};
/* Send an error packet to the client */
static void
tftpd_send_error(int s, struct tftphdr * reply, int err,
struct sockaddr_in *from_addr, int from_len)
{
if ( ( 0 <= err ) && ( sizeof(errmsg)/sizeof(errmsg[0]) > err) ) {
reply->th_opcode = htons(ERROR);
reply->th_code = htons(err);
if ( (0 > err) || (sizeof(errmsg)/sizeof(errmsg[0]) <= err) )
err = 0; // Do not copy a random string from hyperspace
strcpy(reply->th_msg, errmsg[err]);
sendto(s, reply, 4+strlen(reply->th_msg)+1, 0,
(struct sockaddr *)from_addr, from_len);
}
}
portCHAR cRamBuffer[2048];
int lCurrentBlock = 0;
int lTotalLength = 0;
int tftpd_close_data_file(int fd)
{
lCurrentBlock = 0;
return (5);
}
int tftpd_open_data_file(int fd, int mode)
{
lCurrentBlock = 0;
return (5);
}
int tftpd_read_data_file(int fd, portCHAR * buffer, int length)
{
int lReturnValue;
if ((lTotalLength -= length) >= 0) {
lReturnValue = length;
}
else
{
lReturnValue = lTotalLength + length;
lTotalLength = 0;
}
memcpy(buffer, &cRamBuffer[lCurrentBlock * SEGSIZE], lReturnValue);
lCurrentBlock++;
return (lReturnValue);
}
//
// callback to store data to the RAM buffer
//
int tftpd_write_data_file(int fd, portCHAR * buffer, int length)
{
lTotalLength += length;
memcpy(&cRamBuffer[lCurrentBlock * SEGSIZE], buffer, length);
lCurrentBlock++;
return (length);
}
//
// Receive a file from the client
//
static void
tftpd_write_file(struct tftphdr *hdr,
struct sockaddr_in *from_addr, int from_len)
{
struct tftphdr *reply = (struct tftphdr *)data_out;
struct tftphdr *response = (struct tftphdr *)data_in;
int fd, len, ok, tries, closed, data_len, s;
unsigned short block;
struct timeval timeout;
fd_set fds;
int total_timeouts = 0;
struct sockaddr_in client_addr, local_addr;
int client_len;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
return;
}
memset((char *)&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_len = sizeof(local_addr);
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(INADDR_ANY);
if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
// Problem setting up my end
close(s);
return;
}
if ((fd = tftpd_open_data_file((int)hdr->th_stuff, O_WRONLY)) < 0) {
tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len);
close(s);
return;
}
ok = pdTRUE;
closed = pdFALSE;
block = 0;
while (ok) {
// Send ACK telling client he can send data
reply->th_opcode = htons(ACK);
reply->th_block = htons(block++); // postincrement
for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) {
sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len);
repeat_select:
timeout.tv_sec = TFTP_TIMEOUT_PERIOD;
timeout.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(s, &fds);
vParTestToggleLED( TFTP_LED );
if (lwip_select(s+1, &fds, 0, 0, &timeout) <= 0) {
if (++total_timeouts > TFTP_TIMEOUT_MAX) {
tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
ok = pdFALSE;
break;
}
continue; // retry the send, using up one retry.
}
vParTestToggleLED( TFTP_LED );
// Some data has arrived
data_len = sizeof(data_in);
client_len = sizeof(client_addr);
if ((data_len = recvfrom(s, data_in, data_len, 0,
(struct sockaddr *)&client_addr, &client_len)) < 0) {
// What happened? No data here!
continue; // retry the send, using up one retry.
}
if (ntohs(response->th_opcode) == DATA &&
ntohs(response->th_block) < block) {
// Then it is repeat DATA with an old block; listen again,
// but do not repeat sending the current ack, and do not
// use up a retry count. (we do re-send the ack if
// subsequently we time out)
goto repeat_select;
}
if (ntohs(response->th_opcode) == DATA &&
ntohs(response->th_block) == block) {
// Good data - write to file
len = tftpd_write_data_file(fd, response->th_data, data_len-4);
if (len < (data_len-4)) {
// File is "full"
tftpd_send_error(s,reply,TFTP_ENOSPACE,
from_addr, from_len);
ok = pdFALSE; // Give up
break; // out of the retries loop
}
if (data_len < (SEGSIZE+4)) {
// End of file
closed = pdTRUE;
ok = pdFALSE;
vParTestSetLED( 0 , 0 );
if (tftpd_close_data_file(fd) == -1) {
tftpd_send_error(s,reply,TFTP_EACCESS,
from_addr, from_len);
break; // out of the retries loop
}
// Exception to the loop structure: we must ACK the last
// packet, the one that implied EOF:
reply->th_opcode = htons(ACK);
reply->th_block = htons(block++); // postincrement
sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len);
break; // out of the retries loop
}
// Happy! Break out of the retries loop.
break;
}
} // End of the retries loop.
if (TFTP_RETRIES_MAX <= tries) {
tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
ok = pdFALSE;
}
}
close(s);
if (!closed) {
tftpd_close_data_file(fd);
}
}
//
// Send a file to the client
//
static void
tftpd_read_file(struct tftphdr *hdr,
struct sockaddr_in *from_addr, int from_len)
{
struct tftphdr *reply = (struct tftphdr *)data_out;
struct tftphdr *response = (struct tftphdr *)data_in;
int fd, len, tries, ok, data_len, s;
unsigned short block;
struct timeval timeout;
fd_set fds;
int total_timeouts = 0;
struct sockaddr_in client_addr, local_addr;
int client_len;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
return;
}
memset((char *)&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_len = sizeof(local_addr);
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(INADDR_ANY);
if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
// Problem setting up my end
close(s);
return;
}
if ((fd = tftpd_open_data_file((int)hdr->th_stuff, O_RDONLY)) < 0) {
tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len);
close(s);
return;
}
block = 0;
ok = pdTRUE;
while (ok) {
// Read next chunk of file
len = tftpd_read_data_file(fd, reply->th_data, SEGSIZE);
reply->th_block = htons(++block); // preincrement
reply->th_opcode = htons(DATA);
for (tries = 0; tries < TFTP_RETRIES_MAX; tries++) {
if (sendto(s, reply, 4+len, 0,
(struct sockaddr *)from_addr, from_len) < 0) {
// Something went wrong with the network!
ok = pdFALSE;
break;
}
repeat_select:
timeout.tv_sec = TFTP_TIMEOUT_PERIOD;
timeout.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(s, &fds);
vParTestToggleLED( TFTP_LED );
if (select(s+1, &fds, 0, 0, &timeout) <= 0) {
if (++total_timeouts > TFTP_TIMEOUT_MAX) {
tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
ok = pdFALSE;
break;
}
continue; // retry the send, using up one retry.
}
vParTestToggleLED( TFTP_LED );
data_len = sizeof(data_in);
client_len = sizeof(client_addr);
if ((data_len = recvfrom(s, data_in, data_len, 0,
(struct sockaddr *)&client_addr,
&client_len)) < 0) {
// What happened? Maybe someone lied to us...
continue; // retry the send, using up one retry.
}
if ((ntohs(response->th_opcode) == ACK) &&
(ntohs(response->th_block) < block)) {
// Then it is a repeat ACK for an old block; listen again,
// but do not repeat sending the current block, and do not
// use up a retry count. (we do re-send the data if
// subsequently we time out)
goto repeat_select;
}
if ((ntohs(response->th_opcode) == ACK) &&
(ntohs(response->th_block) == block)) {
// Happy! Break out of the retries loop.
break;
}
} // End of the retries loop.
if (TFTP_RETRIES_MAX <= tries) {
tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
ok = pdFALSE;
}
if (len < SEGSIZE) {
break; // That's end of file then.
}
}
close(s);
tftpd_close_data_file(fd);
}
portTASK_FUNCTION( vBasicTFTPServer, pvParameters )
{
int lSocket;
int lDataLen, lRecvLen, lFromLen;
struct sockaddr_in sLocalAddr, sFromAddr;
portCHAR cData[SEGSIZE+sizeof(struct tftphdr)];
struct tftphdr *sHdr = (struct tftphdr *)cData;
// Set up port
// Network order in info; host order in server:
for (;;) {
// Create socket
lSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (lSocket < 0) {
return;
}
memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
sLocalAddr.sin_family = AF_INET;
sLocalAddr.sin_len = sizeof(sLocalAddr);
sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
sLocalAddr.sin_port = TFTP_PORT;
if (bind(lSocket, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr)) < 0) {
// Problem setting up my end
close(lSocket);
return;
}
lRecvLen = sizeof(cData);
lFromLen = sizeof(sFromAddr);
lDataLen = recvfrom(lSocket, sHdr, lRecvLen, 0,
(struct sockaddr *)&sFromAddr, &lFromLen);
vParTestSetLED( TFTP_LED , pdTRUE );
close(lSocket); // so that other servers can bind to the TFTP socket
if ( lDataLen < 0) {
} else {
switch (ntohs(sHdr->th_opcode)) {
case WRQ:
tftpd_write_file(sHdr, &sFromAddr, lFromLen);
vParTestSetLED( TFTP_LED , pdFALSE );
break;
case RRQ:
tftpd_read_file(sHdr, &sFromAddr, lFromLen);
vParTestSetLED( TFTP_LED , pdFALSE );
break;
case ACK:
case DATA:
case ERROR:
vParTestSetLED( TFTP_LED , pdFALSE );
// Ignore
break;
default:
for(;;)
{
vParTestToggleLED( TFTP_LED );
vTaskDelay(200);
}
}
}
}
}
#endif

View file

@ -0,0 +1,143 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Basic TFTP Server for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASIC_TFTP_SERVER_H
#define BASIC_TFTP_SERVER_H
#include "portmacro.h"
/* tftp_support.h */
/*
* File transfer modes
*/
#define TFTP_NETASCII 0 // Text files
#define TFTP_OCTET 1 // Binary files
/*
* Errors
*/
// These initial 7 are passed across the net in "ERROR" packets.
#define TFTP_ENOTFOUND 1 /* file not found */
#define TFTP_EACCESS 2 /* access violation */
#define TFTP_ENOSPACE 3 /* disk full or allocation exceeded */
#define TFTP_EBADOP 4 /* illegal TFTP operation */
#define TFTP_EBADID 5 /* unknown transfer ID */
#define TFTP_EEXISTS 6 /* file already exists */
#define TFTP_ENOUSER 7 /* no such user */
// These extensions are return codes in our API, *never* passed on the net.
#define TFTP_TIMEOUT 8 /* operation timed out */
#define TFTP_NETERR 9 /* some sort of network error */
#define TFTP_INVALID 10 /* invalid parameter */
#define TFTP_PROTOCOL 11 /* protocol violation */
#define TFTP_TOOLARGE 12 /* file is larger than buffer */
#define TFTP_TIMEOUT_PERIOD 5 // Seconds between retries
#define TFTP_TIMEOUT_MAX 50 // Max timeouts over all blocks
#define TFTP_RETRIES_MAX 5 // retries per block before giving up
/* netdb.h */
// Internet services
struct servent {
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s_port; /* port number */
char *s_proto; /* protocol to use */
};
/* arpa/tftp.h */
/*
* Trivial File Transfer Protocol (IEN-133)
*/
#define SEGSIZE 512 /* data segment size */
/*
* Packet types.
*/
#define th_block th_u.tu_block
#define th_code th_u.tu_code
#define th_stuff th_u.tu_stuff
#define th_msg th_data
/*
* Error codes.
*/
#define EUNDEF 0 /* not defined */
#define ENOTFOUND 1 /* file not found */
#define EACCESS 2 /* access violation */
#define ENOSPACE 3 /* disk full or allocation exceeded */
#define EBADOP 4 /* illegal TFTP operation */
#define EBADID 5 /* unknown transfer ID */
#define EEXISTS 6 /* file already exists */
#define ENOUSER 7 /* no such user */
#define RRQ 01 /* read request */
#define WRQ 02 /* write request */
#define DATA 03 /* data packet */
#define ACK 04 /* acknowledgement */
#define ERROR 05 /* error code */
struct tftphdr {
short th_opcode; /* packet type */
union {
unsigned short tu_block; /* block # */
short tu_code; /* error code */
char tu_stuff[1]; /* request packet stuff */
} __attribute__ ((packed)) th_u;
char th_data[1]; /* data or error string */
} __attribute__ ((packed));
/* The function that implements the TFTP server task. */
portTASK_FUNCTION_PROTO( vBasicTFTPServer, pvParameters );
#endif

View file

@ -0,0 +1,209 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Basic WEB Server for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Implements a simplistic WEB server. Every time a connection is made and
data is received a dynamic page that shows the current FreeRTOS.org kernel
statistics is generated and returned. The connection is then closed.
This file was adapted from a FreeRTOS lwIP slip demo supplied by a third
party.
*/
#if (HTTP_USED == 1)
/* Standard includes. */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "conf_eth.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "partest.h"
#include "serial.h"
/* Demo includes. */
/* Demo app includes. */
#include "AVR32_EMAC.h"
#include "portmacro.h"
/* lwIP includes. */
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include "netif/loopif.h"
/* ethernet includes */
#include "ethernet.h"
/*! The size of the buffer in which the dynamic WEB page is created. */
#define webMAX_PAGE_SIZE 512
/*! Standard GET response. */
#define webHTTP_OK "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
/*! The port on which we listen. */
#define webHTTP_PORT ( 80 )
/*! Delay on close error. */
#define webSHORT_DELAY ( 10 )
/*! Format of the dynamic page that is returned on each connection. */
#define webHTML_START \
"<html>\
<head>\
</head>\
<BODY onLoad=\"window.setTimeout(&quot;location.href='index.html'&quot;,1000)\" bgcolor=\"#FFFFFF\" text=\"#2477E6\">\
\r\nPage Hits = "
#define webHTML_END \
"\r\n</pre>\
\r\n</font></BODY>\
</html>"
portCHAR cDynamicPage[ webMAX_PAGE_SIZE ];
portCHAR cPageHits[ 11 ];
/*! Function to process the current connection */
static void prvweb_ParseHTMLRequest( struct netconn *pxNetCon );
/*! \brief WEB server main task
* check for incoming connection and process it
*
* \param pvParameters Input. Not Used.
*
*/
portTASK_FUNCTION( vBasicWEBServer, pvParameters )
{
struct netconn *pxHTTPListener, *pxNewConnection;
/* Create a new tcp connection handle */
pxHTTPListener = netconn_new( NETCONN_TCP );
netconn_bind(pxHTTPListener, NULL, webHTTP_PORT );
netconn_listen( pxHTTPListener );
/* Loop forever */
for( ;; )
{
/* Wait for a first connection. */
pxNewConnection = netconn_accept(pxHTTPListener);
vParTestSetLED(webCONN_LED, pdTRUE);
if(pxNewConnection != NULL)
{
prvweb_ParseHTMLRequest(pxNewConnection);
}/* end if new connection */
vParTestSetLED(webCONN_LED, pdFALSE);
} /* end infinite loop */
}
/*! \brief parse the incoming request
* parse the HTML request and send file
*
* \param pxNetCon Input. The netconn to use to send and receive data.
*
*/
static void prvweb_ParseHTMLRequest( struct netconn *pxNetCon )
{
struct netbuf *pxRxBuffer;
portCHAR *pcRxString;
unsigned portSHORT usLength;
static unsigned portLONG ulPageHits = 0;
/* We expect to immediately get data. */
pxRxBuffer = netconn_recv( pxNetCon );
if( pxRxBuffer != NULL )
{
/* Where is the data? */
netbuf_data( pxRxBuffer, ( void * ) &pcRxString, &usLength );
/* Is this a GET? We don't handle anything else. */
if( !strncmp( pcRxString, "GET", 3 ) )
{
pcRxString = cDynamicPage;
/* Update the hit count. */
ulPageHits++;
sprintf( cPageHits, "%d", (int)ulPageHits );
/* Write out the HTTP OK header. */
netconn_write( pxNetCon, webHTTP_OK, (u16_t) strlen( webHTTP_OK ), NETCONN_COPY );
/* Generate the dynamic page... First the page header. */
strcpy( cDynamicPage, webHTML_START );
/* ... Then the hit count... */
strcat( cDynamicPage, cPageHits );
strcat( cDynamicPage, "<p><pre>Task State Priority Stack #<br>************************************************<br>" );
/* ... Then the list of tasks and their status... */
vTaskList( ( signed portCHAR * ) cDynamicPage + strlen( cDynamicPage ) );
/* ... Finally the page footer. */
strcat( cDynamicPage, webHTML_END );
/* Write out the dynamically generated page. */
netconn_write( pxNetCon, cDynamicPage, (u16_t) strlen( cDynamicPage ), NETCONN_COPY );
}
netbuf_delete( pxRxBuffer );
}
netconn_close( pxNetCon );
netconn_delete( pxNetCon );
}
#endif

View file

@ -0,0 +1,59 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Basic WEB Server for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASIC_WEB_SERVER_H
#define BASIC_WEB_SERVER_H
#include "portmacro.h"
/*! \brief WEB server main task
*
* \param pvParameters Input. Not Used.
*
*/
portTASK_FUNCTION_PROTO( vBasicWEBServer, pvParameters );
#endif

View file

@ -0,0 +1,62 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief EMAC abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AVR32_CONF_EMAC_H
#define AVR32_CONF_EMAC_H
#include "lwip/opt.h"
/*! Number of receive buffers */
#define NB_RX_BUFFERS 20
/*! USE_RMII_INTERFACE must be defined as 1 to use an RMII interface, or 0
to use an MII interface. */
#define USE_RMII_INTERFACE 1
/*! Number of Transmit buffers */
#define NB_TX_BUFFERS ( MEMP_NUM_PBUF / 2 )
/*! Size of each Transmit buffer. */
#define ETH_TX_BUFFER_SIZE 1024 //( PBUF_POOL_BUFSIZE )
#endif //* AVR32_CONF_EMAC_H

View file

@ -0,0 +1,785 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief EMAC abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a MACB can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Interrupt driven driver for the EMAC peripheral. This driver is not
* reentrant, re-entrancy is handled by a semaphore at the network interface
* level.
*/
/* Standard includes. */
#include <stdio.h>
#include <string.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
/* Demo app includes. */
#include "AVR32_EMAC.h"
#include "AVR32_CONF_EMAC.h"
#include "DP83848.h"
#include "intc.h"
/* Hardware specific includes. */
#include "gpio.h"
/* Size of each receive buffer - DO NOT CHANGE. */
#define ETH_RX_BUFFER_SIZE 128
/* The buffer addresses written into the descriptors must be aligned so the
last few bits are zero. These bits have special meaning for the EMAC
peripheral and cannot be used as part of the address. */
#define emacADDRESS_MASK ( ( unsigned portLONG ) 0xFFFFFFFC )
/* Bit used within the address stored in the descriptor to mark the last
descriptor in the array. */
#define emacRX_WRAP_BIT ( ( unsigned portLONG ) 0x02 )
/* A short delay is used to wait for a buffer to become available, should
one not be immediately available when trying to transmit a frame. */
#define emacBUFFER_WAIT_DELAY ( 2 )
#define emacMAX_WAIT_CYCLES ( ( portBASE_TYPE ) ( configTICK_RATE_HZ / 40 ) )
/* The time to block waiting for input. */
#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 )
/* Misc defines. */
#define emacNO_DELAY ( 0 )
/*-----------------------------------------------------------*/
/* Buffer written to by the EMAC DMA. Must be aligned as described by the
comment above the emacADDRESS_MASK definition. */
static volatile portCHAR pcRxBuffer[ NB_RX_BUFFERS * ETH_RX_BUFFER_SIZE ] __attribute__ ((aligned (8)));
/* Buffer read by the EMAC DMA. Must be aligned as described by the comment
above the emacADDRESS_MASK definition. */
static portCHAR pcTxBuffer[ NB_TX_BUFFERS * ETH_TX_BUFFER_SIZE ] __attribute__ ((aligned (8)));
/* Descriptors used to communicate between the program and the EMAC peripheral.
These descriptors hold the locations and state of the Rx and Tx buffers. */
static volatile AVR32_TxTdDescriptor xTxDescriptors[ NB_TX_BUFFERS ];
static volatile AVR32_RxTdDescriptor xRxDescriptors[ NB_RX_BUFFERS ];
/* The IP and Ethernet addresses are read from the header files. */
portCHAR cMACAddress[ 6 ] = { emacETHADDR0, emacETHADDR1, emacETHADDR2, emacETHADDR3, emacETHADDR4, emacETHADDR5 };
/*-----------------------------------------------------------*/
/* See the header file for descriptions of public functions. */
/*
* Prototype for the EMAC interrupt function - called by the asm wrapper.
*/
void vEMAC_ISR( void ) __attribute__ ((naked));
/*
* Initialise both the Tx and Rx descriptors used by the EMAC.
*/
static void prvSetupDescriptors(void);
/*
* Write our MAC address into the EMAC.
*/
static void prvSetupMACAddress( void );
/*
* Configure the EMAC and AIC for EMAC interrupts.
*/
static void prvSetupEMACInterrupt( void );
/*
* Some initialisation functions taken from the Atmel EMAC sample code.
*/
static unsigned portLONG vReadPHY( unsigned portCHAR ucAddress );
static void vWritePHY( unsigned portCHAR ucAddress, unsigned portLONG ulValue);
static portBASE_TYPE prvProbePHY( void );
/* The semaphore used by the EMAC ISR to wake the EMAC task. */
static xSemaphoreHandle xSemaphore = NULL;
/* Holds the index to the next buffer from which data will be read. */
static volatile unsigned portLONG ulNextRxBuffer = 0;
/*-----------------------------------------------------------*/
/* See the header file for descriptions of public functions. */
portLONG lEMACSend( portCHAR *pcFrom, unsigned portLONG ulLength, portLONG lEndOfFrame )
{
static unsigned portBASE_TYPE uxTxBufferIndex = 0;
//portBASE_TYPE xWaitCycles = 0;
portLONG lReturn = pdPASS;
portCHAR *pcBuffer;
unsigned portLONG ulLastBuffer, ulDataBuffered = 0, ulDataRemainingToSend, ulLengthToSend;
/* If the length of data to be transmitted is greater than each individual
transmit buffer then the data will be split into more than one buffer.
Loop until the entire length has been buffered. */
while( ulDataBuffered < ulLength )
{
/* Is a buffer available? */
while( !( xTxDescriptors[ uxTxBufferIndex ].U_Status.status & AVR32_TRANSMIT_OK ) )
{
/* There is no room to write the Tx data to the Tx buffer. Wait a
short while, then try again. */
vTaskDelay( emacBUFFER_WAIT_DELAY );
}
/* lReturn will only be pdPASS if a buffer is available. */
if( lReturn == pdPASS )
{
portENTER_CRITICAL();
{
/* Get the address of the buffer from the descriptor, then copy
the data into the buffer. */
pcBuffer = ( portCHAR * ) xTxDescriptors[ uxTxBufferIndex ].addr;
/* How much can we write to the buffer? */
ulDataRemainingToSend = ulLength - ulDataBuffered;
if( ulDataRemainingToSend <= ETH_TX_BUFFER_SIZE )
{
/* We can write all the remaining bytes. */
ulLengthToSend = ulDataRemainingToSend;
}
else
{
/* We can not write more than ETH_TX_BUFFER_SIZE in one go. */
ulLengthToSend = ETH_TX_BUFFER_SIZE;
}
/* Copy the data into the buffer. */
memcpy( ( void * ) pcBuffer, ( void * ) &( pcFrom[ ulDataBuffered ] ), ulLengthToSend );
ulDataBuffered += ulLengthToSend;
/* Is this the last data for the frame? */
if( lEndOfFrame && ( ulDataBuffered >= ulLength ) )
{
/* No more data remains for this frame so we can start the
transmission. */
ulLastBuffer = AVR32_LAST_BUFFER;
}
else
{
/* More data to come for this frame. */
ulLastBuffer = 0;
}
/* Fill out the necessary in the descriptor to get the data sent,
then move to the next descriptor, wrapping if necessary. */
if( uxTxBufferIndex >= ( NB_TX_BUFFERS - 1 ) )
{
xTxDescriptors[ uxTxBufferIndex ].U_Status.status = ( ulLengthToSend & ( unsigned portLONG ) AVR32_LENGTH_FRAME )
| ulLastBuffer
| AVR32_TRANSMIT_WRAP;
uxTxBufferIndex = 0;
}
else
{
xTxDescriptors[ uxTxBufferIndex ].U_Status.status = ( ulLengthToSend & ( unsigned portLONG ) AVR32_LENGTH_FRAME )
| ulLastBuffer;
uxTxBufferIndex++;
}
/* If this is the last buffer to be sent for this frame we can
start the transmission. */
if( ulLastBuffer )
{
AVR32_MACB.ncr |= AVR32_MACB_TSTART_MASK;
}
}
portEXIT_CRITICAL();
}
else
{
break;
}
}
return lReturn;
}
/*-----------------------------------------------------------*/
/* See the header file for descriptions of public functions. */
unsigned portLONG ulEMACInputLength( void )
{
register unsigned portLONG ulIndex , ulLength = 0;
/* Skip any fragments. We are looking for the first buffer that contains
data and has the SOF (start of frame) bit set. */
while( ( xRxDescriptors[ ulNextRxBuffer ].addr & AVR32_OWNERSHIP_BIT ) && !( xRxDescriptors[ ulNextRxBuffer ].U_Status.status & AVR32_SOF ) )
{
/* Ignoring this buffer. Mark it as free again. */
xRxDescriptors[ ulNextRxBuffer ].addr &= ~( AVR32_OWNERSHIP_BIT );
ulNextRxBuffer++;
if( ulNextRxBuffer >= NB_RX_BUFFERS )
{
ulNextRxBuffer = 0;
}
}
/* We are going to walk through the descriptors that make up this frame,
but don't want to alter ulNextRxBuffer as this would prevent vEMACRead()
from finding the data. Therefore use a copy of ulNextRxBuffer instead. */
ulIndex = ulNextRxBuffer;
/* Walk through the descriptors until we find the last buffer for this
frame. The last buffer will give us the length of the entire frame. */
while( ( xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT ) && !ulLength )
{
ulLength = xRxDescriptors[ ulIndex ].U_Status.status & AVR32_LENGTH_FRAME;
/* Increment to the next buffer, wrapping if necessary. */
ulIndex++;
if( ulIndex >= NB_RX_BUFFERS )
{
ulIndex = 0;
}
}
return ulLength;
}
/*-----------------------------------------------------------*/
/* See the header file for descriptions of public functions. */
void vEMACRead( portCHAR *pcTo, unsigned portLONG ulSectionLength, unsigned portLONG ulTotalFrameLength )
{
static unsigned portLONG ulSectionBytesReadSoFar = 0, ulBufferPosition = 0, ulFameBytesReadSoFar = 0;
static portCHAR *pcSource;
register unsigned portLONG ulBytesRemainingInBuffer, ulRemainingSectionBytes;
/* Read ulSectionLength bytes from the Rx buffers. This is not necessarily any
correspondence between the length of our Rx buffers, and the length of the
data we are returning or the length of the data being requested. Therefore,
between calls we have to remember not only which buffer we are currently
processing, but our position within that buffer. This would be greatly
simplified if PBUF_POOL_BUFSIZE could be guaranteed to be greater than
the size of each Rx buffer, and that memory fragmentation did not occur.
This function should only be called after a call to ulEMACInputLength().
This will ensure ulNextRxBuffer is set to the correct buffer. */
/* vEMACRead is called with pcTo set to NULL to indicate that we are about
to read a new frame. Any fragments remaining in the frame we were
processing during the last call should be dropped. */
if( pcTo == NULL )
{
/* How many bytes are indicated as being in this buffer? If none then
the buffer is completely full and the frame is contained within more
than one buffer. */
/* Reset our state variables ready for the next read from this buffer. */
pcSource = ( portCHAR * )( xRxDescriptors[ ulNextRxBuffer ].addr & emacADDRESS_MASK );
ulFameBytesReadSoFar = ( unsigned portLONG ) 0;
ulBufferPosition = ( unsigned portLONG ) 0;
}
else
{
/* Loop until we have obtained the required amount of data. */
ulSectionBytesReadSoFar = 0;
while( ulSectionBytesReadSoFar < ulSectionLength )
{
/* We may have already read some data from this buffer. How much
data remains in the buffer? */
ulBytesRemainingInBuffer = ( ETH_RX_BUFFER_SIZE - ulBufferPosition );
/* How many more bytes do we need to read before we have the
required amount of data? */
ulRemainingSectionBytes = ulSectionLength - ulSectionBytesReadSoFar;
/* Do we want more data than remains in the buffer? */
if( ulRemainingSectionBytes > ulBytesRemainingInBuffer )
{
/* We want more data than remains in the buffer so we can
write the remains of the buffer to the destination, then move
onto the next buffer to get the rest. */
memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulBytesRemainingInBuffer );
ulSectionBytesReadSoFar += ulBytesRemainingInBuffer;
ulFameBytesReadSoFar += ulBytesRemainingInBuffer;
/* Mark the buffer as free again. */
xRxDescriptors[ ulNextRxBuffer ].addr &= ~( AVR32_OWNERSHIP_BIT );
/* Move onto the next buffer. */
ulNextRxBuffer++;
if( ulNextRxBuffer >= NB_RX_BUFFERS )
{
ulNextRxBuffer = ( unsigned portLONG ) 0;
}
/* Reset the variables for the new buffer. */
pcSource = ( portCHAR * )( xRxDescriptors[ ulNextRxBuffer ].addr & emacADDRESS_MASK );
ulBufferPosition = ( unsigned portLONG ) 0;
}
else
{
/* We have enough data in this buffer to send back. Read out
enough data and remember how far we read up to. */
memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulRemainingSectionBytes );
/* There may be more data in this buffer yet. Increment our
position in this buffer past the data we have just read. */
ulBufferPosition += ulRemainingSectionBytes;
ulSectionBytesReadSoFar += ulRemainingSectionBytes;
ulFameBytesReadSoFar += ulRemainingSectionBytes;
/* Have we now finished with this buffer? */
if( ( ulBufferPosition >= ETH_RX_BUFFER_SIZE ) || ( ulFameBytesReadSoFar >= ulTotalFrameLength ) )
{
/* Mark the buffer as free again. */
xRxDescriptors[ ulNextRxBuffer ].addr &= ~( AVR32_OWNERSHIP_BIT );
/* Move onto the next buffer. */
ulNextRxBuffer++;
if( ulNextRxBuffer >= NB_RX_BUFFERS )
{
ulNextRxBuffer = 0;
}
pcSource = ( portCHAR * )( xRxDescriptors[ ulNextRxBuffer ].addr & emacADDRESS_MASK );
ulBufferPosition = 0;
}
}
}
}
}
/*-----------------------------------------------------------*/
void vEMACSetMACAddress(const portCHAR * EMACAddress)
{
memcpy(cMACAddress, EMACAddress, sizeof(cMACAddress));
}
/* See the header file for descriptions of public functions. */
xSemaphoreHandle xEMACInit( void )
{
unsigned long status;
/* enable GPIO's */
gpio_enable_module_pin(AVR32_MACB_TX_CLK_0_PIN, AVR32_MACB_TX_CLK_0_FUNCTION); //PB0
gpio_enable_module_pin(AVR32_MACB_TX_EN_0_PIN, AVR32_MACB_TX_EN_0_FUNCTION); //PB1
gpio_enable_module_pin(AVR32_MACB_TXD_0_PIN, AVR32_MACB_TXD_0_FUNCTION); //PB2
gpio_enable_module_pin(AVR32_MACB_TXD_1_PIN, AVR32_MACB_TXD_1_FUNCTION); //PB3
gpio_enable_module_pin(AVR32_MACB_RXD_0_PIN, AVR32_MACB_RXD_0_FUNCTION); //PB5
gpio_enable_module_pin(AVR32_MACB_RXD_1_PIN, AVR32_MACB_RXD_1_FUNCTION); //PB6
gpio_enable_module_pin(AVR32_MACB_RX_ER_0_PIN, AVR32_MACB_RX_ER_0_FUNCTION); //PB7
gpio_enable_module_pin(AVR32_MACB_MDC_0_PIN, AVR32_MACB_MDC_0_FUNCTION); //PB8
gpio_enable_module_pin(AVR32_MACB_MDIO_0_PIN, AVR32_MACB_MDIO_0_FUNCTION); //PB9
gpio_enable_module_pin(AVR32_MACB_RX_DV_0_PIN, AVR32_MACB_RX_DV_0_FUNCTION); //PB15
/* set up registers */
AVR32_MACB.ncr = 0;
AVR32_MACB.tsr = ~0UL;
AVR32_MACB.rsr = ~0UL;
AVR32_MACB.idr = ~0UL;
status = AVR32_MACB.isr;
#ifndef USE_RMII_INTERFACE
// RMII not used, set 1 to the USRIO Register
AVR32_MACB.usrio |= AVR32_MACB_RMII_MASK;
#else
// RMII used, set 0 to the USRIO Register
AVR32_MACB.usrio &= ~AVR32_MACB_RMII_MASK;
#endif
/* Load our MAC address into the EMAC. */
prvSetupMACAddress();
/* Setup the buffers and descriptors. */
prvSetupDescriptors();
#if configCPU_CLOCK_HZ <= 20000000
AVR32_MACB.ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV8 << AVR32_MACB_NCFGR_CLK_OFFSET);
#elif configCPU_CLOCK_HZ <= 40000000
AVR32_MACB.ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV16 << AVR32_MACB_NCFGR_CLK_OFFSET);
#elif configCPU_CLOCK_HZ <= 80000000
AVR32_MACB.ncfgr |= AVR32_MACB_NCFGR_CLK_DIV32 << AVR32_MACB_NCFGR_CLK_OFFSET;
#elif configCPU_CLOCK_HZ <= 160000000
AVR32_MACB.ncfgr |= AVR32_MACB_NCFGR_CLK_DIV64 << AVR32_MACB_NCFGR_CLK_OFFSET;
#else
# error System clock too fast
#endif
/* Are we connected? */
if( prvProbePHY() )
{
/* Enable the interrupt! */
portENTER_CRITICAL();
{
prvSetupEMACInterrupt();
vPassEMACSemaphore( xSemaphore );
}
portEXIT_CRITICAL();
/* Enable Rx and Tx, plus the stats register. */
AVR32_MACB.ncr = AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK;
}
return xSemaphore;
}
/* See the header file for descriptions of public functions. */
void vClearEMACTxBuffer( void )
{
static unsigned portBASE_TYPE uxNextBufferToClear = 0;
/* Called on Tx interrupt events to set the AT91C_TRANSMIT_OK bit in each
Tx buffer within the frame just transmitted. This marks all the buffers
as available again.
The first buffer in the frame should have the bit set automatically. */
if( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_TRANSMIT_OK )
{
/* Loop through the other buffers in the frame. */
while( !( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_LAST_BUFFER ) )
{
uxNextBufferToClear++;
if( uxNextBufferToClear >= NB_TX_BUFFERS )
{
uxNextBufferToClear = 0;
}
xTxDescriptors[ uxNextBufferToClear ].U_Status.status |= AVR32_TRANSMIT_OK;
}
/* Start with the next buffer the next time a Tx interrupt is called. */
uxNextBufferToClear++;
/* Do we need to wrap back to the first buffer? */
if( uxNextBufferToClear >= NB_TX_BUFFERS )
{
uxNextBufferToClear = 0;
}
}
}
/*-----------------------------------------------------------*/
static void prvSetupDescriptors(void)
{
unsigned portBASE_TYPE xIndex;
unsigned portLONG ulAddress;
/* Initialise xRxDescriptors descriptor. */
for( xIndex = 0; xIndex < NB_RX_BUFFERS; ++xIndex )
{
/* Calculate the address of the nth buffer within the array. */
ulAddress = ( unsigned portLONG )( pcRxBuffer + ( xIndex * ETH_RX_BUFFER_SIZE ) );
/* Write the buffer address into the descriptor. The DMA will place
the data at this address when this descriptor is being used. Mask off
the bottom bits of the address as these have special meaning. */
xRxDescriptors[ xIndex ].addr = ulAddress & emacADDRESS_MASK;
}
/* The last buffer has the wrap bit set so the EMAC knows to wrap back
to the first buffer. */
xRxDescriptors[ NB_RX_BUFFERS - 1 ].addr |= emacRX_WRAP_BIT;
/* Initialise xTxDescriptors. */
for( xIndex = 0; xIndex < NB_TX_BUFFERS; ++xIndex )
{
/* Calculate the address of the nth buffer within the array. */
ulAddress = ( unsigned portLONG )( pcTxBuffer + ( xIndex * ETH_TX_BUFFER_SIZE ) );
/* Write the buffer address into the descriptor. The DMA will read
data from here when the descriptor is being used. */
xTxDescriptors[ xIndex ].addr = ulAddress & emacADDRESS_MASK;
xTxDescriptors[ xIndex ].U_Status.status = AVR32_TRANSMIT_OK;
}
/* The last buffer has the wrap bit set so the EMAC knows to wrap back
to the first buffer. */
xTxDescriptors[ NB_TX_BUFFERS - 1 ].U_Status.status = AVR32_TRANSMIT_WRAP | AVR32_TRANSMIT_OK;
/* Tell the EMAC where to find the descriptors. */
AVR32_MACB.rbqp = ( unsigned portLONG )xRxDescriptors;
AVR32_MACB.tbqp = ( unsigned portLONG )xTxDescriptors;
/* Enable the copy of data into the buffers, ignore broadcasts,
and don't copy FCS. */
AVR32_MACB.ncfgr |= (AVR32_MACB_CAF_MASK | AVR32_MACB_NBC_MASK | AVR32_MACB_NCFGR_DRFCS_MASK);
}
/*-----------------------------------------------------------*/
static void prvSetupMACAddress( void )
{
/* Must be written SA1L then SA1H. */
AVR32_MACB.sa1b = ( ( unsigned portLONG ) cMACAddress[ 3 ] << 24 ) |
( ( unsigned portLONG ) cMACAddress[ 2 ] << 16 ) |
( ( unsigned portLONG ) cMACAddress[ 1 ] << 8 ) |
cMACAddress[ 0 ];
AVR32_MACB.sa1t = ( ( unsigned portLONG ) cMACAddress[ 5 ] << 8 ) |
cMACAddress[ 4 ];
}
/*-----------------------------------------------------------*/
static void prvSetupEMACInterrupt( void )
{
/* Create the semaphore used to trigger the EMAC task. */
if (xSemaphore == NULL)
{
vSemaphoreCreateBinary( xSemaphore );
}
if( xSemaphore )
{
/* We start by 'taking' the semaphore so the ISR can 'give' it when the
first interrupt occurs. */
xSemaphoreTake( xSemaphore, emacNO_DELAY );
portENTER_CRITICAL();
{
/* Setup the interrupt for USART0.
Register the USART0 interrupt handler to the interrupt controller
at interrupt level 2. */
INTC_register_interrupt(&vEMAC_ISR, AVR32_MACB_IRQ, INT2);
/* We want to interrupt on Rx and Tx events. */
AVR32_MACB.ier = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK;
}
portEXIT_CRITICAL();
}
}
/*
* The following functions are initialisation functions taken from the Atmel
* EMAC sample code.
*/
static portBASE_TYPE prvProbePHY( void )
{
unsigned long mii_status, advertise, lpa, phy_ctrl;
unsigned long config;
unsigned long upper, lower,mode;
unsigned long physID;
/* Read Phy Identifier register 1 & 2 */
lower = vReadPHY(PHY_PHYSID2);
upper = vReadPHY(PHY_PHYSID1);
/* get Phy ID, ignore Revision */
physID = ((upper << 16) & 0xFFFF0000) | (lower & 0xFFF0);
/* check if it match config */
if (physID == MII_DP83848_ID)
{
/* read RBR */
mode = vReadPHY(PHY_RBR);
/* set RMII mode if not done */
if ((mode & RBR_RMII) != RBR_RMII)
{
/* force RMII flag if strap options are wrong */
mode |= RBR_RMII;
vWritePHY(PHY_RBR,mode);
}
/* set advertise register */
#if ETHERNET_CONF_AN_ENABLE == 1
advertise = ADVERTISE_CSMA | ADVERTISE_ALL;
#else
advertise = ADVERTISE_CSMA;
#if ETHERNET_CONF_USE_100MB
#if ETHERNET_CONF_USE_FULL_DUPLEX
advertise |= ADVERTISE_100FULL;
#else
advertise |= ADVERTISE_100HALF;
#endif
#else
#if ETHERNET_CONF_USE_FULL_DUPLEX
advertise |= ADVERTISE_10FULL;
#else
advertise |= ADVERTISE_10HALF;
#endif
#endif
#endif
/* write advertise register */
vWritePHY(PHY_ADVERTISE, advertise);
/* read Control register */
config = vReadPHY(PHY_BMCR);
/* read Phy Control register */
phy_ctrl = vReadPHY(PHY_PHYCR);
#if ETHERNET_CONF_AN_ENABLE
#if ETHERNET_CONF_AUTO_CROSS_ENABLE
/* enable Auto MDIX */
phy_ctrl |= PHYCR_MDIX_EN;
#else
/* disable Auto MDIX */
phy_ctrl &= ~PHYCR_MDIX_EN;
#if ETHERNET_CONF_CROSSED_LINK
/* force direct link = Use crossed RJ45 cable */
phy_ctrl &= ~PHYCR_MDIX_FORCE;
#else
/* force crossed link = Use direct RJ45 cable */
phy_ctrl |= PHYCR_MDIX_FORCE;
#endif
#endif
/* reset auto-negociation capability */
config |= (BMCR_ANRESTART | BMCR_ANENABLE);
#else
/* disable Auto MDIX */
phy_ctrl &= ~PHYCR_MDIX_EN;
#if ETHERNET_CONF_CROSSED_LINK
/* force direct link = Use crossed RJ45 cable */
phy_ctrl &= ~PHYCR_MDIX_FORCE;
#else
/* force crossed link = Use direct RJ45 cable */
phy_ctrl |= PHYCR_MDIX_FORCE;
#endif
/* clear AN bit */
config &= ~BMCR_ANENABLE;
#if ETHERNET_CONF_USE_100MB
config |= BMCR_SPEED100;
#else
config &= ~BMCR_SPEED100;
#endif
#if ETHERNET_CONF_USE_FULL_DUPLEX
config |= BMCR_FULLDPLX;
#else
config &= ~BMCR_FULLDPLX;
#endif
#endif
/* update Phy ctrl register */
vWritePHY(PHY_PHYCR, phy_ctrl);
/* update ctrl register */
vWritePHY(PHY_BMCR, config);
/* loop while link status isn't OK */
do {
mii_status = vReadPHY(PHY_BMSR);
} while (!(mii_status & BMSR_LSTATUS));
/* read the LPA configuration of the PHY */
lpa = vReadPHY(PHY_LPA);
/* read the MACB config register */
config = AVR32_MACB.ncfgr;
/* if 100MB needed */
if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL))
{
config |= AVR32_MACB_SPD_MASK;
}
else
{
config &= ~(AVR32_MACB_SPD_MASK);
}
/* if FULL DUPLEX needed */
if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL))
{
config |= AVR32_MACB_FD_MASK;
}
else
{
config &= ~(AVR32_MACB_FD_MASK);
}
/* write the MACB config register */
AVR32_MACB.ncfgr = config;
return pdPASS;
}
return pdFAIL;
}
static unsigned portLONG vReadPHY( unsigned portCHAR ucAddress )
{
unsigned portLONG pulValue;
/* Enable management port */
AVR32_MACB.ncr |= AVR32_MACB_NCR_MPE_MASK;
/* configure MDIO frame in MAN register */
AVR32_MACB.man = (AVR32_MACB_SOF_MASK & (0x01<<AVR32_MACB_SOF_OFFSET)) // SOF
| (2 << AVR32_MACB_CODE_OFFSET) // Code
| (2 << AVR32_MACB_RW_OFFSET) // Read operation
| ((DP83848_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET) // Phy Add
| (ucAddress << AVR32_MACB_REGA_OFFSET); // Reg Add
/* Wait until IDLE bit in Network Status register is cleared. */
while( !( AVR32_MACB.nsr & AVR32_MACB_NSR_IDLE_MASK ) )
{
__asm( "NOP" );
}
pulValue = (AVR32_MACB.man & 0x0000ffff );
/* Disable management port */
AVR32_MACB.ncr &= ~AVR32_MACB_NCR_MPE_MASK;
return (pulValue);
}
static void vWritePHY( unsigned portCHAR ucAddress, unsigned portLONG ulValue )
{
/* Enable management port */
AVR32_MACB.ncr |= AVR32_MACB_NCR_MPE_MASK;
/* configure MDIO frame in MAN register */
AVR32_MACB.man = (( AVR32_MACB_SOF_MASK & (0x01<<AVR32_MACB_SOF_OFFSET)) // SOF
| (2 << AVR32_MACB_CODE_OFFSET) // Code
| (1 << AVR32_MACB_RW_OFFSET) // Write operation
| ((DP83848_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET) // Phy Add
| (ucAddress << AVR32_MACB_REGA_OFFSET)) // Reg Add
| (ulValue & 0xffff); // Data
/* Wait until IDLE bit in Network Status register is cleared */
while( !( AVR32_MACB.nsr & AVR32_MACB_NSR_IDLE_MASK ) )
{
__asm( "NOP" );
};
/* Disable management port */
AVR32_MACB.ncr &= ~AVR32_MACB_NCR_MPE_MASK;
}
void vEMACWaitForInput( void )
{
/* Just wait until we are signled from an ISR that data is available, or
we simply time out. */
xSemaphoreTake( xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT );
}

View file

@ -0,0 +1,206 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief EMAC abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AVR32_EMAC_H
#define AVR32_EMAC_H
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
#else
# error Unknown compiler
#endif
#include <arch/sys_arch.h>
#include "conf_eth.h"
/* Receive Transfer descriptor structure */
typedef struct _AVR32_RxTdDescriptor {
unsigned int addr;
union
{
unsigned int status;
struct {
unsigned int BroadCast:1;
unsigned int MultiCast:1;
unsigned int UniCast:1;
unsigned int ExternalAdd:1;
unsigned int Res1:1;
unsigned int Sa1Match:1;
unsigned int Sa2Match:1;
unsigned int Sa3Match:1;
unsigned int Sa4Match:1;
unsigned int TypeID:1;
unsigned int VlanTag:1;
unsigned int PriorityTag:1;
unsigned int VlanPriority:3;
unsigned int Cfi:1;
unsigned int EndOfFrame:1;
unsigned int StartOfFrame:1;
unsigned int Rxbuf_off:2;
unsigned int Res0:1;
unsigned int Length:11;
}S_Status;
}U_Status;
}AVR32_RxTdDescriptor, *AVR32P_RxTdDescriptor;
/* Transmit Transfer descriptor structure */
typedef struct _AVR32_TxTdDescriptor {
unsigned int addr;
union
{
unsigned int status;
struct {
unsigned int BuffUsed:1;
unsigned int Wrap:1;
unsigned int TransmitError:1;
unsigned int TransmitUnderrun:1;
unsigned int BufExhausted:1;
unsigned int Res1:10;
unsigned int NoCrc:1;
unsigned int LastBuff:1;
unsigned int Res0:4;
unsigned int Length:11;
}S_Status;
}U_Status;
}AVR32_TxTdDescriptor, *AVR32P_TxTdDescriptor;
#define AVR32_OWNERSHIP_BIT 0x00000001
/* Receive status defintion */
#define AVR32_BROADCAST_ADDR ((unsigned int) (1 << 31)) //* Broadcat address detected
#define AVR32_MULTICAST_HASH ((unsigned int) (1 << 30)) //* MultiCast hash match
#define AVR32_UNICAST_HASH ((unsigned int) (1 << 29)) //* UniCast hash match
#define AVR32_EXTERNAL_ADDR ((unsigned int) (1 << 28)) //* External Address match
#define AVR32_SA1_ADDR ((unsigned int) (1 << 26)) //* Specific address 1 match
#define AVR32_SA2_ADDR ((unsigned int) (1 << 25)) //* Specific address 2 match
#define AVR32_SA3_ADDR ((unsigned int) (1 << 24)) //* Specific address 3 match
#define AVR32_SA4_ADDR ((unsigned int) (1 << 23)) //* Specific address 4 match
#define AVR32_TYPE_ID ((unsigned int) (1 << 22)) //* Type ID match
#define AVR32_VLAN_TAG ((unsigned int) (1 << 21)) //* VLAN tag detected
#define AVR32_PRIORITY_TAG ((unsigned int) (1 << 20)) //* PRIORITY tag detected
#define AVR32_VLAN_PRIORITY ((unsigned int) (7 << 17)) //* PRIORITY Mask
#define AVR32_CFI_IND ((unsigned int) (1 << 16)) //* CFI indicator
#define AVR32_EOF ((unsigned int) (1 << 15)) //* EOF
#define AVR32_SOF ((unsigned int) (1 << 14)) //* SOF
#define AVR32_RBF_OFFSET ((unsigned int) (3 << 12)) //* Receive Buffer Offset Mask
#define AVR32_LENGTH_FRAME ((unsigned int) 0x0FFF) //* Length of frame
/* Transmit Status definition */
#define AVR32_TRANSMIT_OK ((unsigned int) (1 << 31)) //*
#define AVR32_TRANSMIT_WRAP ((unsigned int) (1 << 30)) //* Wrap bit: mark the last descriptor
#define AVR32_TRANSMIT_ERR ((unsigned int) (1 << 29)) //* RLE:transmit error
#define AVR32_TRANSMIT_UND ((unsigned int) (1 << 28)) //* Transmit Underrun
#define AVR32_BUF_EX ((unsigned int) (1 << 27)) //* Buffers exhausted in mid frame
#define AVR32_TRANSMIT_NO_CRC ((unsigned int) (1 << 16)) //* No CRC will be appended to the current frame
#define AVR32_LAST_BUFFER ((unsigned int) (1 << 15)) //*
#define AVR32_EMAC_CLKEN 0x2
/*
* Initialise the EMAC driver. If successful a semaphore is returned that
* is used by the EMAC ISR to indicate that Rx packets have been received.
* If the initialisation fails then NULL is returned.
*/
xSemaphoreHandle xEMACInit( void );
/*
* Send ulLength bytes from pcFrom. This copies the buffer to one of the
* EMAC Tx buffers, then indicates to the EMAC that the buffer is ready.
* If lEndOfFrame is true then the data being copied is the end of the frame
* and the frame can be transmitted.
*/
portLONG lEMACSend( portCHAR *pcFrom, unsigned portLONG ulLength, portLONG lEndOfFrame );
/*
* Frames can be read from the EMAC in multiple sections.
* Read ulSectionLength bytes from the EMAC receive buffers to pcTo.
* ulTotalFrameLength is the size of the entire frame. Generally vEMACRead
* will be repetedly called until the sum of all the ulSectionLenths totals
* the value of ulTotalFrameLength.
*/
void vEMACRead( portCHAR *pcTo, unsigned portLONG ulSectionLength, unsigned portLONG ulTotalFrameLength );
/*
* The EMAC driver and interrupt service routines are defined in different
* files as the driver is compiled to THUMB, and the ISR to ARM. This function
* simply passes the semaphore used to communicate between the two.
*/
void vPassEMACSemaphore( xSemaphoreHandle xCreatedSemaphore );
/*
* Called by the Tx interrupt, this function traverses the buffers used to
* hold the frame that has just completed transmission and marks each as
* free again.
*/
void vClearEMACTxBuffer( void );
/*
* Suspend on a semaphore waiting either for the semaphore to be obtained
* or a timeout. The semaphore is used by the EMAC ISR to indicate that
* data has been received and is ready for processing.
*/
void vEMACWaitForInput( void );
/*
* Return the length of the next frame in the receive buffers.
*/
unsigned portLONG ulEMACInputLength( void );
/*
* Set the MACB Physical address (SA1B & SA1T registers).
*/
void vEMACSetMACAddress(const portCHAR * EMACAddress);
/*
* Get the MACB Physical address (SA1B & SA1T registers).
*/
void vEMACGetMACAddress(portCHAR * EMACAddress);
#endif

View file

@ -0,0 +1,129 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief EMAC abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "AVR32_EMAC.h"
#include "AVR32_CONF_EMAC.h"
#include "lwipopts.h"
/*-----------------------------------------------------------*/
/* The semaphore used to signal the arrival of new data to the interface
task. */
static xSemaphoreHandle xSemaphore = NULL;
static __attribute__((__noinline__)) portBASE_TYPE prvEMAC_ISR_NonNakedBehaviour( void );
/*
* The EMAC ISR. Handles both Tx and Rx complete interrupts.
*/
//__attribute__((naked,section (".handlers"))) void vEMAC_ISR( void )
__attribute__((naked)) void vEMAC_ISR( void )
{
/* This ISR can cause a context switch, so the first statement must be a
call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
variable declarations. */
portENTER_SWITCHING_ISR();
prvEMAC_ISR_NonNakedBehaviour();
/* Exit the ISR. If a task was woken by either a character being received
or transmitted then a context switch will occur. */
portEXIT_SWITCHING_ISR();
}
/*-----------------------------------------------------------*/
static __attribute__((__noinline__)) portBASE_TYPE prvEMAC_ISR_NonNakedBehaviour( void )
{
/* Variable definitions can be made now. */
volatile unsigned portLONG ulIntStatus, ulEventStatus;
portBASE_TYPE xSwitchRequired = pdFALSE;
extern void vClearEMACTxBuffer( void );
/* Find the cause of the interrupt. */
ulIntStatus = AVR32_MACB.isr;
ulEventStatus = AVR32_MACB.rsr;
if( ( ulIntStatus & AVR32_MACB_IDR_RCOMP_MASK ) || ( ulEventStatus & AVR32_MACB_REC_MASK ) )
{
/* A frame has been received, signal the lwIP task so it can process
the Rx descriptors. */
portENTER_CRITICAL();
xSwitchRequired = xSemaphoreGiveFromISR( xSemaphore, pdFALSE );
portEXIT_CRITICAL();
AVR32_MACB.rsr = AVR32_MACB_REC_MASK;
AVR32_MACB.rsr;
}
if( ulIntStatus & AVR32_MACB_TCOMP_MASK )
{
/* A frame has been transmitted. Mark all the buffers used by the
frame just transmitted as free again. */
vClearEMACTxBuffer();
AVR32_MACB.tsr = AVR32_MACB_TSR_COMP_MASK;
AVR32_MACB.tsr;
}
return ( xSwitchRequired );
}
/*-----------------------------------------------------------*/
void vPassEMACSemaphore( xSemaphoreHandle xCreatedSemaphore )
{
/* Simply store the semaphore that should be used by the ISR. */
xSemaphore = xCreatedSemaphore;
}

View file

@ -0,0 +1,166 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief PHY abstraction layer for AVR32 UC3 on EVK1100.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* DP83848 registers. */
/*! Generic MII registers. */
#define PHY_BMCR 0x00 /* Basic mode control register */
#define PHY_BMSR 0x01 /* Basic mode status register */
#define PHY_PHYSID1 0x02 /* PHYS ID 1 */
#define PHY_PHYSID2 0x03 /* PHYS ID 2 */
#define PHY_ADVERTISE 0x04 /* Advertisement control reg */
#define PHY_LPA 0x05 /* Link partner ability reg */
#if BOARD == EVK1100
/*! Extended registers for DP83848 */
#define PHY_RBR 0x17 /* RMII Bypass reg */
#define PHY_MICR 0x11 /* Interrupt Control reg */
#define PHY_MISR 0x12 /* Interrupt Status reg */
#define PHY_PHYCR 0x19 /* Phy CTRL reg */
#endif
/*! Basic mode control register. */
#define BMCR_RESV 0x007f /* Unused... */
#define BMCR_CTST 0x0080 /* Collision test */
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
#define BMCR_ISOLATE 0x0400 /* Disconnect PHY from MII */
#define BMCR_PDOWN 0x0800 /* Powerdown the PHY */
#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
#define BMCR_RESET 0x8000 /* Reset the PHY */
/*! Basic mode status register. */
#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
#define BMSR_JCD 0x0002 /* Jabber detected */
#define BMSR_LSTATUS 0x0004 /* Link status */
#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
#define BMSR_RFAULT 0x0010 /* Remote fault detected */
#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
#define BMSR_RESV 0x00c0 /* Unused... */
#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */
#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
/*! Advertisement control register. */
#define ADVERTISE_SLCT 0x001f /* Selector bits */
#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
#define ADVERTISE_RESV 0x1000 /* Unused... */
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_CSMA)
#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
ADVERTISE_100HALF | ADVERTISE_100FULL)
/*! Link partner ability register. */
#define LPA_SLCT 0x001f /* Same as advertise selector */
#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
#define LPA_PAUSE_CAP 0x0400 /* Can pause */
#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
#define LPA_RESV 0x1000 /* Unused... */
#define LPA_RFAULT 0x2000 /* Link partner faulted */
#define LPA_LPACK 0x4000 /* Link partner acked us */
#define LPA_NPAGE 0x8000 /* Next page bit */
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
#if BOARD == EVK1100
/*! RMII Bypass Register */
#define RBR_RMII 0x0020 /* RMII Mode */
/*! Interrupt Ctrl Register */
#define MICR_INTEN 0x0002 /* Enable interrupts */
#define MICR_INTOE 0x0001 /* Enable INT output */
/*! Interrupt Status Register */
#define MISR_ED_INT_EN 0x0040 /* Energy Detect enabled */
#define MISR_LINK_INT_EN 0x0020 /* Link status change enabled */
#define MISR_SPD_INT_EN 0x0010 /* Speed change enabled */
#define MISR_DP_INT_EN 0x0008 /* Duplex mode change enabled */
#define MISR_ANC_INT_EN 0x0004 /* Auto-Neg complete enabled */
#define MISR_FHF_INT_EN 0x0002 /* False Carrier enabled */
#define MISR_RHF_INT_EN 0x0001 /* Receive Error enabled */
#define MISR_ED_INT 0x4000 /* Energy Detect */
#define MISR_LINK_INT 0x2000 /* Link status change */
#define MISR_SPD_INT 0x1000 /* Speed change */
#define MISR_DP_INT 0x0800 /* Duplex mode change */
#define MISR_ANC_INT 0x0400 /* Auto-Neg complete */
#define MISR_FHF_INT 0x0200 /* False Carrier */
#define MISR_RHF_INT 0x0100 /* Receive Error */
/*! Phy Ctrl Register */
#define PHYCR_MDIX_EN 0x8000 /* Enable Auto MDIX */
#define PHYCR_MDIX_FORCE 0x4000 /* Force MDIX crossed */
#endif
/*! PHY ID */
#define MII_DP83848_ID 0x20005C90 /* 0x00225541 */
/*! PHY Address */
#define DP83848_PHY_ADDR 0x01

View file

@ -0,0 +1,195 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief ethernet management for AVR32 UC3.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "conf_eth.h"
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
/* Demo program include files. */
#include "partest.h"
#include "serial.h"
/* ethernet includes */
#include "ethernet.h"
#include "AVR32_EMAC.h"
#if (HTTP_USED == 1)
#include "BasicWEB.h"
#endif
#if (TFTP_USED == 1)
#include "BasicTFTP.h"
#endif
#if (SMTP_USED == 1)
#include "BasicSMTP.h"
#endif
/* lwIP includes */
#include "lwip/sys.h"
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include "netif/loopif.h"
//_____ M A C R O S ________________________________________________________
//_____ D E F I N I T I O N S ______________________________________________
/* global variable containing MAC Config (hw addr, IP, GW, ...) */
struct netif EMAC_if;
//_____ D E C L A R A T I O N S ____________________________________________
/* Initialisation required by lwIP. */
static void prvlwIPInit( void );
/* Initialisation of ethernet interfaces by reading config file */
static void prvEthernetConfigureInterface(void * param);
/*! \brief create ethernet task, for ethernet management.
*
* \param uxPriority Input. priority for the task, it should be low
*
*/
void vStartEthernetTask( unsigned portBASE_TYPE uxPriority )
{
/* Setup lwIP. */
prvlwIPInit();
#if (HTTP_USED == 1)
/* Create the WEB server task. This uses the lwIP RTOS abstraction layer.*/
sys_thread_new( vBasicWEBServer, ( void * ) NULL, ethWEBSERVER_PRIORITY );
#endif
#if (TFTP_USED == 1)
/* Create the TFTP server task. This uses the lwIP RTOS abstraction layer.*/
sys_thread_new( vBasicTFTPServer, ( void * ) NULL, ethTFTPSERVER_PRIORITY );
#endif
#if (SMTP_USED == 1)
/* Create the SMTP Host task. This uses the lwIP RTOS abstraction layer.*/
sys_thread_new( vBasicSMTPHost, ( void * ) NULL, ethSMTPHOST_PRIORITY );
#endif
}
/*!
* \brief start lwIP layer.
*/
static void prvlwIPInit( void )
{
/* Initialize lwIP and its interface layer. */
#if LWIP_STATS
stats_init();
#endif
sys_init();
mem_init();
memp_init();
pbuf_init();
netif_init();
/* once TCP stack has been initalized, set hw and IP parameters, initialize MACB too */
tcpip_init( prvEthernetConfigureInterface, NULL );
}
/*!
* \brief set ethernet config
*/
static void prvEthernetConfigureInterface(void * param)
{
struct ip_addr xIpAddr, xNetMask, xGateway;
extern err_t ethernetif_init( struct netif *netif );
portCHAR MacAddress[6];
/* Default MAC addr. */
MacAddress[0] = emacETHADDR0;
MacAddress[1] = emacETHADDR1;
MacAddress[2] = emacETHADDR2;
MacAddress[3] = emacETHADDR3;
MacAddress[4] = emacETHADDR4;
MacAddress[5] = emacETHADDR5;
/* pass the EMAC address to AVR32_EMAC module */
vEMACSetMACAddress( MacAddress );
/* set MAC hardware address length to be used by lwIP */
EMAC_if.hwaddr_len = 6;
/* set MAC hardware address to be used by lwIP */
memcpy( EMAC_if.hwaddr, MacAddress, EMAC_if.hwaddr_len );
/* Default ip addr. */
IP4_ADDR( &xIpAddr,emacIPADDR0,emacIPADDR1,emacIPADDR2,emacIPADDR3 );
/* Default Subnet mask. */
IP4_ADDR( &xNetMask,emacNET_MASK0,emacNET_MASK1,emacNET_MASK2,emacNET_MASK3 );
/* Default Gw addr. */
IP4_ADDR( &xGateway,emacGATEWAY_ADDR0,emacGATEWAY_ADDR1,emacGATEWAY_ADDR2,emacGATEWAY_ADDR3 );
/* add data to netif */
netif_add( &EMAC_if, &xIpAddr, &xNetMask, &xGateway, NULL, ethernetif_init, tcpip_input );
/* make it the default interface */
netif_set_default( &EMAC_if );
/* bring it up */
netif_set_up( &EMAC_if );
}

View file

@ -0,0 +1,59 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief ethernet headers for AVR32 UC3.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ETHERNET_H
#define ETHERNET_H
/*! \brief create ethernet task, for ethernet management.
*
* \param uxPriority Input. priority for the task, it should be low
*
*/
void vStartEthernetTask( unsigned portBASE_TYPE uxPriority );
#endif

View file

@ -0,0 +1,75 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CC_H__
#define __CC_H__
#include "cpu.h"
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
typedef u32_t mem_ptr_t;
typedef int sys_prot_t;
/*! Defines for the LWIP_STATS feature. */
#define S16_F "d"
#define U16_F "d"
#define X16_F "d"
#define X32_F "d"
#define U32_F "d"
#define S32_F "d"
#define LWIP_PLATFORM_DIAG(x)
#define LWIP_PLATFORM_ASSERT(x)
/* */
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#endif /* __CC_H__ */

View file

@ -0,0 +1,50 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CPU_H__
#define __CPU_H__
#define BYTE_ORDER BIG_ENDIAN
#endif /* __CPU_H__ */

View file

@ -0,0 +1,57 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_INIT_H__
#define __ARCH_INIT_H__
#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg)
void tcpip_init_done(void *);
int wait_for_tcpip_init(void);
#endif /* __ARCH_INIT_H__ */

View file

@ -0,0 +1,50 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LIB_H__
#define __LIB_H__
#include <string.h>
#endif /* __LIB_H__ */

View file

@ -0,0 +1,50 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View file

@ -0,0 +1,60 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL (xQueueHandle)0
#define SYS_SEM_NULL (xSemaphoreHandle)0
typedef xSemaphoreHandle sys_sem_t;
typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t;
#endif /* __SYS_RTXC_H__ */

View file

@ -0,0 +1,384 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* This file is a skeleton for developing Ethernet network interface
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include "conf_eth.h"
#include "netif/etharp.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "AVR32_EMAC.h"
#include "AVR32_CONF_EMAC.h"
#define netifMTU ( 1500 )
#define netifGUARD_BLOCK_TIME ( 250 )
#define IFNAME0 'e'
#define IFNAME1 'm'
struct ethernetif {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
/* Forward declarations. */
void ethernetif_input(void * );
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
static struct netif *xNetIf = NULL;
static void
low_level_init(struct netif *netif)
{
// struct ethernetif *ethernetif = netif->state;
unsigned portBASE_TYPE uxPriority;
/* maximum transfer unit */
netif->mtu = netifMTU;
/* broadcast capability */
netif->flags = NETIF_FLAG_BROADCAST;
/* Do whatever else is needed to initialize interface. */
xNetIf = netif;
/* Initialise the EMAC. This routine contains code that polls status bits.
If the Ethernet cable is not plugged in then this can take a considerable
time. To prevent this starving lower priority tasks of processing time we
lower our priority prior to the call, then raise it back again once the
initialisation is complete. */
uxPriority = uxTaskPriorityGet( NULL );
vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
while( xEMACInit() == NULL )
{
__asm( "NOP" );
}
vTaskPrioritySet( NULL, uxPriority );
/* Create the task that handles the EMAC. */
// xTaskCreate( ethernetif_input, ( signed portCHAR * ) "ETH_INT", netifINTERFACE_TASK_STACK_SIZE, NULL, netifINTERFACE_TASK_PRIORITY, NULL );
sys_thread_new( ethernetif_input, NULL, netifINTERFACE_TASK_PRIORITY );
}
/*
* low_level_output():
*
* Should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
*/
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
static xSemaphoreHandle xTxSemaphore = NULL;
err_t xReturn = ERR_OK;
/* Parameter not used. */
( void ) netif;
if( xTxSemaphore == NULL )
{
vSemaphoreCreateBinary( xTxSemaphore );
}
#if ETH_PAD_SIZE
pbuf_header( p, -ETH_PAD_SIZE ); /* drop the padding word */
#endif
/* Access to the EMAC is guarded using a semaphore. */
if( xSemaphoreTake( xTxSemaphore, netifGUARD_BLOCK_TIME ) )
{
for( q = p; q != NULL; q = q->next )
{
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. if q->next == NULL then this is the last pbuf in the
chain. */
if( !lEMACSend( q->payload, q->len, ( q->next == NULL ) ) )
{
xReturn = ~ERR_OK;
}
}
xSemaphoreGive( xTxSemaphore );
}
#if ETH_PAD_SIZE
pbuf_header( p, ETH_PAD_SIZE ); /* reclaim the padding word */
#endif
#if LINK_STATS
lwip_stats.link.xmit++;
#endif /* LINK_STATS */
return xReturn;
}
/*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
static struct pbuf *
low_level_input(struct netif *netif) {
struct pbuf *p = NULL;
struct pbuf *q;
u16_t len = 0;
static xSemaphoreHandle xRxSemaphore = NULL;
/* Parameter not used. */
( void ) netif;
if( xRxSemaphore == NULL )
{
vSemaphoreCreateBinary( xRxSemaphore );
}
/* Access to the emac is guarded using a semaphore. */
if( xSemaphoreTake( xRxSemaphore, netifGUARD_BLOCK_TIME ) )
{
/* Obtain the size of the packet. */
len = ulEMACInputLength();
if( len )
{
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc( PBUF_RAW, len, PBUF_POOL );
if( p != NULL )
{
#if ETH_PAD_SIZE
pbuf_header( p, -ETH_PAD_SIZE ); /* drop the padding word */
#endif
/* Let the driver know we are going to read a new packet. */
vEMACRead( NULL, 0, len );
/* We iterate over the pbuf chain until we have read the entire
packet into the pbuf. */
for( q = p; q != NULL; q = q->next )
{
/* Read enough bytes to fill this pbuf in the chain. The
available data in the pbuf is given by the q->len variable. */
vEMACRead( q->payload, q->len, len );
}
#if ETH_PAD_SIZE
pbuf_header( p, ETH_PAD_SIZE ); /* reclaim the padding word */
#endif
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
}
else
{
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif /* LINK_STATS */
}
}
xSemaphoreGive( xRxSemaphore );
}
return p;
}
/*
* ethernetif_output():
*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actual transmission of the packet.
*
*/
static err_t
ethernetif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
/* resolve hardware address, then send (or queue) packet */
return etharp_output(netif, ipaddr, p);
}
/*
* ethernetif_input():
*
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface.
*
*/
void ethernetif_input( void * pvParameters )
{
struct ethernetif *ethernetif;
struct eth_hdr *ethhdr;
struct pbuf *p;
( void ) pvParameters;
for( ;; ) {
ethernetif = xNetIf->state;
do
{
ethernetif = xNetIf->state;
/* move received packet into a new pbuf */
p = low_level_input( xNetIf );
if( p == NULL )
{
/* No packet could be read. Wait a for an interrupt to tell us
there is more data available. */
vEMACWaitForInput();
}
} while( p == NULL );
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
ethhdr = p->payload;
switch( htons( ethhdr->type ) )
{
/* IP packet? */
case ETHTYPE_IP:
/* update ARP table */
etharp_ip_input( xNetIf, p );
/* skip Ethernet header */
pbuf_header( p, (s16_t)-sizeof(struct eth_hdr) );
/* pass to network layer */
xNetIf->input( p, xNetIf );
break;
case ETHTYPE_ARP:
/* pass p to ARP module */
etharp_arp_input( xNetIf, ethernetif->ethaddr, p );
break;
default:
pbuf_free( p );
p = NULL;
break;
}
}
}
static void
arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
/*
* ethernetif_init():
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
*/
extern struct netif EMAC_if;
err_t
ethernetif_init(struct netif *netif)
{
struct ethernetif *ethernetif;
int i;
ethernetif = (struct ethernetif *)mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
return ERR_MEM;
}
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = ethernetif_output;
netif->linkoutput = low_level_output;
for(i = 0; i < 6; i++) netif->hwaddr[i] = EMAC_if.hwaddr[i];
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
}

View file

@ -0,0 +1,724 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_OPT_H__
#define __LWIP_OPT_H__
/* Include user defined options first */
#include "lwipopts.h"
#include "lwip/debug.h"
/* Define default values for unconfigured parameters. */
/* Platform specific locking */
/*
* enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
* for certain critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#ifndef SYS_LIGHTWEIGHT_PROT
#define SYS_LIGHTWEIGHT_PROT 0
#endif
#ifndef NO_SYS
#define NO_SYS 0
#endif
/* ---------- Memory options ---------- */
#ifndef MEM_LIBC_MALLOC
#define MEM_LIBC_MALLOC 0
#endif
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#ifndef MEM_ALIGNMENT
#define MEM_ALIGNMENT 1
#endif
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#ifndef MEM_SIZE
#define MEM_SIZE 1600
#endif
#ifndef MEMP_SANITY_CHECK
#define MEMP_SANITY_CHECK 0
#endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#ifndef MEMP_NUM_PBUF
#define MEMP_NUM_PBUF 16
#endif
/* Number of raw connection PCBs */
#ifndef MEMP_NUM_RAW_PCB
#define MEMP_NUM_RAW_PCB 4
#endif
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#ifndef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB 4
#endif
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#ifndef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB 5
#endif
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#ifndef MEMP_NUM_TCP_PCB_LISTEN
#define MEMP_NUM_TCP_PCB_LISTEN 8
#endif
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#ifndef MEMP_NUM_TCP_SEG
#define MEMP_NUM_TCP_SEG 16
#endif
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#ifndef MEMP_NUM_SYS_TIMEOUT
#define MEMP_NUM_SYS_TIMEOUT 3
#endif
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#ifndef MEMP_NUM_NETBUF
#define MEMP_NUM_NETBUF 2
#endif
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#ifndef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 4
#endif
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
communication between the TCP/IP stack and the sequential
programs. */
#ifndef MEMP_NUM_API_MSG
#define MEMP_NUM_API_MSG 8
#endif
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#ifndef MEMP_NUM_TCPIP_MSG
#define MEMP_NUM_TCPIP_MSG 8
#endif
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#ifndef PBUF_POOL_SIZE
#define PBUF_POOL_SIZE 16
#endif
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#ifndef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE 128
#endif
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. Defaults to 14 for Ethernet. */
#ifndef PBUF_LINK_HLEN
#define PBUF_LINK_HLEN 14
#endif
/* ---------- ARP options ---------- */
/** Number of active hardware address, IP address pairs cached */
#ifndef ARP_TABLE_SIZE
#define ARP_TABLE_SIZE 10
#endif
/**
* If enabled, outgoing packets are queued during hardware address
* resolution.
*
* This feature has not stabilized yet. Single-packet queueing is
* believed to be stable, multi-packet queueing is believed to
* clash with the TCP segment queueing.
*
* As multi-packet-queueing is currently disabled, enabling this
* _should_ work, but we need your testing feedback on lwip-users.
*
*/
#ifndef ARP_QUEUEING
#define ARP_QUEUEING 1
#endif
/* This option is deprecated */
#ifdef ETHARP_QUEUE_FIRST
#error ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h.
#endif
/* This option is removed to comply with the ARP standard */
#ifdef ETHARP_ALWAYS_INSERT
#error ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h.
#endif
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#ifndef IP_FORWARD
#define IP_FORWARD 0
#endif
/* If defined to 1, IP options are allowed (but not parsed). If
defined to 0, all packets with IP options are dropped. */
#ifndef IP_OPTIONS
#define IP_OPTIONS 1
#endif
/** IP reassembly and segmentation. Even if they both deal with IP
* fragments, note that these are orthogonal, one dealing with incoming
* packets, the other with outgoing packets
*/
/** Reassemble incoming fragmented IP packets */
#ifndef IP_REASSEMBLY
#define IP_REASSEMBLY 1
#endif
/** Fragment outgoing IP packets if their size exceeds MTU */
#ifndef IP_FRAG
#define IP_FRAG 1
#endif
/* IP reassemly default age in seconds */
#ifndef IP_REASS_MAXAGE
#define IP_REASS_MAXAGE 3
#endif
/* IP reassembly buffer size (minus IP header) */
#ifndef IP_REASS_BUFSIZE
#define IP_REASS_BUFSIZE 5760
#endif
/* Assumed max MTU on any interface for IP frag buffer */
#ifndef IP_FRAG_MAX_MTU
#define IP_FRAG_MAX_MTU 1500
#endif
/** Global default value for Time To Live used by transport layers. */
#ifndef IP_DEFAULT_TTL
#define IP_DEFAULT_TTL 255
#endif
/* ---------- ICMP options ---------- */
#ifndef ICMP_TTL
#define ICMP_TTL (IP_DEFAULT_TTL)
#endif
/* ---------- RAW options ---------- */
#ifndef LWIP_RAW
#define LWIP_RAW 1
#endif
#ifndef RAW_TTL
#define RAW_TTL (IP_DEFAULT_TTL)
#endif
/* ---------- DHCP options ---------- */
#ifndef LWIP_DHCP
#define LWIP_DHCP 0
#endif
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#ifndef DHCP_DOES_ARP_CHECK
#define DHCP_DOES_ARP_CHECK 1
#endif
/* ---------- SNMP options ---------- */
/** @note UDP must be available for SNMP transport */
#ifndef LWIP_SNMP
#define LWIP_SNMP 0
#endif
/** @note At least one request buffer is required. */
#ifndef SNMP_CONCURRENT_REQUESTS
#define SNMP_CONCURRENT_REQUESTS 1
#endif
/** @note At least one trap destination is required */
#ifndef SNMP_TRAP_DESTINATIONS
#define SNMP_TRAP_DESTINATIONS 1
#endif
#ifndef SNMP_PRIVATE_MIB
#define SNMP_PRIVATE_MIB 0
#endif
/* ---------- UDP options ---------- */
#ifndef LWIP_UDP
#define LWIP_UDP 1
#endif
#ifndef UDP_TTL
#define UDP_TTL (IP_DEFAULT_TTL)
#endif
/* ---------- TCP options ---------- */
#ifndef LWIP_TCP
#define LWIP_TCP 1
#endif
#ifndef TCP_TTL
#define TCP_TTL (IP_DEFAULT_TTL)
#endif
#ifndef TCP_WND
#define TCP_WND 2048
#endif
#ifndef TCP_MAXRTX
#define TCP_MAXRTX 12
#endif
#ifndef TCP_SYNMAXRTX
#define TCP_SYNMAXRTX 6
#endif
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#ifndef TCP_QUEUE_OOSEQ
#define TCP_QUEUE_OOSEQ 1
#endif
/* TCP Maximum segment size. */
#ifndef TCP_MSS
#define TCP_MSS 128 /* A *very* conservative default. */
#endif
/* TCP sender buffer space (bytes). */
#ifndef TCP_SND_BUF
#define TCP_SND_BUF 256
#endif
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#ifndef TCP_SND_QUEUELEN
#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS
#endif
/* Maximum number of retransmissions of data segments. */
/* Maximum number of retransmissions of SYN segments. */
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
available in the tcp snd_buf for select to return writable */
#ifndef TCP_SNDLOWAT
#define TCP_SNDLOWAT TCP_SND_BUF/2
#endif
/* Support loop interface (127.0.0.1) */
#ifndef LWIP_HAVE_LOOPIF
#define LWIP_HAVE_LOOPIF 0
#endif
#ifndef LWIP_EVENT_API
#define LWIP_EVENT_API 0
#define LWIP_CALLBACK_API 1
#else
#define LWIP_EVENT_API 1
#define LWIP_CALLBACK_API 0
#endif
#ifndef LWIP_COMPAT_SOCKETS
#define LWIP_COMPAT_SOCKETS 1
#endif
#ifndef TCPIP_THREAD_PRIO
#define TCPIP_THREAD_PRIO 1
#endif
#ifndef SLIPIF_THREAD_PRIO
#define SLIPIF_THREAD_PRIO 1
#endif
#ifndef PPP_THREAD_PRIO
#define PPP_THREAD_PRIO 1
#endif
#ifndef DEFAULT_THREAD_PRIO
#define DEFAULT_THREAD_PRIO 1
#endif
/* ---------- Socket Options ---------- */
/* Enable SO_REUSEADDR and SO_REUSEPORT options */
#ifdef SO_REUSE
/* I removed the lot since this was an ugly hack. It broke the raw-API.
It also came with many ugly goto's, Christiaan Simons. */
#error "SO_REUSE currently unavailable, this was a hack"
#endif
/* ---------- Statistics options ---------- */
#ifndef LWIP_STATS
#define LWIP_STATS 1
#endif
#if LWIP_STATS
#ifndef LWIP_STATS_DISPLAY
#define LWIP_STATS_DISPLAY 0
#endif
#ifndef LINK_STATS
#define LINK_STATS 1
#endif
#ifndef IP_STATS
#define IP_STATS 1
#endif
#ifndef IPFRAG_STATS
#define IPFRAG_STATS 1
#endif
#ifndef ICMP_STATS
#define ICMP_STATS 1
#endif
#ifndef UDP_STATS
#define UDP_STATS 1
#endif
#ifndef TCP_STATS
#define TCP_STATS 1
#endif
#ifndef MEM_STATS
#define MEM_STATS 1
#endif
#ifndef MEMP_STATS
#define MEMP_STATS 1
#endif
#ifndef PBUF_STATS
#define PBUF_STATS 1
#endif
#ifndef SYS_STATS
#define SYS_STATS 1
#endif
#ifndef RAW_STATS
#define RAW_STATS 0
#endif
#else
#define LINK_STATS 0
#define IP_STATS 0
#define IPFRAG_STATS 0
#define ICMP_STATS 0
#define UDP_STATS 0
#define TCP_STATS 0
#define MEM_STATS 0
#define MEMP_STATS 0
#define PBUF_STATS 0
#define SYS_STATS 0
#define RAW_STATS 0
#define LWIP_STATS_DISPLAY 0
#endif /* LWIP_STATS */
/* ---------- PPP options ---------- */
#ifndef PPP_SUPPORT
#define PPP_SUPPORT 0 /* Set for PPP */
#endif
#if PPP_SUPPORT
#define NUM_PPP 1 /* Max PPP sessions. */
#ifndef PAP_SUPPORT
#define PAP_SUPPORT 0 /* Set for PAP. */
#endif
#ifndef CHAP_SUPPORT
#define CHAP_SUPPORT 0 /* Set for CHAP. */
#endif
#define MSCHAP_SUPPORT 0 /* Set for MSCHAP (NOT FUNCTIONAL!) */
#define CBCP_SUPPORT 0 /* Set for CBCP (NOT FUNCTIONAL!) */
#define CCP_SUPPORT 0 /* Set for CCP (NOT FUNCTIONAL!) */
#ifndef VJ_SUPPORT
#define VJ_SUPPORT 0 /* Set for VJ header compression. */
#endif
#ifndef MD5_SUPPORT
#define MD5_SUPPORT 0 /* Set for MD5 (see also CHAP) */
#endif
/*
* Timeouts.
*/
#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */
#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */
#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */
#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */
/* Interval in seconds between keepalive echo requests, 0 to disable. */
#if 1
#define LCP_ECHOINTERVAL 0
#else
#define LCP_ECHOINTERVAL 10
#endif
/* Number of unanswered echo requests before failure. */
#define LCP_MAXECHOFAILS 3
/* Max Xmit idle time (in jiffies) before resend flag char. */
#define PPP_MAXIDLEFLAG 100
/*
* Packet sizes
*
* Note - lcp shouldn't be allowed to negotiate stuff outside these
* limits. See lcp.h in the pppd directory.
* (XXX - these constants should simply be shared by lcp.c instead
* of living in lcp.h)
*/
#define PPP_MTU 1500 /* Default MTU (size of Info field) */
#if 0
#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN)
#else
#define PPP_MAXMTU 1500 /* Largest MTU we allow */
#endif
#define PPP_MINMTU 64
#define PPP_MRU 1500 /* default MRU = max length of info field */
#define PPP_MAXMRU 1500 /* Largest MRU we allow */
#define PPP_DEFMRU 296 /* Try for this */
#define PPP_MINMRU 128 /* No MRUs below this */
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
#define MAXSECRETLEN 256 /* max length of password or secret */
#endif /* PPP_SUPPORT */
/* checksum options - set to zero for hardware checksum support */
#ifndef CHECKSUM_GEN_IP
#define CHECKSUM_GEN_IP 1
#endif
#ifndef CHECKSUM_GEN_UDP
#define CHECKSUM_GEN_UDP 1
#endif
#ifndef CHECKSUM_GEN_TCP
#define CHECKSUM_GEN_TCP 1
#endif
#ifndef CHECKSUM_CHECK_IP
#define CHECKSUM_CHECK_IP 1
#endif
#ifndef CHECKSUM_CHECK_UDP
#define CHECKSUM_CHECK_UDP 1
#endif
#ifndef CHECKSUM_CHECK_TCP
#define CHECKSUM_CHECK_TCP 1
#endif
/* Debugging options all default to off */
#ifndef DBG_TYPES_ON
#define DBG_TYPES_ON 0
#endif
#ifndef ETHARP_DEBUG
#define ETHARP_DEBUG DBG_OFF
#endif
#ifndef NETIF_DEBUG
#define NETIF_DEBUG DBG_OFF
#endif
#ifndef PBUF_DEBUG
#define PBUF_DEBUG DBG_OFF
#endif
#ifndef API_LIB_DEBUG
#define API_LIB_DEBUG DBG_OFF
#endif
#ifndef API_MSG_DEBUG
#define API_MSG_DEBUG DBG_OFF
#endif
#ifndef SOCKETS_DEBUG
#define SOCKETS_DEBUG DBG_OFF
#endif
#ifndef ICMP_DEBUG
#define ICMP_DEBUG DBG_OFF
#endif
#ifndef INET_DEBUG
#define INET_DEBUG DBG_OFF
#endif
#ifndef IP_DEBUG
#define IP_DEBUG DBG_OFF
#endif
#ifndef IP_REASS_DEBUG
#define IP_REASS_DEBUG DBG_OFF
#endif
#ifndef RAW_DEBUG
#define RAW_DEBUG DBG_OFF
#endif
#ifndef MEM_DEBUG
#define MEM_DEBUG DBG_OFF
#endif
#ifndef MEMP_DEBUG
#define MEMP_DEBUG DBG_OFF
#endif
#ifndef SYS_DEBUG
#define SYS_DEBUG DBG_OFF
#endif
#ifndef TCP_DEBUG
#define TCP_DEBUG DBG_OFF
#endif
#ifndef TCP_INPUT_DEBUG
#define TCP_INPUT_DEBUG DBG_OFF
#endif
#ifndef TCP_FR_DEBUG
#define TCP_FR_DEBUG DBG_OFF
#endif
#ifndef TCP_RTO_DEBUG
#define TCP_RTO_DEBUG DBG_OFF
#endif
#ifndef TCP_REXMIT_DEBUG
#define TCP_REXMIT_DEBUG DBG_OFF
#endif
#ifndef TCP_CWND_DEBUG
#define TCP_CWND_DEBUG DBG_OFF
#endif
#ifndef TCP_WND_DEBUG
#define TCP_WND_DEBUG DBG_OFF
#endif
#ifndef TCP_OUTPUT_DEBUG
#define TCP_OUTPUT_DEBUG DBG_OFF
#endif
#ifndef TCP_RST_DEBUG
#define TCP_RST_DEBUG DBG_OFF
#endif
#ifndef TCP_QLEN_DEBUG
#define TCP_QLEN_DEBUG DBG_OFF
#endif
#ifndef UDP_DEBUG
#define UDP_DEBUG DBG_OFF
#endif
#ifndef TCPIP_DEBUG
#define TCPIP_DEBUG DBG_OFF
#endif
#ifndef PPP_DEBUG
#define PPP_DEBUG DBG_OFF
#endif
#ifndef SLIP_DEBUG
#define SLIP_DEBUG DBG_OFF
#endif
#ifndef DHCP_DEBUG
#define DHCP_DEBUG DBG_OFF
#endif
#ifndef SNMP_MSG_DEBUG
#define SNMP_MSG_DEBUG DBG_OFF
#endif
#ifndef SNMP_MIB_DEBUG
#define SNMP_MIB_DEBUG DBG_OFF
#endif
#ifndef DBG_MIN_LEVEL
#define DBG_MIN_LEVEL DBG_LEVEL_OFF
#endif
#endif /* __LWIP_OPT_H__ */

View file

@ -0,0 +1,228 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP configuration for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
/* Include user defined options first */
#include "conf_eth.h"
// #include "lwip/debug.h"
/* Define default values for unconfigured parameters. */
#define LWIP_NOASSERT 1 // To suppress some errors for now (no debug output)
/* These two control is reclaimer functions should be compiled
in. Should always be turned on (1). */
#define MEM_RECLAIM 1
#define MEMP_RECLAIM 1
/* Platform specific locking */
/*
* enable SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
* for certain critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT 1
/* ---------- Memory options ---------- */
// #define MEM_LIBC_MALLOC 0
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 4
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 3 * 1024
// #define MEMP_SANITY_CHECK 1
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 6
/* Number of raw connection PCBs */
#define MEMP_NUM_RAW_PCB 1
#if (TFTP_USED == 1)
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define UDP_TTL 255
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 1
#else
/* ---------- UDP options ---------- */
#define LWIP_UDP 0
#define UDP_TTL 0
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 0
#endif
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 14
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 2
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 6
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 6
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 3
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 6
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
communication between the TCP/IP stack and the sequential
programs. */
#define MEMP_NUM_API_MSG 4
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG 4
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 6
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 500
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. */
#define PBUF_LINK_HLEN 16
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* TCP receive window. */
#define TCP_WND 1500
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS 1500
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 2150
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN 6 * TCP_SND_BUF/TCP_MSS
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4
/* ---------- ARP options ---------- */
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 0
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#define IP_FORWARD 0
/* If defined to 1, IP options are allowed (but not parsed). If
defined to 0, all packets with IP options are dropped. */
#define IP_OPTIONS 1
/* ---------- ICMP options ---------- */
#define ICMP_TTL 255
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 0
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK 1
#define TCPIP_THREAD_PRIO lwipINTERFACE_TASK_PRIORITY
/* ---------- Statistics options ---------- */
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#if LWIP_STATS
#define LINK_STATS 1
#define IP_STATS 1
#define ICMP_STATS 1
#define UDP_STATS 1
#define TCP_STATS 1
#define MEM_STATS 1
#define MEMP_STATS 1
#define PBUF_STATS 1
#define SYS_STATS 1
#endif /* STATS */
#endif /* __LWIPOPTS_H__ */

View file

@ -0,0 +1,431 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief lwIP abstraction layer for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "conf_eth.h"
#if (HTTP_USED == 1)
#include "BasicWEB.h"
#endif
#if (TFTP_USED == 1)
#include "BasicTFTP.h"
#endif
#if (SMTP_USED == 1)
#include "BasicSMTP.h"
#endif
/* lwIP includes. */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
/* Message queue constants. */
#define archMESG_QUEUE_LENGTH ( 6 )
#define archPOST_BLOCK_TIME_MS ( ( unsigned portLONG ) 10000 )
struct timeoutlist
{
struct sys_timeouts timeouts;
xTaskHandle pid;
};
static struct timeoutlist timeoutlist[SYS_THREAD_MAX];
static u16_t nextthread = 0;
int intlevel = 0;
extern void ethernetif_input( void * pvParameters );
/*-----------------------------------------------------------------------------------*/
// Creates an empty mailbox.
sys_mbox_t
sys_mbox_new(void)
{
xQueueHandle mbox;
mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) );
return mbox;
}
/*-----------------------------------------------------------------------------------*/
/*
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
*/
void
sys_mbox_free(sys_mbox_t mbox)
{
if( uxQueueMessagesWaiting( mbox ) )
{
/* Line for breakpoint. Should never break here! */
__asm volatile ( "NOP" );
}
vQueueDelete( mbox );
}
/*-----------------------------------------------------------------------------------*/
// Posts the "msg" to the mailbox.
void
sys_mbox_post(sys_mbox_t mbox, void *data)
{
xQueueSend( mbox, &data, ( portTickType ) ( archPOST_BLOCK_TIME_MS / portTICK_RATE_MS ) );
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
The return values are the same as for the sys_arch_sem_wait() function:
Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
timeout.
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
*/
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
void *dummyptr;
portTickType StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if( msg == NULL )
{
msg = &dummyptr;
}
if( timeout != 0 )
{
if(pdTRUE == xQueueReceive( mbox, &(*msg), timeout ) )
{
EndTime = xTaskGetTickCount();
Elapsed = EndTime - StartTime;
if( Elapsed == 0 )
{
Elapsed = 1;
}
return ( Elapsed );
}
else // timed out blocking for message
{
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
}
else // block forever for a message.
{
while( pdTRUE != xQueueReceive( mbox, &(*msg), 10000 ) ) // time is arbitrary
{
;
}
EndTime = xTaskGetTickCount();
Elapsed = EndTime - StartTime;
if( Elapsed == 0 )
{
Elapsed = 1;
}
return ( Elapsed ); // return time blocked TBD test
}
}
/*-----------------------------------------------------------------------------------*/
// Creates and returns a new semaphore. The "count" argument specifies
// the initial state of the semaphore. TBD finish and test
sys_sem_t
sys_sem_new(u8_t count)
{
xSemaphoreHandle xSemaphore = NULL;
portENTER_CRITICAL();
vSemaphoreCreateBinary( xSemaphore );
if( xSemaphore == NULL )
{
return NULL; // TBD need assert
}
if(count == 0) // Means we want the sem to be unavailable at init state.
{
xSemaphoreTake(xSemaphore,1);
}
portEXIT_CRITICAL();
return xSemaphore;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the number of
milliseconds spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return value is
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), the function may return zero.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
u32_t
sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
{
portTickType StartTime, EndTime, Elapsed;
StartTime = xTaskGetTickCount();
if( timeout != 0)
{
if( xSemaphoreTake( sem, timeout ) == pdTRUE )
{
EndTime = xTaskGetTickCount();
Elapsed = EndTime - StartTime;
if( Elapsed == 0 )
{
Elapsed = 1;
}
return (Elapsed); // return time blocked TBD test
}
else
{
return SYS_ARCH_TIMEOUT;
}
}
else // must block without a timeout
{
while( xSemaphoreTake( sem, 10000 ) != pdTRUE )
{
;
}
EndTime = xTaskGetTickCount();
Elapsed = EndTime - StartTime;
if( Elapsed == 0 )
{
Elapsed = 1;
}
return ( Elapsed ); // return time blocked
}
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore
void
sys_sem_signal(sys_sem_t sem)
{
xSemaphoreGive( sem );
}
/*-----------------------------------------------------------------------------------*/
// Deallocates a semaphore
void
sys_sem_free(sys_sem_t sem)
{
vQueueDelete( sem );
}
/*-----------------------------------------------------------------------------------*/
// Initialize sys arch
void
sys_init(void)
{
int i;
// Initialize the the per-thread sys_timeouts structures
// make sure there are no valid pids in the list
for(i = 0; i < SYS_THREAD_MAX; i++)
{
timeoutlist[i].pid = 0;
timeoutlist[i].timeouts.next = NULL;
}
// keep track of how many threads have been created
nextthread = 0;
}
/*-----------------------------------------------------------------------------------*/
/*
Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
each thread has a list of timeouts which is represented as a linked
list of sys_timeout structures. The sys_timeouts structure holds a
pointer to a linked list of timeouts. This function is called by
the lwIP timeout scheduler and must not return a NULL value.
In a single threaded sys_arch implementation, this function will
simply return a pointer to a global sys_timeouts variable stored in
the sys_arch module.
*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
int i;
xTaskHandle pid;
struct timeoutlist *tl;
pid = xTaskGetCurrentTaskHandle( );
for(i = 0; i < nextthread; i++)
{
tl = &(timeoutlist[i]);
if(tl->pid == pid)
{
return &(tl->timeouts);
}
}
// If we're here, this means the scheduler gave the focus to the task as it was
// being created(because of a higher priority). Since timeoutlist[] update is
// done just after the task creation, the array is not up-to-date.
// => the last array entry must be the one of the current task.
return( &( timeoutlist[nextthread].timeouts ) );
/*
// Error
return NULL;
*/
}
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
// TBD
/*-----------------------------------------------------------------------------------*/
/*
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
xTaskHandle CreatedTask;
int result = pdFAIL;
static int iCall = 0;
if( thread == ethernetif_input )
{
result = xTaskCreate( thread, ( signed portCHAR * ) "ETHINT", netifINTERFACE_TASK_STACK_SIZE, arg, prio, &CreatedTask );
}
else if( iCall == 0 )
{
/* The first time this is called we are creating the lwIP handler. */
result = xTaskCreate( thread, ( signed portCHAR * ) "lwIP", lwipINTERFACE_STACK_SIZE, arg, prio, &CreatedTask );
iCall++;
}
#if (HTTP_USED == 1)
else if (thread == vBasicWEBServer)
{
result = xTaskCreate( thread, ( signed portCHAR * ) "WEB", lwipBASIC_WEB_SERVER_STACK_SIZE, arg, prio, &CreatedTask );
}
#endif
#if (TFTP_USED == 1)
else if (thread == vBasicTFTPServer)
{
result = xTaskCreate( thread, ( signed portCHAR * ) "TFTP", lwipBASIC_TFTP_SERVER_STACK_SIZE, arg, prio, &CreatedTask );
}
#endif
#if (SMTP_USED == 1)
else if (thread == vBasicSMTPHost)
{
result = xTaskCreate( thread, ( signed portCHAR * ) "SMTP", lwipBASIC_SMTP_HOST_STACK_SIZE, arg, prio, &CreatedTask );
}
#endif
// For each task created, store the task handle (pid) in the timers array.
// This scheme doesn't allow for threads to be deleted
timeoutlist[nextthread++].pid = CreatedTask;
if(result == pdPASS)
{
return CreatedTask;
}
else
{
return NULL;
}
}
/*
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
sys_prot_t sys_arch_protect(void)
{
vPortEnterCritical();
return 1;
}
/*
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
void sys_arch_unprotect(sys_prot_t pval)
{
( void ) pval;
vPortExitCritical();
}