// Errors are 5.x
#include "global.h"
#if defined(PC) || defined(RASPBERRY)
#include <stdarg.h>
#include <time.h>
#endif
#ifdef PC
#define PORT 5555
Platform* _platform = new Win32();
#elif defined(RASPBERRY)
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/select.h>
#include <signal.h>
#define PORT 5555
Platform* _platform = new Raspberry();
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
#define TIMER_BASE (BCM2708_PERI_BASE + 0x00B000) /* TIMER ARM controller */
#define TIMER_LOAD (0x400 >> 2)
#define TIMER_VALUE (0x404 >> 2)
#define TIMER_CONTROL (0x408 >> 2)
#define TIMER_IRQ_CLR (0x40C >> 2)
#define TIMER_IRQ_RAW (0x410 >> 2)
#define TIMER_IRQ_MASK (0x414 >> 2)
#define TIMER_RELOAD (0x418 >> 2)
#define TIMER_PRE_DIV (0x41C >> 2)
#define TIMER_COUNTER (0x420 >> 2)
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
#define INPUT 0
#define OUTPUT 1
#define PUD_OFF 0
#define PUD_DOWN 1
#define PUD_UP 2
// pinToGpio:
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
byte pinToGpio [] =
{
17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
0, 1, // I2C - SDA0, SCL0
8, 7, // SPI - CE1, CE0
10, 9, 11, // SPI - MOSI, MISO, SCLK
14, 15 // UART - Tx, Rx
};
uint32_t pinToGpioValue [] =
{
1 << 17, 1 << 18, 1 << 21, 1 << 22, 1 << 23, 1 << 24, 1 << 25, 1 << 4, // From the Original Wiki - GPIO 0 through 7
1 << 0, 1 << 1, // I2C - SDA0, SCL0
1 << 8, 1 << 7, // SPI - CE1, CE0
1 << 10, 1 << 9, 1 << 11, // SPI - MOSI, MISO, SCLK
1 << 14, 1 << 15 // UART - Tx, Rx
};
// gpioToGPFSEL:
// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
uint8_t gpioToGPFSEL [] =
{
0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,
} ;
// gpioToShift
// Define the shift up for the 3 bits per pin in each GPFSEL port
uint8_t gpioToShift [] =
{
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
0,3,6,9,12,15,18,21,24,27,
} ;
#else
Platform* _platform = new Arduino();
// pinToGpio:
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
byte pinToGpio[] =
{
#if defined(BOARD2560) && defined(USEPORTL)
// this works fine for non-parallel operation but i think i have them in the wrong order for parallel ... i must check the port L spec
42, 43, 44, 45, 46, 47, 48, 49, 11, 13 , 0, 11, 0, 13
#else
2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 0, 11, 0, 13
#endif
};
#endif
int lastByte = 0;
#if defined(PC)
Win32::Win32()
{
_sClient = INVALID_SOCKET;
FILE *f = NULL;
fopen_s(&f, "tcpip.txt", "rt");
// if the file was opened
if (f != NULL)
{
memset(_addr, sizeof(_addr), 0x00);
int read = fread(_addr, 1, sizeof(_addr)-1, f);
_addr[read] = 0x00;
fclose(f);
}
else
{
strcpy_s(_addr, sizeof(_addr), "127.0.0.1");
}
}
#elif defined(RASPBERRY)
Raspberry::Raspberry()
{
gpio = NULL;
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
sockfd = 0;
FILE *f = fopen("tcpip.txt", "rt");
// if the file was opened
if (f != NULL)
{
memset(_addr, sizeof(_addr), 0x00);
int read = fread(_addr, 1, sizeof(_addr)-1, f);
_addr[read] = 0x00;
fclose(f);
}
else
{
strcpy(_addr, "127.0.0.1");
}
#endif
}
#endif
///************************************************************************************************************
///
/// WriteDebugMessage
///
///************************************************************************************************************
#ifdef PC
#ifdef MINMEMORY
void Win32::sxssage(const char* message)
{
printf("MSG:%s", message);
SendToEmulator(message);
}
#else
void Win32::WriteMessage(const char* message, ...)
{
va_list args;
va_start(args, message);
printf("MSG:");
vprintf(message, args);
char msg[1024];
vsprintf_s(msg, sizeof(msg), message, args);
SendToEmulator(msg);
va_end(args);
}
#endif
#elif defined(RASPBERRY)
#ifdef MINMEMORY
void Raspberry::WriteMessage(const char* message)
{
printf("MSG:%s", message);
SendToEmulator(message);
}
#else
void Raspberry::WriteMessage(const char* message, ...)
{
char buffer[4096];
va_list args;
va_start(args, message);
vsprintf(buffer, message, args);
printf("MSG: %s", buffer);
// send message over TCP/IP
SendToEmulator(buffer);
va_end(args);
}
#endif
#else
int Arduino::freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
#ifdef MINMEMORY
void Arduino::WriteMessage(const char* message)
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
SendToEmulator(message);
#endif
}
#else
void Arduino::WriteMessage(const char* message, ...)
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
// potential buffer overflow
char buffer[256];
va_list args;
va_start(args, message);
vsprintf(buffer, message, args);
SendToEmulator(buffer);
va_end(args);
#endif
}
#endif
#endif
///************************************************************************************************************
///
/// Randomise
///
///************************************************************************************************************
#ifdef PC
void Win32::Randomise()
{
// initliase the random number generator
srand((unsigned)time(NULL));
}
#elif defined(RASPBERRY)
void Raspberry::Randomise()
{
// initliase the random number generator
srand((unsigned)time(NULL));
}
#else
void Arduino::Randomise()
{
// initliase the random number generator
randomSeed(analogRead(0));
}
#endif
///************************************************************************************************************
///
/// InitialisePins
///
///************************************************************************************************************
#ifdef PC
void Win32::InitialisePins()
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
// nothing required
ConnectTCPIP();
#endif
}
#elif defined(RASPBERRY)
void Raspberry::pinMode(int pin, int mode)
{
int gpioPin, fSel, shift ;
gpioPin = pinToGpio [pin] ;
fSel = gpioToGPFSEL [gpioPin] ;
shift = gpioToShift [gpioPin] ;
if (mode == INPUT)
{
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
}
else if (mode == OUTPUT)
{
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
}
// When we change mode of any pin, we remove the pull up/downs
pullUpDnControl (pin, PUD_OFF) ;
}
void Raspberry::pullUpDnControl (int pin, int pud)
{
int gpioPin ;
gpioPin = pinToGpio [pin] ;
*(gpio + 37) = pud ;
DelayMicroseconds (10) ;
*(gpio + 38) = 1 << gpioPin ;
DelayMicroseconds (10) ;
*(gpio + 37) = 0 ;
}
void Raspberry::MapController(volatile uint32_t** controller, off_t offset)
{
// these are created but never destroyed as this is assumed to be forever ... or at least until the next reboot
int fd ; // device file descriptor
uint8_t *pMem; // mapped memory
// Open the master /dev/memory device
if ((fd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.1\n");
#else
WriteMessage("MapController: Unable to open /dev/mem: %s\n", strerror(errno));
#endif
#endif
#ifndef DONT_FAIL_ON_HARDWARE_ERRORS
Error(5);
#endif
*controller = NULL;
return;
}
// Allocate 2 pages - 1 byte so i can fit a 4K aligned page ...
if ((pMem = (uint8_t*)malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.2\n");
#else
WriteMessage("MapController: malloc failed: %s\n", strerror(errno));
#endif
#endif
#ifndef DONT_FAIL_ON_HARDWARE_ERRORS
Error(5);
#endif
*controller = NULL;
return;
}
// 4K align my page
if (((uint32_t)pMem % PAGE_SIZE) != 0)
{
pMem += PAGE_SIZE - ((uint32_t)pMem % PAGE_SIZE) ;
}
// Map the memory
*controller = (volatile uint32_t *)mmap((caddr_t)pMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, offset) ;
if ((int32_t)controller < 0)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.3\n");
#else
WriteMessage("MapController: mmap failed: %s\n", strerror (errno));
#endif
#endif
#ifndef DONT_FAIL_ON_HARDWARE_ERRORS
Error(5);
#endif
*controller = NULL;
return;
}
return;
}
void Raspberry::InitialisePins()
{
gpio = NULL;
timer = NULL;
#ifdef USEINTERRUPT
timerIrqRaw = NULL;
#endif
// do this first just in case the rest fails
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
ConnectTCPIP();
#endif
MapController(&gpio, GPIO_BASE);
MapController(&timer, TIMER_BASE);
//*(timer+(0x408>>2)) = 0xF90200; // run at 1MHz
// Set the timer to free-running, 1MHz.
// 0xF9 is 249, the timer divide is base clock / (divide+1)
// so base clock is 250MHz / 250 = 1MHz.
*(timer + TIMER_CONTROL) = 0x0000280;
*(timer + TIMER_PRE_DIV) = 0x00000F9;
#ifdef USEINTERRUPT
timerIrqRaw = timer + TIMER_IRQ_RAW;
#endif
for(int i = 0; i<MAXSTRINGS; i++)
{
pinMode(i, OUTPUT);
}
pinMode(ERRORPIN, OUTPUT);
pinMode(PROGRESSPIN, OUTPUT);
return;
}
#else
void Arduino::InitialisePins()
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
Serial.begin(115200);
#endif
// initialise our error pin. This pin will be flashed if an error occurs
pinMode(ERRORPIN, OUTPUT);
digitalWrite(ERRORPIN, 1);
Delay(100);
digitalWrite(ERRORPIN, 0);
// set the progress pin as an output pin - we flash this each time the program goes through a cycle
pinMode(PROGRESSPIN, OUTPUT);
digitalWrite(PROGRESSPIN, 1);
Delay(100);
digitalWrite(PROGRESSPIN, 0);
for(int i = 0; i<MAXSTRINGS; i++)
{
//byte gpioPin = pgm_read_byte_near(pinToGpio+i);
pinMode(pinToGpio[i], OUTPUT);
digitalWrite(pinToGpio[i], 0);
}
pinMode(DEBUG1, INPUT);
pinMode(DEBUG2, INPUT);
}
#endif
///************************************************************************************************************
///
/// Error
///
///************************************************************************************************************
void Platform::Error(byte err)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("Err\n");
#else
WriteMessage("Err %d\n", err);
#endif
#endif
// hang
while(true)
{
for(byte i = 0; i < err; i++)
{
WritePin(ERRORPIN, 1);
SendToEmulator(ERRORPIN, 1);
Delay(500);
WritePin(ERRORPIN, 0);
SendToEmulator(ERRORPIN, 0);
Delay(500);
}
Delay(3000);
}
}
///************************************************************************************************************
///
/// Delay
///
///************************************************************************************************************
#ifdef PC
inline void Win32::Delay(unsigned long millisecs)
{
Sleep(millisecs);
}
#elif defined(RASPBERRY)
void Raspberry::Delay(unsigned long millisecs)
{
struct timespec sleeper;
struct timespec dummy;
sleeper.tv_sec = (time_t)(millisecs / 1000) ;
sleeper.tv_nsec = (long)(millisecs % 1000) * 1000000 ;
nanosleep (&sleeper, &dummy) ;
}
#else
inline void Arduino::Delay(unsigned long millisecs)
{
delay(millisecs);
}
#endif
///************************************************************************************************************
///
/// DelayUntil
///
///************************************************************************************************************
#ifdef RASPBERRY
unsigned Raspberry::DelayUntil(unsigned until)
{
if (until == 0)
{
return *(timer+(0x420>>2)); // the value of free running counter
}
else
{
unsigned current_count = 0;
while(current_count < until)
{
current_count = *(timer+(0x420>>2));
// does not handle when the counter loops around ... assume this does not happen very often
}
return current_count;
}
}
#endif
///************************************************************************************************************
///
/// DelayMicroseconds
///
///************************************************************************************************************
#ifdef PC
void Win32::DelayMicroseconds(unsigned long microsecs)
{
// not required
}
#elif defined(RASPBERRY)
void Raspberry::DelayMicroseconds(unsigned long microsecs)
{
if (microsecs != 0)
{
#ifdef USEINTERRUPT
*(timer + TIMER_LOAD) = howLong ;
*(timer + TIMER_IRQ_CLR) = 0 ;
while (*timerIrqRaw == 0);
#else
unsigned count_at_start;
unsigned current_count;
count_at_start = *(timer+(0x420>>2)); // the value of free running counter
current_count = count_at_start;
while((current_count - count_at_start) < (unsigned)microsecs)
{
current_count = *(timer+(0x420>>2));
// does not handle when the counter loops around ... assume this does not happen very often
}
#endif
//struct timeval end;
//struct timeval now;
//gettimeofday(&now, NULL);
//end.tv_sec = now.tv_sec;
//end.tv_usec = now.tv_usec + microsecs;
//if (end.tv_usec > 1000000)
//{
// end.tv_usec -= 1000000;
// end.tv_sec++;
//}
//gettimeofday(&now, NULL);
//while (now.tv_sec < end.tv_sec || (now.tv_sec == end.tv_sec && now.tv_usec < end.tv_usec))
//{
// gettimeofday(&now, NULL);
//}
}
}
#else
inline void Arduino::DelayMicroseconds(unsigned long microsecs)
{
if (microsecs != 0)
{
delayMicroseconds(microsecs);
}
}
#endif
///************************************************************************************************************
///
/// ReadPin
///
///************************************************************************************************************
#ifdef INCLUDE_DEBUG_PATTERNS
#ifdef USEARDUINO
inline bool Arduino::ReadPin(byte pin)
{
// set the pin to one
return (bool)digitalRead(pin);
}
#endif
#endif
///************************************************************************************************************
///
/// WritePin
///
///************************************************************************************************************
#ifdef PC
void Win32::WritePin(byte pin, byte value)
{
}
#elif defined(RASPBERRY)
void Raspberry::WritePin(byte pin, byte value)
{
if (gpio != NULL)
{
int gpioPin = pinToGpio [pin] ;
if (value == 0)
{
*(gpio + 10) = 1 << gpioPin ;
}
else
{
*(gpio + 7) = 1 << gpioPin ;
}
}
}
#else
inline void Arduino::WritePin(byte pin, byte value)
{
// set the pin to one
digitalWrite(pinToGpio[pin],value);
}
#endif
///************************************************************************************************************
///
/// WriteParallel
///
///************************************************************************************************************
#ifdef PC
void Win32::WriteParallel(byte b)
{
for(int i = 0; i < MAXSTRINGS; i++)
{
WritePin(i, b & (0x80 >> i));
}
}
#elif defined(RASPBERRY)
inline uint32_t Raspberry::GetSet(byte b, int pin)
{
if (b != 0)
{
return pinToGpioValue[pin];
}
return 0;
}
inline uint32_t Raspberry::GetClr(byte b, int pin)
{
if (b == 0)
{
return pinToGpioValue[pin];
}
return 0;
}
void Raspberry::WriteParallel(byte b)
{
if (gpio != NULL)
{
// set
uint32_t bout = 0;
byte mask = 0x80;
for(int i = 0; i < MAXSTRINGS; i++)
{
bout = bout + GetSet(b & mask, i);
mask = mask >> 1;
}
*(gpio + 7) = bout;
// clear
bout = 0;
mask = 0x80;
for(int i = 0; i < MAXSTRINGS; i++)
{
bout = bout + GetClr(b & mask, i);
mask = mask >> 1;
}
*(gpio + 10) = bout;
}
}
#else
inline void Arduino::WriteParallel(byte b)
{
#ifdef BOARD2560
#ifdef USEPORTL
PORTL = b;
#else
//PORTE notused,notused,3,2,5,notused,notused,notused
PORTE = (b&0x03)<<4 | (b&0x08);
//PORTG notused,notused,4,notused,notused,notused,notused,notused
PORTG = (b&0x04)<<3;
//PORTH 9,8,7,6,notused,notused,notused
PORTH = (b&0xF0);
#endif
#else
// PORTD 0->7 : 7,6,5,4,3,2,notused,notused
PORTD = b << 2;
// PORTB 8-13 (bits 6-7 unusable) : unusable, unusable, 13,12,11,10,9,8
PORTB = b >> 6;
#endif
}
#endif
///************************************************************************************************************
///
/// SendToEmulator
///
///************************************************************************************************************
#ifdef PC
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
void Win32::ConnectTCPIP()
{
WSADATA wsaData;
SOCKADDR_IN RemoteAddr;
//start up winsock (we are expecting version 1.1 winsock DLL)
int nRet=WSAStartup(MAKEWORD(1, 1), &wsaData);
if(nRet)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.4\n");
#else
WriteMessage("Error starting winsock %d.\n", WSAGetLastError());
#endif
#endif
_sClient = INVALID_SOCKET;
return;
}
//check version compliance
if((LOBYTE(wsaData.wVersion) != 1) || (HIBYTE(wsaData.wVersion) != 1))
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.5\n");
#else
WriteMessage("Incorrect WinSock Version.\n");
#endif
#endif
_sClient=INVALID_SOCKET;
return;
}
//create socket
_sClient=socket(AF_INET, SOCK_STREAM, 0);
//if socket creation failed, exit
if(_sClient == INVALID_SOCKET)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.6\n");
#else
WriteMessage("Error creating client socket %d.\n", WSAGetLastError());
#endif
#endif
_sClient=INVALID_SOCKET;
return;
}
RemoteAddr.sin_family=PF_INET;
//connecting to localhost
RemoteAddr.sin_addr.s_addr=inet_addr(_addr);
//port 5555
RemoteAddr.sin_port=htons(PORT);
int AddrLen=sizeof(SOCKADDR);
nRet=connect(_sClient, (PSOCKADDR)&RemoteAddr, AddrLen);
if(nRet == SOCKET_ERROR)
{
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.7\n");
#else
WriteMessage("Error connecting to emulator %d.\n", WSAGetLastError());
#endif
#endif
_sClient=INVALID_SOCKET;
return;
}
}
#endif
void Win32::SendToEmulator(byte value)
{
#ifdef SENDTOEMULATOR
if (_sClient!=INVALID_SOCKET)
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf_s(buffer, sizeof(buffer), "P%d\n", value);
int nRet=send(_sClient, buffer, strlen(buffer), 0);
if (nRet < 0)
{
_sClient = INVALID_SOCKET;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.8\n");
#else
WriteMessage("Error writing to emulator %d - %d.\n", nRet);
#endif
#endif
return;
}
}
#endif
}
void Win32::SendToEmulator(byte pin, byte value)
{
#ifdef SENDTOEMULATOR
if (_sClient!=INVALID_SOCKET)
{
if (pin == ERRORPIN)
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf_s(buffer, sizeof(buffer), "E%d\n", value);
int nRet=send(_sClient, buffer, strlen(buffer), 0);
if (nRet < 0)
{
_sClient = INVALID_SOCKET;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.9\n");
#else
WriteMessage("Error writing to emulator %d.\n", nRet);
#endif
#endif
return;
}
}
else if (pin == PROGRESSPIN)
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf_s(buffer, sizeof(buffer), "G%d\n", value);
int nRet=send(_sClient, buffer, strlen(buffer), 0);
if (nRet < 0)
{
_sClient = INVALID_SOCKET;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.10\n");
#else
WriteMessage("Error writing to emulator %d.\n", nRet);
#endif
#endif
return;
}
}
else
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf_s(buffer, sizeof(buffer), "B%d%d\n", pin, value);
int nRet=send(_sClient, buffer, strlen(buffer), 0);
if (nRet < 0)
{
_sClient = INVALID_SOCKET;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.11\n");
#else
WriteMessage("Error writing to emulator %d.\n", nRet);
#endif
#endif
return;
}
}
}
#endif
}
void Win32::SendStartToEmulator()
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
if (_sClient!=INVALID_SOCKET)
{
int nRet = send(_sClient, "**START**\n", strlen("**START**\n"), 0);
if (nRet < 0)
{
_sClient = INVALID_SOCKET;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.19\n");
#else
WriteMessage("Error writing start message to emulator %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
#endif
}
void Win32::SendToEmulator(const char* szMsg)
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
if (_sClient!=INVALID_SOCKET)
{
char msg[1024];
memset(msg, 0x00, sizeof(msg));
strcpy_s(msg, sizeof(msg), "M");
strcat_s(msg, sizeof(msg), szMsg);
int nRet=send(_sClient, msg, strlen(msg), 0);
if (nRet < 0)
{
_sClient = INVALID_SOCKET;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.12\n");
#else
WriteMessage("Error writing to emulator %d.\n", nRet);
#endif
#endif
return;
}
}
#endif
}
#elif defined(RASPBERRY)
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
void Raspberry::ConnectTCPIP()
{
int nRet = 0;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.13\n");
#else
WriteMessage("Error creating client socket %d.\n", sockfd);
#endif
#endif
return;
}
fd_set rset;
fd_set wset;
//clear out descriptor sets for select
//add socket to the descriptor sets
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset; //structure assignment ok
int flags = 0;
if((flags = fcntl(sockfd, F_GETFL, 0)) < 0)
{
//close(sockfd);
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.13.1\n");
#else
WriteMessage("Error getting socket non blocking flag.\n");
#endif
#endif
return;
}
if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
//close(sockfd);
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.13.2\n");
#else
WriteMessage("Error setting socket non blocking flag.\n");
#endif
#endif
return;
}
memset(&serv_addr, 0x00, sizeof(serv_addr));
serv_addr.sin_family=PF_INET;
serv_addr.sin_addr.s_addr=inet_addr(_addr);
serv_addr.sin_port = htons(PORT);
nRet = connect(sockfd, (sockaddr*)&serv_addr, sizeof(serv_addr));
if (nRet < 0 && errno != EINPROGRESS)
{
//close(sockfd);
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.14\n");
#else
WriteMessage("Error connecting to emulator %d.\n", nRet);
#endif
#endif
return;
}
// wait for a while to see it we get a connect
if (nRet != 0)
{
struct timeval ts;
memset(&ts, 0x00, sizeof(ts));
ts.tv_sec = 2;
nRet = select(sockfd + 1, &rset, &wset, NULL, &ts);
if(nRet < 0)
{
//close(sockfd);
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.14.2\n");
#else
WriteMessage("Error waiting for connection %d.\n", nRet);
#endif
#endif
return;
}
else if(nRet == 0)
{
//close(sockfd);
sockfd = 0;
#ifdef INCLUDE_MSG_IMPORTANT
#ifdef MINMEMORY
WriteMessage("5.14.3\n");
#else
WriteMessage("Timeout waiting for emulator connection.\n");
#endif
#endif
return;
}
}
if(fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK) < 0)
{
//close(sockfd);
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.13.2\n");
#else
WriteMessage("Error re-setting socket non blocking flag.\n");
#endif
#endif
return;
}
#ifdef INCLUDE_MSG_IMPORTANT
#ifdef MINMEMORY
WriteMessage("5.14.1\n");
#else
WriteMessage("Emulator connected.\n");
#endif
#endif
}
#endif
void Raspberry::SendToEmulator(byte pin, byte value)
{
#ifdef SENDTOEMULATOR
if (sockfd != 0)
{
if (pin == ERRORPIN)
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf(buffer, "E%d\n", value);
int nRet = send(sockfd, buffer, strlen(buffer), 0);
if (nRet < 0)
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.15\n");
#else
WriteMessage("Error writing to emulator error pin/value %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
else if (pin == PROGRESSPIN)
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf(buffer, "G%d\n", value);
int nRet = send(sockfd, buffer, strlen(buffer), 0);
if (nRet < 0)
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.16\n");
#else
WriteMessage("Error writing to emulator progress pin/value %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
else
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf(buffer, "B%d%d\n", pin, value);
int nRet = send(sockfd, buffer, strlen(buffer), 0);
if (nRet < 0 )
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.17\n");
#else
WriteMessage("Error writing to emulator data pin/value %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
}
#endif
}
void Raspberry::SendToEmulator(byte value)
{
#ifdef SENDTOEMULATOR
if (sockfd != 0)
{
char buffer[256];
memset(buffer, 0x00, sizeof(buffer));
sprintf(buffer, "P%d\n", value);
int nRet = send(sockfd, buffer, strlen(buffer), 0);
if (nRet < 0)
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.18\n");
#else
WriteMessage("Error writing to emulator parallel %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
#endif
}
void Raspberry::SendStartToEmulator()
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
if (sockfd != 0)
{
int nRet = send(sockfd, "**START**\n", strlen("**START**\n"), 0);
if (nRet < 0)
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.19\n");
#else
WriteMessage("Error writing start message to emulator %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
#endif
}
void Raspberry::SendToEmulator(const char* szMsg)
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
if (sockfd != 0)
{
char msg[1024];
memset(msg, 0x00, sizeof(msg));
strcpy(msg, "M");
strcat(msg, szMsg);
int nRet = send(sockfd, msg, strlen(msg), 0);
if (nRet < 0)
{
sockfd = 0;
#ifdef INCLUDE_MSG_CRITICAL
#ifdef MINMEMORY
WriteMessage("5.19\n");
#else
WriteMessage("Error writing to emulator message %d - %d.\n", nRet, errno);
#endif
#endif
return;
}
}
#endif
}
#else
void Arduino::SendToEmulator(byte pin, byte value)
{
#ifdef SENDTOEMULATOR
if (pin == ERRORPIN)
{
Serial.print("E");
Serial.println(value, DEC);
}
else if (pin == PROGRESSPIN)
{
Serial.print("G");
Serial.println(value, DEC);
}
else
{
Serial.print("B");
Serial.print(pin, DEC);
Serial.println(value, DEC);
}
#endif
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
Serial.print("F");
Serial.println(freeRam(),DEC);
#endif
}
void Arduino::SendToEmulator(byte value)
{
#ifdef SENDTOEMULATOR
Serial.print("P");
Serial.println(value, DEC);
#endif
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
Serial.print("F");
Serial.println(freeRam(),DEC);
#endif
}
void Arduino::SendToEmulator(const char* szMSG)
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
Serial.print("M");
Serial.println(szMSG);
Serial.print("F");
Serial.println(freeRam(),DEC);
#endif
}
void Arduino::SendStartToEmulator()
{
#if defined(SENDTOEMULATOR) || defined(SENDTOEMULATORMSGS)
Serial.println("");
Serial.println("**START**\n");
Serial.print("F");
Serial.println(freeRam(),DEC);
#endif
}
#endif