Page MenuHomePhabricator

No OneTemporary

diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,32 +1,47 @@
PROJECT(BlindControl)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_VERBOSE_MAKEFILE ON)
+OPTION(BLINDCONTROL_USE_MEGA2560 "Use ATMega2560 instead of ATMega328p" OFF)
+OPTION(BLINDCONTROL_USE_ETH_INTERRUPT "Use Ethernet Interrupt" OFF)
+
SET(CMAKE_C_COMPILER avr-gcc)
#SET(CMAKE_CXX_COMPILER avr-g++)
SET(CSTANDARD "-std=gnu99")
SET(CDEBUG "-gstabs")
SET(CWARN "-Wall -Wstrict-prototypes")
SET(CTUNING "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums")
SET(COPT "-Os")
-SET(CMCU "-mmcu=atmega2560")
+IF(BLINDCONTROL_USE_MEGA2560)
+ SET(CMCU "-mmcu=atmega2560")
+ SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker_script.x")
+ ADD_DEFINITIONS(-DUSE_MEGA2560)
+ELSE()
+ SET(CMCU "-mmcu=atmega328p")
+ SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+ENDIF()
SET(CDEFS "-DF_CPU=16000000")
-SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker_script.x")
+IF(BLINDCONTROL_USE_ETH_INTERRUPT)
+ ADD_DEFINITIONS(-DUSE_ETHERNET_INTERRUPT)
+ENDIF()
SET(CFLAGS "${CMCU} ${CDEBUG} ${CDEFS} ${COPT} ${CWARN} ${CSTANDARD} ${CEXTRA}")
#SET(CXXFLAGS "${CMCU} ${CDEFS} ${CINCS} ${COPT}")
SET(CMAKE_C_FLAGS ${CFLAGS})
#SET(CMAKE_CXX_FLAGS ${CXXFLAGS})
ADD_EXECUTABLE(BlindControl main.c w5100.c ethernet.c spi.c)
ADD_CUSTOM_COMMAND(TARGET BlindControl POST_BUILD COMMAND avr-objcopy -O ihex -R .eeprom ${CMAKE_CURRENT_BINARY_DIR}/BlindControl ${CMAKE_CURRENT_BINARY_DIR}/BlindControl.hex)
-
ADD_CUSTOM_TARGET(upload ${CMAKE_COMMAND} ${PROJECT_SOURCE_DIR})
-ADD_CUSTOM_COMMAND(TARGET upload POST_BUILD COMMAND avrdude -V -c stk500v2 -p m2560 -b 115200 -P /dev/ttyACM0 -U flash:w:${CMAKE_CURRENT_BINARY_DIR}/BlindControl.hex)
+IF(BLINDCONTROL_USE_MEGA2560)
+ ADD_CUSTOM_COMMAND(TARGET upload POST_BUILD COMMAND avrdude -V -c stk500v2 -p m2560 -b 115200 -P /dev/ttyACM0 -U flash:w:${CMAKE_CURRENT_BINARY_DIR}/BlindControl.hex)
+ELSE()
+ ADD_CUSTOM_COMMAND(TARGET upload POST_BUILD COMMAND avrdude -V -c usbtiny -p m328p -U flash:w:${CMAKE_CURRENT_BINARY_DIR}/BlindControl.hex)
+ENDIF()
SET_TARGET_PROPERTIES(BlindControl PROPERTIES COMPILE_FLAGS -D__AVR_LIBC_DEPRECATED_ENABLE__)
diff --git a/ethernet.c b/ethernet.c
--- a/ethernet.c
+++ b/ethernet.c
@@ -1,200 +1,202 @@
/*
* Simple socket server for FreeRTOS based on the Arduino Ethernet Library
* (c) 2011 Andreas Boehler <andreas@aboehler.at>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "ethernet.h"
#include "main.h"
/**
* \file ethernet.c
* \brief Main ethernet source code
* This file contains the main ethernet handling code.
*/
/********************
* Global variables *
********************/
uint8_t eth_state[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; ///< Ethernet states
uint16_t eth_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; ///< Ethernet ports
uint8_t ethernet_init(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
{
w5100_init();
w5100_setMACAddress(mac);
w5100_setIPAddress(ip);
w5100_setGatewayIp(gateway);
w5100_setSubnetMask(subnet);
return TRUE;
}
uint8_t socket_server_init(uint16_t port)
{
uint8_t sock;
for(sock = 0; sock < MAX_SOCK_NUM; sock++)
{
if(w5100_readSnSR(sock) == SNSR_CLOSED)
{
eth_server_port[sock] = port;
socket_server_create_socket(sock, SNMR_TCP, eth_server_port[sock], 0);
if(socket_server_listen(sock))
return sock+1;
else
return FALSE;
}
}
return FALSE;
}
uint8_t socket_server_socket_status(SOCKET s)
{
return w5100_readSnSR(s);
}
uint8_t socket_server_create_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
{
if((protocol == SNMR_TCP) || (protocol == SNMR_UDP) || (protocol == SNMR_IPRAW) || (protocol == SNMR_MACRAW) || (protocol == SNMR_PPPOE))
{
socket_server_close_socket(s);
w5100_writeSnMR(s, protocol | flag);
if(port != 0)
w5100_writeSnPORT(s, port);
else
w5100_writeSnPORT(s, 80); // We hardcode a default port here
w5100_execCmdSn(s, Sock_OPEN);
return TRUE;
}
else
return FALSE;
}
uint8_t socket_server_close_socket(SOCKET s)
{
w5100_execCmdSn(s, Sock_CLOSE);
w5100_writeSnIR(s, 0xFF);
return TRUE;
}
uint8_t socket_server_listen(SOCKET s)
{
if(w5100_readSnSR(s) != SNSR_INIT)
return FALSE;
else
w5100_execCmdSn(s, Sock_LISTEN);
return TRUE;
}
uint8_t socket_server_data_available(SOCKET s)
{
//uint8_t stat = socket_server_socket_status(s);
//if((stat == SNSR_ESTABLISHED) || (stat == SNSR_CLOSE_WAIT))
return w5100_getRXReceivedSize(s);
//else
// return FALSE;
}
uint8_t socket_server_socket_connected(SOCKET s)
{
uint8_t stat = socket_server_socket_status(s);
if((stat == SNSR_ESTABLISHED))
return TRUE;
else
return FALSE;
}
uint8_t socket_server_socket_closed(SOCKET s)
{
uint8_t stat = socket_server_socket_status(s);
if((stat == SNSR_CLOSE_WAIT))
return TRUE;
else
return FALSE;
}
+#ifdef USE_ETHERNET_INTERRUPT
uint8_t socket_server_handle_interrupt(void)
{
uint8_t ir = w5100_readIR();
uint8_t sock = 0;
uint8_t sr = 0;
uint8_t i;
for(i=0; i<MAX_SOCK_NUM; i++)
{
if(ir & (1<<i))
{
sr = w5100_readSnIR(i);
sock = i;
}
}
if(sock != MAX_SOCK_NUM)
{
w5100_writeSnIR(sock, sr);
return sock;
}
else
{
return FALSE;
}
}
+#endif
uint16_t socket_server_write(SOCKET s, uint8_t *buffer, size_t size)
{
uint16_t ret = 0;
uint16_t freesize = 0;
if(socket_server_socket_status(s) == SNSR_ESTABLISHED)
{
if(size > SSIZE)
ret = SSIZE;
else
ret = size;
freesize = w5100_getTXFreeSize(s);
if(freesize < ret)
ret = 0;
/*
do
{
freesize = w5100_getTXFreeSize(s);
stat = w5100_readSnSR(s);
if((stat != SNSR_ESTABLISHED) && (stat != SNSR_CLOSE_WAIT))
{
ret = 0;
break;
}
}
while(freesize < ret);
*/
w5100_send_data_processing(s, (uint8_t *) buffer, ret);
w5100_execCmdSn(s, Sock_SEND);
while((w5100_readSnIR(s) & SNIR_SEND_OK) != SNIR_SEND_OK)
{
if(w5100_readSnSR(s) == SNSR_CLOSED)
{
socket_server_close_socket(s);
return FALSE;
}
}
w5100_writeSnIR(s, SNIR_SEND_OK);
return ret;
}
return FALSE;
}
uint16_t socket_server_receive(SOCKET s, uint8_t *buf, uint16_t len)
{
uint16_t ret = FALSE;
if(len>0)
{
w5100_recv_data_processing(s, buf, len, 0);
w5100_execCmdSn(s, Sock_RECV);
ret = len;
}
return ret;
}
diff --git a/ethernet.h b/ethernet.h
--- a/ethernet.h
+++ b/ethernet.h
@@ -1,195 +1,197 @@
/*
* Simple socket server for FreeRTOS based on the Arduino Ethernet Library
* (c) 2011 Andreas Boehler <andreas@aboehler.at>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
/**
* \file ethernet.h
* Simple socket server for FreeRTOS based on the Arduino Ethernet Library for the
* W5100 Ethernet controller.
*/
#ifndef ETHERNET_H
#define ETHERNET_H
#include "w5100.h"
/**
* ethernet.h
*
* <pre>ethernet_init(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)</pre>
*
* <i>Function</i> that initializes the ethernet controller with the given parameters.
*
* @param mac Pointer to a byte holding the mac address of the ethernet controller
* @param ip Pointer to an array of bytes holding the IP address for the ethernet controller
* @param gateway Pointer to an array of bytes holding the Gateway IP Address
* @param subnet Pointer to an array of bytes holding the Subnet address
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t ethernet_init(uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet);
/**
* ethernet.h
*
* <pre>socket_server_init(uint16_t port)</pre>
*
* <i>Function</i> that initializes a new socket server on the given port.
*
* @param port Integer that specifies the Port Number to create
* @return Socket Number +1 on success, 0 on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_init(uint16_t port);
/**
* ethernet.h
*
* <pre>socket_server_create_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)</pre>
*
* <i>Function</i> used e.g. by socker_server_init that creates a new socket server on the
* specified socket number using given protocol, port and flags.
* If the socket is already opened, it is automatically closed.
*
* @param s The socket number to create (0-3)
* @param protocol The protocol the socket should use
* @param port The port the new socket should listen one
* @param flag Additional flags to use
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_create_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag);
/**
* ethernet.h
*
* <pre>socket_server_close_socket(SOCKET s)</pre>
*
* <i>Function</i> that closes a previously opened socket.
*
* @param s The socket to close
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_close_socket(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_listen(SOCKET s)</pre>
*
* <i>Function</i> to start listening on the given socket.
*
* @param s The socket number to start listening on
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint8_t socket_server_listen(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_socket_status(SOCKET s)</pre>
*
* <i>Function</i> that checks the status of a given socket.
*
* @param s The socket number to check.
* @return The status of the socket
* \ingroup Ethernet
*/
uint8_t socket_server_socket_status(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_socket_connected(SOCKET s)</pre>
*
* <i>Function</i> that checks whether a socket is connected or not.
*
* @param s The socket number to check
* @return TRUE if a node is connected, FALSE if nothing is connected to the socket.
* \ingroup Ethernet
*/
uint8_t socket_server_socket_connected(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_socket_closed(SOCKET s)</pre>
*
* <i>Function</i> that checks whether a given socket is closed or no.
*
* @param s The socket number to check
* @return TRUE if the socket's status is closed, otherwise FALSE.
* \ingroup Ethernet
*/
uint8_t socket_server_socket_closed(SOCKET s);
/**
* ethernet.h
*
* <pre>socket_server_data_available(SOCKET s)</pre>
*
* <i>Function</i> that checks if and how many data is available on a given socket.
*
* @param s The socket number to check
* @return FALSE if no data is available, otherwise the number of bytes that have been received.
* \ingroup Ethernet
*/
uint8_t socket_server_data_available(SOCKET s);
+#ifdef USE_ETHERNET_INTERRUPT
/**
* ethernet.h
*
* <pre>socket_server_handle_interrupt(void)</pre>
*
* <i>Function</i> that handles the W5100 interrupt. It reads the interrupt register,
* extracts the socket number the interrupt happened on and clears the interrupt register
* (by mirroring the register values back).
*
* @return The socket number if successful, otherwise FALSE
* \warning If the socket number is 0, it might be misinterpreted as FALSE!
* \ingroup Ethernet
*/
uint8_t socket_server_handle_interrupt(void);
+#endif
/**
* ethernet.h
*
* <pre>socket_server_write(SOCKET s, uint8_t *buffer, size_t size)</pre>
*
* <i>Function</i> that writes a character array, buffer, of length size to a given socket.
*
* @param s The socket to write to
* @param buffer Pointer to an array of uint8_t that holds the data
* @param size The length of the buffer array
* @return TRUE on success, FALSE on failure.
* \ingroup Ethernet
*/
uint16_t socket_server_write(SOCKET s, uint8_t *buffer, size_t size);
/**
* ethernet.h
*
* <pre>socket_server_receive(SOCKET s, uint8_t *buf, uint16_t len)</pre>
*
* <i>Function</i> that receives a given number of bytes from a given socket to the
* buffer specified.
*
* @param s The socket to receive from
* @param buf Pointer to a character Array to store the bytes to
* @param len Maximum number of characters to receive, usually retrieved by socket_server_data_available
* \ingroup Ethernet
*/
uint16_t socket_server_receive(SOCKET s, uint8_t *buf, uint16_t len);
#endif //ETHERNET_H
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
@@ -1,455 +1,491 @@
/*
* This is COSMICrtOS based on FreeRTOS port to ATmega2560.
* (c) 2011 Andreas Boehler <andreas@aboehler.at>
*
* ATTENTION: Software licenses apply! GPL is probably incompatible
* with our NDA! Can we link to a binary blob instead?
*/
// FIXME: Get rid of FreeRTOS
#include <stdlib.h>
#include <string.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "iomacro.h"
#include "main.h"
#include "ethernet.h"
volatile int gEthFired = FALSE;
SOCKET gSock = MAX_SOCK_NUM;
#define TOGGLE_DELAY 300
#define INCR_DELAY 200
#define CMD_STOP 5
#define CMD_SELECT 6
#define CMD_UP 7
#define CMD_DOWN 8
+#ifdef USE_MEGA2560 // ATMega2560 (Arduino Mega2560) defines
+
#define AI_PIN0 F,0
#define AI_PIN1 F,1
#define AI_PIN2 F,2
#define AI_PIN3 F,3
#define DO_PIN_STOP E,3
#define DO_PIN_SELECT H,3
#define DO_PIN_UP H,4
#define DO_PIN_DOWN H,5
+#else // ATMega328p (Arduino Ethernet) defines
+#define AI_PIN0 C,0
+#define AI_PIN1 C,1
+#define AI_PIN2 C,2
+#define AI_PIN3 C,3
+
+#define DO_PIN_STOP D,5
+#define DO_PIN_SELECT D,6
+#define DO_PIN_UP D,7
+#define DO_PIN_DOWN B,0
+#endif
+
+#ifdef USE_ETHERNET_INTERRUPT
/***************************************
* Helper function to setup interrupts *
***************************************/
void setupExternalInterrupts(void)
{
EICRB |= (1 << ISC41); // Enable falling edge interrupt
EIMSK |= (1 << INT4); // enable external interrupt 4
}
/****************************************************
* Setup the interrupt handler for ethernet traffic *
****************************************************/
ISR(INT4_vect)
{
gEthFired = TRUE;
}
+#endif
/************************************************
* Setup and initialize the ethernet controller *
************************************************/
void setupEthernet(void)
{
uint8_t mac[] = { 0x00, 0x01, 0x02, 0x0D, 0x74, 0x47 };
uint8_t ip[] = { 192, 168, 1, 20 };
uint8_t gateway[] = { 192, 168, 1, 1 };
uint8_t subnet[] = { 255, 255, 255, 0 };
if(ethernet_init(mac, ip, gateway, subnet))
{
if((gSock = socket_server_init(SOCK_PORT)))
{
gSock -= 1;
}
}
}
/*****************
* Main function *
*****************/
int main( void )
{
// Setup registers for input and output
setupIOPorts();
+#ifdef USE_ETHERNET_INTERRUPT
setupExternalInterrupts();
+#endif
if(spi_init())
setupEthernet();
+#ifdef USE_ETHERNET_INTERRUPT
sei();
+#endif
/*
selectBlindChannel(5);
_delay_ms(5000);
blindUp(1);
blindDown(1);
blindDown(2);
blindDown(3);
blindDown(4);
blindDown(5);
*/
uint8_t new_connect[MAX_SOCK_NUM];
uint8_t connected[MAX_SOCK_NUM];
uint8_t i;
uint16_t len;
SOCKET sock;
unsigned char clientline[BUF_SIZE];
for(i=0; i < MAX_SOCK_NUM; i++)
{
new_connect[i] = TRUE;
connected[i] = FALSE;
}
for( ;; )
{
+#ifndef USE_ETHERNET_INTERRUPT
+ for(i=0; i<MAX_SOCK_NUM; i++)
+ {
+ if(socket_server_socket_connected(i))
+ {
+ if((new_connect[i]) || (socket_server_data_available(i)))
+ {
+ gEthFired = TRUE;
+ sock = i;
+ break;
+ }
+ }
+ }
+#endif
if(gEthFired)
{
gEthFired = FALSE;
+#ifdef USE_ETHERNET_INTERRUPT
sock = socket_server_handle_interrupt();
+#endif
connected[sock] = socket_server_socket_connected(sock);
if(connected[sock])
{
if(new_connect[sock])
{
socket_server_write(sock, (unsigned char*)"BlindControl ready\n", (uint16_t)19);
new_connect[sock] = FALSE;
}
}
else
{
if (!new_connect[sock])
new_connect[sock] = TRUE;
if(socket_server_socket_closed(sock))
{
socket_server_close_socket(gSock);
setupEthernet();
}
}
if(connected[sock] && (len = socket_server_data_available(sock)))
{
if(len > BUF_SIZE)
len = BUF_SIZE;
socket_server_receive(sock, clientline, len);
if(!handle_req((signed char*)clientline))
{
socket_server_close_socket(gSock);
new_connect[sock] = TRUE;
setupEthernet();
}
}
}
}
return 0;
}
int handle_req(signed char *clientline)
{
int blindNum;
char helpStr[] = "Available Commands: SelectBlind N, BlindUp[ N], BlindDown[ N], "
"BlindStop[ N], BlindIncr[ N], BlindDecr[ N], AllUp, AllDown, AllStop, help, quit\n\n";
if(strncmp(clientline, "SelectBlind ", 12) == 0)
{
blindNum = atoi(&clientline[12]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(gSock, (unsigned char *)"ERR\n", 4);
}
else
{
selectBlindChannel(blindNum);
socket_server_write(gSock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindUp ", 8) == 0)
{
blindNum = atoi(&clientline[8]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(gSock, (unsigned char *)"ERR\n", 4);
}
else
{
blindUp(blindNum);
socket_server_write(gSock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindDown ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(gSock, (unsigned char *)"ERR\n", 4);
}
else
{
blindDown(blindNum);
socket_server_write(gSock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindStop ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(gSock, (unsigned char *)"ERR\n", 4);
}
else
{
blindStop(blindNum);
socket_server_write(gSock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindIncr ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(gSock, (unsigned char *)"ERR\n", 4);
}
else
{
selectBlindChannel(blindNum);
sendCommand(CMD_UP);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(gSock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindDecr ", 10) == 0)
{
blindNum = atoi(&clientline[10]);
if((blindNum > 5) || (blindNum < 0))
{
socket_server_write(gSock, (unsigned char *)"ERR\n", 4);
}
else
{
selectBlindChannel(blindNum);
sendCommand(CMD_DOWN);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP); socket_server_write(gSock, "OK\n", 3);
}
}
else if(strncmp(clientline, "BlindUp", 7) == 0)
{
sendCommand(CMD_UP);
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindDown", 9) == 0)
{
sendCommand(CMD_DOWN);
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindStop", 9) == 0)
{
sendCommand(CMD_STOP);
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindIncr", 9) == 0)
{
sendCommand(CMD_UP);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "BlindDecr", 9) == 0)
{
sendCommand(CMD_DOWN);
_delay_ms(INCR_DELAY);
sendCommand(CMD_STOP);
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "AllUp", 5) == 0)
{
for(blindNum=1; blindNum<6; blindNum++)
{
blindUp(blindNum);
}
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "AllDown", 7) == 0)
{
for(blindNum=1; blindNum<6; blindNum++)
{
blindDown(blindNum);
}
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "AllStop", 7) == 0)
{
for(blindNum = 1; blindNum < 6; blindNum++)
{
blindStop(blindNum);
}
socket_server_write(gSock, "OK\n", 3);
}
else if(strncmp(clientline, "help", 4) == 0)
{
socket_server_write(gSock, helpStr, strlen(helpStr));
}
else if(strncmp(clientline, "quit", 4) == 0)
{
return FALSE;
}
else
{
socket_server_write(gSock, "ERR\n", 4);
}
return TRUE;
}
int getCurrentBlindChannel(void)
{
int currentChannel = 0;
int readValues;
readValues = readFromADC();
if(readValues == 0)
{
sendCommand(CMD_SELECT);
readValues = readFromADC();
}
switch(readValues)
{
case 1:
currentChannel = 1;
break;
case 2:
currentChannel = 2;
break;
case 4:
currentChannel = 3;
break;
case 8:
currentChannel = 4;
break;
case 15:
currentChannel = 5;
break;
default:
currentChannel = 0;
}
return currentChannel;
}
int readFromADC(void)
{
int j;
int channel = 0;
for(j=0;j<200;j++)
{
if(!IS_SET(AI_PIN0))
channel |= 0x01;
if(!IS_SET(AI_PIN1))
channel |= 0x02;
if(!IS_SET(AI_PIN2))
channel |= 0x04;
if(!IS_SET(AI_PIN3))
channel |= 0x08;
}
return channel;
}
int selectBlindChannel(int telisChannel)
{
while(getCurrentBlindChannel() != telisChannel)
sendCommand(CMD_SELECT);
return TRUE;
}
int blindUp(int telisChannel)
{
selectBlindChannel(telisChannel);
sendCommand(CMD_UP);
return TRUE;
}
int blindDown(int telisChannel)
{
selectBlindChannel(telisChannel);
sendCommand(CMD_DOWN);
return TRUE;
}
int blindStop(int telisChannel)
{
selectBlindChannel(telisChannel);
sendCommand(CMD_STOP);
return TRUE;
}
int sendCommand(int digitalChannel)
{
switch(digitalChannel)
{
case CMD_STOP:
SET(DO_PIN_STOP);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_STOP);
break;
case CMD_SELECT:
SET(DO_PIN_SELECT);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_SELECT);
break;
case CMD_UP:
SET(DO_PIN_UP);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_UP);
break;
case CMD_DOWN:
SET(DO_PIN_DOWN);
_delay_ms(TOGGLE_DELAY);
RESET(DO_PIN_DOWN);
break;
}
_delay_ms(TOGGLE_DELAY);
return TRUE;
}
/****************************************
* Setup all required I/O Ports for use *
****************************************/
uint8_t setupIOPorts( void )
{
SET_INPUT(AI_PIN0);
SET_INPUT(AI_PIN1);
SET_INPUT(AI_PIN2);
SET_INPUT(AI_PIN3);
RESET(DO_PIN_STOP);
RESET(DO_PIN_SELECT);
RESET(DO_PIN_UP);
RESET(DO_PIN_DOWN);
SET_OUTPUT(DO_PIN_STOP);
SET_OUTPUT(DO_PIN_SELECT);
SET_OUTPUT(DO_PIN_UP);
SET_OUTPUT(DO_PIN_DOWN);
return TRUE;
}
//EOF
diff --git a/main.h b/main.h
--- a/main.h
+++ b/main.h
@@ -1,31 +1,44 @@
#ifndef MAIN_H
#define MAIN_H
#define TRUE 1
#define FALSE 0
+#ifdef USE_MEGA2560 // Arduino Mega2560 defines
#define P_MOSI B,2
#define P_MISO B,3
#define P_SCK B,1
-#define P_SS B,0
+#define P_SS B,0
+
+#define W5100_CS B,4
+#define W5100_INT D,2
+
+#else // Arduino Ethernet defines
+#define P_MOSI B,3 //B,2
+#define P_MISO B,4 //B,3
+#define P_SCK B,5 //B,1
+#define P_SS B,2 //B,0
+
+#define W5100_CS B,2 //B,4
+#define W5100_INT E,4 // D,2
+#endif
#define BUF_SIZE 255
-#define W5100_CS B,4
-#define W5100_INT E,4 // #D,2
-
#define SOCK_PORT 63543
int readADC(int digitalChannel);
int getCurrentBlindChannel(void);
int selectBlindChannel(int telisChannel);
int blindUp(int telisChannel);
int blindDown(int telisChannel);
int blindStop(int telisChannel);
int sendCommand(int digitalChannel);
int readFromADC(void);
int main(void);
+#ifdef USE_ETHERNET_INTERRUPT
void setupExternalInterrupts(void);
+#endif
int handle_req(signed char* clientline);
uint8_t setupIOPorts(void);
#endif
diff --git a/w5100.c b/w5100.c
--- a/w5100.c
+++ b/w5100.c
@@ -1,190 +1,191 @@
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
* Ported to plain C and FreeRTOS by Andreas Boehler <andreas@aboehler.at>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include "w5100.h"
#include "main.h"
#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)
#define TXBUF_BASE 0x4000
#define RXBUF_BASE 0x6000
uint8_t w5100_init(void)
{
_delay_ms(300);
-
+#ifdef USE_ETHERNET_INTERRUPT
SET_INPUT(W5100_INT);
SET(W5100_INT);
-
+#endif
SET_OUTPUT(W5100_CS);
w5100_writeMR(1<<RST);
w5100_writeTMSR(0x55);
w5100_writeRMSR(0x55);
+#ifdef USE_ETHERNET_INTERRUPT
w5100_writeIMR((1<<IM_IR3)|(1<<IM_IR2)|(1<<IM_IR1)|(1<<IM_IR0));
-
+#endif
for (int i=0; i<MAX_SOCK_NUM; i++) {
SBASE[i] = TXBUF_BASE + SSIZE * i;
RBASE[i] = RXBUF_BASE + RSIZE * i;
}
return TRUE;
}
uint16_t w5100_getTXFreeSize(SOCKET s)
{
uint16_t val=0, val1=0;
do {
val1 = w5100_readSnTX_FSR(s);
if (val1 != 0)
val = w5100_readSnTX_FSR(s);
}
while (val != val1);
return val;
}
uint16_t w5100_getRXReceivedSize(SOCKET s)
{
uint16_t val=0,val1=0;
do {
val1 = w5100_readSnRX_RSR(s);
if (val1 != 0)
val = w5100_readSnRX_RSR(s);
}
while (val != val1);
return val;
}
void w5100_send_data_processing(SOCKET s, uint8_t *data, uint16_t len)
{
uint16_t ptr = w5100_readSnTX_WR(s);
uint16_t offset = ptr & SMASK;
uint16_t dstAddr = offset + SBASE[s];
if (offset + len > SSIZE)
{
// Wrap around circular buffer
uint16_t size = SSIZE - offset;
w5100_write_16(dstAddr, data, size);
w5100_write_16(SBASE[s], data + size, len - size);
}
else {
w5100_write_16(dstAddr, data, len);
}
ptr += len;
w5100_writeSnTX_WR(s, ptr);
}
void w5100_recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
{
uint16_t ptr;
ptr = w5100_readSnRX_RD(s);
w5100_read_data(s, (uint8_t *)ptr, data, len);
if (!peek)
{
ptr += len;
w5100_writeSnRX_RD(s, ptr);
}
}
void w5100_read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
{
uint16_t size;
uint16_t src_mask;
uint16_t src_ptr;
src_mask = (uint16_t)src & RMASK;
src_ptr = RBASE[s] + src_mask;
if( (src_mask + len) > RSIZE )
{
size = RSIZE - src_mask;
w5100_read_16(src_ptr, (uint8_t *)dst, size);
dst += size;
w5100_read_16(RBASE[s], (uint8_t *) dst, len - size);
}
else
w5100_read_16(src_ptr, (uint8_t *) dst, len);
}
uint8_t w5100_write_8(uint16_t _addr, uint8_t _data)
{
RESET(W5100_CS);
spi_putc(0xF0);
spi_putc(_addr >> 8);
spi_putc(_addr & 0xFF);
spi_putc(_data);
SET(W5100_CS);
return TRUE;
}
uint16_t w5100_write_16(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
for (int i=0; i<_len; i++)
{
RESET(W5100_CS);
spi_putc(0xF0);
spi_putc(_addr >> 8);
spi_putc(_addr & 0xFF);
_addr++;
spi_putc(_buf[i]);
SET(W5100_CS);
}
return _len;
}
uint8_t w5100_read_8(uint16_t _addr)
{
RESET(W5100_CS);
spi_putc(0x0F);
spi_putc(_addr >> 8);
spi_putc(_addr & 0xFF);
uint8_t _data = spi_putc(0);
SET(W5100_CS);
return _data;
}
uint16_t w5100_read_16(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
for (int i=0; i<_len; i++)
{
RESET(W5100_CS);
spi_putc(0x0F);
spi_putc(_addr >> 8);
spi_putc(_addr & 0xFF);
_addr++;
_buf[i] = spi_putc(0);
SET(W5100_CS);
}
return _len;
}
void w5100_execCmdSn(SOCKET s, enum SockCMD _cmd) {
// Send command to socket
w5100_writeSnCR(s, _cmd);
// Wait for command to complete
while (w5100_readSnCR(s))
;
}
void w5100_clearIR()
{
w5100_writeIR(0x00);
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 24, 5:52 PM (1 d, 14 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
542160
Default Alt Text
(28 KB)

Event Timeline