Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1880293
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
9 KB
Subscribers
None
View Options
diff --git a/daemon.c b/daemon.c
new file mode 100644
--- /dev/null
+++ b/daemon.c
@@ -0,0 +1,259 @@
+#include <errno.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <memory.h>
+#include "dns320l.h"
+
+#define FAN_POLL_TIME 15
+
+int
+set_interface_attribs (int fd, int speed, int parity)
+{
+ struct termios tty;
+ memset (&tty, 0, sizeof tty);
+ if (tcgetattr (fd, &tty) != 0)
+ {
+ printf("error %d from tcgetattr", errno);
+ return -1;
+ }
+
+ cfsetospeed (&tty, speed);
+ cfsetispeed (&tty, speed);
+
+ tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
+ // disable IGNBRK for mismatched speed tests; otherwise receive break
+ // as \000 chars
+ tty.c_iflag &= ~IGNBRK; // ignore break signal
+ tty.c_lflag = 0; // no signaling chars, no echo,
+ // no canonical processing
+ tty.c_oflag = 0; // no remapping, no delays
+ tty.c_cc[VMIN] = 0; // read doesn't block
+ tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
+
+ tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
+
+ tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
+ // enable reading
+ tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
+ tty.c_cflag |= parity;
+ tty.c_cflag &= ~CSTOPB;
+ tty.c_cflag &= ~CRTSCTS;
+
+ if (tcsetattr (fd, TCSANOW, &tty) != 0)
+ {
+ printf("error %d from tcsetattr", errno);
+ return -1;
+ }
+ return 0;
+}
+
+void
+set_blocking (int fd, int should_block)
+{
+ struct termios tty;
+ memset (&tty, 0, sizeof tty);
+ if (tcgetattr (fd, &tty) != 0)
+ {
+ printf("error %d from tggetattr", errno);
+ return;
+ }
+
+ tty.c_cc[VMIN] = should_block ? 1 : 0;
+ tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
+
+ if (tcsetattr (fd, TCSANOW, &tty) != 0)
+ printf("error %d setting term attributes", errno);
+}
+
+int CheckResponse(char *buf, const char *cmd, int len)
+{
+ int i;
+ int tmp;
+
+ for(i=0;i<5;i++)
+ {
+ if(buf[i] != cmd[i])
+ {
+ printf("Char %i is %i but should be %i\n", i, buf[i], cmd[i]);
+ return ERR_WRONG_ANSWER;
+ }
+ }
+ if(buf[len-1] != cmd[len-1])
+ return ERR_WRONG_ANSWER;
+ tmp = (unsigned char)buf[5];
+ return tmp;
+}
+
+int SendCommand(int fd, const char *cmd, int checkAnswer)
+{
+ int n;
+ int i;
+ unsigned int tmp;
+
+ char buf[15]; // We need to keep the DateAndTime values here
+ // Yes, we're sending byte by byte here - b/c the lenght of
+ // commands and responses can vary!
+
+ i=0;
+ do
+ {
+ write(fd, &cmd[i], 1);
+ i++;
+ } while(cmd[i-1] != CMD_STOP_MAGIC);
+
+ i=0;
+ do
+ {
+ n = read(fd, &buf[i], 1);
+ i++;
+ } while((n == 1) && (buf[i-1] != CMD_STOP_MAGIC));
+
+
+ if(buf[i-1] != CMD_STOP_MAGIC)
+ {
+ printf("Got no stop magic!\n");
+ return ERR_WRONG_ANSWER;
+ }
+ else
+ {
+ if(checkAnswer)
+ {
+ tmp = CheckResponse(buf, cmd, i);
+ usleep(10000); // Give the µC some time to answer...
+
+ i=0;
+ do
+ {
+ n = read(fd, &buf[i], 1);
+ i++;
+ } while((n == 1) && (buf[i-1] != CMD_STOP_MAGIC));
+
+
+ if(buf[i-1] != CMD_STOP_MAGIC)
+ {
+ printf("Got no stop magic!\n");
+ return ERR_WRONG_ANSWER;
+ }
+
+ CheckResponse(buf, AckFromSerial, i);
+ return tmp;
+ }
+ else
+ {
+ return CheckResponse(buf, AckFromSerial, i);
+ }
+ }
+}
+
+int main(int args, char *argv[])
+{
+
+ char *portname = "/dev/ttyS1"; // We hardcode the path, as this daemon is inteded to run on one box only
+ int fd;
+ int n;
+ int i;
+ int sleepCount;
+ int sleepTimeUs;
+ char buf [100];
+ int temperature;
+ int fanSpeed;
+
+ fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
+ if (fd < 0)
+ {
+ printf("error %d opening %s: %s", errno, portname, strerror (errno));
+ return;
+ }
+
+ set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity)
+ set_blocking (fd, 0); // set no blocking
+
+ // Flush the serial port first...
+
+ read(fd, buf, 100);
+
+
+ if(SendCommand(fd, DeviceReadyCmd, 0) == 0)
+ printf("DeviceReady command sent, going to Fan Control Mode...\n");
+ else
+ {
+ printf("Error sending DeviceReady command, exit!\n");
+ return 1;
+ }
+
+
+ sleepCount = 0;
+ sleepTimeUs = 1000 * 100; // Sleep 100ms for every loop
+ fanSpeed = 0;
+ while(1)
+ {
+ sleepCount = 0;
+ temperature = SendCommand(fd, FanStatusGetCmd, 1);
+ if(temperature > 0)
+ {
+ temperature = ThermalTable[temperature];
+ printf("Read Temperature: %i\n", temperature);
+ if(temperature < (TEMP_LOW - HYSTERESIS))
+ {
+ if(fanSpeed != 0)
+ {
+ printf("Set Fan Stop\n");
+ SendCommand(fd, FanStopCmd, 0);
+ fanSpeed = 0;
+ }
+ }
+ else if(temperature < TEMP_LOW)
+ {
+ if(fanSpeed > 1)
+ {
+ printf("Set Fan Half\n");
+ SendCommand(fd, FanHalfCmd, 0);
+ fanSpeed = 1;
+ }
+ }
+ else if(temperature < (TEMP_HIGH - HYSTERESIS))
+ {
+ if(fanSpeed != 1)
+ {
+ printf("Set Fan Half\n");
+ SendCommand(fd, FanHalfCmd, 0);
+ fanSpeed = 1;
+ }
+ }
+ else if(temperature < TEMP_HIGH)
+ {
+ if(fanSpeed < 1)
+ {
+ printf("Set Fan Half\n");
+ SendCommand(fd, FanHalfCmd, 0);
+ fanSpeed = 1;
+ }
+ }
+ else
+ {
+ if(fanSpeed != 2)
+ {
+ printf("Set Fan Full\n");
+ SendCommand(fd, FanFullCmd, 0);
+ fanSpeed = 2;
+ }
+ }
+ }
+ else
+ {
+ printf("Error reading Temperature!\n");
+ }
+
+
+ while((sleepCount * sleepTimeUs) < (FAN_POLL_TIME * 1000 * 1000))
+ {
+ usleep(sleepTimeUs); // Sleep 100ms, replace by socket polling code for IPC
+ sleepCount++;
+ }
+
+ }
+
+ return 0;
+}
diff --git a/dns320l.h b/dns320l.h
new file mode 100644
--- /dev/null
+++ b/dns320l.h
@@ -0,0 +1,41 @@
+#ifndef DNS320L_H
+#define DNS320L_H
+
+#define ERR_WRONG_ANSWER -1
+
+#define TEMP_LOW 40
+#define TEMP_HIGH 45
+#define HYSTERESIS 2
+#define CMD_START_MAGIC 0xfa
+#define CMD_STOP_MAGIC 0xfb
+
+const char DeviceReadyCmd[] = {0xfa, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfb};
+const char AckFromSerial[] = {0xfa, 0x30, 0x00, 0x00, 0x00, 0x00, 0xfb};
+const char FanStatusGetCmd[] = {0xfa, 0x03, 0x08, 0x00, 0x00, 0x00, 0xfb};
+const char FanStopCmd[] = {0xfa, 0x02, 0x00, 0x00, 0x00, 0x00, 0xfb};
+const char FanHalfCmd[] = {0xfa, 0x02, 0x00, 0x01, 0x00, 0x00, 0xfb};
+const char FanFullCmd[] = {0xfa, 0x02, 0x00, 0x02, 0x00, 0x00, 0xfb};
+
+
+const char ThermalTable[] = {0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B,
+ 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61,
+ 0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 0x57,
+ 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D,
+ 0x4C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43,
+ 0x42, 0x41, 0x41, 0x40, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D, 0x3C,
+ 0x3B, 0x3A, 0x3A, 0x39, 0x38, 0x38, 0x37, 0x36, 0x36, 0x35,
+ 0x34, 0x34, 0x33, 0x33, 0x32, 0x31, 0x31, 0x30, 0x30, 0x2F,
+ 0x2F, 0x2E, 0x2E, 0x2D, 0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A,
+ 0x29, 0x29, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x25,
+ 0x25, 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21, 0x21,
+ 0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1C,
+ 0x1C, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x19, 0x19, 0x19, 0x18,
+ 0x18, 0x17, 0x17, 0x25, 0x1B, 0x1B, 0x19, 0x19, 0x19, 0x18,
+ 0x18, 0x17, 0x17, 0x16, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14,
+ 0x14, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10,
+ 0x10, 0xF, 0xF, 0xE, 0xE, 0xE, 0xD, 0xD, 0xC, 0xC, 0xC, 0xB,
+ 0xB, 0xA, 0xA, 9, 9, 9, 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3,
+ 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
+
+
+#endif //DNS320L_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Jan 24, 3:45 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
532537
Default Alt Text
(9 KB)
Attached To
rDNSD DNS-320L Daemon
Event Timeline
Log In to Comment