Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1822381
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
28 KB
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
rBC BlindControl
Event Timeline
Log In to Comment