Bläddra i källkod

Merge pull request #11 from jancoow/HttpRadioCommunicatie

Http radio communicatie
Janco Kock 9 år sedan
förälder
incheckning
4efaac5e78
13 ändrade filer med 806 tillägg och 106 borttagningar
  1. 90 0
      alarm.c
  2. 11 0
      alarm.h
  3. 49 13
      display.c
  4. 2 1
      display.h
  5. 42 7
      displayHandler.c
  6. 1 1
      displayHandler.h
  7. 330 0
      jsmn.c
  8. 86 0
      jsmn.h
  9. 64 74
      main.c
  10. 121 3
      network.c
  11. 3 0
      network.h
  12. 6 6
      ntp.c
  13. 1 1
      rtc.c

+ 90 - 0
alarm.c

@@ -0,0 +1,90 @@
+#define LOG_MODULE  LOG_MAIN_MODULE
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "log.h"
+#include "rtc.h"
+#include "alarm.h"
+
+struct _alarm{
+	int seconds;
+	char name[16];
+};
+
+void setAlarm(struct _tm time, char *name, int sec){
+	struct _alarm al;
+	
+	X12RtcSetAlarm(0, &time, AFLGS);
+	NutDelay(100);
+	
+	al.seconds = sec;
+	strncpy(al.name, name, sizeof(al.name));
+	
+	//Schrijf struct naar eeprom
+}
+
+int getDuration(){
+	//Haal duration op uit eeprom
+	return 10;
+}
+
+char* getName(){
+	//haal naam op uit eeprom en geef de pointer mee
+	char str[17];
+	//int x = 561;
+	//sprintf(str,"test123456789%d", x);
+	sprintf(str, "     Wekker     ");
+	return str;
+}
+
+void handleAlarm(){
+	struct _tm alarmtime;
+	
+    alarmtime = GetRTCTime();
+	
+    X12RtcGetAlarm(0,&alarmtime,AFLGS);
+	alarmtime.tm_min = (alarmtime.tm_min-79);
+	alarmtime.tm_mday = (alarmtime.tm_mday - 80);
+	alarmtime.tm_mon = (alarmtime.tm_mon - 80);
+	
+		
+	X12RtcSetAlarm(0,&alarmtime, AFLGS);
+	NutDelay(100);
+	X12RtcClearStatus(ALARM_1);
+}
+
+int checkTime(){
+	/*struct _tm ctime;
+	struct _tm atime;
+	time_t at;
+	time_t ct;
+	time_t diff;
+	
+	atime = GetRTCTime();
+	ctime = GetRTCTime();
+	
+	X12RtcGetAlarm(0,&atime,0b11111111);
+	atime.tm_min = atime.tm_min - 80;
+	atime.tm_mday = (atime.tm_mday - 80);
+	atime.tm_mon = (atime.tm_mon - 80);
+	atime.tm_year = 116;
+	
+	LogMsg_P(LOG_INFO, PSTR("at %02d-%02d-%04d || %02d-%02d-%02d"), atime.tm_mday, atime.tm_mon+1, atime.tm_year+1900, atime.tm_hour, atime.tm_min, atime.tm_sec);
+	
+	ct = mktime(&ctime);
+	at = mktime(&atime);
+	
+	at += getDuration();
+	
+	LogMsg_P(LOG_INFO, PSTR("at = %d, ct = %d"), at, ct);
+	
+	diff = ct - at;
+	
+	if (diff > 0){
+		return 1;
+	}*/
+	return 0;
+}
+

+ 11 - 0
alarm.h

@@ -0,0 +1,11 @@
+/* Alarm get/set status values */
+#define ALARM_1 	5
+#define ALARM_2		6
+
+#define AFLGS		0b11111111
+
+void handleAlaram(void);
+void setAlarm(struct _tm time, char *name, int sec);
+int getDuration(void);
+char* getName(void);
+int checkTime(void);

+ 49 - 13
display.c

@@ -26,7 +26,7 @@
 #include "portio.h"
 #include "display.h"
 #include "log.h"
-
+#include <time.h>
 /*-------------------------------------------------------------------------*/
 /* local defines                                                           */
 /*-------------------------------------------------------------------------*/
@@ -42,6 +42,18 @@ static void LcdWriteByte(u_char, u_char);
 static void LcdWriteNibble(u_char, u_char);
 static void LcdWaitBusy(void);
 
+int timerLCD(u_char Mode){
+    time_t Start;
+    if(Mode == startLCD)
+    {
+            time_t diff = time(0) - Start;
+            return diff;
+    }
+    else if(Mode == stopLCD)
+    {
+        Start = time(0);
+    }
+}
 /*!
  * \addtogroup Display
  */
@@ -52,11 +64,11 @@ static void LcdWaitBusy(void);
 /*                         start of code                                   */
 /*-------------------------------------------------------------------------*/
 
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 /*!
  * \brief control backlight
  */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 void LcdBackLight(u_char Mode)
 {
     if (Mode==LCD_BACKLIGHT_ON)
@@ -70,7 +82,31 @@ void LcdBackLight(u_char Mode)
     }
 }
 
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+
+/* ����������������������������������������������������������������������� */
+
+/*
+ * Lcdbacklight knipperen
+ */
+
+void LcdBacklightKnipperen(u_char Mode)
+{
+    time_t Start;
+    time_t Stop;
+    if (Mode==startLCD)
+    {
+        sbi(LCD_BL_PORT, LCD_BL_BIT);   // Turn on backlight
+        timer(Start);
+    }
+    if (Mode==stopLCD)
+    {
+        cbi(LCD_BL_PORT, LCD_BL_BIT);   // Turn off backlight
+        timer(Stop);
+    }
+}
+/*
+
+/* ����������������������������������������������������������������������� */
 /*!
  * \brief Write a single character on the LCD
  *
@@ -78,14 +114,14 @@ void LcdBackLight(u_char Mode)
  *
  * \param LcdChar character to write
  */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 void LcdChar(char MyChar)
 {
     LcdWriteByte(WRITE_DATA, MyChar);
 }
 
 
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 /*!
  * \brief Low-level initialisation function of the LCD-controller
  *
@@ -94,7 +130,7 @@ void LcdChar(char MyChar)
  *           1 line dislay, 10 dots high characters
  *
  */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
  void LcdLowLevelInit()
 {
     u_char i;
@@ -127,7 +163,7 @@ void LcdChar(char MyChar)
 }
 
 
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 /*!
  * \brief Low-level routine to write a byte to LCD-controller
  *
@@ -139,7 +175,7 @@ void LcdChar(char MyChar)
  * \param LcdByte byte to write
  *
  */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 static void LcdWriteByte(u_char CtrlState, u_char LcdByte)
 {
     LcdWaitBusy();                      // see if the controller is ready to receive next byte
@@ -148,7 +184,7 @@ static void LcdWriteByte(u_char CtrlState, u_char LcdByte)
 
 }
 
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 /*!
  * \brief Low-level routine to write a nibble to LCD-controller
  *
@@ -160,7 +196,7 @@ static void LcdWriteByte(u_char CtrlState, u_char LcdByte)
  * \param LcdNibble nibble to write (upper 4 bits in this byte
  *
  */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 static void LcdWriteNibble(u_char CtrlState, u_char LcdNibble)
 {
     outp((inp(LCD_DATA_DDR) & 0x0F) | 0xF0, LCD_DATA_DDR);  // set data-port to output again
@@ -186,7 +222,7 @@ static void LcdWriteNibble(u_char CtrlState, u_char LcdNibble)
     outp((inp(LCD_DATA_PORT) & 0x0F) | 0xF0, LCD_DATA_PORT);  // enable pull-ups in data-port
 }
 
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 /*!
  * \brief Low-level routine to see if the controller is ready to receive
  *
@@ -194,7 +230,7 @@ static void LcdWriteNibble(u_char CtrlState, u_char LcdNibble)
  * has become '0'. If a '0' is detected on bit 7 the function returns.
  *
  */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
+/* ����������������������������������������������������������������������� */
 static void LcdWaitBusy()
 {
     u_char Busy = 1;

+ 2 - 1
display.h

@@ -30,7 +30,8 @@
 
 #define LCD_BACKLIGHT_ON            1
 #define LCD_BACKLIGHT_OFF           0
-
+#define startLCD        1
+#define stopLCD          0
 #define ALL_ZERO          			0x00      // 0000 0000 B
 #define WRITE_COMMAND     			0x02      // 0000 0010 B
 #define WRITE_DATA        			0x03      // 0000 0011 B

+ 42 - 7
displayHandler.c

@@ -1,6 +1,7 @@
 //
 // Created by Jordy Sipkema on 26/02/16.
 //
+#define LOG_MODULE  LOG_MAIN_MODULE
 
 #include <stdlib.h>
 #include <string.h>
@@ -9,7 +10,10 @@
 #include "display.h"
 #include "displayHandler.h"
 #include "ntp.h"
+#include "log.h"
 #include "rtc.h"
+#include "alarm.h"
+#include "network.h"
 
 #define MONTH_OFFSET 1
 #define YEAR_OFFSET 1900
@@ -32,24 +36,55 @@ void displayTime(int line_number){
     }
 }
 
-void displayDate(int line_number){
+void displayDate(int line_number) {
     tm *time;
     X12RtcGetClock(time);
 
     char str[13];
-    if (NtpTimeIsValid()){
-        sprintf(str, "   %02d-%02d-%04d", time->tm_mday, time->tm_mon+MONTH_OFFSET, time->tm_year+YEAR_OFFSET);
-    }else {
-        sprintf(str, "   ??-??-????");
+
+    if (NtpTimeIsValid()) {
+        sprintf(str, "   %02d-%02d-%04d   ", time->tm_mday, time->tm_mon + MONTH_OFFSET, time->tm_year + YEAR_OFFSET);
+    } else {
+        sprintf(str, "   ??-??-????   ");
     }
 
-    if(NtpIsSyncing())
-        str[1] = 'S';
+    if (NtpIsSyncing()) {
+       str[1] = 'S';
+    }else if(NetworkIsReceiving()){
+        str[1] = 'N';
+    }
 
     if (line_number > -1 && line_number < 2){
         (*write_display_ptr[line_number])(str, 13);
     }
 }
 
+void displayAlarm(int line_number, int line_numberTwo)
+{
+    struct _tm alarmtime;
+	int i;
+    alarmtime = GetRTCTime();
+	
+    X12RtcGetAlarm(0,&alarmtime,0b11111111);
+    char str[12];
+    sprintf(str, "    %02d:%02d:%02d    ", alarmtime.tm_hour, alarmtime.tm_min - 80, alarmtime.tm_sec);
+    if (line_number > -1 && line_number < 2){
+        (*write_display_ptr[line_number])(str, 12);
+    }
+
+    char str2[17];
+	char *data = getName();
+	for(i = 0; i < 17; i++){
+		str2[i] = data[i];
+	}
+	//LogMsg_P(LOG_INFO, PSTR("%d"), str2);
+    //sprintf(str2,"     Wekker     ");
+	//LogMsg_P(LOG_INFO, PSTR("%d"), str2);
+    if (line_numberTwo > -1 && line_numberTwo < 2){
+        (*write_display_ptr[line_numberTwo])(str2, 16);
+        LcdBacklightKnipperen(startLCD);
+    }
+}
+
 
 

+ 1 - 1
displayHandler.h

@@ -7,5 +7,5 @@
 
 void displayTime(int);
 void displayDate(int);
-
+void displayAlarm(int line_number, int line_numberTwo);
 #endif //MUTLI_OS_BUILD_DISPLAYHANDLER_H

+ 330 - 0
jsmn.c

@@ -0,0 +1,330 @@
+#include "jsmn.h"
+
+/**
+ * Allocates a fresh unused token from the token pull.
+ */
+static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
+		jsmntok_t *tokens, size_t num_tokens) {
+	jsmntok_t *tok;
+	if (parser->toknext >= num_tokens) {
+		return NULL;
+	}
+	tok = &tokens[parser->toknext++];
+	tok->start = tok->end = -1;
+	tok->size = 0;
+#ifdef JSMN_PARENT_LINKS
+	tok->parent = -1;
+#endif
+	return tok;
+}
+
+/**
+ * Fills token type and boundaries.
+ */
+static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
+                            int start, int end) {
+	token->type = type;
+	token->start = start;
+	token->end = end;
+	token->size = 0;
+}
+
+/**
+ * Fills next available token with JSON primitive.
+ */
+static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
+		size_t len, jsmntok_t *tokens, size_t num_tokens) {
+	jsmntok_t *token;
+	int start;
+
+	start = parser->pos;
+
+	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+		switch (js[parser->pos]) {
+#ifndef JSMN_STRICT
+			/* In strict mode primitive must be followed by "," or "}" or "]" */
+			case ':':
+#endif
+			case '\t' : case '\r' : case '\n' : case ' ' :
+			case ','  : case ']'  : case '}' :
+				goto found;
+		}
+		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
+			parser->pos = start;
+			return JSMN_ERROR_INVAL;
+		}
+	}
+#ifdef JSMN_STRICT
+	/* In strict mode primitive must be followed by a comma/object/array */
+	parser->pos = start;
+	return JSMN_ERROR_PART;
+#endif
+
+found:
+	if (tokens == NULL) {
+		parser->pos--;
+		return 0;
+	}
+	token = jsmn_alloc_token(parser, tokens, num_tokens);
+	if (token == NULL) {
+		parser->pos = start;
+		return JSMN_ERROR_NOMEM;
+	}
+	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
+#ifdef JSMN_PARENT_LINKS
+	token->parent = parser->toksuper;
+#endif
+	parser->pos--;
+	return 0;
+}
+
+/**
+ * Fills next token with JSON string.
+ */
+static int jsmn_parse_string(jsmn_parser *parser, const char *js,
+		size_t len, jsmntok_t *tokens, size_t num_tokens) {
+	jsmntok_t *token;
+
+	int start = parser->pos;
+
+	parser->pos++;
+
+	/* Skip starting quote */
+	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+		char c = js[parser->pos];
+
+		/* Quote: end of string */
+		if (c == '\"') {
+			if (tokens == NULL) {
+				return 0;
+			}
+			token = jsmn_alloc_token(parser, tokens, num_tokens);
+			if (token == NULL) {
+				parser->pos = start;
+				return JSMN_ERROR_NOMEM;
+			}
+			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
+#ifdef JSMN_PARENT_LINKS
+			token->parent = parser->toksuper;
+#endif
+			return 0;
+		}
+
+		/* Backslash: Quoted symbol expected */
+		if (c == '\\' && parser->pos + 1 < len) {
+			int i;
+			parser->pos++;
+			switch (js[parser->pos]) {
+				/* Allowed escaped symbols */
+				case '\"': case '/' : case '\\' : case 'b' :
+				case 'f' : case 'r' : case 'n'  : case 't' :
+					break;
+				/* Allows escaped symbol \uXXXX */
+				case 'u':
+					parser->pos++;
+					for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
+						/* If it isn't a hex character we have an error */
+						if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
+									(js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
+									(js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
+							parser->pos = start;
+							return JSMN_ERROR_INVAL;
+						}
+						parser->pos++;
+					}
+					parser->pos--;
+					break;
+				/* Unexpected symbol */
+				default:
+					parser->pos = start;
+					return JSMN_ERROR_INVAL;
+			}
+		}
+	}
+	parser->pos = start;
+	return JSMN_ERROR_PART;
+}
+
+/**
+ * Parse JSON string and fill tokens.
+ */
+int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+		jsmntok_t *tokens, unsigned int num_tokens) {
+	int r;
+	int i;
+	jsmntok_t *token;
+	int count = parser->toknext;
+
+	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
+		char c;
+		jsmntype_t type;
+
+		c = js[parser->pos];
+		switch (c) {
+			case '{': case '[':
+				count++;
+				if (tokens == NULL) {
+					break;
+				}
+				token = jsmn_alloc_token(parser, tokens, num_tokens);
+				if (token == NULL)
+					return JSMN_ERROR_NOMEM;
+				if (parser->toksuper != -1) {
+					tokens[parser->toksuper].size++;
+#ifdef JSMN_PARENT_LINKS
+					token->parent = parser->toksuper;
+#endif
+				}
+				token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
+				token->start = parser->pos;
+				parser->toksuper = parser->toknext - 1;
+				break;
+			case '}': case ']':
+				if (tokens == NULL)
+					break;
+				type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
+#ifdef JSMN_PARENT_LINKS
+				if (parser->toknext < 1) {
+					return JSMN_ERROR_INVAL;
+				}
+				token = &tokens[parser->toknext - 1];
+				for (;;) {
+					if (token->start != -1 && token->end == -1) {
+						if (token->type != type) {
+							return JSMN_ERROR_INVAL;
+						}
+						token->end = parser->pos + 1;
+						parser->toksuper = token->parent;
+						break;
+					}
+					if (token->parent == -1) {
+						break;
+					}
+					token = &tokens[token->parent];
+				}
+#else
+				for (i = parser->toknext - 1; i >= 0; i--) {
+					token = &tokens[i];
+					if (token->start != -1 && token->end == -1) {
+						if (token->type != type) {
+							return JSMN_ERROR_INVAL;
+						}
+						parser->toksuper = -1;
+						token->end = parser->pos + 1;
+						break;
+					}
+				}
+				/* Error if unmatched closing bracket */
+				if (i == -1) return JSMN_ERROR_INVAL;
+				for (; i >= 0; i--) {
+					token = &tokens[i];
+					if (token->start != -1 && token->end == -1) {
+						parser->toksuper = i;
+						break;
+					}
+				}
+#endif
+				break;
+			case '\"':
+				r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
+				if (r < 0) return r;
+				count++;
+				if (parser->toksuper != -1 && tokens != NULL)
+					tokens[parser->toksuper].size++;
+				break;
+			case '\t' : case '\r' : case '\n' : case ' ':
+				break;
+			case ':':
+				parser->toksuper = parser->toknext - 1;
+				break;
+			case ',':
+				if (tokens != NULL && parser->toksuper != -1 &&
+						tokens[parser->toksuper].type != JSMN_ARRAY &&
+						tokens[parser->toksuper].type != JSMN_OBJECT) {
+#ifdef JSMN_PARENT_LINKS
+					parser->toksuper = tokens[parser->toksuper].parent;
+#else
+					for (i = parser->toknext - 1; i >= 0; i--) {
+						if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
+							if (tokens[i].start != -1 && tokens[i].end == -1) {
+								parser->toksuper = i;
+								break;
+							}
+						}
+					}
+#endif
+				}
+				break;
+#ifdef JSMN_STRICT
+			/* In strict mode primitives are: numbers and booleans */
+			case '-': case '0': case '1' : case '2': case '3' : case '4':
+			case '5': case '6': case '7' : case '8': case '9':
+			case 't': case 'f': case 'n' :
+				/* And they must not be keys of the object */
+				if (tokens != NULL && parser->toksuper != -1) {
+					jsmntok_t *t = &tokens[parser->toksuper];
+					if (t->type == JSMN_OBJECT ||
+							(t->type == JSMN_STRING && t->size != 0)) {
+						return JSMN_ERROR_INVAL;
+					}
+				}
+#else
+			/* In non-strict mode every unquoted value is a primitive */
+			default:
+#endif
+				r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
+				if (r < 0) return r;
+				count++;
+				if (parser->toksuper != -1 && tokens != NULL)
+					tokens[parser->toksuper].size++;
+				break;
+
+#ifdef JSMN_STRICT
+			/* Unexpected char in strict mode */
+			default:
+				return JSMN_ERROR_INVAL;
+#endif
+		}
+	}
+
+	if (tokens != NULL) {
+		for (i = parser->toknext - 1; i >= 0; i--) {
+			/* Unmatched opened object or array */
+			if (tokens[i].start != -1 && tokens[i].end == -1) {
+				return JSMN_ERROR_PART;
+			}
+		}
+	}
+
+	return count;
+}
+
+/**
+ * Creates a new parser based over a given  buffer with an array of tokens
+ * available.
+ */
+void jsmn_init(jsmn_parser *parser) {
+	parser->pos = 0;
+	parser->toknext = 0;
+	parser->toksuper = -1;
+}
+
+/**
+ * Compare a token string with a token, returns the token value
+ */
+int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
+	if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
+		strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
+		return 0;
+	}
+	return -1;
+}
+
+/**
+ * Get the value of the token in a integer format.
+ */
+int getIntegerToken(const char *json, jsmntok_t *tok){
+	char s[ ((tok->end - tok->start) + 1) ];
+	sprintf(s, "%.*s", tok->end - tok->start, json + tok->start);
+	return atoi(s);
+}

+ 86 - 0
jsmn.h

@@ -0,0 +1,86 @@
+#ifndef __JSMN_H_
+#define __JSMN_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * JSON type identifier. Basic types are:
+ * 	o Object
+ * 	o Array
+ * 	o String
+ * 	o Other primitive: number, boolean (true/false) or null
+ */
+typedef enum {
+	JSMN_UNDEFINED = 0,
+	JSMN_OBJECT = 1,
+	JSMN_ARRAY = 2,
+	JSMN_STRING = 3,
+	JSMN_PRIMITIVE = 4
+} jsmntype_t;
+
+enum jsmnerr {
+	/* Not enough tokens were provided */
+	JSMN_ERROR_NOMEM = -1,
+	/* Invalid character inside JSON string */
+	JSMN_ERROR_INVAL = -2,
+	/* The string is not a full JSON packet, more bytes expected */
+	JSMN_ERROR_PART = -3
+};
+
+/**
+ * JSON token description.
+ * @param		type	type (object, array, string etc.)
+ * @param		start	start position in JSON data string
+ * @param		end		end position in JSON data string
+ */
+typedef struct {
+	jsmntype_t type;
+	int start;
+	int end;
+	int size;
+#ifdef JSMN_PARENT_LINKS
+	int parent;
+#endif
+} jsmntok_t;
+
+/**
+ * JSON parser. Contains an array of token blocks available. Also stores
+ * the string being parsed now and current position in that string
+ */
+typedef struct {
+	unsigned int pos; /* offset in the JSON string */
+	unsigned int toknext; /* next token to allocate */
+	int toksuper; /* superior token node, e.g parent object or array */
+} jsmn_parser;
+
+/**
+ * Create JSON parser over an array of tokens
+ */
+void jsmn_init(jsmn_parser *parser);
+
+/**
+ * Compare a token string with a token, returns the token value
+ */
+int jsoneq(const char *json, jsmntok_t *tok, const char *s);
+
+/**
+ * Get the value of the token in a integer format.
+ */
+int getIntegerToken(const char *json, jsmntok_t *tok);
+
+/**
+ * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
+ * a single JSON object.
+ */
+int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+		jsmntok_t *tokens, unsigned int num_tokens);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __JSMN_H_ */

+ 64 - 74
main.c

@@ -9,8 +9,8 @@
  */
 
 /*! \file
- *  COPYRIGHT (C) STREAMIT BV 2010
- *  \date 19 december 2003
+ *  COPYRIGHT (C) SaltyRadio 2016
+ *  \date 20-02-2016
  */
 
 #define LOG_MODULE  LOG_MAIN_MODULE
@@ -41,21 +41,11 @@
 #include "spidrv.h"
 #include "network.h"
 
-
 #include <time.h>
 #include "rtc.h"
+#include "alarm.h"
 #include "ntp.h"
 
-
-/*-------------------------------------------------------------------------*/
-/* global variable definitions                                             */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/* local variable definitions                                              */
-/*-------------------------------------------------------------------------*/
-
-
 /*-------------------------------------------------------------------------*/
 /* local routines (prototyping)                                            */
 /*-------------------------------------------------------------------------*/
@@ -78,7 +68,6 @@ static void SysControlMainBeat(u_char);
 /*-------------------------------------------------------------------------*/
 
 
-/* ����������������������������������������������������������������������� */
 /*!
  * \brief ISR MainBeat Timer Interrupt (Timer 2 for Mega128, Timer 0 for Mega256).
  *
@@ -89,7 +78,6 @@ static void SysControlMainBeat(u_char);
  *
  * \param *p not used (might be used to pass parms from the ISR)
  */
-/* ����������������������������������������������������������������������� */
 static void SysMainBeatInterrupt(void *p)
 {
 
@@ -100,8 +88,6 @@ static void SysMainBeatInterrupt(void *p)
     CardCheckCard();
 }
 
-
-/* ����������������������������������������������������������������������� */
 /*!
  * \brief Initialise Digital IO
  *  init inputs to '0', outputs to '1' (DDRxn='0' or '1')
@@ -109,7 +95,6 @@ static void SysMainBeatInterrupt(void *p)
  *  Pull-ups are enabled when the pin is set to input (DDRxn='0') and then a '1'
  *  is written to the pin (PORTxn='1')
  */
-/* ����������������������������������������������������������������������� */
 void SysInitIO(void)
 {
     /*
@@ -166,12 +151,10 @@ void SysInitIO(void)
     outp(0x18, DDRG);
 }
 
-/* ����������������������������������������������������������������������� */
 /*!
  * \brief Starts or stops the 4.44 msec mainbeat of the system
  * \param OnOff indicates if the mainbeat needs to start or to stop
  */
-/* ����������������������������������������������������������������������� */
 static void SysControlMainBeat(u_char OnOff)
 {
     int nError = 0;
@@ -191,58 +174,66 @@ static void SysControlMainBeat(u_char OnOff)
     }
 }
 
-int timer(time_t start){
-	time_t diff = time(0) - start;
-	return diff;
-}
-
-int checkOffPressed(){
-	if (KbScan() < -1){
-		LcdBackLight(LCD_BACKLIGHT_ON);
-		return 1;
-	} else {
-		return 0;
-	}
-}
 
-/* ����������������������������������������������������������������������� */
-/*!
- * \brief Main entry of the SIR firmware
- *
- * All the initialisations before entering the for(;;) loop are done BEFORE
- * the first key is ever pressed. So when entering the Setup (POWER + VOLMIN) some
- * initialisatons need to be done again when leaving the Setup because new values
- * might be current now
- *
- * \return \b never returns
- */
-/* ����������������������������������������������������������������������� */
+/*-------------------------------------------------------------------------*/
+/* global variable definitions                                             */
+/*-------------------------------------------------------------------------*/
+int isAlarmSyncing;
+/*-------------------------------------------------------------------------*/
+/* local variable definitions                                              */
+/*-------------------------------------------------------------------------*/
 
+/*-------------------------------------------------------------------------*/
+/* Thread init                                                             */
+/*-------------------------------------------------------------------------*/
 THREAD(StartupInit, arg)
 {
+    isAlarmSyncing = 1;
     NetworkInit();
+
     NtpSync();
+
+    char* content = httpGet("/getAlarmen.php?radioid=DE370");
+    parseAlarmJson(content);
+    isAlarmSyncing = 0;
+
+    free(content);
     NutThreadExit();
 }
 
+/*-------------------------------------------------------------------------*/
+/* Global functions                                                        */
+/*-------------------------------------------------------------------------*/
+
+int timer(time_t start){
+    time_t diff = time(0) - start;
+    return diff;
+}
+
+int checkOffPressed(){
+    if (KbScan() < -1){
+        LcdBackLight(LCD_BACKLIGHT_ON);
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
 int main(void)
 {
 	time_t start;
 	int running = 0;
 
-    /*
-     *  First disable the watchdog
-     */
     WatchDogDisable();
 
     NutDelay(100);
-	
+
     SysInitIO();
-	
+
 	SPIinit();
-    
+
 	LedInit();
-	
+
 	LcdLowLevelInit();
 
     Uart0DriverInit();
@@ -256,28 +247,17 @@ int main(void)
     LcdBackLight(LCD_BACKLIGHT_ON);
     NtpInit();
 
-    NutThreadCreate("BackgroundThread", StartupInit, NULL, 512);
-    
+    NutThreadCreate("BackgroundThread", StartupInit, NULL, 1024);
+
     /** Quick fix for turning off the display after 10 seconds boot */
     start = time(0);
     running = 1;
 
-	/*
-	 * Kroeske: sources in rtc.c en rtc.h
-	 */
-
-    if (At45dbInit()==AT45DB041B)
-    {
-        // ......
-    }
-
-
-
     RcInit();
-    
+
 	KbInit();
 
-    SysControlMainBeat(ON);             // enable 4.4 msecs hartbeat interrupt
+    SysControlMainBeat(ON);             // enable 4.4 msecs heartbeat interrupt
 
     /*
      * Increase our priority so we can feed the watchdog.
@@ -286,15 +266,16 @@ int main(void)
 
 	/* Enable global interrupts */
 	sei();
-	
+
     for (;;)
-    {		
+    {
 		//Check if a button is pressed
 		if (checkOffPressed() == 1){
 			start = time(0);
 			running = 1;
+            LcdBacklightKnipperen(startLCD);
 		}
-		
+
 		//Check if background LED is on, and compare to timer
 		if (running == 1){
 			if (timer(start) >= 10){
@@ -303,11 +284,20 @@ int main(void)
 			}
 		}
 
-        displayDate(0);
-		displayTime(1);
-		
+        if(!isAlarmSyncing && X12RtcGetStatus(5) > 0)
+        {
+			displayAlarm(0,1);
+			if (KbScan() < -1 || checkTime() == 1){
+				handleAlarm();
+				LcdBackLight(LCD_BACKLIGHT_OFF);
+			}
+        }
+        else {
+            displayTime(0);
+            displayDate(1);
+        }
         WatchDogRestart();
     }
 
-    return(0);      // never reached, but 'main()' returns a non-void, so.....
+    return(0);
 }

+ 121 - 3
network.c

@@ -2,8 +2,15 @@
 // Created by janco on 25-2-16.
 //
 #include <dev/board.h>
+#include <dev/debug.h>
 #include <sys/timer.h>
 #include <sys/confnet.h>
+#include <sys/socket.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <net/route.h>
 
 #include <dev/nicrtl.h>
 
@@ -11,16 +18,127 @@
 #include <io.h>
 #include <arpa/inet.h>
 #include <pro/dhcp.h>
+#include <pro/sntp.h>
 #include "network.h"
+#include "ntp.h"
+#include "jsmn.h"
+#include "rtc.h"
+#include "alarm.h"
+
+bool isReceiving;
 
 void NetworkInit() {
     /* Register de internet controller. */
     if (NutRegisterDevice(&DEV_ETHER, 0, 0)) {
-        printf("Registering  failed.");
+        printf("Registering  failed. \n");
     }/* Netwerk configureren op dhcp */
     else if (NutDhcpIfConfig(DEV_ETHER_NAME, NULL, 0)) {
-        /* Done. */
+        printf("DHCP failed. \n");
     }else {
-        printf("Ik heb een internet connectie. Ip is: %s", inet_ntoa(confnet.cdn_ip_addr));
+        printf("Ik heb een internet connectie. Ip is: %s \n\n", inet_ntoa(confnet.cdn_ip_addr));
+    }
+}
+
+char* httpGet(char address[]){
+    isReceiving = true;
+    NutDelay(1000);
+    printf("\n\n #-- HTTP get -- #\n");
+
+    TCPSOCKET* sock = NutTcpCreateSocket();
+
+    char http[strlen(address) + 49]; //49 chars based on get command. Change this number if you change the domain name
+    sprintf(http, "GET %s HTTP/1.1\r\nHost: saltyradio.jancokock.me \r\n\r\n", address);
+    int len = sizeof(http);
+
+    char buffer[300];
+    if (NutTcpConnect(sock, inet_addr("62.195.226.247"), 80)) {
+        printf("Can't connect to server\n");
+    }else{
+        //FILE *stream;
+        //stream = _fdopen((int) sock, "r b");
+        if(NutTcpSend(sock, http, len) != len){
+            printf("Writing headers failed.\n");
+            NutDelay(1000);
+        }else{
+            printf("Headers %s writed. Now reading.", http);
+            NutDelay(1000);
+            NutTcpReceive(sock, buffer, sizeof(buffer));
+            //fread(buffer, 1, sizeof(buffer), stream);
+            NutDelay(1000);
+            printf(buffer);
+        };
+        //fclose(stream);
     }
+    NutTcpCloseSocket(sock);
+    int i;
+    int enters = 0;
+    int t = 0;
+    char* content = (char*) calloc(1 , sizeof(buffer));
+    for(i = 0; i < strlen(buffer); i++)
+    {
+        if(enters == 4) {
+            content[t] = buffer[i];
+            t++;
+        }else {
+            if (buffer[i] == '\n' || buffer[i] == '\r') {
+                enters++;
+            }
+            else {
+                enters = 0;
+            }
+        }
+    }
+    content[t] = '\0';
+    printf("\nContent size: %d, Content: %s \n", t, content);
+    isReceiving = false;
+    return content;
 }
+
+void parseAlarmJson(char* content){
+    int r;
+    int i;
+    jsmn_parser p;
+    jsmntok_t token[50]; /* We expect no more than 128 tokens */
+
+    jsmn_init(&p);
+    r = jsmn_parse(&p, content, strlen(content), token, sizeof(token)/sizeof(token[0]));
+    if (r < 0) {
+        printf("Failed to parse JSON: %d \n", r);
+    }else{
+        printf("Aantal tokens found: %d \n", r);
+    }
+
+    struct _tm time = GetRTCTime();
+
+    for (i = 1; i < r; i++) {
+        if (jsoneq(content, &token[i], "YYYY") == 0) {
+            time.tm_year= getIntegerToken(content, &token[i + 1]) - 1900;
+            i++;
+        }else if (jsoneq(content, &token[i], "MM") == 0) {
+            time.tm_mon=  getIntegerToken(content, &token[i + 1]) - 1;
+            i++;
+        }else if (jsoneq(content, &token[i], "DD") == 0) {
+            time.tm_mday =  getIntegerToken(content, &token[i + 1]);
+            i++;
+        }else if (jsoneq(content, &token[i], "hh") == 0) {
+            time.tm_hour = 	getIntegerToken(content, &token[i + 1]);
+            i++;
+        }else if (jsoneq(content, &token[i], "mm") == 0) {
+            time.tm_min = getIntegerToken(content, &token[i + 1]);
+            i++;
+        }else if (jsoneq(content, &token[i], "ss") == 0) {
+            time.tm_sec = getIntegerToken(content, &token[i + 1]);
+            i++;
+        }
+    }
+
+    printf("Alarm time is: %02d:%02d:%02d\n", time.tm_hour, time.tm_min, time.tm_sec);
+    printf("Alarm date is: %02d.%02d.%02d\n\n", time.tm_mday, (time.tm_mon + 1), (time.tm_year + 1900));
+
+    X12RtcSetAlarm(0,&time,0b11111111);
+    NutDelay(1000);
+}
+
+bool NetworkIsReceiving(void){
+    return isReceiving;
+}

+ 3 - 0
network.h

@@ -5,6 +5,9 @@
 #ifndef _Network_H
 #define _Network_H
 
+
 extern void NetworkInit(void);
+char* httpGet(char address[]);
+void parseAlarmJson(char* content);
 
 #endif /* _Network_H */

+ 6 - 6
ntp.c

@@ -54,13 +54,13 @@ void NtpCheckValidTime(void){
 
     if (eeprom_tm_struct.len != sizeof(eeprom_tm_struct)){
         // Size mismatch: There is no valid configuration present.
-        puts("NtpCheckValidTime(): Size mismatch");
+        puts("NtpCheckValidTime(): Size mismatch \n");
         validTime = false;
         return;
     }
 
     // Valid configuration available.
-    puts("NtpCheckValidTime(): Valid config available");
+    puts("NtpCheckValidTime(): Valid config available \n");
     tm stored_tm = eeprom_tm_struct.tm_struct;
 
     // Check time is valid;
@@ -69,16 +69,16 @@ void NtpCheckValidTime(void){
 
     validTime = NtpCompareTime(current_tm, stored_tm);
     if (validTime){
-        puts("NtpCheckValidTime(): Time was valid");
+        puts("NtpCheckValidTime(): Time was valid \n");
     }else {
-        puts("NtpCheckValidTime(): Invalid time!");
+        puts("NtpCheckValidTime(): Invalid time! \n");
     }
 }
 
 //Tests if t1 is after t2.
 bool NtpCompareTime(tm t1, tm t2){
     char debug[120];
-    sprintf(&debug, "Comparing two times\nt1=%04d-%02d-%02d+%02d:%02d:%02d\nt2=%04d-%02d-%02d+%02d:%02d:%02d",
+    sprintf(&debug, "Comparing two times\nt1=%04d-%02d-%02d+%02d:%02d:%02d\nt2=%04d-%02d-%02d+%02d:%02d:%02d \n",
             t1.tm_year+1900,
             t1.tm_mon+1,
             t1.tm_mday,
@@ -151,7 +151,7 @@ void NtpWriteTimeToEeprom(tm time_struct){
     eeprom_tm_struct.tm_struct = time_struct;
 
     int success = NutNvMemSave(256, &eeprom_tm_struct, sizeof(eeprom_tm_struct));
-    if (success == 0){ puts("NtpWriteTimeToEeprom: Time succesfully written to eeprom"); }
+    if (success == 0){ puts("NtpWriteTimeToEeprom: Time succesfully written to eeprom \n"); }
 
     NutDelay(100);
 }

+ 1 - 1
rtc.c

@@ -352,7 +352,7 @@ int X12RtcGetStatus(u_long *sflgs)
  */
 int X12RtcClearStatus(u_long sflgs)
 {
-    rtc_status &= ~sflgs;
+    rtc_status &= sflgs;
 
     return(0);
 }