Browse Source

Merge branch 'developer' into TwitterFeed

# Conflicts:
#	contentparser.c
#	jsmn.c
#	main.c
#	vs10xx.c
MalekSediqi 9 years ago
parent
commit
56f71bcba7
32 changed files with 514 additions and 4860 deletions
  1. 3 1
      .idea/InternetRadio.iml
  2. 24 5
      alarm.c
  3. 6 7
      alarm.h
  4. 61 8
      contentparser.c
  5. 1 0
      contentparser.h
  6. 0 60
      display.c
  7. 4 4
      displayHandler.c
  8. 0 2154
      fat.c
  9. 0 119
      fat.h
  10. 0 153
      fatdrv.h
  11. 0 399
      flash.c
  12. 0 68
      flash.h
  13. 0 287
      httpstream.c
  14. 0 15
      httpstream.h
  15. 5 12
      jsmn.c
  16. 0 13
      keyboard.c
  17. 1 1
      keyboard.h
  18. 28 52
      main.c
  19. 0 347
      mmc.c
  20. 0 41
      mmc.h
  21. 0 758
      mmcdrv.c
  22. 0 100
      mmcdrv.h
  23. 332 0
      mp3stream.c
  24. 25 0
      mp3stream.h
  25. 12 12
      network.c
  26. 4 4
      network.h
  27. 4 22
      ntp.c
  28. 3 3
      ntp.h
  29. 0 151
      remcon.c
  30. 0 52
      remcon.h
  31. 0 3
      uart0driver.c
  32. 1 9
      vs10xx.c

+ 3 - 1
.idea/InternetRadio.iml

@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module type="CPP_MODULE" version="4">
   <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/CMakeLists.txt" isTestSource="false" />
+    </content>
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="module-library">
       <library name="Header Search Paths">

+ 24 - 5
alarm.c

@@ -4,12 +4,13 @@
 #include <string.h>
 #include <time.h>
 #include <assert.h>
+#include <math.h>
 
 #include "log.h"
 #include "rtc.h"
 #include "alarm.h"
 #include "display.h"
-#include "httpstream.h"
+#include "mp3stream.h"
 
 #define n 5
 
@@ -71,7 +72,6 @@ void setSnooze(int idx){
 	alarm[idx].state = 2;
 	snooze[idx].snoozeTime = ct;
 	snooze[idx].snoozeTime.tm_min += alarm[idx].snooze;
-	stopStream();
 }
 
 int daysInMonth(int m, int y) {
@@ -124,7 +124,16 @@ void setState(int idx){
 	}
 	
 	if (compareTime(ct, alarm[idx].time) >= 1 && alarm[idx].time.tm_year != 0 && alarm[idx].state != 2){
-		alarm[idx].state = 1;
+		if(alarm[idx].state != 1) {
+			alarm[idx].state = 1;
+			printf("\n\nAlarm gaat nu af!\n\n");
+			bool success = connectToStream(alarm[idx].ip, alarm[idx].port, alarm[idx].url);
+			if (success == true){
+				play();
+			}else {
+				printf("ConnectToStream failed. Aborting.\n\n");
+			}
+		}
 	} else if (alarm[idx].state != 2){
 		alarm[idx].state = 0;
 	}
@@ -138,11 +147,20 @@ void setState(int idx){
 		snooze[idx].snoozeTime = ct;
 		AddSnoozeMinutes(idx, alarm[idx].snooze);
 		LcdBackLight(LCD_BACKLIGHT_OFF);
-		stopStream();
+		killPlayerThread();
 	}
 	
 	if (alarm[idx].state == 2 && compareTime(ct, snooze[idx].snoozeTime) >= 1){
-		alarm[idx].state = 1;
+		if(alarm[idx].state != 1){
+			printf("Alarm komt nu uit snooze!!");
+			bool success = connectToStream(alarm[idx].ip, alarm[idx].port, alarm[idx].url);
+			if (success == true){
+				play();
+			}else {
+				printf("ConnectToStream failed. Aborting.\n\n");
+			}
+			alarm[idx].state = 1;
+		}
 		AddSnoozeMinutes(idx, 1);
 	}
 }
@@ -181,6 +199,7 @@ void deleteAlarm(int idx){
 void handleAlarm(int idx){
 	alarm[idx].state = 0;
 	alarm[idx].time.tm_mday += 1;
+	killPlayerThread();
 	printf("state is %d \n",alarm[idx].state);
 }
 

+ 6 - 7
alarm.h

@@ -1,10 +1,7 @@
 /* Alarm get/set status values */
-#define ALARM_1 	5
-#define ALARM_2		6
-
-#define AFLGS		0b11111111
 
 #ifndef _ALARM_DEFINED
+#define _ALARM_DEFINED
 struct _alarm
 {
 	struct _tm time;
@@ -16,8 +13,6 @@ struct _alarm
 	int id;
 	int state;
 };
-#define _ALARM_DEFINED
-#endif
 
 void handleAlarm(int idx);
 int checkAlarms(void);
@@ -27,4 +22,8 @@ void deleteAlarm(int idx);
 int compareTime(tm t1, tm t2);
 void setState(int idx);
 int getState(int idx);
-struct _alarm getAlarm(int idx);
+struct _alarm getAlarm(int idx);
+int maxAlarms(void);
+int isLeapYear(int y);
+void setSnooze(int idx);
+#endif

+ 61 - 8
contentparser.c

@@ -5,18 +5,25 @@
 #include "ntp.h"
 #include "network.h"
 #include "jsmn.h"
+#include "mp3stream.h"
 #include "rtc.h"
 #include "alarm.h"
+<<<<<<< HEAD
 #include "displayHandler.h"
 
 int streamid;
 
+=======
+#include "vs10xx.h"
+>>>>>>> developer
 
 void parseAlarmJson(char* content){
     int r;
-    int i = 2;
+    int i;
+    int usedAlarms[maxAlarms()];
+    int j;
     jsmn_parser p;
-    jsmntok_t token[150]; /* We expect no more than 128 tokens */
+    jsmntok_t token[160]; /* We expect no more than 128 tokens */
 
     jsmn_init(&p);
     r = jsmn_parse(&p, content, strlen(content), token, sizeof(token)/sizeof(token[0]));
@@ -27,25 +34,25 @@ void parseAlarmJson(char* content){
         printf("Aantal tokens found: %d \n", r);
     }
 
-    int usedAlarms[maxAlarms()];
-    int j;
+
     struct _tm time = GetRTCTime();
     for(j = 0; j < maxAlarms(); j++){
         usedAlarms[j] = 0;
     }
-    for(i; i < r; i++)
+    for(i = 2; i < r; i++)
     {
-        int id;
-        u_short port;
+        int id = 0;
+        u_short port = 0;
         char url[24];
         char ip[24];
         char name[16];
         char st = -1;
+        char oo = -1;
         memset(url, 0, 24);
         memset(ip, 0, 24);
         memset(name, 0, 17);
 
-        for (i; (st == -1 && i < r); i+=2) {                                //Zodra ST is gevonden, betekent dit de laatste token van een alarm.
+        for (i = i; (st == -1 && i < r); i+=2) {                                //Zodra ST is gevonden, betekent dit de laatste token van een alarm.
             if (jsoneq(content, &token[i], "YYYY") == 0) {
                 time.tm_year= getIntegerToken(content, &token[i + 1]) - 1900;
             }else if (jsoneq(content, &token[i], "MM") == 0) {
@@ -68,6 +75,8 @@ void parseAlarmJson(char* content){
                 getStringToken(content, &token[i + 1], url, 24);
             }else if (jsoneq(content, &token[i], "name") == 0) {
                 getStringToken(content, &token[i + 1], name, 16);
+            }else if (jsoneq(content, &token[i], "oo") == 0) {
+                oo = getIntegerToken(content, &token[i + 1]);
             }else if (jsoneq(content, &token[i], "st") == 0) {
                 st = getIntegerToken(content, &token[i + 1]);
                 i+=2;
@@ -101,6 +110,50 @@ void parseAlarmJson(char* content){
     }
 }
 
+void parseCommandQue(char* content){
+    int r;
+    int i;
+    jsmn_parser p;
+    jsmntok_t token[150]; /* 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);
+        return;
+    }else{
+        printf("Aantal tokens found: %d \n", r);
+    }
+
+    for(i = 0; i < r; i++)
+    {
+        if (jsoneq(content, &token[i], "command") == 0) {
+            if(jsoneq(content, &token[i + 1], "volume") == 0){
+                char vol = getIntegerToken(content, &token[i + 3]);
+                vol = 128 - ((vol * 128) / 100);
+                VsSetVolume(vol, vol);
+                i += 3;
+            }else if(jsoneq(content, &token[i + 1], "stopstream") == 0){
+                killPlayerThread();
+                i += 3;
+            }else if(jsoneq(content, &token[i + 1], "startstream") == 0){
+                u_short port = getIntegerToken(content, &token[i + 9]);
+                char url[24];
+                char ip[24];
+                getStringToken(content, &token[i + 7], url);
+                getStringToken(content, &token[i + 5], ip);
+                bool success = connectToStream(ip, port, url);
+                if (success == true){
+                    play();
+                }else {
+                    printf("ConnectToStream failed. Aborting.\n\n");
+                }
+                i += 9;
+            }
+        }
+    }
+}
+
 void parsetimezone(char* content)
 {
     int timezone = atoi(content); //parsing string to int (only works when everything is int)

+ 1 - 0
contentparser.h

@@ -5,6 +5,7 @@
 #define CONTENTPARSER_H
 
 void parseAlarmJson(char* content);
+void parseCommandQue(char* content);
 void parsetimezone(char* content);
 void parseTwitch(char* content);
 void TwitterParser(char* content);

+ 0 - 60
display.c

@@ -42,33 +42,6 @@ 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
- */
-
-/*@{*/
-
-/*-------------------------------------------------------------------------*/
-/*                         start of code                                   */
-/*-------------------------------------------------------------------------*/
-
-/* ����������������������������������������������������������������������� */
-/*!
- * \brief control backlight
- */
-/* ����������������������������������������������������������������������� */
 void LcdBackLight(u_char Mode)
 {
     if (Mode==LCD_BACKLIGHT_ON)
@@ -82,39 +55,6 @@ 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
- *
- * Writes a single character on the LCD on the current cursor position
- *
- * \param LcdChar character to write
- */
-/* ����������������������������������������������������������������������� */
 void LcdChar(char MyChar)
 {
     LcdWriteByte(WRITE_DATA, MyChar);

+ 4 - 4
displayHandler.c

@@ -14,7 +14,6 @@
 #include "rtc.h"
 #include "alarm.h"
 #include "network.h"
-#include "httpstream.h"
 
 #define MONTH_OFFSET 1
 #define YEAR_OFFSET 1900
@@ -69,12 +68,11 @@ void displayAlarm(int line_number, int line_numberTwo, int idx)
 	int startidx;
     char str[16];
 	struct _alarm am = getAlarm(idx);
-	
+
     sprintf(str, "    %02d:%02d:%02d    ", am.time.tm_hour, am.time.tm_min, am.time.tm_sec);
     if (line_number > -1 && line_number < 2){
         (*write_display_ptr[line_number])(str, 16);
     }
-    playStream(am.ip, am.port, am.url);
 
 	j = 0;
     char str2[16];
@@ -83,7 +81,7 @@ void displayAlarm(int line_number, int line_numberTwo, int idx)
 			j = j + 1;
 		}
 	}
-	
+
 	if (j != 16){
 		startidx = (8-(j/2));
 	}
@@ -104,6 +102,8 @@ void displayAlarm(int line_number, int line_numberTwo, int idx)
         (*write_display_ptr[line_numberTwo])(str2, 16);
         LcdBackLight(LCD_BACKLIGHT_ON);
     }
+
+
 }
 
 void displayVolume(int pos)

+ 0 - 2154
fat.c

@@ -1,2154 +0,0 @@
-/****************************************************************************
-*  This file is part of the AVRIDE device driver.
-*
-*  Copyright (c) 2002-2004 by Michael Fischer. All rights reserved.
-*
-*  Redistribution and use in source and binary forms, with or without 
-*  modification, are permitted provided that the following conditions 
-*  are met:
-*  
-*  1. Redistributions of source code must retain the above copyright 
-*     notice, this list of conditions and the following disclaimer.
-*  2. Redistributions in binary form must reproduce the above copyright
-*     notice, this list of conditions and the following disclaimer in the 
-*     documentation and/or other materials provided with the distribution.
-*  3. Neither the name of the author nor the names of its contributors may 
-*     be used to endorse or promote products derived from this software 
-*     without specific prior written permission.
-*
-*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
-*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
-*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
-*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
-*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
-*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
-*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
-*  SUCH DAMAGE.
-*
-****************************************************************************
-*  History:
-*
-*  14.12.02  mifi   First Version 
-*  23.12.02  mifi   Add FileOpen, FileClose, FileError, FileSize,
-*                   FileSeek and FileRead. But the FileSeek function.
-*                   does not work in the moment, later...
-*  28.12.02  mifi   Now support FAT16 AND FAT32.
-*  01.01.03  mifi   Support long directory entries, but without to 
-*                   check the checksum of the short entry.
-*                   Change FAT32FileSize return value from int to long.
-*                   The max size of a long filename segment is
-*                   (FAT_LONG_NAME_LEN-1). But the complete filename can
-*                   be longer. 
-*
-*                   segment1/segment2/segment3/index.html
-*
-*                   segmentX max length = (FAT_LONG_NAME_LEN-1)
-*
-*  04.01.03  mifi   Take a look at the return values...
-*  18.01.03  mifi   Change Licence from GPL to BSD.
-*  25.01.03  mifi   Implement a new FindFile function.
-*                   I have some trouble with short file names under
-*                   Win98. Win98 store a short name like "enlogo.gif"
-*                   as a long name, nasty OS. 
-*                   Remove FAT32_MAX_FILES and the array aFileHandle,
-*                   a file handle will now be allocated by NutHeapAlloc, 
-*                   therefore we have no restrictions about the count of 
-*                   the open file handle. (Only by available memory)
-*  27.01.03  mifi   Rename all FAT32xxx function to FATxxx.
-*
-*  28.01.03  mifi   Start porting to Nut/OS 3.X.X
-*  19.06.03  mifi   Change the call of IDEInit, now we use the BaseAddress
-*                   of 0. Because the fat module does not need to know the
-*                   address. It will be handled in ide.c.
-*  29.06.03  mifi   First ATAPI-Version
-*                   Now we can read files from a CD-ROM. But there exist
-*                   some open points:
-*                   - only first session from a multisession CD is supported
-*                   - only iso9660, no Joliet support now, later
-*  24.07.04  mifi   Some changes to support more than one drive (datanut)
-*  25.07.04  mifi   Add support for the PCMCIA_11 hardware.
-*  27.07.04  mifi   Start to add functionality for write function.
-*  03.08.04  mifi   Add format function.
-****************************************************************************/
-#define __FAT_C__
-
-#define LOG_MODULE  LOG_FAT_MODULE
-
-#include <string.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <time.h>
-
-#include <sys/heap.h>
-#include <sys/event.h>
-#include <sys/thread.h>
-
-#include <sys/device.h>
-
-#include "typedefs.h"
-
-#include "fat.h"
-#include "fatdrv.h"
-#include "portio.h"
-#include "log.h"
-
-
-/*==========================================================*/
-/*  DEFINE: All Structures and Common Constants             */
-/*==========================================================*/
-//
-// FAT return codes
-//
-#define FAT_OK                0
-#define FAT_ERROR             -1
-#define FAT_ERROR_EOF         -2
-#define FAT_ERROR_IDE         -3
-
-//
-// Define for correct return values Nut/OS
-//
-#define NUTDEV_OK                       0
-#define NUTDEV_ERROR                    -1
-#define NUTDEV_WRONG_HW                 -2
-
-#define FAT_MAX_DRIVE                   3
-
-//
-// Some defines for the FAT structures
-//
-#define ZIP_DRIVE_BR_SECTOR             32
-
-#define BPB_RsvdSecCnt                  32
-#define BPB_NumFATs                     2
-#define BPB_HiddSec                     63
-
-#define FAT32_MEDIA                     0xf8
-#define FAT32_SECTOR_SIZE               HW_SECTOR_SIZE
-
-#define FAT32_OFFSET_FSINFO             1
-#define FAT32_OFFSET_BACKUP_BOOT        6
-
-#define FAT16_CLUSTER_EOF               0x0000FFFF
-#define FAT16_CLUSTER_ERROR             0x0000FFF7
-#define FAT16_CLUSTER_MASK              0x0000FFFF
-
-#define FAT32_CLUSTER_EOF               0x0FFFFFFF
-#define FAT32_CLUSTER_ERROR             0x0FFFFFF7
-#define FAT32_CLUSTER_MASK              0x0FFFFFFF
-
-#define FAT_SIGNATURE                   0xAA55
-
-#define MBR_SIGNATURE                   FAT_SIGNATURE
-#define MBR_FAT32                       0x0B
-
-#define FSINFO_FIRSTSIGNATURE           0x41615252
-#define FSINFO_FSINFOSIGNATURE          0x61417272
-#define FSINFO_SIGNATURE                FAT_SIGNATURE
-
-#define DIRECTORY_ATTRIBUTE_READ_ONLY   0x01
-#define DIRECTORY_ATTRIBUTE_HIDDEN      0x02
-#define DIRECTORY_ATTRIBUTE_SYSTEM_FILE 0x04
-#define DIRECTORY_ATTRIBUTE_VOLUME_ID   0x08
-#define DIRECTORY_ATTRIBUTE_DIRECTORY   0x10
-#define DIRECTORY_ATTRIBUTE_ARCHIVE     0x20
-
-//
-// DIRECTORY_ATTRIBUTE_READ_ONLY   |
-// DIRECTORY_ATTRIBUTE_HIDDEN      |
-// DIRECTORY_ATTRIBUTE_SYSTEM_FILE |
-// DIRECTORY_ATTRIBUTE_VOLUME_ID
-//
-#define DIRECTORY_ATTRIBUTE_LONG_NAME   0x0F
-
-//
-// DIRECTORY_ATTRIBUTE_READ_ONLY   |
-// DIRECTORY_ATTRIBUTE_HIDDEN      |
-// DIRECTORY_ATTRIBUTE_SYSTEM_FILE |
-// DIRECTORY_ATTRIBUTE_VOLUME_ID   |
-// DIRECTORY_ATTRIBUTE_DIRECTORY   |
-// DIRECTORY_ATTRIBUTE_ARCHIVE
-// 
-#define DIRECTORY_ATTRIBUTE_LONG_NAME_MASK  0x3F
-
-#define FAT_NAME_LEN                    8
-#define FAT_EXT_LEN                     3
-
-//
-// FAT_SHORT_NAME_LEN name len = 
-// name + ext + 1 for the point
-//
-#define FAT_SHORT_NAME_LEN              (FAT_NAME_LEN+FAT_EXT_LEN+1)
-#define FAT_LONG_NAME_LEN               64
-
-
-//
-// Some stuff for HD and CD, DRIVE_INFO Flags
-// 
-//
-#define FLAG_FAT_IS_CDROM               0x0001
-#define FLAG_FAT_IS_ZIP                 0x0002
-
-//
-//  DiskSize to SectorPerCluster table
-//
-typedef struct
-{
-    DWORD DiskSize;
-    BYTE  SecPerClusVal;
-} DSKSZTOSECPERCLUS;
-
-typedef struct _FAT32FileDataTime
-{
-    unsigned Seconds:5;
-    unsigned Minute:6;
-    unsigned Hour:5;
-    unsigned Day:5;
-    unsigned Month:4;
-    unsigned Year:7;
-} FAT32_FILEDATETIME, *PFAT32_FILEDATETIME;
-
-typedef struct _FAT32DirectoryEntry
-{
-    BYTE               Name[FAT_NAME_LEN];
-    BYTE               Extension[FAT_EXT_LEN];
-    BYTE               Attribute;
-    BYTE               Reserved[8];
-    WORD               HighCluster;
-    FAT32_FILEDATETIME Date;
-    WORD               LowCluster;
-    DWORD              FileSize;
-} FAT32_DIRECTORY_ENTRY;
-
-typedef struct _FAT32DirectoryEntryLong
-{
-    BYTE Order;
-    WORD Name1[5];
-    BYTE Attribute;
-    BYTE Type;
-    BYTE Chksum;
-    WORD Name2[6];
-    WORD LowCluster;
-    WORD Name3[2];
-} FAT32_DIRECTORY_ENTRY_LONG;
-
-typedef struct _FAT32FileSystemInformation
-{
-    DWORD FirstSignature;
-    BYTE  Reserved1[480];
-    DWORD FSInfoSignature;
-    DWORD NumberOfFreeClusters;
-    DWORD MostRecentlyAllocatedCluster;
-    BYTE  Reserved2[12];
-    BYTE  Reserved3[2];
-    WORD  Signature;
-} FAT32_FSINFO;
-
-typedef struct _FAT32PartitionEntry
-{
-    BYTE  BootInd;
-    BYTE  FirstHead;
-    BYTE  FirstSector;
-    BYTE  FirstTrack;
-    BYTE  FileSystem;
-    BYTE  LastHead;
-    BYTE  LastSector;
-    BYTE  LastTrack;
-    DWORD StartSectors;
-    DWORD NumSectors;
-} FAT32_PARTITION_ENTRY;
-
-typedef struct _FAT32PartionTable
-{
-    BYTE                  LoadInstruction[446];
-    FAT32_PARTITION_ENTRY Partition[4];
-    WORD                  Signature;               /* AA55 */
-} FAT32_PARTITION_TABLE;
-
-typedef struct _bpbfat16
-{
-    BYTE  DrvNum;
-    BYTE  Reserved1;
-    BYTE  BootSig;
-    DWORD VollID;
-    BYTE  VolLab[11];
-    BYTE  FilSysType[8];
-    BYTE  Reserved2[28];
-} BPBFAT16;
-
-typedef struct _bpbfat32
-{
-    DWORD FATSz32;          // xxx
-    WORD  ExtFlags;         // 0
-    WORD  FSVer;            // must 0
-    DWORD RootClus;         // 
-    WORD  FSInfo;           // typically 1
-    WORD  BkBootSec;        // typically 6
-    BYTE  Reserved[12];     // set all to zero
-    BYTE  DrvNum;           // must 0x80
-    BYTE  Reserved1;        // set all to zero
-    BYTE  BootSig;          // must 0x29 
-    DWORD VollID;           // xxx
-    BYTE  VolLab[11];       // "abcdefghijk"
-    BYTE  FilSysType[8];    // "FAT32   "
-} BPBFAT32;
-
-typedef union _bpboffset36
-{
-    BPBFAT16 FAT16;
-    BPBFAT32 FAT32;
-} BPBOFFSET36;
-
-typedef struct _FAT32BootRecord
-{
-    BYTE        JumpBoot[3];    // 0xeb, 0x58, 0x90
-    BYTE        OEMName[8];     // "MSWIN4.1"
-    WORD        BytsPerSec;     // must 512
-    BYTE        SecPerClus;     // 8 for 4K cluster
-    WORD        RsvdSecCnt;     // typically 32 for FAT32
-    BYTE        NumFATs;        // always 2
-    WORD        RootEntCnt;     // must 0 for FAT32
-    WORD        TotSec16;       // must 0 for FAT32
-    BYTE        Media;          // must 0xf8
-
-    WORD        FATSz16;        // 0   for FAT32
-    WORD        SecPerTrk;      // 63  for FAT32
-    WORD        NumHeads;       // 255 for FAT32
-    DWORD       HiddSec;        // 63  for FAT32
-
-    DWORD       TotSec32;       // xxx
-
-    BPBOFFSET36 Off36;
-
-    BYTE        Reserved[420];
-    WORD        Signature;      // must 0xAA55
-} FAT32_BOOT_RECORD, *PFAT32_BOOT_RECORD;
-
-typedef struct _fat_entry_table16
-{
-    WORD aEntry[256];
-} FAT_ENTRY_TABLE16;
-
-typedef struct _fat_entry_table32
-{
-    DWORD aEntry[128];
-} FAT_ENTRY_TABLE32;
-
-typedef union _fat_dir_table
-{
-    FAT32_DIRECTORY_ENTRY      aShort[16];
-    FAT32_DIRECTORY_ENTRY_LONG aLong[16];
-} FAT_DIR_TABLE;
-
-typedef struct _drive_info
-{
-    BYTE  bIsFAT32;
-    BYTE  bDevice;
-    BYTE  bSectorsPerCluster;
-    BYTE  bFlags;
-
-    WORD  wSectorSize;
-
-    DWORD dwRootDirSectors;
-    DWORD dwFirstRootDirSector;
-
-    DWORD dwRootCluster;
-    DWORD dwFAT1StartSector;
-    DWORD dwFAT2StartSector;
-    DWORD dwCluster2StartSector;
-
-    DWORD dwClusterSize;
-} DRIVE_INFO;
-
-typedef struct _fhandle
-{
-    DWORD      dwFileSize;
-    DWORD      dwStartCluster;
-    DWORD      dwReadCluster;
-    DWORD      dwFilePointer;          /* total file pointer   */
-    DWORD      dwClusterPointer;       /* cluster read pointer */
-
-    int         nLastError;
-    int         nEOF;
-
-    DRIVE_INFO *pDrive;
-} FHANDLE;
-
-static int QuickFormat(NUTDEVICE *dev, DRIVE_INFO *pDrive);
-
-/*==========================================================*/
-/*  DEFINE: Definition of all local Data                    */
-/*==========================================================*/
-static int        nIsInit = FALSE;
-
-static BYTE      *pSectorBuffer = NULL;
-static char      *pLongName1 = NULL;
-static char      *pLongName2 = NULL;
-static DRIVE_INFO sDriveInfo[FAT_MAX_DRIVE];
-
-static HANDLE hFATSemaphore;
-
-static DSKSZTOSECPERCLUS DskTableFAT32[] = {
-    {      66600,  0}, /* disks up to 32.5MB, the 0 value for SecPerClusVal trips an error */
-    {     532480,  1}, /* disks up to 260 MB, 0.5k cluster */
-    {   16777216,  8}, /* disks up to   8 GB,   4k cluster */
-    {   33554432, 16}, /* disks up to  16 GB,   8k cluster */
-    {   67108864, 32}, /* disks up to  32 GB,  16k cluster */
-    { 0xFFFFFFFF, 64}  /* disks greather than 32GB, 32k cluster */
-};
-
-#define DSK_TABLE_FAT32_ENTRY_COUNT (sizeof(DskTableFAT32) / sizeof(DSKSZTOSECPERCLUS))
-/*==========================================================*/
-/*  DEFINE: Definition of all local Procedures              */
-/*==========================================================*/
-
-void FATRelease()
-{
-    nIsInit=FALSE;
-}
-/************************************************************/
-/*  FATLock                                                 */
-/************************************************************/
-void FATLock(void)
-{
-    NutEventWait(&hFATSemaphore, 0);
-}
-
-/************************************************************/
-/*  FATFree                                                 */
-/************************************************************/
-void FATFree(void)
-{
-    NutEventPost(&hFATSemaphore);
-}
-
-/************************************************************/
-/*  FATSemaInit                                             */
-/************************************************************/
-void FATSemaInit(void)
-{
-    NutEventPost(&hFATSemaphore);
-}
-
-/************************************************************/
-/*  GetFirstSectorOfCluster                                 */
-/************************************************************/
-static DWORD GetFirstSectorOfCluster(DRIVE_INFO *pDrive, DWORD dwCluster)
-{
-    DWORD dwSector;
-
-    if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
-    {
-        dwSector  = dwCluster;
-    }
-    else
-    {
-        dwSector  = (dwCluster - 2) * pDrive->bSectorsPerCluster;
-        dwSector += pDrive->dwCluster2StartSector;
-    }
-
-    return(dwSector);
-}
-
-/************************************************************/
-/*  GetNextCluster                                          */
-/************************************************************/
-static DWORD GetNextCluster(DRIVE_INFO *pDrive, DWORD dwCluster)
-{
-    DWORD             dwNextCluster;
-    DWORD             dwSector;
-    DWORD             dwIndex;
-    FAT_ENTRY_TABLE16 *pFatTable16;
-    FAT_ENTRY_TABLE32 *pFatTable32;
-
-    if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
-    {
-        dwNextCluster = dwCluster + 1;
-    }
-    else
-    {
-        if (pDrive->bIsFAT32 == TRUE)
-        {
-            //
-            //  (HW_SECTOR_SIZE / sizeof(long)) == 128
-            // 
-            dwSector = (dwCluster / 128) + pDrive->dwFAT1StartSector;
-            dwIndex  = dwCluster % 128;
-
-            HWReadSectors(pDrive->bDevice, pSectorBuffer, dwSector, 1);
-            pFatTable32 = (FAT_ENTRY_TABLE32 *) pSectorBuffer;
-
-            dwNextCluster = (pFatTable32->aEntry[dwIndex] & FAT32_CLUSTER_MASK);
-            if ((dwNextCluster == FAT32_CLUSTER_EOF) || (dwNextCluster == FAT32_CLUSTER_ERROR))
-            {
-                dwNextCluster = 0;
-            }
-
-        }
-        else
-        {  /* FAT16 */
-            //
-            //  (HW_SECTOR_SIZE / sizeof(word)) == 256
-            // 
-            dwSector = (dwCluster / 256) + pDrive->dwFAT1StartSector;
-            dwIndex  = dwCluster % 256;
-
-            HWReadSectors(pDrive->bDevice, pSectorBuffer, dwSector, 1);
-            pFatTable16 = (FAT_ENTRY_TABLE16 *) pSectorBuffer;
-
-            dwNextCluster = (pFatTable16->aEntry[dwIndex] & FAT16_CLUSTER_MASK);
-            if ((dwNextCluster == FAT16_CLUSTER_EOF) || (dwNextCluster == FAT16_CLUSTER_ERROR))
-            {
-                dwNextCluster = 0;
-            }
-
-        } /* endif pDrive->bIsFAT32 */
-    }
-
-    return(dwNextCluster);
-}
-
-/************************************************************/
-/*  GetLongChar                                             */
-/************************************************************/
-static char GetLongChar(WORD wValue)
-{
-    BYTE Value;
-
-    Value = (BYTE)(wValue & 0x00FF);
-    if (Value == 0xFF)
-    {
-        Value = 0;
-    }
-
-    if (Value != 0)
-    {
-        Value = toupper(Value);
-    }
-
-    return((char)Value);
-}
-
-/************************************************************/
-/*  FindFile                                                */
-/*                                                          */
-/*  Find a file by a given name pLongName.                  */
-/*                                                          */
-/*  It is possible that a SHORT name like "enlogo.gif"      */
-/*  is stored as a LONG name. I have seen this              */
-/*  nasty behaviour by Win98. Therefore I will check        */
-/*  the long name too, even if nIsLongName is FALSE.        */
-/************************************************************/
-static DWORD FindFile(DRIVE_INFO            *pDrive,
-                      FAT32_DIRECTORY_ENTRY *pSearchEntry, 
-                      char                  *pLongName,
-                      DWORD                 dwDirCluster, 
-                      DWORD                 *pFileSize, 
-                      int                    nIsLongName)
-{
-    int                       i, x;
-    BYTE                      bError;
-    int                       nNameLen;
-    int                       nMaxLen;
-    BYTE                      bFound;
-    BYTE                      bEndLoop;
-    BYTE                      bOrder;
-    BYTE                      bMaxOrder;
-    int                       nDirMaxSector;
-    DWORD                     dwSector;
-    DWORD                     dwNewCluster;
-    FAT32_DIRECTORY_ENTRY      *pDirEntryShort;
-    FAT32_DIRECTORY_ENTRY_LONG *pDirEntryLong;
-    char                       *pDirName = 0;
-    FAT_DIR_TABLE              *pDirTable;
-
-    bError       = FALSE;
-    *pFileSize   = 0;
-    dwNewCluster = 0;
-
-    nNameLen  = strlen(pLongName);
-
-    bMaxOrder = (BYTE) ((nNameLen + 12) / 13);
-    nMaxLen   = (int) (bMaxOrder * 13);
-    if (nMaxLen >= (FAT_LONG_NAME_LEN - 1))
-    {
-        bError = TRUE;
-    }
-
-    bOrder = (BYTE) (0x40 | bMaxOrder);
-    if (bOrder == 0xE5)
-    {
-        //
-        // I do not know what should I do if the bOrder is 0xe5.
-        // This is a sign for a "empty" entry. 
-        //
-        bError = TRUE;
-    }
-
-    if (bError == FALSE)
-    {
-        bFound   = FALSE;
-        bEndLoop = FALSE;
-        while ((bEndLoop == FALSE) && (dwDirCluster != 0))
-        {
-            dwSector = GetFirstSectorOfCluster(pDrive, dwDirCluster);
-            nDirMaxSector = (int) pDrive->bSectorsPerCluster;
-
-            //
-            // Test for special case dwDirCluster and FAT16.
-            //
-            if ((dwDirCluster == 1) && (pDrive->bIsFAT32 == FALSE))
-            {
-                dwSector = pDrive->dwFirstRootDirSector;
-                nDirMaxSector = (int) pDrive->dwRootDirSectors;
-            }
-            //
-            // One cluster has SecPerCluster sectors.
-            //
-            for (i = 0; i < nDirMaxSector; i++)
-            {
-                HWReadSectors(pDrive->bDevice, pSectorBuffer, dwSector + i, 1);
-                pDirTable = (FAT_DIR_TABLE *) pSectorBuffer;
-
-                //
-                // And one sector has 16 entries.
-                //
-                // HW_SECTOR_SIZE / sizeof(FAT32_DIRECTORY_ENTRY) = 16
-                //
-                for (x = 0; x < 16; x++)
-                {
-                    if (bFound == TRUE)
-                    {
-                        pDirEntryShort = (FAT32_DIRECTORY_ENTRY *) & pDirTable->aShort[x];
-                        dwNewCluster   = pDirEntryShort->HighCluster;
-                        dwNewCluster   = (dwNewCluster << 16) | (DWORD) pDirEntryShort->LowCluster;
-                        *pFileSize     = pDirEntryShort->FileSize;
-                        bEndLoop       = TRUE;
-                        break;
-                    }
-                    //
-                    // Check for valid entry.
-                    //
-                    pDirEntryShort = (FAT32_DIRECTORY_ENTRY *) & pDirTable->aShort[x];
-                    pDirEntryLong = (FAT32_DIRECTORY_ENTRY_LONG *) & pDirTable->aLong[x];
-
-                    if (nIsLongName == FALSE)
-                    {
-                        //
-                        // Check if it could be a short name. If Win2000 tell us it
-                        // is a short name, it is true. But with Win98 we must
-                        // test both, short and long...
-                        //
-                        if ((pDirEntryShort->Name[0] != 0xE5) && (pDirEntryShort->Name[0] != 0x00))
-                        {
-                            if (memcmp(pDirEntryShort, pSearchEntry, 11) == 0)
-                            {
-                                //
-                                // Check for the correct attribute, this is done with
-                                // the '&' and not with the memcmp.
-                                // With the '&' it is possible to find a hidden archive too :-)
-                                //
-                                if ((pDirEntryShort->Attribute & pSearchEntry->Attribute) ==
-                                    pSearchEntry->Attribute)
-                                {
-
-                                    dwNewCluster = pDirEntryShort->HighCluster;
-                                    dwNewCluster = (dwNewCluster << 16) | (DWORD) pDirEntryShort->LowCluster;
-                                    *pFileSize   = pDirEntryShort->FileSize;
-
-                                    bEndLoop = TRUE;
-                                    break;
-
-                                } /* endif Attribute */
-                            } /* endif test Name+Ext */
-                        } /* endif Name[0] != 0xe5, 0x00 */
-                    }
-                    /*
-                     * endif nIsLongName == FALSE 
-                     */
-                    if ((pDirEntryLong->Attribute == DIRECTORY_ATTRIBUTE_LONG_NAME)
-                        && (pDirEntryLong->Order == bOrder))
-                    {
-                        //
-                        // Next bOrder is bOrder--
-                        //  
-                        if (bOrder & 0x40)
-                        {
-                            bOrder &= ~0x40;
-
-                            //
-                            // Get the space for the name.
-                            //
-                            pDirName = pLongName2;
-
-                            //
-                            // Set the end of string.
-                            //
-                            pDirName[nMaxLen--] = 0;
-                        }
-
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name3[1]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name3[0]);
-
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[5]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[4]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[3]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[2]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[1]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[0]);
-
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[4]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[3]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[2]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[1]);
-                        pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[0]);
-
-                        bOrder--;
-                        if (bOrder == 0)
-                        {
-                            //
-                            // Now compare the name.
-                            //
-                            bOrder = (BYTE) (0x40 | bMaxOrder);
-                            nMaxLen = (int) (bMaxOrder * 13);
-                            if (memcmp(pLongName, pDirName, strlen(pLongName)) == 0)
-                            {
-                                //
-                                // The next entry will be the correct entry.
-                                //
-                                bFound = TRUE;
-                            }
-                        }
-                    }
-                    /*
-                     * pDirEntryLong->Order == bOrder 
-                     */
-                } /* endfor x<16 */
-
-                if (bEndLoop == TRUE)
-                {
-                    break;
-                }
-            }
-
-            if (bEndLoop == FALSE)
-            {
-                //
-                // No file found in this cluster, get the next one.
-                //
-                dwDirCluster = GetNextCluster(pDrive, dwDirCluster);
-            }
-        } /* endwhile */
-
-    }
-    /*
-     * endif bError == FALSE 
-     */
-    return(dwNewCluster);
-}
-
-/************************************************************/
-/*  MountHW                                                 */
-/************************************************************/
-static int MountHW(int nDrive)
-{
-    int                    nError;
-    int                    i;
-    DWORD                 dwSector;
-    DWORD                 dwFATSz;
-    DWORD                 dwRootDirSectors;
-    FAT32_PARTITION_TABLE *pPartitionTable;
-    FAT32_BOOT_RECORD     *pBootRecord;
-    DRIVE_INFO            *pDrive;
-
-    nError   = HW_OK;
-    i        = nDrive;
-    pDrive   = &sDriveInfo[nDrive];
-    dwSector = 0;
-
-    if (pDrive->bFlags & FLAG_FAT_IS_ZIP)
-    {
-        dwSector = ZIP_DRIVE_BR_SECTOR;
-    }
-    else
-    {
-        //
-        // Try to find a PartitionTable.
-        // 
-        nError = HWReadSectors(nDrive, pSectorBuffer, 0, 1);
-        if (nError == HW_OK)
-        {
-            pPartitionTable = (FAT32_PARTITION_TABLE *) pSectorBuffer;
-
-            if (pPartitionTable->Signature == FAT_SIGNATURE)
-            {
-                if (pPartitionTable->Partition[0].NumSectors)
-                {
-                    //
-                    // We found a PartitionTable, read BootRecord.
-                    // 
-                    dwSector = pPartitionTable->Partition[0].StartSectors;
-                }
-            }
-        }
-    }
-
-    if (dwSector != 0)
-    {
-        HWReadSectors(i, pSectorBuffer, dwSector, 1);
-        pBootRecord = (FAT32_BOOT_RECORD *) pSectorBuffer;
-
-        //
-        // Test valid BootRecord.
-        //
-        if (pBootRecord->Signature == FAT_SIGNATURE)
-        {
-            pDrive->bSectorsPerCluster = pBootRecord->SecPerClus;
-
-            if (pBootRecord->FATSz16 != 0)
-            {
-                dwFATSz = pBootRecord->FATSz16;
-                pDrive->bIsFAT32 = FALSE;
-                pDrive->dwRootCluster = 1;  /* special value, see */
-                                            /* FindFile           */
-            }
-            else
-            {
-                dwFATSz               = pBootRecord->Off36.FAT32.FATSz32;
-                pDrive->bIsFAT32      = TRUE;
-                pDrive->dwRootCluster = pBootRecord->Off36.FAT32.RootClus;
-            }
-
-            dwRootDirSectors =
-            ((pBootRecord->RootEntCnt * 32) +
-             (pBootRecord->BytsPerSec - 1)) / pBootRecord->BytsPerSec;
-
-            pDrive->dwFAT1StartSector = pBootRecord->HiddSec + pBootRecord->RsvdSecCnt;
-            pDrive->dwFAT2StartSector = pDrive->dwFAT1StartSector + dwFATSz;
-
-            pDrive->dwCluster2StartSector =
-            pBootRecord->HiddSec + pBootRecord->RsvdSecCnt +
-            (pBootRecord->NumFATs * dwFATSz) + dwRootDirSectors;
-
-            pDrive->dwClusterSize = pBootRecord->SecPerClus * pDrive->wSectorSize;
-
-            pDrive->dwRootDirSectors = dwRootDirSectors;
-            pDrive->dwFirstRootDirSector = pDrive->dwFAT2StartSector + dwFATSz;
-
-        } /* endif pBootRecord->Signature */
-    }
-    /*
-     * endif dwSector != 0 
-     */
-    return(nError);
-}
-
-/************************************************************/
-/*  MountAllDrives                                          */
-/************************************************************/
-static int MountDrive(BYTE bDrive)
-{
-    int nError;
-
-    nError = HW_OK;
-
-    FATLock();
-
-    if (pLongName1 == NULL)
-    {
-        pLongName1 = (char *)NutHeapAlloc(FAT_LONG_NAME_LEN);
-    }
-    if (pLongName2 == NULL)
-    {
-        pLongName2 = (char *)NutHeapAlloc(FAT_LONG_NAME_LEN);
-    }
-    if (pSectorBuffer == NULL)
-    {
-        pSectorBuffer = (BYTE *)NutHeapAlloc(MAX_SECTOR_SIZE);
-    }
-
-    if ((pSectorBuffer != NULL) && (pLongName1 != NULL) && (pLongName2 != NULL))
-    {
-        memset((BYTE *) & sDriveInfo[bDrive], 0x00, sizeof(DRIVE_INFO));
-
-        sDriveInfo[bDrive].bDevice     = bDrive;
-        sDriveInfo[bDrive].wSectorSize = HWGetSectorSize(bDrive);
-
-        if (HWIsCDROMDevice(bDrive) == TRUE)
-        {
-            sDriveInfo[bDrive].bFlags |= FLAG_FAT_IS_CDROM;
-        }
-
-        if (HWIsZIPDevice(bDrive) == TRUE)
-        {
-            sDriveInfo[bDrive].bFlags |= FLAG_FAT_IS_ZIP;
-        }
-
-        switch (sDriveInfo[bDrive].wSectorSize)
-        {
-            case HW_SECTOR_SIZE:{
-                    nError = MountHW(bDrive);
-                    break;
-                }
-            default:{
-                    nError = HW_ERROR;
-                    break;
-                }
-        }
-    }
-    /*
-     * endif pSectorBuffer != NULL 
-     */
-    FATFree();
-
-    return(nError);
-}
-
-/************************************************************/
-/*  MountAllDrives                                          */
-/************************************************************/
-static int MountAllDrives(void)
-{
-    BYTE  i;
-    int  nError = HW_OK;
-
-    for (i = 0; i < FAT_MAX_DRIVE; i++)
-    {
-        MountDrive(i);
-    }
-
-    return(nError);
-}
-
-/*==========================================================*/
-/*  DEFINE: All code exported by the NUTDEVICE              */
-/*==========================================================*/
-/************************************************************/
-/*  FATUnMountDrive                                         */
-/************************************************************/
-static int FATUnMountDrive(int nDrive)
-{
-    int         nError;
-    DRIVE_INFO *pDrive;
-
-    FATLock();
-
-    nError = FAT_OK;
-
-    if ((nDrive >= HW_DRIVE_C) && (nDrive <= HW_DRIVE_D))
-    {
-        pDrive = &sDriveInfo[nDrive];
-        pDrive->bSectorsPerCluster = 0;
-    }
-    else
-    {
-        nError = FAT_ERROR;
-    }
-
-    FATFree();
-
-    return(nError);
-}
-
-/************************************************************/
-/*  CFMount                                                 */
-/************************************************************/
-static void CFMount(int nDrive)
-{
-    BYTE *pSectorBuffer;
-
-    pSectorBuffer = (BYTE *) NutHeapAlloc(MAX_SECTOR_SIZE);
-    if (pSectorBuffer != NULL)
-    {
-        MountDrive(nDrive);
-        NutHeapFree(pSectorBuffer);
-    }
-}
-
-/************************************************************/
-/*  CFUnMount                                               */
-/************************************************************/
-static void CFUnMount(int nDrive)
-{
-    FATUnMountDrive(nDrive);
-}
-
-/************************************************************/
-/*  FATInit                                                 */
-/************************************************************/
-static int FATInit(NUTDEVICE * pDevice)
-{
-    int   nError;
-    int   nHWMode;  
-    BYTE *pSectorBuffer;
-
-    nError        = NUTDEV_ERROR;
-    nHWMode       = 0;
-    pSectorBuffer = NULL;
-
-    if ((nIsInit              == FALSE) && 
-        (pDevice->dev_name[0] == 'F')   &&
-        (pDevice->dev_name[1] == 'A')   &&
-        (pDevice->dev_name[2] == 'T'))
-    {
-        nError = NUTDEV_OK;      
-
-        //
-        // Get the mode.
-        //    
-        switch (pDevice->dev_base)
-        {
-
-#if (FAT_USE_MMC_INTERFACE >= 1)
-            case FAT_MODE_MMC:
-                nHWMode = 0;   
-                break; 
-#endif        
-            default:
-                nError = NUTDEV_ERROR;
-                break;
-        }
-
-        if (nError == NUTDEV_OK)
-        {
-            //
-            // Init my semaphore.
-            //
-            FATSemaInit();
-
-            pSectorBuffer = (BYTE *) NutHeapAlloc(MAX_SECTOR_SIZE);
-            if (pSectorBuffer != NULL)
-            {
-                /*
-                 * HW init
-                 */
-                nError = HWInit(nHWMode, CFMount, CFUnMount);
-                if (nError == HW_OK)
-                {
-                    HWMountAllDevices(nHWMode, pSectorBuffer);
-
-                    /*
-                     * FAT init
-                     */
-                    MountAllDrives();
-
-                    nError  = NUTDEV_OK;
-                    nIsInit = TRUE;    
-                }
-                else
-                {
-                    nError  = NUTDEV_WRONG_HW;
-                }  
-
-                NutHeapFree(pSectorBuffer);
-            } /* endif pSectorBuffer != NULL */
-        } /* endif nError == NUTDEV_OK */
-    }
-    else
-    {
-        if (nIsInit == TRUE)
-        {
-#if (FAT_USE_MMC_INTERFACE >= 1)
-            if ((pDevice->dev_name[0] == 'F')   &&
-                (pDevice->dev_name[1] == 'M')   &&
-                (pDevice->dev_name[2] == '0'))
-            {
-                /*
-                 * Always OK, because the MMC card
-                 * can be inserted later.
-                 */
-                nError = NUTDEV_OK;  
-            }
-#endif /* (FAT_USE_MMC_INTERFACE >= 0) */      
-
-        } /* endif (nIsInit == TRUE) */
-    } /* endif nIsInit == FALSE */
-
-    return(nError);
-}
-
-/************************************************************/
-/*  GetDriveByDevice                                        */
-/************************************************************/
-static DRIVE_INFO* GetDriveByDevice (NUTDEVICE *pDevice)
-{
-    DRIVE_INFO* pDrive = NULL;
-
-    if (pDevice != NULL)
-    {
-        switch (pDevice->dev_name[2])
-        {
-            case 'F':{
-                    pDrive = &sDriveInfo[HW_DRIVE_C];
-                    break;
-                }
-            case '0':{
-                    pDrive = &sDriveInfo[HW_DRIVE_D];
-                    break;
-                }
-            case '1':{
-                    pDrive = &sDriveInfo[HW_DRIVE_E];
-                    break;        
-                }      
-        }
-    }
-
-    return(pDrive);
-}  
-
-/************************************************************/
-/*  FATFileOpen                                             */
-/*                                                          */
-/*  Opens an existing file for reading.                     */
-/*                                                          */
-/*  Parameters: pName points to a string that specifies the */
-/*              name of the file to open. The name must     */
-/*              exactly match the full pathname of the file.*/
-/*                                                          */
-/*  Returns:    A pointer to a FILE structure that can be   */
-/*              used to read the file and retrieve          */
-/*              information about the file.                 */
-/*                                                          */
-/*              A return value of -1 indicates an error.    */
-/************************************************************/
-static NUTFILE *FATFileOpen(NUTDEVICE *pDevice, CONST char *pName, int nMode,
-                            int nAccess)
-{
-    int                    i, x;
-    int                    nError;
-    int                    nEndWhile;
-    DWORD                 dwFileSize;
-    DWORD                 dwCluster;
-    FHANDLE               *hFile;
-    DRIVE_INFO            *pDrive;
-    FAT32_DIRECTORY_ENTRY  sDirEntry;
-    NUTFILE               *hNUTFile;
-    int                    nLongName;
-    char                  *pLongName;
-    char                  *pShortName;
-    char                  *pExtension;
-
-    //
-    // If the user has forgotten to call NUTDeviceOpen,
-    // we must call FATInit.
-    //
-    if (nIsInit == FALSE)
-    {
-        FATInit(pDevice);
-    }
-
-    FATLock();
-
-    pDrive    = NULL;
-    nError    = TRUE;
-    nLongName = FALSE;
-    pLongName = (char *)pLongName1;
-
-    //
-    // hFile is our FAT-Handle.
-    //
-    hFile = NULL;
-
-    //
-    // hNUTFile is the.... correct, NUT handle.
-    //   
-    hNUTFile = (NUTFILE *) NUTDEV_ERROR;
-
-    pDrive = GetDriveByDevice(pDevice);
-
-    if ((pDrive != NULL) && (pDrive->bSectorsPerCluster != 0) && (pName[0] != 0))
-    {
-
-        //
-        // Create a new file handle.
-        //    
-        hFile = (FHANDLE *) NutHeapAlloc(sizeof(FHANDLE));
-
-        if ((pDrive->dwFAT1StartSector) && (hFile != NULL) && (*pName != '.'))
-        {
-
-            memset(hFile, 0x00, sizeof(FHANDLE));
-
-            //
-            // Start by the ROOT dir...
-            //
-            dwCluster = pDrive->dwRootCluster;
-
-            //
-            // If the first char a "/", jump over, e.g. "/index.html"
-            // 
-            //
-            if (*pName == '/')
-            {
-                pName++;
-            }
-
-            nEndWhile = FALSE;
-            while (nEndWhile == FALSE)
-            {  /* master loop */
-
-                nLongName = FALSE;
-
-                //
-                // Get Name
-                //
-                i = 0;
-                while ((*pName != '/') && (*pName != '\\') && (*pName != 0))
-                {
-
-                    if (i >= (FAT_LONG_NAME_LEN - 1))
-                    {
-                        nEndWhile = TRUE;
-                        break;
-                    }
-
-                    pLongName[i] = toupper(*pName);
-
-                    i++;
-                    pName++;
-                } /* endwhile Name */
-
-                if (nEndWhile == FALSE)
-                {
-                    pLongName[i] = 0;
-
-                    //
-                    // Check if it is a Long Directory Entry.
-                    // Yes, I know that 'i' is the length of the string.
-                    // But the code is easier to read with the next strlen.
-                    //
-                    if (strlen(pLongName) <= FAT_SHORT_NAME_LEN)
-                    {
-                        //
-                        // It could be a ShortName, but "abc.defg" is possible
-                        // and this is a long name too. Therfore we need some tests.
-                        //
-                        pExtension = strchr(pLongName, '.');
-                        if (pExtension == NULL)
-                        {
-                            if (strlen(pLongName) > FAT_NAME_LEN)
-                            {
-                                nLongName = TRUE;
-                            }
-                            else
-                            {
-                                nLongName = FALSE;
-                            }
-                        }
-                        else
-                        {
-                            //
-                            // Check the length of the extensions.
-                            //
-                            pExtension++; /* jump over the '.' */
-                            if (strlen(pExtension) > 3)
-                            {
-                                nLongName = TRUE;
-                            }
-                        }
-                    }
-                    else
-                    {  /* Len > FAT_SHORT_NAME_LEN */
-                        //
-                        // Now we have a LongName, sure.
-                        // See the "nasty Win98" in FindFile :-)
-                        //
-                        nLongName = TRUE;
-                    }
-
-                    //
-                    // Here we knows, if we have a LongName or ShortName.
-                    //
-                    if (nLongName == FALSE)
-                    {
-                        //
-                        // ShortName
-                        //
-                        pShortName = pLongName;
-                        memset(&sDirEntry, 0x00, sizeof(FAT32_DIRECTORY_ENTRY));
-                        memset(sDirEntry.Name, 0x20, FAT_NAME_LEN);
-                        memset(sDirEntry.Extension, 0x20, FAT_EXT_LEN);
-
-                        //
-                        // Get the name
-                        //
-                        i = 0;
-                        while ((pShortName[i] != '.') && (pShortName[i] != 0))
-                        {
-                            sDirEntry.Name[i] = pShortName[i];
-                            i++;
-                        }
-                        //
-                        // And the extension
-                        //
-                        if (pShortName[i] == '.')
-                        {
-                            i++;  /* jump over the '.' */
-                            x = 0;
-                            while (pShortName[i] != 0)
-                            {
-                                sDirEntry.Extension[x] = pShortName[i];
-                                i++;
-                                x++;
-                            }
-                        }
-                    }
-                    //
-                    // The file could be a long or short one.
-                    // I have seen that Win98 store the short filename
-                    // in a long one :-(
-                    //
-                    switch (*pName)
-                    {
-                        //
-                        // The file is an ARCHIVE
-                        //
-                        case 0:{
-                                nEndWhile = TRUE;
-                                sDirEntry.Attribute = DIRECTORY_ATTRIBUTE_ARCHIVE;
-
-                                if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
-                                {
-                                    dwCluster = 0;
-                                }
-                                else
-                                {
-                                    dwCluster =
-                                    FindFile(pDrive, &sDirEntry, pLongName, dwCluster, &dwFileSize,
-                                             nLongName);
-                                }
-                                if (dwCluster != 0)
-                                {
-                                    hFile->dwFileSize       = dwFileSize;
-                                    hFile->dwStartCluster   = dwCluster;
-                                    hFile->dwReadCluster    = dwCluster;
-                                    hFile->dwFilePointer    = 0;
-                                    hFile->dwClusterPointer = 0;
-                                    hFile->pDrive           = pDrive;
-                                    hFile->nLastError       = FAT_OK;
-                                    hFile->nEOF             = FALSE;
-
-                                    nError                  = FALSE;
-                                }
-                                break;
-                            } /* endcase 0 */
-
-                            //
-                            // The file is a DIRECTORY
-                            //
-                        case '/':
-                        case '\\':{
-                                pName++;  /* jump over the char */
-
-                                sDirEntry.Attribute = DIRECTORY_ATTRIBUTE_DIRECTORY;
-
-                                if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
-                                {
-                                    dwCluster = 0;
-                                }
-                                else
-                                {
-                                    dwCluster =
-                                    FindFile(pDrive, &sDirEntry, pLongName, dwCluster, &dwFileSize,
-                                             nLongName);
-                                }
-                                if (dwCluster != 0)
-                                {
-
-                                    //
-                                    // The new Cluster is the Cluster of the directory
-                                    //
-
-                                }
-                                else
-                                {
-                                    nEndWhile = TRUE;
-                                }
-                                break;
-                            } /* endcase / \ */
-
-                        default:{
-                                nEndWhile = TRUE;
-                                break;
-                            }
-                    } /* end switch */
-
-                }
-                /*
-                 * endif nEndWhile == FALSE 
-                 */
-            } /* end while */
-
-        }
-        /*
-         * endif pDrive->dwFAT1StartSector 
-         */
-        if (nError == TRUE)
-        {
-            //
-            // We found no file, therefore we can delete our FAT-Handle
-            //
-            if (hFile != NULL)
-            {
-                NutHeapFree(hFile);
-            }
-        }
-        else
-        {
-            //
-            // We have found a FILE and can create a NUT-Handle.
-            //
-            hNUTFile = NutHeapAlloc(sizeof(NUTFILE));
-            if (hNUTFile != NULL)
-            {
-                hNUTFile->nf_next = 0;
-                hNUTFile->nf_dev  = pDevice;
-                hNUTFile->nf_fcb  = hFile;
-            }
-            else
-            {
-                //
-                // Error, no mem for the NUT-Handle, therefore we 
-                // can delete our FAT-Handle too.
-                //
-                NutHeapFree(hFile);
-            }
-        }
-
-    }
-    /*
-     * endif pName[0] != 0 
-     */
-    FATFree();
-
-    return(hNUTFile);
-}
-
-/************************************************************/
-/*  FATFileClose                                            */
-/*                                                          */
-/*  Close a previously opened file.                         */
-/*                                                          */
-/*  Parameters: hNUTFile Identifies the file to close.      */
-/*              This pointer must have been created by      */
-/*              calling FAT32FileOpen().                    */
-/*                                                          */
-/*  Returns:    0 if the function is successfully closed,   */
-/*              -1 otherwise.                               */
-/************************************************************/
-static int FATFileClose(NUTFILE * hNUTFile)
-{
-    int      nError;
-    FHANDLE *hFile;
-
-    nError = NUTDEV_ERROR;
-
-    FATLock();
-
-    if (hNUTFile != NULL)
-    {
-        hFile = (FHANDLE *) hNUTFile->nf_fcb;
-        if (hFile != NULL)
-        {
-            //
-            // Clear our FAT-Handle
-            //
-            NutHeapFree(hFile);
-        }
-        //
-        // Clear the NUT-Handle
-        //
-        NutHeapFree(hNUTFile);
-
-        nError = NUTDEV_OK;
-    }
-
-    FATFree();
-
-    return(nError);
-}
-
-/************************************************************/
-/*  FATFileSize                                             */
-/*                                                          */
-/*  Retrieve the size of a file.                            */
-/*                                                          */
-/*  Parameters: pFile Identifies the file to query.         */
-/*              This pointer must have been created by      */
-/*              calling FAT32FileOpen().                    */
-/*                                                          */
-/*  Returns:    The number of bytes in this file or         */
-/*              -1 if an error occured                      */
-/************************************************************/
-long FATFileSize(NUTFILE * hNUTFile)
-{
-    long     lSize;
-    FHANDLE *hFile;
-
-    FATLock();
-
-    lSize = NUTDEV_ERROR;
-
-    if (hNUTFile != NULL)
-    {
-        hFile = (FHANDLE *) hNUTFile->nf_fcb;
-        if (hFile != NULL)
-        {
-            lSize = hFile->dwFileSize;
-        }
-    }
-
-    FATFree();
-
-    return(lSize);
-}
-
-#if 0
-/************************************************************/
-/*  FATFileSeek                                             */
-/*                                                          */
-/*  Move the file pointer to a new position.                */
-/*  It points to the next byte to be read from a file.      */
-/*  The file pointer is automatically incremented for       */
-/*  each byte read. When the file is opened, it is at       */
-/*  position 0, the beginning of the file.                  */
-/*                                                          */
-/*  Parameters: pFile Identifies the file to seek.          */
-/*              This pointer must have been created by      */
-/*              calling FAT32FileOpen().                    */
-/*                                                          */
-/*              lPos Specifies the new absolute position    */
-/*              of the file pointer.                        */
-/*                                                          */
-/*  Returns:    0 if the function is successful,            */
-/*              -1 otherwise.                               */
-/************************************************************/
-int FATFileSeek(FILE * pFile, long lPos)
-{
-    int      nError = NUTDEV_ERROR;
-    FHANDLE *hFile;
-
-    FATLock();
-
-    hFile = (FHANDLE *) pFile;
-
-    //
-    // We must do some work here...
-    //
-    nError = FAT32_ERROR;
-
-    FATFree();
-
-    return(nError);
-}
-#endif
-
-/************************************************************/
-/*  FATFileRead                                             */
-/*                                                          */
-/*  Read data from a file.                                  */
-/*                                                          */
-/*  Parameters: pFile Identifies the file to read from.     */
-/*              This pointer must have been created by      */
-/*              calling FAT32FileOpen().                    */
-/*                                                          */
-/*              pData Points to the buffer that receives    */
-/*              the data.                                   */
-/*                                                          */
-/*              nSize Specifies the number of bytes to      */
-/*              read from the file.                         */
-/*                                                          */
-/*  Returns:    The number of bytes read from the file or   */
-/*               -1 if an error occured.                    */
-/************************************************************/
-int FATFileRead(NUTFILE * hNUTFile, void *pData, int nSize)
-{
-    int         nError;
-    int         nBytesRead;
-    int         nBytesToRead;
-    FHANDLE    *hFile;
-    DRIVE_INFO *pDrive;
-    BYTE       *pByte;
-    DWORD      dwReadSector;
-    DWORD      dwSector;
-    int         nSectorCount;
-    int         nSectorOffset;
-    WORD        wSectorSize;
-
-    nBytesRead = 0;
-
-    FATLock();
-
-    hFile  = NULL;
-    nError = NUTDEV_ERROR;
-
-    if (hNUTFile != NULL)
-    {
-        hFile = (FHANDLE *) hNUTFile->nf_fcb;
-    }
-
-    if ((hFile != NULL) && (nSize != 0))
-    {
-        if (hFile->dwFilePointer < hFile->dwFileSize)
-        {
-
-            if ((hFile->dwFilePointer + nSize) > hFile->dwFileSize)
-            {
-                nSize = (int) (hFile->dwFileSize - hFile->dwFilePointer);
-            }
-
-            pDrive = (DRIVE_INFO *) hFile->pDrive;
-            pByte  = (BYTE *) pData;
-
-            nBytesRead  = nSize;
-            wSectorSize = pDrive->wSectorSize;
-
-            while (nSize)
-            {
-                dwSector = GetFirstSectorOfCluster(pDrive, hFile->dwReadCluster);
-                nSectorCount = hFile->dwClusterPointer / wSectorSize;
-                nSectorOffset = hFile->dwClusterPointer % wSectorSize;
-
-                //
-                // (Sector + SectorCount) is the sector to read
-                // SectorOffset is the start position in the sector itself
-                //
-                dwReadSector = dwSector + nSectorCount;
-
-                nError = HWReadSectors(pDrive->bDevice, pSectorBuffer, dwReadSector, 1);
-                if (nError == HW_OK)
-                {
-                    //
-                    // Find the size we can read from ONE sector
-                    //
-                    if (nSize > (int) wSectorSize)
-                    {
-                        nBytesToRead = wSectorSize;
-                    }
-                    else
-                    {
-                        nBytesToRead = nSize;
-                    }
-
-                    //
-                    // Test inside a sector
-                    //
-                    if ((nSectorOffset + nBytesToRead) > (int) wSectorSize)
-                    {
-                        nBytesToRead = wSectorSize - nSectorOffset;
-                    }
-
-                    memcpy(pByte, &pSectorBuffer[nSectorOffset], nBytesToRead);
-                    pByte += nBytesToRead;
-
-                    hFile->dwFilePointer    += nBytesToRead;
-                    hFile->dwClusterPointer += nBytesToRead;
-
-                    //
-                    // Check for EOF
-                    if (hFile->dwFilePointer >= hFile->dwFileSize)
-                    {
-                        hFile->nEOF = TRUE;
-                    }
-
-                    if (hFile->dwClusterPointer >= pDrive->dwClusterSize)
-                    {
-                        //
-                        // We must switch to the next cluster
-                        //
-                        hFile->dwReadCluster = GetNextCluster(pDrive, hFile->dwReadCluster);
-                        hFile->dwClusterPointer = 0;
-                    }
-
-                    nSize -= nBytesToRead;
-
-                }
-                else
-                {  /* HWReadSectors Error */
-
-                    nBytesRead = 0;
-                    hFile->nLastError = FAT_ERROR_IDE;
-                    break;
-                } /* endif nError == HW_OK */
-
-            } /* endwhile */
-
-        }
-        else
-        {  /* reached the EOF */
-            hFile->nLastError = FAT_ERROR_EOF;
-        } /* endif hFile->dwFilePointer < hFile->dwFileSize */
-
-    }
-    /*
-     * endif (hFile != NULL) && (nSize != 0) 
-     */
-    FATFree();
-
-    return(nBytesRead);
-}
-
-/************************************************************/
-/*  FATFileWrite                                            */
-/*                                                          */
-/*  Write data to a file.                                   */
-/*                                                          */
-/*  Parameters: pFile Identifies the file to write to.      */
-/*              This pointer must have been created by      */
-/*              calling FAT32FileOpen().                    */
-/*                                                          */
-/*              pData Points to the buffer that holds       */
-/*              the data.                                   */
-/*                                                          */
-/*              nSize Specifies the number of bytes to      */
-/*              write to the file.                          */
-/*                                                          */
-/*  Returns:    The number of bytes written to the file or  */
-/*               -1 if an error occured.                    */
-/************************************************************/
-static int FATFileWrite(NUTFILE * hNUTFile, CONST void *pData, int nSize)
-{
-    int nError;
-
-    nError = NUTDEV_ERROR;
-
-    return(nError);
-}
-
-#ifdef __HARVARD_ARCH__
-static int FATFileWriteP(NUTFILE * hNUTFile, PGM_P pData, int nSize)
-{
-    int nError;
-
-    nError = NUTDEV_ERROR;
-
-    return(nError);
-}
-#endif
-
-/************************************************************/
-/*  FATIOCtl                                                */
-/*                                                          */
-/*  Perform IOCTL control functions.                        */
-/*                                                          */
-/*  reg May be set to one of the following constants:       */
-/*                                                          */
-/*  Parameters: dev  Identifies the device to use.          */
-/*              reg  Requested control function.            */
-/*              conf Points to a buffer that contains any   */
-/*                   data required for the given control    */
-/*                   function or receives data from that    */
-/*                   function.                              */
-/*  Returns:    0 on success, or -1 if an error occured.    */
-/************************************************************/
-int FATIOCtl(NUTDEVICE *dev, int req, void *conf)
-{
-    int         nError = NUTDEV_ERROR;
-    DRIVE_INFO *pDrive = GetDriveByDevice(dev);
-
-    if (pDrive != NULL)
-    {
-        switch (req)
-        {
-
-#if (FAT_SUPPORT_FORMAT >= 1)    
-            case FAT_IOCTL_QUICK_FORMAT: {
-                    nError = QuickFormat(dev, pDrive);
-                    break;
-                }
-#endif
-
-            default: {
-                    nError = NUTDEV_ERROR;
-                    break; 
-                }
-
-        }  
-    }
-
-    return(nError);
-}
-
-//
-// FAT Device information structure.
-// Is mapped to the FAT-Device.
-// The user MUST first register the FAT hardware.
-//
-NUTDEVICE devFAT = {
-    0,              /* Pointer to next device. */
-
-    /*
-     * Unique device name.     
-     */
-    {'F', 'A', 'T', 0, 0, 0, 0, 0, 0},
-
-    IFTYP_STREAM,   /* Type of device.                   */
-    2,              /* Base address.                     */
-    0,              /* First interrupt number.           */
-    0,              /* Interface control block.          */
-    0,              /* Driver control block.             */
-    FATInit,        /* Driver initialization routine.    */
-    0,              /* Driver specific control function. */
-    0,              /* Driver specific read function.    */
-    0,              /* Driver specific write function.   */
-
-#ifdef __HARVARD_ARCH__
-    0,              /* Driver specific write_p function. */
-#endif
-
-    0,              /* Driver specific open function.    */
-    0,              /* Driver specific close function.   */
-    0
-};
-
-#if (FAT_USE_MMC_INTERFACE >= 1)
-//
-// FATUSB Device information structure.
-// Is mapped to the first USB drive
-//
-NUTDEVICE devFATMMC0 = {
-    0,              /* Pointer to next device. */
-
-    /*
-     * Unique device name.     
-     */
-    {'F', 'M', '0', 0, 0, 0, 0, 0, 0},
-
-    IFTYP_STREAM,   /* Type of device.                   */
-    2,              /* Base address.                     */
-    0,              /* First interrupt number.           */
-    0,              /* Interface control block.          */
-    0,              /* Driver control block.             */
-    FATInit,        /* Driver initialization routine.    */
-    FATIOCtl,       /* Driver specific control function. */
-    FATFileRead,    /* Driver specific read function.    */
-    FATFileWrite,   /* Driver specific write function.   */
-
-#ifdef __HARVARD_ARCH__
-    FATFileWriteP,  /* Driver specific write_p function. */
-#endif
-
-    FATFileOpen,    /* Driver specific open function.    */
-    FATFileClose,   /* Driver specific close function.   */
-    FATFileSize
-};
-#endif /* (FAT_USE_MMC_INTERFACE >= 1) */
-
-
-#if (FAT_SUPPORT_FORMAT >= 1)
-/************************************************************/
-/*  GetClusterSize                                          */
-/************************************************************/
-static BYTE GetClusterSize (DWORD dTotalSectors)
-{
-    BYTE bIndex;
-    BYTE bSecPerClus = 0;
-
-    for (bIndex=0; bIndex<DSK_TABLE_FAT32_ENTRY_COUNT; bIndex++)
-    {
-        if (dTotalSectors <= DskTableFAT32[bIndex].DiskSize)
-        {
-            bSecPerClus = DskTableFAT32[bIndex].SecPerClusVal;
-            break;      
-        }
-    }
-
-    return(bSecPerClus);
-}
-
-/************************************************************/
-/*  QuickFormat                                             */
-/************************************************************/
-static int QuickFormat(NUTDEVICE *dev, DRIVE_INFO *pDrive)
-{
-    DWORD                   i;
-    int                    nError = NUTDEV_ERROR;
-    BYTE                  *pBuffer;
-    BYTE                   bDevice;
-    BYTE                   bSecPerClus;  
-    DWORD                  dSector;
-    DWORD                  dFirstDataSector;
-    DWORD                  dLastDataSector;
-    DWORD                  dMaxClusterCount;
-    DWORD                  dFAT1StartSector=0;
-    DWORD                  dFAT2StartSector=0;
-    DWORD                  dCluster2StartSector;
-    DWORD                  dClearCount;
-    DWORD                  dTotalSectors;
-    DWORD                  dPossibleClusterCount;
-    DWORD                  dFATSz32;
-    FAT32_PARTITION_TABLE *pPartitionTable;  
-    FAT32_BOOT_RECORD     *pBootRecord;
-    FAT32_FSINFO          *pFSInfo;
-    FAT32_DIRECTORY_ENTRY *pDirEntry;
-    LONG                  *pLong;
-    DWORD                  dVollID;
-
-    FATLock();
-
-    /*
-     * Get the sector buffer
-     */  
-    pBuffer = (u_char *)NutHeapAlloc(pDrive->wSectorSize);
-    if (pBuffer != NULL)
-    {
-
-        bDevice        = pDrive->bDevice;    
-        dTotalSectors  = HWGetTotalSectors(bDevice);
-        dTotalSectors -= BPB_RsvdSecCnt;
-
-        bSecPerClus = GetClusterSize(dTotalSectors);     
-        if (bSecPerClus == 0)
-        {
-            /*
-             * Sorry, to small for FAT32,
-             * the lib will support FAT16 later....
-             */
-            NutHeapFree(pBuffer);  
-            return(NUTDEV_ERROR);    
-        }
-
-        dPossibleClusterCount = (dTotalSectors / (LONG)bSecPerClus);
-
-        dFATSz32              = (dPossibleClusterCount * sizeof(long) + 
-                                 (FAT32_SECTOR_SIZE -1) ) / FAT32_SECTOR_SIZE; 
-
-        /*
-         * First we will clear the sectors which we will use
-         * for the MBR, BPB and the FA's.
-         */
-        dClearCount  = BPB_HiddSec + BPB_RsvdSecCnt;
-        dClearCount += (BPB_NumFATs * dFATSz32) + bSecPerClus;
-
-        memset(pBuffer, 0x00, pDrive->wSectorSize);        
-        for (i=0; i<dClearCount; i++)
-        {
-            nError = HWWriteSectors(bDevice, pBuffer, i, 1);    
-            if (nError != HW_OK)
-            {
-                break;
-            }
-        }
-
-        /*
-         * Create the Volume serial number,
-         * we have no random value, therefore
-         * use the dTotalSectors and time.
-         */
-        dVollID = (DWORD)time(NULL) * dTotalSectors;
-
-        /*
-         * Create MBR (MasterBootRecord)
-         */
-        memset(pBuffer, 0x00, pDrive->wSectorSize);
-        pPartitionTable = (FAT32_PARTITION_TABLE *)pBuffer;
-
-        pPartitionTable->Partition[0].BootInd      = 0x00;
-        pPartitionTable->Partition[0].FirstHead    = 1;
-        pPartitionTable->Partition[0].FirstSector  = 1;
-        pPartitionTable->Partition[0].FirstTrack   = 0;
-        pPartitionTable->Partition[0].FileSystem   = MBR_FAT32;
-        pPartitionTable->Partition[0].LastHead     = 0;
-        pPartitionTable->Partition[0].LastSector   = 0;
-        pPartitionTable->Partition[0].StartSectors = BPB_HiddSec;
-        pPartitionTable->Partition[0].NumSectors   = dTotalSectors;
-        pPartitionTable->Signature                 = MBR_SIGNATURE;
-
-        /*
-         * Write the MBR to the drive
-         */
-        nError = HWWriteSectors(bDevice, pBuffer, 0, 1);    
-        if (nError == HW_OK)
-        {
-            /*
-             * Create the BPB
-             */
-            memset(pBuffer, 0x00, pDrive->wSectorSize);
-            pBootRecord = (FAT32_BOOT_RECORD *)pBuffer;
-
-            pBootRecord->JumpBoot[0] = 0xEB;
-            pBootRecord->JumpBoot[1] = 0x58;
-            pBootRecord->JumpBoot[2] = 0x90;
-
-            pBootRecord->OEMName[0]  = 'M';
-            pBootRecord->OEMName[1]  = 'S';
-            pBootRecord->OEMName[2]  = 'D';
-            pBootRecord->OEMName[3]  = 'O';
-            pBootRecord->OEMName[4]  = 'S';
-            pBootRecord->OEMName[5]  = '5';
-            pBootRecord->OEMName[6]  = '.';
-            pBootRecord->OEMName[7]  = '0';
-
-            pBootRecord->BytsPerSec  = FAT32_SECTOR_SIZE;
-            pBootRecord->SecPerClus  = bSecPerClus;
-            pBootRecord->RsvdSecCnt  = BPB_RsvdSecCnt;
-            pBootRecord->NumFATs     = BPB_NumFATs;
-            pBootRecord->RootEntCnt  = 0;
-            pBootRecord->TotSec16    = 0;
-            pBootRecord->Media       = FAT32_MEDIA;      
-
-            pBootRecord->FATSz16     = 0;
-            pBootRecord->SecPerTrk   = 63;
-            pBootRecord->NumHeads    = 255;
-
-            pBootRecord->HiddSec     = BPB_HiddSec;
-            pBootRecord->TotSec32    = dTotalSectors;
-
-            pBootRecord->Off36.FAT32.FATSz32       = dFATSz32;
-            pBootRecord->Off36.FAT32.ExtFlags      = 0;
-            pBootRecord->Off36.FAT32.FSVer         = 0;
-            pBootRecord->Off36.FAT32.RootClus      = 2;
-            pBootRecord->Off36.FAT32.FSInfo        = FAT32_OFFSET_FSINFO;
-            pBootRecord->Off36.FAT32.BkBootSec     = FAT32_OFFSET_BACKUP_BOOT;
-
-            pBootRecord->Off36.FAT32.DrvNum        = 0x00; 
-            pBootRecord->Off36.FAT32.BootSig       = 0x29;
-            pBootRecord->Off36.FAT32.VollID        = dVollID;
-            pBootRecord->Off36.FAT32.VolLab[0]     = 'N';
-            pBootRecord->Off36.FAT32.VolLab[1]     = 'O';
-            pBootRecord->Off36.FAT32.VolLab[2]     = ' ';
-            pBootRecord->Off36.FAT32.VolLab[3]     = 'N';
-            pBootRecord->Off36.FAT32.VolLab[4]     = 'A'; 
-            pBootRecord->Off36.FAT32.VolLab[5]     = 'M'; 
-            pBootRecord->Off36.FAT32.VolLab[6]     = 'E'; 
-            pBootRecord->Off36.FAT32.VolLab[7]     = ' '; 
-            pBootRecord->Off36.FAT32.VolLab[8]     = ' '; 
-            pBootRecord->Off36.FAT32.VolLab[9]     = ' '; 
-            pBootRecord->Off36.FAT32.VolLab[10]    = ' '; 
-
-            pBootRecord->Off36.FAT32.FilSysType[0] = 'F';
-            pBootRecord->Off36.FAT32.FilSysType[1] = 'A';
-            pBootRecord->Off36.FAT32.FilSysType[2] = 'T';
-            pBootRecord->Off36.FAT32.FilSysType[3] = '3';
-            pBootRecord->Off36.FAT32.FilSysType[4] = '2';
-            pBootRecord->Off36.FAT32.FilSysType[5] = ' ';
-            pBootRecord->Off36.FAT32.FilSysType[6] = ' ';
-            pBootRecord->Off36.FAT32.FilSysType[7] = ' ';
-
-            pBootRecord->Signature                 = FAT_SIGNATURE;
-
-            /*
-             * Write the BPB to the drive
-             */
-            dSector = BPB_HiddSec;
-            nError  = HWWriteSectors(bDevice, pBuffer, dSector, 1);    
-            if (nError == HW_OK)
-            {
-                dSector += FAT32_OFFSET_BACKUP_BOOT;
-                nError   = HWWriteSectors(bDevice, pBuffer, dSector, 1);            
-            }
-        }
-
-        /*
-         * Create the FSINFO
-         */
-        if (nError == HW_OK)
-        {
-            memset(pBuffer, 0x00, pDrive->wSectorSize);
-            pFSInfo = (FAT32_FSINFO *)pBuffer;
-
-            dFirstDataSector = BPB_HiddSec + BPB_RsvdSecCnt;
-            dLastDataSector  = dTotalSectors;
-            dMaxClusterCount = dLastDataSector - dFirstDataSector;
-            dMaxClusterCount = dMaxClusterCount / (LONG)bSecPerClus;
-
-            pFSInfo->FirstSignature               = FSINFO_FIRSTSIGNATURE;
-            pFSInfo->FSInfoSignature              = FSINFO_FSINFOSIGNATURE;
-            pFSInfo->NumberOfFreeClusters         = dMaxClusterCount;
-            pFSInfo->MostRecentlyAllocatedCluster = 2;
-            pFSInfo->Signature                    = FSINFO_SIGNATURE;
-
-            /*
-             * Write the FSINFO to the drive
-             */      
-            dSector = BPB_HiddSec + FAT32_OFFSET_FSINFO;
-            nError  = HWWriteSectors(bDevice, pBuffer, dSector, 1);        
-        }
-
-        /*
-         * Write first FAT entry after format.
-         */
-        if (nError == HW_OK)
-        {
-            dFAT1StartSector = BPB_HiddSec + BPB_RsvdSecCnt;    
-            dFAT2StartSector = dFAT1StartSector + dFATSz32; 
-
-            memset(pBuffer, 0x00, pDrive->wSectorSize);
-            pLong = (LONG *)pBuffer;
-
-            /*
-             * Set the two reserved cluster after the format,
-             * take a look in the MS Hardware White Paper
-             * Version 1.03, December 6, 2000 for more information.
-             */
-            *pLong++ = 0x0FFFFFF8;
-            *pLong++ = FAT32_CLUSTER_EOF;
-            *pLong++ = FAT32_CLUSTER_EOF;
-
-            nError = HWWriteSectors(bDevice, pBuffer, dFAT1StartSector, 1);        
-            if (nError == HW_OK)
-            {
-                nError = HWWriteSectors(bDevice, pBuffer, dFAT2StartSector, 1);              
-            }
-        }
-
-        /*
-         * Create RootDir
-         */
-        if (nError == HW_OK)
-        {
-            memset(pBuffer, 0x00, pDrive->wSectorSize);
-            pDirEntry = (FAT32_DIRECTORY_ENTRY *)pBuffer;
-
-            pDirEntry->Name[0]      = 'E'; 
-            pDirEntry->Name[1]      = 'T';
-            pDirEntry->Name[2]      = 'H';
-            pDirEntry->Name[3]      = 'E';
-            pDirEntry->Name[4]      = 'R';
-            pDirEntry->Name[5]      = 'N';
-            pDirEntry->Name[6]      = 'U';
-            pDirEntry->Name[7]      = 'T';
-
-            pDirEntry->Extension[0] = ' ';
-            pDirEntry->Extension[1] = ' ';
-            pDirEntry->Extension[2] = ' ';
-
-            pDirEntry->Attribute    = DIRECTORY_ATTRIBUTE_VOLUME_ID;
-            pDirEntry->HighCluster  = 0;
-            pDirEntry->LowCluster   = 0;
-            pDirEntry->FileSize     = 0;
-
-            dCluster2StartSector = dFAT2StartSector + dFATSz32;
-            nError = HWWriteSectors(bDevice, pBuffer, dCluster2StartSector, 1);                    
-        }
-
-        NutHeapFree(pBuffer);  
-
-        FATFree();
-
-
-        /*
-         * Don't forget to mount the drive
-         */   
-        if (nError == HW_OK)
-        {
-            nError = MountDrive(bDevice);
-        }
-
-        if (nError == HW_OK)
-        {
-            nError = NUTDEV_OK;        
-        }
-        else
-        {
-            nError = NUTDEV_ERROR;    
-        }    
-    }
-
-    return(nError);
-}
-#endif /* (FAT_SUPPORT_FORMAT >= 1) */
-

+ 0 - 119
fat.h

@@ -1,119 +0,0 @@
-/****************************************************************************
-*  This file is part of the AVRIDE device driver.
-*
-*  Copyright (c) 2002-2004 by Michael Fischer. All rights reserved.
-*
-*  Redistribution and use in source and binary forms, with or without 
-*  modification, are permitted provided that the following conditions 
-*  are met:
-*  
-*  1. Redistributions of source code must retain the above copyright 
-*     notice, this list of conditions and the following disclaimer.
-*  2. Redistributions in binary form must reproduce the above copyright
-*     notice, this list of conditions and the following disclaimer in the 
-*     documentation and/or other materials provided with the distribution.
-*  3. Neither the name of the author nor the names of its contributors may 
-*     be used to endorse or promote products derived from this software 
-*     without specific prior written permission.
-*
-*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
-*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
-*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
-*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
-*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
-*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
-*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
-*  SUCH DAMAGE.
-*
-****************************************************************************
-*  History:
-*
-*  14.12.02  mifi   First Version 
-*  18.01.03  mifi   Change Licence from GPL to BSD
-*  25.01.03  mifi   Change FAT32Init 
-*                   New function FAT32MountDrive and FAT32UnMountDrive
-*                   Remove FAT32_MAX_FILES, a file handle will be 
-*                   allocated by NutHeapAlloc, therefore we have no
-*                   restrictions about the count of the open file handle.
-*                   (Only by available memory)
-*  27.01.03  mifi   Rename all FAT32xxx function to FATxxx.
-*
-*  28.01.03  mifi   Start porting to Nut/OS 3.X.X
-*  29.06.03  mifi   First ATAPI-Version
-*  24.07.04  mifi   Some changes to support more than one drive (datanut)
-*  25.07.04  mifi   Add support for the PCMCIA_11 hardware.
-*  27.07.04  mifi   Add support for IOCTL function
-****************************************************************************/
-#ifndef __FAT_H__
-#define __FAT_H__
-
-#include <sys/device.h>
-#include "fatdrv.h"
-
-/*-------------------------------------------------------------------------*/
-/* global defines                                                          */
-/*-------------------------------------------------------------------------*/
-
-/*
- * Device mode
- */
-#define FAT_MODE_IDE_HD           0x0000
-#define FAT_MODE_IDE_CF           0x0001
-#define FAT_MODE_MEM_CF           0x0002
-#define FAT_MODE_DATANUT_CF       0x0003
-#define FAT_MODE_DATANUT_IDECF    0x0004
-#define FAT_MODE_DATANUT_IDEWLAN  0x0005
-#define FAT_MODE_USB              0x0006
-#define FAT_MODE_MMC              0x0007
-
-
-/*
- * If the function should be 
- * supported, set it to 1
- */
-#define FAT_SUPPORT_FORMAT        1
-
-/*
- * IOCTL-Function
- */
-#define FAT_IOCTL_QUICK_FORMAT    0x1000
-
-/*-------------------------------------------------------------------------*/
-/* global types                                                            */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/* global macros                                                           */
-/*-------------------------------------------------------------------------*/
-#define FAT_IOCTL(_a,_b,_c)   ((NUTDEVICE *)_a)->dev_ioctl((_a), (_b), (_c))
-
-#define FATQuickFormat(_a)    FAT_IOCTL(_a, FAT_IOCTL_QUICK_FORMAT, NULL)
- 
-
-/*-------------------------------------------------------------------------*/
-/* Prototypes                                                              */
-/*-------------------------------------------------------------------------*/
-extern NUTDEVICE devFAT;
-
-#if (FAT_USE_IDE_INTERFACE >= 1)
-extern NUTDEVICE devFATCF;
-extern NUTDEVICE devFATIDE0;
-extern NUTDEVICE devFATIDE1;
-#endif
-
-#if (FAT_USE_USB_INTERFACE >= 1)
-extern NUTDEVICE devFATUSB0;
-#endif
-
-#if (FAT_USE_MMC_INTERFACE >= 1)
-extern NUTDEVICE devFATMMC0;
-extern void FATRelease(void);
-
-#endif
-
-
-#endif                          /* !__FAT_H__ */

+ 0 - 153
fatdrv.h

@@ -1,153 +0,0 @@
-/****************************************************************************
-*  This file is part of the FAT device driver.
-*
-*  Copyright (c) 2002-2004 by Michael Fischer. All rights reserved.
-*
-*  Redistribution and use in source and binary forms, with or without 
-*  modification, are permitted provided that the following conditions 
-*  are met:
-*  
-*  1. Redistributions of source code must retain the above copyright 
-*     notice, this list of conditions and the following disclaimer.
-*  2. Redistributions in binary form must reproduce the above copyright
-*     notice, this list of conditions and the following disclaimer in the 
-*     documentation and/or other materials provided with the distribution.
-*  3. Neither the name of the author nor the names of its contributors may 
-*     be used to endorse or promote products derived from this software 
-*     without specific prior written permission.
-*
-*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
-*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
-*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
-*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
-*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
-*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
-*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
-*  SUCH DAMAGE.
-*
-****************************************************************************
-*  History:
-*
-*  03.08.04  mifi   First Version
-****************************************************************************/
-#ifndef __FATDRV_H__
-#define __FATDRV_H__
-
-#include "typedefs.h"
-
-/*-------------------------------------------------------------------------*/
-/* global defines                                                          */
-/*-------------------------------------------------------------------------*/
-
-/*
- * Define the hardware here
- */
-#define FAT_USE_IDE_INTERFACE     0 
-#define FAT_USE_USB_INTERFACE     0
-#define FAT_USE_MMC_INTERFACE     1 
-
-
-#if (FAT_USE_IDE_INTERFACE >= 1)
-#include "ide.h"
-
-#define HW_SUPPORT_WRITE  IDE_SUPPORT_WRITE
-#define HW_SUPPORT_ATAPI  IDE_SUPPORT_ATAPI
-
-#define HW_OK             IDE_OK
-#define HW_ERROR          IDE_ERROR
-
-#define HW_DRIVE_C        IDE_DRIVE_C
-#define HW_DRIVE_D        IDE_DRIVE_D
-#define HW_DRIVE_E        IDE_DRIVE_E
-
-#define HW_SECTOR_SIZE    IDE_SECTOR_SIZE
-#endif /* (FAT_USE_IDE_INTERFACE >= 1) */ 
-
-
-#if (FAT_USE_USB_INTERFACE >= 1)
-#include "usbdrv.h"
-
-#define HW_SUPPORT_WRITE  USB_SUPPORT_WRITE
-#define HW_SUPPORT_ATAPI  USB_SUPPORT_ATAPI
-
-#define HW_OK             USB_OK
-#define HW_ERROR          USB_ERROR
-
-#define HW_DRIVE_C        USB_DRIVE_C
-#define HW_DRIVE_D        USB_DRIVE_D
-#define HW_DRIVE_E        USB_DRIVE_E
-
-#define HW_SECTOR_SIZE    USB_SECTOR_SIZE
-
-#endif /* (FAT_USE_USB_INTERFACE >= 1) */
-
-
-#if (FAT_USE_MMC_INTERFACE >= 1)
-#include "mmcdrv.h"
-
-#define HW_SUPPORT_WRITE  MMC_SUPPORT_WRITE
-#define HW_SUPPORT_ATAPI  MMC_SUPPORT_ATAPI
-
-#define HW_OK             MMC_OK
-#define HW_ERROR          MMC_ERROR
-
-#define HW_DRIVE_C        MMC_DRIVE_C
-#define HW_DRIVE_D        MMC_DRIVE_C
-#define HW_DRIVE_E        MMC_DRIVE_C
-
-#define HW_SECTOR_SIZE    MMC_SECTOR_SIZE
-
-#endif /* (FAT_USE_MMC_INTERFACE >= 1) */
-
-/*-------------------------------------------------------------------------*/
-/* global types                                                            */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/* global macros                                                           */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/* Prototypes                                                              */
-/*-------------------------------------------------------------------------*/
-#if (FAT_USE_IDE_INTERFACE >= 1)
-#define HWInit              IDEInit
-#define HWMountAllDevices   IDEMountAllDevices
-#define HWGetSectorSize     IDEGetSectorSize
-#define HWIsCDROMDevice     IDEIsCDROMDevice
-#define HWIsZIPDevice       IDEIsZIPDevice
-#define HWUnMountDevice     IDEUnMountDevice
-#define HWGetTotalSectors   IDEGetTotalSectors
-#define HWReadSectors       IDEReadSectors  
-#define HWWriteSectors      IDEWriteSectors
-#endif /* (FAT_USE_IDE_INTERFACE >= 1) */ 
-
-#if (FAT_USE_USB_INTERFACE >= 1)
-#define HWInit              USBInit
-#define HWMountAllDevices   USBMountAllDevices
-#define HWGetSectorSize     USBGetSectorSize
-#define HWIsCDROMDevice     USBIsCDROMDevice
-#define HWIsZIPDevice       USBIsZIPDevice
-#define HWUnMountDevice     USBUnMountDevice
-#define HWGetTotalSectors   USBGetTotalSectors
-#define HWReadSectors       USBReadSectors  
-#define HWWriteSectors      USBWriteSectors
-#endif /* (FAT_USE_USB_INTERFACE == 1) */
-
-#if (FAT_USE_MMC_INTERFACE >= 1)
-#define HWInit              MMCInit
-#define HWMountAllDevices   MMCMountAllDevices
-#define HWGetSectorSize     MMCGetSectorSize
-#define HWIsCDROMDevice     MMCIsCDROMDevice
-#define HWIsZIPDevice       MMCIsZIPDevice
-#define HWUnMountDevice     MMCUnMountDevice
-#define HWGetTotalSectors   MMCGetTotalSectors
-#define HWReadSectors       MMCReadSectors  
-#define HWWriteSectors      MMCWriteSectors
-#endif /* (FAT_USE_MMC_INTERFACE == 1) */
-
-#endif /* !__FATDRV_H__ */

+ 0 - 399
flash.c

@@ -1,399 +0,0 @@
-/* ========================================================================
- * [PROJECT]    SIR
- * [MODULE]     Flash
- * [TITLE]      Routines for Atmel AT45 serial dataflash memory chips.
- * [FILE]       flash.c
- * [VSN]        1.0
- * [CREATED]    11042007
- * [LASTCHNGD]  11042007
- * [COPYRIGHT]  Copyright (C) STREAMIT BV 2010
- * [PURPOSE]    contains all interface- and low-level routines to
- *              read/write/delete blocks in the serial DataFlash (AT45DBXX)
- * ======================================================================== */
-
-#define LOG_MODULE  LOG_FLASH_MODULE
-
-//#include <stdio.h>
-#include <cfg/os.h>
-#include <cfg/memory.h>
-
-#include <sys/timer.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "typedefs.h"
-#include "flash.h"
-#include "portio.h"
-#include "log.h"
-#include "spidrv.h"
-
-
-/*-------------------------------------------------------------------------*/
-/* local defines                                                           */
-/*-------------------------------------------------------------------------*/
-#ifndef MAX_AT45_CMDLEN
-#define MAX_AT45_CMDLEN         8
-#endif
-
-#ifndef AT45_ERASE_WAIT
-#define AT45_ERASE_WAIT         3000
-#endif
-
-#ifndef AT45_CHIP_ERASE_WAIT
-#define AT45_CHIP_ERASE_WAIT    50000
-#endif
-
-#ifndef AT45_WRITE_POLLS
-#define AT45_WRITE_POLLS        1000
-#endif
-
-#define DFCMD_READ_PAGE         0xD2    /* Read main memory page. */
-#define DFCMD_READ_STATUS       0xD7    /* Read status register. */
-#define DFCMD_CONT_READ         0xE8    /* Continuos read. */
-#define DFCMD_PAGE_ERASE        0x81    /* Page erase. */
-#define DFCMD_BUF1_WRITE        0x84    /* Buffer 1 write. */
-#define DFCMD_BUF1_FLASH        0x83    /* Buffer 1 flash with page erase. */
-
-/*
- *  \brief last page of flash (264 bytes) can be dedicated for parameter storage
- *   Special routines are provided for that goal but can be disabled here to save
- *   codespace (about 360 bytes of code for GCC)
- */
-
-//#define USE_FLASH_PARAM_PAGE
-
-/*-------------------------------------------------------------------------*/
-/* typedefs & structs                                                      */
-/*-------------------------------------------------------------------------*/
-/*!
- * \brief Known device type entry.
- */
-typedef struct _AT45_DEVTAB
-{
-    u_long devt_pages;
-    u_int devt_pagsiz;
-    u_int devt_offs;
-    u_char devt_srmsk;
-    u_char devt_srval;
-} AT45_DEVTAB;
-
-/*!
- * \brief Active device entry.
- */
-typedef struct _AT45DB_DCB
-{
-    AT45_DEVTAB *dcb_devt;
-    u_char dcb_cmdbuf[MAX_AT45_CMDLEN];
-} AT45DB_DCB;
-
-/*!
- * \brief Table of known Dataflash types.
- */
-AT45_DEVTAB at45_devt[] = {
-    {512,  264,  9,  0x3C, 0x0C},   // AT45DB011B - 128kB
-    {1025, 264,  9,  0x3C, 0x14},   // AT45DB021B - 256kB
-    {2048, 264,  9,  0x3C, 0x1C},   // AT45DB041B - 512kB
-    {4096, 264,  9,  0x3C, 0x24},   // AT45DB081B - 1MB
-    {4096, 528,  10, 0x3C, 0x2C},   // AT45DB0161B - 2MB
-    {8192, 528,  10, 0x3C, 0x34},   // AT45DB0321B - 4MB
-    {8192, 1056, 11, 0x38, 0x38},   // AT45DB0642 - 8MB
-    {0,    0,    0,  0,    0}       // End of table
-};
-
-/*-------------------------------------------------------------------------*/
-/* local variable definitions                                              */
-/*-------------------------------------------------------------------------*/
-/*!
- * \brief Table of active devices.
- */
-static AT45DB_DCB dcbtab;
-
-/*-------------------------------------------------------------------------*/
-/* local routines (prototyping)                                            */
-/*-------------------------------------------------------------------------*/
-static int At45dbTransfer(CONST void *txbuf, void *rxbuf, int xlen, CONST void *txnbuf, void *rxnbuf, int xnlen);
-
-/*!
- * \addtogroup SerialFlash
- */
-
-/*@{*/
-
-/*-------------------------------------------------------------------------*/
-/*                         start of code                                   */
-/*-------------------------------------------------------------------------*/
-
-/*!
- * \brief mid-level SPI-interface routine
- *
- *  This routine handles sending a command an reading back the reply in one routine
- *  It will perform 'xlen' + 'xnlen' SPI-byte cycles. During the 'xlen' cycles, data in 'txbuf'
- *  is sent using the SPI, and each resulting byte is stored in 'rxbuf'. Then it starts with
- *  the 'xnlen' cycles whereby the contents of the 'txnbuf' are sent using the SPI.
- *  Each resulting byte then is stored in 'rxnbuf'
- */
-//                                        cb,          cb,        len,             tdata,         rdata,      datalen
-static int At45dbTransfer(CONST void *txbuf, void *rxbuf, int xlen, CONST void *txnbuf, void *rxnbuf, int xnlen)
-{   int i;
-    u_char *ptTxbuf, *ptRxbuf;
-
-    SPIselect(SPI_DEV_FLASH);
-
-    ptTxbuf=(u_char*)txbuf;
-    ptRxbuf=(u_char*)rxbuf;
-    /*
-     *  send command, store the bytes that were read the same time
-     */
-    for (i=0; i<xlen; ++i)
-    {
-        *ptRxbuf++=SPItransferByte(*ptTxbuf++);
-    }
-
-    ptTxbuf=(u_char*)txnbuf;
-    ptRxbuf=(u_char*)rxnbuf;
-    /*
-     *  send dummy data, store the bytes that were read the same time
-     */
-    for (i=0; i<xnlen; ++i)
-    {
-        *ptRxbuf++=SPItransferByte(*ptTxbuf++);
-    }
-
-    SPIdeselect();
-
-    return(0);  // always...
-
-}
-
-/*!
- * \brief send a command to the AT45dbXX
- *
- */
-int At45dbSendCmd(u_char op, u_long parm, int len, CONST void *tdata, void *rdata, int datalen)
-{
-    u_char *cb = dcbtab.dcb_cmdbuf;
-
-    if (len > MAX_AT45_CMDLEN)
-    {
-        return (-1);
-    }
-    memset(cb, 0, len);
-    cb[0] = op;
-    if (parm)
-    {
-        cb[1] = (u_char) (parm >> 16);
-        cb[2] = (u_char) (parm >> 8);
-        cb[3] = (u_char) parm;
-    }
-    return (At45dbTransfer(cb, cb, len, tdata, rdata, datalen));
-}
-
-/*!
- * \brief read status
- *
- */
-u_char At45dbGetStatus()
-{
-    u_char buf[2] = { DFCMD_READ_STATUS, 0xFF};
-
-    if (At45dbTransfer(buf, buf, 2, NULL, NULL, 0))
-    {
-        return(u_char) - 1;
-    }
-    return (buf[1]);
-}
-
-/*!
- * \brief Wait until flash memory cycle finished.
- *
- * \return 0 on success or -1 in case of an error.
- */
-int At45dbWaitReady(u_long tmo, int poll)
-{
-    u_char sr;
-
-    while (((sr = At45dbGetStatus()) & 0x80) == 0)
-    {
-        if (!poll)
-        {
-            NutSleep(1);
-        }
-        if (tmo-- == 0)
-        {
-            return (-1);
-        }
-    }
-    return (0);
-}
-
-/*!
- * \brief runtime detection of serial flash device
- */
-int At45dbInit()
-{
-    u_char sr;
-    u_char i;
-
-    At45dbGetStatus();
-    sr = At45dbGetStatus();
-
-    for (i=0; at45_devt[i].devt_pages; i++)
-    {
-        if ((sr & at45_devt[i].devt_srmsk) == at45_devt[i].devt_srval)
-        {
-            dcbtab.dcb_devt = &at45_devt[i];
-            break;
-        }
-    }
-    return (i);
-}
-
-/*!
- * \brief Erase sector at the specified offset.
- */
-int At45dbPageErase(u_int pgn)
-{
-    return (At45dbSendCmd(DFCMD_PAGE_ERASE, pgn, 4, NULL, NULL, 0));
-}
-
-/*!
- * \brief Erase entire flash memory chip.
- */
-int At45dbChipErase(void)
-{
-    return (-1);
-}
-
-/*!
- * \brief Read data from flash memory.
- *
- * \param pgn  Page number to read, starting at 0.
- * \param data Points to a buffer that receives the data.
- * \param len  Number of bytes to read.
- *
- * \return 0 on success or -1 in case of an error.
- */
-int At45dbPageRead(u_long pgn, void *data, u_int len)
-{
-    pgn <<= dcbtab.dcb_devt->devt_offs;
-    return (At45dbSendCmd(DFCMD_CONT_READ, pgn, 8, data, data, len));
-}
-
-/*!
- * \brief Write data into flash memory.
- *
- * The related sector must have been erased before calling this function.
- *
- * \param pgn  Start location within the chip, starting at 0.
- * \param data Points to a buffer that contains the bytes to be written.
- * \param len  Number of bytes to write.
- *
- * \return 0 on success or -1 in case of an error.
- */
-int At45dbPageWrite(u_long pgn, CONST void *data, u_int len)
-{
-    int rc = -1;
-    void *rp;
-
-    if ((rp = malloc(len)) != NULL)
-    {
-        /* Copy data to dataflash RAM buffer. */
-        if (At45dbSendCmd(DFCMD_BUF1_WRITE, 0, 4, data, rp, len) == 0)
-        {
-            /* Flash RAM buffer. */
-            pgn <<= dcbtab.dcb_devt->devt_offs;
-            if (At45dbSendCmd(DFCMD_BUF1_FLASH, pgn, 4, NULL, NULL, 0) == 0)
-            {
-                rc = At45dbWaitReady(AT45_WRITE_POLLS, 1);
-            }
-        }
-        free(rp);
-    }
-    return (rc);
-}
-
-#ifdef USE_FLASH_PARAM_PAGE
-
-u_long At45dbParamPage(void)
-{
-#ifdef AT45_CONF_PAGE
-    return (AT45_CONF_PAGE);
-#else
-    return (dcbtab.dcb_devt->devt_pages - 1);
-#endif
-}
-
-int At45dbParamSize(void)
-{
-    int rc;
-
-#ifdef AT45_CONF_SIZE
-    rc = AT45_CONF_SIZE;
-#else
-    rc = dcbtab.dcb_devt->devt_pagsiz;
-#endif
-    return (rc);
-}
-
-/*!
- * \brief Load configuration parameters from flash memory.
- *
- * \param pos  Start location within configuration sector.
- * \param data Points to a buffer that receives the contents.
- * \param len  Number of bytes to read.
- *
- * \return Always 0.
- */
-int At45dbParamRead(u_int pos, void *data, u_int len)
-{
-    int rc = -1;
-    u_char *buff;
-    int csize = At45dbParamSize();
-    u_long cpage = At45dbParamPage();
-
-    /* Load the complete configuration area. */
-    if (csize > len && (buff = malloc(csize)) != NULL)
-    {
-        rc = At45dbPageRead(cpage, buff, csize);
-        /* Copy requested contents to caller's buffer. */
-        memcpy(data, buff + pos, len);
-        free(buff);
-    }
-    return (rc);
-}
-
-/*!
- * \brief Store configuration parameters in flash memory.
- *
- * \param pos   Start location within configuration sector.
- * \param data  Points to a buffer that contains the bytes to store.
- * \param len   Number of bytes to store.
- *
- * \return 0 on success or -1 in case of an error.
- */
-int At45dbParamWrite(u_int pos, CONST void *data, u_int len)
-{
-    int rc = -1;
-    u_char *buff;
-    int csize = At45dbParamSize();
-    u_long cpage = At45dbParamPage();
-
-    /* Load the complete configuration area. */
-    if (csize > len && (buff = malloc(csize)) != NULL)
-    {
-        rc = At45dbPageRead(cpage, buff, csize);
-        /* Compare old with new contents. */
-        if (memcmp(buff + pos, data, len))
-        {
-            /* New contents differs. Copy it into the sector buffer. */
-            memcpy(buff + pos, data, len);
-            /* Erase sector and write new data. */
-            rc = At45dbPageWrite(cpage, buff, csize);
-        }
-        free(buff);
-    }
-    return (rc);
-}
-
-#endif // USE_FLASH_PARAM_PAGE

+ 0 - 68
flash.h

@@ -1,68 +0,0 @@
-/* ========================================================================
- * [PROJECT]    SIR
- * [MODULE]     Flash
- * [TITLE]      Routines for Atmel AT45 serial dataflash memory chips.
- * [FILE]       flash.c
- * [VSN]        1.0
- * [CREATED]    11042007
- * [LASTCHNGD]  11042007
- * [COPYRIGHT]  Copyright (C) STREAMIT BV 2010
- * [PURPOSE]    contains all interface- and low-level routines to
- *              read/write/delete blocks in the serial DataFlash (AT45DBXX)
- * ======================================================================== */
-#ifndef _Flash_H
-#define _Flash_H
-
-
-#include <sys/types.h>
-
-/*-------------------------------------------------------------------------*/
-/* global defines                                                          */
-/*-------------------------------------------------------------------------*/
-
-/*
- *  next defines have a 1-1 relationship to the index in the 'at45_devt'
- *  array, so do not change the values
- */
-#define AT45DB011B  0
-#define AT45DB021B  1
-#define AT45DB041B  2
-#define AT45DB081B  3
-#define AT45DB0161B 4
-#define AT45DB0321B 5
-#define AT45DB0642  6
-
-/*-------------------------------------------------------------------------*/
-/* typedefs & structs                                                      */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/*  Global variables                                                       */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/* export global routines (interface)                                      */
-/*-------------------------------------------------------------------------*/
-
-extern int At45dbSendCmd(u_char op, u_long parm, int len, CONST void *tdata, void *rdata, int datalen);
-extern u_char At45dbGetStatus(void);
-extern int At45dbWaitReady(u_long tmo, int poll);
-extern int At45dbInit(void);
-extern int At45dbPageErase(u_int off);
-extern int At45dbChipErase(void);
-extern int At45dbPageRead(u_long pgn, void *data, u_int len);
-extern int At45dbPageWrite(u_long pgn, CONST void *data, u_int len);
-
-#ifdef USE_FLASH_PARAM_PAGE
-extern int At45dbParamRead(u_int pos, void *data, u_int len);
-extern int At45dbParamWrite(u_int pos, CONST void *data, u_int len);
-#endif // USE_FLASH_PARAM_PAGE
-
-#endif /* _Flash_H */
-/*  ÍÍÍÍ  End Of File  ÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-
-
-
-
-
-

+ 0 - 287
httpstream.c

@@ -1,287 +0,0 @@
-//
-// Created by janco on 10-3-16.
-//
-#include <stdio.h>
-#include <string.h>
-
-#include <sys/thread.h>
-#include <sys/timer.h>
-#include <sys/version.h>
-#include <dev/irqreg.h>
-
-#include "vs10xx.h"
-#include <sys/socket.h>
-#include <netinet/tcp.h>
-
-#include <sys/confnet.h>
-
-#include <arpa/inet.h>
-#include <net/route.h>
-
-#include <dev/board.h>
-#include <pro/httpd.h>
-#include <pro/dhcp.h>
-#include <pro/asp.h>
-#include <pro/discover.h>
-#include <dev/nicrtl.h>
-
-#include "ntp.h"
-#include "httpstream.h"
-
-#define MAX_HEADERLINE 512
-
-bool isStreaming;
-
-TCPSOCKET *sock;
-u_short mss = 1460;
-u_long rx_to = 3000;
-u_short tcpbufsiz = 8760;
-FILE *stream;
-u_long metaint;
-
-THREAD(Stream, args)
-{
-    if(stream) {
-        PlayMp3Stream(stream, metaint);
-    }
-    stopStream();
-    NutThreadExit();
-}
-
-void playStream(char *ipaddr, u_short port, char *radiourl){
-    if(isStreaming != true){
-        isStreaming = true;
-        ConnectStation(sock, inet_addr(ipaddr), port, radiourl, &metaint);
-        VsPlayerKick();
-        NutThreadCreate("Stream", Stream, NULL, 1024);
-    }
-}
-
-void stopStream(){
-    isStreaming = false;
-    fclose(stream);
-    NutTcpCloseSocket(sock);
-    VsPlayerStop();
-}
-
-bool HttpIsStreaming(){
-    return isStreaming;
-}
-
-void ConnectStation(TCPSOCKET *sock, u_long ip, u_short port, char *radiourl, u_long *metaint){
-    int rc;
-    u_char *line;
-    u_char *cp;
-
-    /*
-     * Connect the TCP server.
-     */
-    if ((sock = NutTcpCreateSocket()) == 0)
-        printf("Probleem bij het creereen van tcp socket");
-    if (NutTcpSetSockOpt(sock, TCP_MAXSEG, &mss, sizeof(mss)))
-        printf("Probleem bij het creereen van tcp socket");
-    if (NutTcpSetSockOpt(sock, SO_RCVTIMEO, &rx_to, sizeof(rx_to)))
-        printf("Probleem bij het creereen van tcp socket");
-    if (NutTcpSetSockOpt(sock, SO_RCVBUF, &tcpbufsiz, sizeof(tcpbufsiz)))
-        printf("Probleem bij het creereen van tcp socket");
-
-    printf("Connecting %s:%u...", inet_ntoa(ip), port);
-    if ((rc = NutTcpConnect(sock, ip, port))) {
-        printf("Error: Connect failed with %d\n", ip);
-        return 0;
-    }
-    puts("OK");
-
-    if ((stream = _fdopen((int) sock, "r+b")) == 0) {
-        printf("Error: Can't create stream");
-        return 0;
-    }
-
-    /*
-     * Send the HTTP request.
-     */
-    printf("GET %s HTTP/1.0\n\n", radiourl);
-    fprintf(stream, "GET %s HTTP/1.0\r\n", radiourl);
-    fprintf(stream, "Host: %s\r\n", inet_ntoa(ip));
-    fprintf(stream, "User-Agent: Ethernut\r\n");
-    fprintf(stream, "Accept: */*\r\n");
-    fprintf(stream, "Icy-MetaData: 1\r\n");
-    fprintf(stream, "Connection: close\r\n");
-    fputs("\r\n", stream);
-    fflush(stream);
-
-    /*
-     * Receive the HTTP header.
-     */
-    line = malloc(MAX_HEADERLINE);
-    while(fgets(line, MAX_HEADERLINE, stream)) {
-
-        /*
-         * Chop off the carriage return at the end of the line. If none
-         * was found, then this line was probably too large for our buffer.
-         */
-        cp = strchr(line, '\r');
-        if(cp == 0) {
-            printf("Warning: Input buffer overflow");
-            continue;
-        }
-        *cp = 0;
-
-        /*
-         * The header is terminated by an empty line.
-         */
-        if(*line == 0) {
-            break;
-        }
-        if(strncmp(line, "icy-metaint:", 12) == 0) {
-            *metaint = atol(line + 12);
-        }
-        printf("%s\n", line);
-    }
-    putchar('\n');
-
-    free(line);
-}
-
-int ProcessMetaData(FILE *stream)
-{
-    u_char blks = 0;
-    u_short cnt;
-    int got;
-    int rc = 0;
-    u_char *mbuf;
-
-    /*
-     * Wait for the lenght byte.
-     */
-    got = fread(&blks, 1, 1, stream);
-    if(got != 1) {
-        return -1;
-    }
-    if (blks) {
-        if (blks > 32) {
-            printf("Error: Metadata too large, %u blocks\n", blks);
-            return -1;
-        }
-
-        cnt = blks * 16;
-        if ((mbuf = malloc(cnt + 1)) == 0) {
-            return -1;
-        }
-
-        /*
-         * Receive the metadata block.
-         */
-        for (;;) {
-            if ((got = fread(mbuf + rc, 1, cnt, stream)) <= 0) {
-                return -1;
-            }
-            if ((cnt -= got) == 0) {
-                break;
-            }
-            rc += got;
-            mbuf[rc] = 0;
-        }
-
-        printf("\nMeta='%s'\n", mbuf);
-        free(mbuf);
-    }
-    return 0;
-}
-
-
-void PlayMp3Stream(FILE *stream, u_long metaint)
-{
-    size_t rbytes;
-    u_char *mp3buf;
-    u_char ief;
-    int got = 0;
-    u_long last;
-    u_long mp3left = metaint;
-
-    /*
-     * Initialize the MP3 buffer. The NutSegBuf routines provide a global
-     * system buffer, which works with banked and non-banked systems.
-     */
-    if (NutSegBufInit(8192) == 0) {
-        puts("Error: MP3 buffer init failed");
-        return;
-    }
-
-    /*
-     * Initialize the MP3 decoder hardware.
-     */
-    if (VsPlayerReset(0)) {
-        puts("Error: MP3 hardware init failed");
-        return;
-    }
-
-    /*
-     * Reset the MP3 buffer.
-     */
-    ief = VsPlayerInterrupts(0);
-    NutSegBufReset();
-    VsPlayerInterrupts(ief);
-    last = NutGetSeconds();
-
-    while (isStreaming == true) {
-        /*
-         * Query number of byte available in MP3 buffer.
-         */
-        ief = VsPlayerInterrupts(0);
-        mp3buf = NutSegBufWriteRequest(&rbytes);
-        VsPlayerInterrupts(ief);
-
-        /*
-         * If the player is not running, kick it.
-         */
-        if (VsGetStatus() != VS_STATUS_RUNNING) {
-            puts("Not running");
-            if(rbytes < 1024 || NutGetSeconds() - last > 4UL) {
-                last = NutGetSeconds();
-                puts("Kick player");
-                VsPlayerKick();
-            }
-        }
-        /*
-         * Do not read pass metadata.
-         */
-        if (metaint && rbytes > mp3left) {
-            rbytes = mp3left;
-        }
-
-        /*
-         * Read data directly into the MP3 buffer.
-         */
-        while (rbytes && (isStreaming == true)) {
-            if ((got = fread(mp3buf, 1, rbytes, stream)) > 0) {
-                ief = VsPlayerInterrupts(0);
-                mp3buf = NutSegBufWriteCommit(got);
-                VsPlayerInterrupts(ief);
-
-                if (metaint) {
-                    mp3left -= got;
-                    if (mp3left == 0) {
-                        ProcessMetaData(stream);
-                        mp3left = metaint;
-                    }
-                }
-
-                if(got < rbytes && got < 512) {
-                    printf("%lu buffered\n", NutSegBufUsed());
-                    NutSleep(250);
-                }
-                else {
-                    NutThreadYield();
-                }
-            } else {
-                break;
-            }
-            rbytes -= got;
-        }
-
-        if(got <= 0) {
-            break;
-        }
-    }
-}

+ 0 - 15
httpstream.h

@@ -1,15 +0,0 @@
-//
-// Created by janco on 25-2-16.
-//
-
-#ifndef _Httpstream_H
-#define _Httpstream_H
-
-#include "ntp.h"
-
-extern bool HttpIsStreaming();
-extern void playStream(char *ipaddr, u_short port, char *radiourl);
-extern void stopStream();
-
-
-#endif /* _Httpstream_H */

+ 5 - 12
jsmn.c

@@ -1,6 +1,7 @@
 #include "jsmn.h"
 #include <assert.h>
-
+#include <stdio.h>
+#include <string.h>
 /**
  * Allocates a fresh unused token from the token pull.
  */
@@ -330,14 +331,6 @@ int getIntegerToken(const char *json, jsmntok_t *tok){
 	return atoi(s);
 }
 
-/**
- * Get the value of the token in a char[] format.
- */
-void getStringToken(const char *json, jsmntok_t *tok, char *res, char maxlength){
-	if((tok->end - tok->start) < maxlength - 1){
-		sprintf(res, "%.*s", tok->end - tok->start, json + tok->start);
-	}else{
-		printf("ERROR: String to large! output string length: %d - Input string length: %d - String: %.*s \n", maxlength - 1, (tok->end - tok->start), tok->end - tok->start, json + tok->start);
-		res[0] = '\0';
-	};
-}
+void getStringToken(const char *json, jsmntok_t *tok, char *res){
+	sprintf(res, "%.*s", tok->end - tok->start, json + tok->start);
+}

+ 0 - 13
keyboard.c

@@ -192,19 +192,6 @@ static u_char KbRemapKey(u_short LongKey)
     }
 }
 
-/* ����������������������������������������������������������������������� */
-/*!
- * \brief Return the repeating property for this key
- *
- * \return 'TRUE' in case the key was repeating, 'FALSE' if not
- *
- */
-/* ����������������������������������������������������������������������� */
-static u_char KbKeyIsRepeating(u_short Key)
-{
-    return(KeyRepeatArray[KbRemapKey(Key)]==KEY_REPEAT);
-}
-
 /* ����������������������������������������������������������������������� */
 /*!
  * \brief set the property of this key to repeating or not-repeating

+ 1 - 1
keyboard.h

@@ -91,7 +91,7 @@
 /*-------------------------------------------------------------------------*/
 void    KbInit(void);
 void  KbScan(void);
-int 	CheckKey();
+int 	CheckKey(void);
 int     KbWaitForKeyEvent(u_long);
 u_char  KbGetKey(void);
 void    KbSetKeyRepeating(u_char, u_char);

+ 28 - 52
main.c

@@ -20,35 +20,34 @@
 /*--------------------------------------------------------------------------*/
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include <sys/thread.h>
 #include <sys/timer.h>
 #include <sys/version.h>
 #include <dev/irqreg.h>
 
-#include "displayHandler.h"
-#include "system.h"
-#include "portio.h"
+// Note: Please keep the includes in alphabetical order!    - Jordy
+#include "alarm.h"
+#include "contentparser.h"
 #include "display.h"
-#include "remcon.h"
+#include "displayHandler.h"
 #include "keyboard.h"
 #include "led.h"
 #include "log.h"
-#include "uart0driver.h"
-#include "mmc.h"
-#include "watchdog.h"
-#include "flash.h"
-#include "spidrv.h"
+#include "mp3stream.h"
 #include "network.h"
+#include "ntp.h"
+#include "portio.h"
+#include "rtc.h"
+#include "spidrv.h"
+#include "system.h"
 #include "typedefs.h"
+#include "uart0driver.h"
+#include "vs10xx.h"
+#include "watchdog.h"
 
 
-#include <time.h>
-#include "rtc.h"
-#include "alarm.h"
-#include "ntp.h"
-#include "httpstream.h"
-#include "contentparser.h"
 
 /*-------------------------------------------------------------------------*/
 /* local routines (prototyping)                                            */
@@ -84,12 +83,7 @@ static void SysControlMainBeat(u_char);
  */
 static void SysMainBeatInterrupt(void *p)
 {
-
-    /*
-     *  scan for valid keys AND check if a MMCard is inserted or removed
-     */
     KbScan();
-    CardCheckCard();
 }
 
 /*!
@@ -186,8 +180,6 @@ bool isAlarmSyncing = false;
 bool initialized = false;
 bool running = false;
 
-u_char VS_volume = 7; //[0-15];
-
 /*-------------------------------------------------------------------------*/
 /* local variable definitions                                              */
 /*-------------------------------------------------------------------------*/
@@ -208,7 +200,7 @@ THREAD(StartupInit, arg)
 
 THREAD(AlarmSync, arg)
 {
-    NutThreadSetPriority(200);
+    NutThreadSetPriority(50);
 
     while(initialized == false){
         NutSleep(1000);
@@ -233,6 +225,10 @@ THREAD(AlarmSync, arg)
             httpGet(url3,TwitterParser);
 
             isAlarmSyncing = false;
+
+            //Command que (Telegram) sync
+            sprintf(url, "%s%s", "/getCommands.php?radiomac=", getMacAdress());
+            httpGet(url, parseCommandQue);
         }
         NutSleep(3000);
     }
@@ -269,8 +265,6 @@ int checkOffPressed(){
 
 int main(void)
 {
-	initialized = 0;
-    int VOL2 = 127;
     struct _tm timeCheck;
 	struct _tm start;
 	int idx = 0;
@@ -291,22 +285,17 @@ int main(void)
     Uart0DriverStart();
 	LogInit();
 
-    CardInit();
-
     X12Init();
 
     VsPlayerInit();
 
- 
-    NtpInit();
+     NtpInit();
 
     NutThreadCreate("BackgroundThread", StartupInit, NULL, 1024);
     NutThreadCreate("BackgroundThread", AlarmSync, NULL, 2500);
     //NutThreadCreate("BackgroundThread", NTPSync, NULL, 700);
     /** Quick fix for turning off the display after 10 seconds boot */
 
-    RcInit();
-
 	KbInit();
 
     SysControlMainBeat(ON);             // enable 4.4 msecs heartbeat interrupt
@@ -318,9 +307,6 @@ int main(void)
 
 	/* Enable global interrupts */
 	sei();
-
-
-
 	
 	LcdBackLight(LCD_BACKLIGHT_OFF);
 	X12RtcGetClock(&timeCheck);
@@ -352,7 +338,7 @@ int main(void)
 
 		//Check if background LED is on, and compare to timer
 		if (running == true){
-			if (timerStruct(start) >= 10 || running > 1){
+			if (timerStruct(start) >= 10){
 				running = false;
 				LcdBackLight(LCD_BACKLIGHT_OFF);
 			}
@@ -363,24 +349,16 @@ int main(void)
             NutSleep(150);
             X12RtcGetClock(&timeCheck);
 
-            if (VS_volume > 0){
-                --VS_volume;
-                VS_volume = VS_volume % 17;
-                VsSetVolume((127 - (VS_volume * 8)) % 128);
-            }
-            displayVolume(VS_volume);
+            u_char newVolume = volumeDown();
+            displayVolume((int)newVolume);
         }
         else if(KbGetKey() == KEY_UP)
         {
             NutSleep(150);
             X12RtcGetClock(&timeCheck);
 
-            if (VS_volume < 16){
-                ++VS_volume;
-                VS_volume = VS_volume % 17;
-                VsSetVolume((127 - (VS_volume * 8)) % 128);
-            }
-            displayVolume(VS_volume);
+            u_char newVolume = volumeUp();
+            displayVolume((int)newVolume);
         }
         else if(timerStruct(timeCheck) >= 5 && checkAlarms() == 1)
         {
@@ -409,12 +387,10 @@ int main(void)
                 LcdBackLight(LCD_BACKLIGHT_OFF);
             }
 
-        }
-		else if (timerStruct(timeCheck) >= 5){
-           /* displayTime(0);
-            displayDate(1);*/
+        } else if (timerStruct(timeCheck) >= 5){
+            displayTime(0);
+            displayDate(1);
 		}
-
         WatchDogRestart();
     }
     return(0);

+ 0 - 347
mmc.c

@@ -1,347 +0,0 @@
-/* ========================================================================
- * [PROJECT]    SIR100
- * [MODULE]     MMC driver
- * [TITLE]      Media Card driver
- * [FILE]       mmc.c
- * [VSN]        1.0
- * [CREATED]    02 october 2006
- * [LASTCHNGD]  20 may 2007
- * [COPYRIGHT]  Copyright (C) STREAMIT BV 2010
- * [PURPOSE]    routines and API to support MMC-application
- * ======================================================================== */
-
-#define LOG_MODULE  LOG_MMC_MODULE
-
-#include <string.h>
-#include <stdio.h>
-#include <io.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <sys/event.h>
-#include <sys/thread.h>
-#include <sys/timer.h>
-#include <sys/device.h>
-#include <sys/bankmem.h>
-#include <sys/heap.h>
-
-//#pragma text:appcode
-
-#include "system.h"
-#include "mmc.h"
-#include "portio.h"
-#include "vs10xx.h"
-#include "display.h"
-#include "log.h"
-#include "fat.h"
-#include "mmcdrv.h"
-#include "led.h"
-#include "keyboard.h"
-
-#ifdef DEBUG
-//#define MMC__DEBUG
-#endif /* #ifdef DEBUG */
-/*-------------------------------------------------------------------------*/
-/* local defines                                                           */
-/*-------------------------------------------------------------------------*/
-
-#define CARD_PRESENT_COUNTER_OK         30
-#define CARD_NOT_PRESENT_COUNTER_OK     20
-
-
-/*--------------------------------------------------------------------------*/
-/*  Type declarations                                                       */
-/*--------------------------------------------------------------------------*/
-/*!\brief Statemachine for card-detection */
-typedef enum T_CARD_STATE
-{
-    CARD_IDLE,                      /* nothing to do */
-    CARD_PRESENT,                   /* card seen at least one time */
-    CARD_VALID,                     /* card seen at least <valid> times */
-    CARD_NOT_PRESENT                /* card not seen at least (valid> times */
-}TCardState;
-
-
-/*-------------------------------------------------------------------------*/
-/* local variable definitions                                              */
-/*-------------------------------------------------------------------------*/
-static u_char CardPresentFlag;
-static u_char ValidateCounter;
-
-/*!\brief state-variable for Card-statemachine */
-static TCardState CardState;
-
-/*!\brief Status of this module */
-static TError g_tStatus;
-
-/*-------------------------------------------------------------------------*/
-/* local routines (prototyping)                                            */
-/*-------------------------------------------------------------------------*/
-
-
-
-/*!
- * \addtogroup Card
- */
-
-/*@{*/
-
-/*-------------------------------------------------------------------------*/
-/*                         start of code                                   */
-/*-------------------------------------------------------------------------*/
-
-/*!
- * \brief check if MM-Card is inserted or removed.
- *
- * \Note: this routine is called from an ISR !
- *
- */
-u_char CardCheckCard(void)
-{
-    u_char RetValue=CARD_NO_CHANGE;
-
-    switch (CardState)
-    {
-        case CARD_IDLE:
-            {
-                if (bit_is_clear(MMC_IN_READ, MMC_CDETECT))
-                {
-                    ValidateCounter=1;
-                    CardState = CARD_PRESENT;
-                }
-            }
-            break;
-        case CARD_PRESENT:
-            {
-                if (bit_is_clear(MMC_IN_READ, MMC_CDETECT))
-                {
-                    if (++ValidateCounter==CARD_PRESENT_COUNTER_OK)
-                    {
-                        CardPresentFlag=CARD_IS_PRESENT;
-                        CardState=CARD_VALID;
-                        RetValue=CARD_IS_PRESENT;
-                    }
-                }
-                else
-                {
-                    CardState=CARD_IDLE;                  // false alarm,start over again
-                }
-            }
-            break;
-        case CARD_VALID:
-            {
-                if (bit_is_set(MMC_IN_READ, MMC_CDETECT))
-                {
-                    ValidateCounter=1;
-                    CardState=CARD_NOT_PRESENT;         // Card removed
-                }
-            }
-            break;
-        case CARD_NOT_PRESENT:
-            {
-                if (++ValidateCounter==CARD_NOT_PRESENT_COUNTER_OK)
-                {
-                    CardPresentFlag=CARD_IS_NOT_PRESENT;
-                    CardState=CARD_IDLE;
-                    RetValue=CARD_IS_NOT_PRESENT;
-                }
-            }
-            break;
-    }
-    return(RetValue);
-}
-
-/*!
- * \brief return status of "Card is Present"
- *
- */
-u_char CardCheckPresent()
-{
-    return(CardPresentFlag);
-}
-
-/*!
- * \brief initialise the card by reading card contents (.pls files)
- *
- * We initialse the card by registering the card and the filesystem
- * that is on the card.
- *
- * Then we start checking if a number of playlists are
- * present on the card. The names of these playlists are hardcoded
- * (1.pls, 2.pls, to 20.pls). We 'search' the card for these list
- * of playlists by trying to open them. If succesfull, we read the
- * number of songs present (int) in that list
- * Finally we update some administration (global) variables
- *
- */
-int CardInitCard()
-{
-    int iResult=-1;
-    int fid;        // current file descriptor
-    char szFileName[10];
-    //u_char i;
-	u_char ief;
-
-    /*
-     * Register our device for the file system (if not done already.....)
-     */
-    if (NutDeviceLookup(devFAT.dev_name) == 0)
-    {
-        ief = VsPlayerInterrupts(0);
-        if ((iResult=NutRegisterDevice(&devFAT, FAT_MODE_MMC, 0)) == 0)
-        {
-            iResult=NutRegisterDevice(&devFATMMC0, FAT_MODE_MMC, 0);
-        }
-        VsPlayerInterrupts(ief);
-    }
-    else
-    {
-        NUTDEVICE * dev;
-
-        /*
-         *  we must call 'FatInit' here to initialise and mount the filesystem (again)
-         */
-
-        FATRelease();
-        ief = VsPlayerInterrupts(0);
-        dev=&devFAT;
-        if (dev->dev_init == 0 || (*dev->dev_init)(dev) == 0)
-        {
-            dev=&devFATMMC0;
-            if (dev->dev_init == 0 || (*dev->dev_init)(dev) == 0)
-            {
-                iResult=0;
-            }
-        }
-        VsPlayerInterrupts(ief);
-    }
-
-    if (iResult==0)
-    {
-        LogMsg_P(LOG_INFO, PSTR("Card mounted"));
-        /*
-         *  try to open the playlists. If an error is returned, we assume the
-         *  playlist does not exist and we do not check any further lists
-         */
-
-		 /* Kroeske: onderstaande code ter illustratie om file op card te openen */
-		 
- //       for (i=1; i<SETTINGS_NROF_PLAYLISTST; ++i)
- //       {
-            // compose name to open
-            //sprintf_P(szFileName, PSTR("FM0:%d.pls"), i);
-            if ((fid = _open(szFileName, _O_RDONLY)) != -1)
-            {
-                _close(fid);
-            }
-            else
-            {
-
-                //g_NrofPlayLists=i-1;
-                //LogMsg_P(LOG_INFO, PSTR("Found %d Playlists on the Card"), i-1);
- //               break;
-            }
-//        }
-    }
-    else
-    {
-        LogMsg_P(LOG_ERR, PSTR("Error initialising File system and Card-driver"));
-    }
-
-    return(iResult);
-}
-
-/*!
- * \brief The CardPresent thread.
- *
- * execute code when card is inserted or redrawn
- *
- * \param   -
- *
- * \return  -
- */
-THREAD(CardPresent, pArg)
-{
-    static u_char OldCardStatus;
-
-    OldCardStatus=CardPresentFlag;
-
-    for (;;)
-    {
-        if ((CardPresentFlag==CARD_IS_PRESENT) && (OldCardStatus==CARD_IS_NOT_PRESENT))
-        {
-            LogMsg_P(LOG_INFO, PSTR("Card inserted"));
-            if (CardInitCard()==0)
-            {
-                KbInjectKey(KEY_MMC_IN);
-            }
-            OldCardStatus=CardPresentFlag;
-        }
-        else if ((CardPresentFlag==CARD_IS_NOT_PRESENT) && (OldCardStatus==CARD_IS_PRESENT))
-        {
-            LogMsg_P(LOG_INFO, PSTR("Card removed"));
-            CardClose();
-            OldCardStatus=CardPresentFlag;
-        }
-        else
-        {
-            NutSleep(500);
-        }
-    }
-}
-
-
-/*!
- * \brief return global variable that indicates the status of this module
- *
- */
-TError CardStatus(void)
-{
-    return(g_tStatus);
-}
-
-/*!
- * \brief Stop playing.
- *
- * \param   -
- *
- * \return  -
- */
-void CardClose(void)
-{
-
-}
-
-
-/*!
- * \brief initialise this module
- *
- */
-void CardInit()
-{
-    char ThreadName[10];
-
-    CardState=CARD_IDLE;
-    CardPresentFlag=CARD_IS_NOT_PRESENT;
-
-    /*
-     * Create a CardPresent thread
-     */
-    strcpy_P(ThreadName, PSTR("CardPres"));
-
-    if (GetThreadByName((char *)ThreadName) == NULL)
-    {
-        if (NutThreadCreate((char *)ThreadName, CardPresent, 0, 768) == 0)
-        {
-            LogMsg_P(LOG_EMERG, PSTR("Thread failed"));
-        }
-    }
-
-}
-
-/* ---------- end of module ------------------------------------------------ */
-
-/*@}*/
-
-

+ 0 - 41
mmc.h

@@ -1,41 +0,0 @@
-/* ========================================================================
- * [PROJECT]    SIR100
- * [MODULE]     MMC driver
- * [TITLE]      Media Card driver include file
- * [FILE]       mmc.h
- * [VSN]        1.0
- * [CREATED]    02 october 2006
- * [LASTCHNGD]  02 october 2006
- * [COPYRIGHT]  Copyright (C) STREAMIT BV 2010
- * [PURPOSE]    routines and API to support MMC-application
- * ======================================================================== */
-
-/*-------------------------------------------------------------------------*/
-/* global defines                                                          */
-/*-------------------------------------------------------------------------*/
-#define CARD_IS_NOT_PRESENT           0
-#define CARD_IS_PRESENT               1
-#define CARD_NO_CHANGE                2       // no change since last event occured
-
-/*-------------------------------------------------------------------------*/
-/* export global routines (interface)                                      */
-/*-------------------------------------------------------------------------*/
-extern void CardInit(void);
-extern int CardInitCard(void);
-extern TError CardOpen(u_char);
-extern void CardClose(void);
-extern TError CardStatus(void);
-extern unsigned int CardGetCurrentSong(void);
-extern char* CardGetCurrentSongName(unsigned int *punLength);
-
-extern u_char CardCheckCard(void);          // check by examining physical PIN
-extern u_char CardCheckPresent(void);       // check by examining administration
-extern TError CardPlayMp3File(char *path);
-extern void CardStopMp3File(void);
-extern void CardUpdateTicks(void);
-extern u_char CardGetNumberOfPlayLists(void);
-
-       //
-/*  ÍÍÍÍ  End Of File  ÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-
-

+ 0 - 758
mmcdrv.c

@@ -1,758 +0,0 @@
-/****************************************************************************
-*  This file is part of the MMC device driver.
-*
-*  Copyright (c) 2004 by Michael Fischer. All rights reserved.
-*
-*  Thanks to Sylvain Bissonnette for some of his low level functions.
-*  Take a look at www.microsyl.com (Led Sign with MMC MemoryCard)
-*
-*  Redistribution and use in source and binary forms, with or without
-*  modification, are permitted provided that the following conditions
-*  are met:
-*
-*  1. Redistributions of source code must retain the above copyright
-*     notice, this list of conditions and the following disclaimer.
-*  2. Redistributions in binary form must reproduce the above copyright
-*     notice, this list of conditions and the following disclaimer in the
-*     documentation and/or other materials provided with the distribution.
-*  3. Neither the name of the author nor the names of its contributors may
-*     be used to endorse or promote products derived from this software
-*     without specific prior written permission.
-*
-*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-*  SUCH DAMAGE.
-*
-****************************************************************************
-*  History:
-*
-*  10.10.04  mifi   First Version
-****************************************************************************/
-#define __MMCDRV_C__
-
-#define LOG_MODULE  LOG_MMCDRV_MODULE
-
-#include <stdio.h>
-#include <string.h>
-
-#include <sys/timer.h>
-#include <sys/thread.h>
-#include <sys/event.h>
-#include <sys/heap.h>
-
-#include "typedefs.h"
-#include "portio.h"
-#include "mmcdrv.h"
-#include "vs10xx.h"
-#include "led.h"
-#include "log.h"
-#include "spidrv.h"
-
-/*==========================================================*/
-/*  DEFINE: All Structures and Common Constants             */
-/*==========================================================*/
-#define MMC_MAX_SUPPORTED_DEVICE    1
-
-/*
- * Drive Flags
- */
-#define MMC_SUPPORT_LBA             0x0001
-#define MMC_SUPPORT_LBA48           0x0002
-
-#define MMC_READ_ONLY               0x4000
-#define MMC_READY                   0x8000
-
-#define Delay_1ms(_x) NutDelay(_x)
-
-#define SPIDDR        DDRB
-#define SPIPORT       PORTB
-#define SPIPIN        PINB
-
-/*
-    PragmaLab: disable PIN-defines (already defined in 'portio.h'
-#define SCLK          0x02
-#define MOSI          0x04
-#define MISO          0x08
-#define CS            0x20
-#define ENABLE        0x40
-    end PragmaLab
-*/
-
-#define MMC_RESET         0
-#define MMC_INIT          1
-#define MMC_READ_CSD    9
-#define MMC_READ_CID    10
-
-typedef struct _drive
-{
-    /*
-     * Interface values
-     */
-    WORD  wFlags;
-    BYTE  bDevice;
-
-    /*
-     * LBA value
-     */
-    DWORD dTotalSectors;
-    WORD  wSectorSize;
-} DRIVE;
-
-/*==========================================================*/
-/*  DEFINE: Definition of all local Data                    */
-/*==========================================================*/
-static HANDLE          hMMCSemaphore;
-static DRIVE           sDrive[MMC_MAX_SUPPORTED_DEVICE];
-
-static MMC_MOUNT_FUNC *pUserMountFunc;
-static MMC_MOUNT_FUNC *pUserUnMountFunc;
-
-/*==========================================================*/
-/*  DEFINE: Definition of all local Procedures              */
-/*==========================================================*/
-
-
-/************************************************************/
-/*  MMCLock                                                 */
-/************************************************************/
-static void MMCLock(void)
-{
-    NutEventWait(&hMMCSemaphore, 0);
-} /* MMCLock */
-
-/************************************************************/
-/*  MMCFree                                                 */
-/************************************************************/
-static void MMCFree(void)
-{
-    NutEventPost(&hMMCSemaphore);
-} /* MMCFree */
-
-/************************************************************/
-/*  MMCSemaInit                                             */
-/************************************************************/
-static void MMCSemaInit(void)
-{
-    NutEventPost(&hMMCSemaphore);
-} /* MMCSemaInit */
-
-
-/************************************************************
- * int MMCDataToken(void)
- *
- * - pings the card until it gets data token
- * - returns one byte of read info (data token)
- ************************************************************/
-static BYTE MMCDataToken(void)
-{
-    WORD i = 0xffff;
-    BYTE Byte = 0xff;
-
-    while ((Byte != 0xfe) && (--i))
-    {
-        Byte = SPIgetByte();
-    }
-    return(Byte);
-} /* MMCDataToken */
-
-/************************************************************
- * unsigned char MMCGet(void)
- *
- * - pings the card until it gets a non-0xff value
- * - returns one byte of read info
- ************************************************************/
-static BYTE MMCGet(void)
-{
-    WORD i = 0xffff;
-    BYTE Byte = 0xff;
-
-    while ((Byte == 0xff) && (--i))
-    {
-        Byte = SPIgetByte();
-    }
-
-    return(Byte);
-} /* MMCGet */
-
-/************************************************************
- * void MMCCommand(unsigned char command, unsigned int px, unsigned int py)
- *
- * - send one byte of 0xff, then issue command + params + (fake) crc
- * - eat up the one command of nothing after the CRC
- ************************************************************/
-static void MMCCommand(unsigned char command, unsigned int px, unsigned int py)
-{
-    SPIselect(SPI_DEV_MMC);
-
-    SPIputByte(0xff);
-    SPIputByte(command | 0x40);
-    SPIputByte((unsigned char)((px >> 8)&0x0ff)); /* high byte of param y */
-    SPIputByte((unsigned char)(px & 0x00ff));     /* low byte of param y */
-    SPIputByte((unsigned char)((py >> 8)&0x0ff)); /* high byte of param x */
-    SPIputByte((unsigned char)(py & 0x00ff));     /* low byte of param x */
-    SPIputByte(0x95);            /* correct CRC for first command in SPI          */
-                              /* after that CRC is ignored, so no problem with */
-                              /* always sending 0x95                           */
-    SPIputByte(0xff);
-} /* MMCCommand */
-
-/************************************************************/
-/* GetCSD                                                   */
-/************************************************************/
-static int GetCSD (DRIVE *pDrive)
-{
-    int   i;
-    int  nError = MMC_ERROR;
-    BYTE bData[16];
-    WORD wREAD_BL_LEN;
-    WORD wC_SIZE;
-    WORD wC_SIZE_MULT;
-    WORD wDummy;
-    DWORD dTotalSectors = 0;
-
-    MMCCommand(MMC_READ_CSD, 0, 0);
-    if (MMCDataToken() != 0xfe)
-    {
-        LogMsg_P(LOG_ERR, PSTR("error during CSD read"));
-    }
-    else
-    {
-        for (i=0; i<16; i++)
-        {
-            bData[i] = SPIgetByte();
-        }
-
-        SPIputByte(0xff);    /* checksum -> don't care about it for now */
-        SPIputByte(0xff);    /* checksum -> don't care about it for now */
-
-        SPIdeselect();
-
-        /*
-         * Get the READ_BL_LEN
-         */
-        wREAD_BL_LEN = (1 << (bData[5] & 0x0F));
-
-        /*
-         * Get the C_SIZE
-         */
-        wC_SIZE  = (bData[6] & 0x03);
-        wC_SIZE  = wC_SIZE << 10;
-
-        wDummy   = bData[7];
-        wDummy   = wDummy << 2;
-        wC_SIZE |= wDummy;
-
-        wDummy   = (bData[8] & 0xC0);
-        wDummy   = wDummy >> 6;
-        wC_SIZE |= wDummy;
-
-        /*
-         * Get the wC_SIZE_MULT
-         */
-        wC_SIZE_MULT  = (bData[9] & 0x03);
-        wC_SIZE_MULT |= wC_SIZE_MULT << 1;
-        wDummy        = (bData[10] & 0x80);
-        wDummy        = wDummy >> 7;
-        wC_SIZE_MULT |= wDummy;
-        wC_SIZE_MULT  = (1 << (wC_SIZE_MULT+2));
-
-        dTotalSectors  = wC_SIZE+1;
-        dTotalSectors *= wC_SIZE_MULT;
-
-        pDrive->dTotalSectors = dTotalSectors;
-        pDrive->wSectorSize   = wREAD_BL_LEN;
-
-        nError = MMC_OK;
-    }
-
-    return(nError);
-} /* GetCSD */
-
-#if 0
-/************************************************************/
-/* GetCID                                                   */
-/************************************************************/
-static void GetCID(void)
-{
-    int i;
-    BYTE bData[16];
-
-    MMCCommand(MMC_READ_CID, 0, 0);
-    if (MMCDataToken() != 0xfe)
-    {
-        printf("MMC: error during CID read\n");
-    }
-    else
-    {
-        printf("MMC: CID read\n");
-    }
-
-    for (i=0; i<16; i++)
-    {
-        bData[i] = SPIgetByte();
-    }
-
-    SPIputByte(0xff);    /* checksum -> don't care about it for now */
-    SPIputByte(0xff);    /* checksum -> don't care about it for now */
-
-    SPIdeselect();
-
-    printf("MMC: Product Name: %c%c%c%c%c%c\n",
-           bData[3], bData[4], bData[5],
-           bData[6], bData[7], bData[8]);
-} /* GetCID */
-#endif
-
-/************************************************************/
-/*  InitMMCCard                                             */
-/*                                                          */
-/* - flushes card receive buffer                            */
-/* - selects card                                           */
-/* - sends the reset command                                */
-/* - sends the initialization command, waits for card ready */
-/************************************************************/
-static int InitMMCCard(void)
-{
-    WORD i;
-
-    /* PragmaLab: disable initit of PINS and SPI, already done in 'SystemInitIO()'
-    SPIDDR = SCLK + MOSI + CS;
-    SPIPORT = 0x00;
-    Delay_1ms(250);
-    Delay_1ms(250);
-    SPIPORT |= CS;
-    SPCR = (1 << SPE) | (1 << MSTR);  // enable SPI as master, set clk divider
-                                      // set to max speed
-    Delay_1ms(250);
-
-
-    SPIdeselect();
-
-    // start off with 80 bits of high data with card deselected
-
-    PragmaLab: why send dummy bytes with card DEselected? This messes up the VS10XX init */
-    for (i = 0; i < 10; i++)
-    {
-        SPIputByte(0xff);
-    }
-
-    /*end PragmaLab */
-
-    /* send CMD0 - go to idle state */
-    MMCCommand(MMC_RESET, 0, 0);
-
-    if (MMCGet() != 1)
-    {
-        SPIdeselect();
-        return(MMC_ERROR);  // MMC Not detected
-    }
-
-    /* send CMD1 until we get a 0 back, indicating card is done initializing */
-    i = 0xffff;
-    while ((SPIgetByte() != 0) && (--i))
-    {
-        MMCCommand(MMC_INIT, 0, 0);
-    }
-    if (i == 0)
-    {
-        SPIdeselect();
-        return(MMC_ERROR);  // Init Fail
-    }
-
-    SPIdeselect();
-    return(MMC_OK);
-} /* InitMMCCard */
-
-/************************************************************/
-/*  ReadSectors                                             */
-/************************************************************/
-static int ReadSectors(DRIVE *pDrive, BYTE *pBuffer, DWORD dStartSector, WORD wSectorCount)
-{
-    int   nError = MMC_OK;
-    int   nSector;
-    WORD  wDataCount;
-    DWORD dReadSector;
-
-    pDrive = pDrive;
-
-    for (nSector=0; nSector<wSectorCount; nSector++)
-    {
-        dReadSector = dStartSector + nSector;
-
-        MMCCommand(17,(dReadSector>>7) & 0xffff, (dReadSector<<9) & 0xffff);
-        if (MMCDataToken() != 0xfe)
-        {
-            nError = MMC_ERROR;
-            SPIdeselect();
-            break;
-        }
-
-        for (wDataCount=0; wDataCount<512; wDataCount++)
-        { /* read the sector */
-            *pBuffer = SPIgetByte();
-            pBuffer++;
-        }
-
-        SPIputByte(0xff);    /* checksum -> don't care about it for now */
-        SPIputByte(0xff);    /* checksum -> don't care about it for now */
-        SPIdeselect();
-    }
-
-    return(nError);
-} /* ReadSectors */
-
-#if (MMC_SUPPORT_WRITE == 1)
-/************************************************************/
-/*  WriteSectors                                            */
-/************************************************************/
-static BYTE WriteSectors(DRIVE *pDrive, BYTE *pBuffer, DWORD dStartSector, WORD wSectorCount)
-{
-    int   nError = MMC_OK;
-    int   nSector;
-    WORD  wDataCount;
-    DWORD dWriteSector;
-
-    pDrive = pDrive;
-
-    for (nSector=0; nSector<wSectorCount; nSector++)
-    {
-        dWriteSector = dStartSector + nSector;
-
-        MMCCommand(24, (dWriteSector>>7)& 0xffff, (dWriteSector<<9)& 0xffff);
-        if (MMCGet() == 0xff)
-        {
-            nError = MMC_ERROR;
-            SPIdeselect();
-            break;
-        }
-
-        SPIputByte(0xfe);  // Send Start Byte
-
-        for (wDataCount=0; wDataCount<512; wDataCount++)
-        { /* read the sector */
-            SPIputByte(*pBuffer);
-            pBuffer++;
-        }
-
-        SPIputByte(0xff);  /* checksum -> don't care about it for now */
-        SPIputByte(0xff);  /* checksum -> don't care about it for now */
-        SPIputByte(0xff);  /* Read "data response byte"               */
-
-        wDataCount = 0xffff;
-        while ((SPIgetByte() == 0x00) && (--wDataCount)); /* wait for write finish */
-        if (wDataCount == 0)
-        {
-            nError = MMC_ERROR;
-            SPIdeselect();
-            break;
-        }
-
-        SPIdeselect();
-    }
-
-    return(nError);
-}
-#endif /* WriteSectors */
-
-/*==========================================================*/
-/*  DEFINE: All code exported                               */
-/*==========================================================*/
-/************************************************************/
-/*  MMCInit                                                 */
-/************************************************************/
-int MMCInit(int nMMCMode, MMC_MOUNT_FUNC *pMountFunc,
-            MMC_MOUNT_FUNC *pUnMountFunc)
-{
-    int  nError = MMC_OK;
-    BYTE bIndex;
-
-    nMMCMode         = nMMCMode;
-    pUserMountFunc   = pMountFunc;
-    pUserUnMountFunc = pUnMountFunc;
-
-    for (bIndex=0; bIndex<MMC_MAX_SUPPORTED_DEVICE; bIndex++)
-    {
-        memset((BYTE *) & sDrive[bIndex], 0x00, sizeof(DRIVE));
-
-        sDrive[bIndex].bDevice  = bIndex;
-    }
-
-    MMCSemaInit();
-
-    nError = InitMMCCard();
-    if (nError == MMC_OK)
-    {
-        sDrive[MMC_DRIVE_C].wFlags = MMC_READY;
-        //GetCID();
-    }
-
-    return(nError);
-} /* MMCInit */
-
-/************************************************************/
-/*  MMCMountAllDevices                                      */
-/************************************************************/
-int MMCMountAllDevices(int nMMCMode, BYTE *pSectorBuffer)
-{
-    int    nError = MMC_ERROR;
-    DRIVE *pDrive;
-
-    nMMCMode = nMMCMode;
-
-    pDrive = NULL;
-
-    MMCLock();
-
-    pDrive = &sDrive[MMC_DRIVE_C];
-    if (pDrive->wFlags & MMC_READY)
-    {
-        nError = GetCSD(pDrive);
-    }
-
-    MMCFree();
-
-    if (nError == MMC_OK)
-    {
-        nError = MMCReadSectors(MMC_DRIVE_C, pSectorBuffer, 0, 1);
-    }
-
-    return(nError);
-} /* MMCMountDevice */
-
-/************************************************************/
-/*  MMCGetSectorSize                                        */
-/************************************************************/
-int MMCGetSectorSize(BYTE bDevice)
-{
-    int    nSectorSize;
-    DRIVE *pDrive;
-
-    nSectorSize = 0;
-
-    MMCLock();
-
-    if (bDevice >= MMC_MAX_SUPPORTED_DEVICE)
-    {
-        nSectorSize = 0;
-    }
-    else
-    {
-        pDrive = &sDrive[bDevice];
-        nSectorSize = pDrive->wSectorSize;
-    }
-
-    MMCFree();
-
-    return(nSectorSize);
-} /* MMCGetSectorSize */
-
-/************************************************************/
-/*  MMCIsCDROMDevice                                        */
-/************************************************************/
-int MMCIsCDROMDevice(BYTE bDevice)
-{
-    return(FALSE);
-} /* MMCIsCDROMDevice */
-
-/************************************************************/
-/*  MMCIsZIPDevice                                          */
-/************************************************************/
-int MMCIsZIPDevice(BYTE bDevice)
-{
-    return(FALSE);
-} /* MMCIsZIPDevice */
-
-/************************************************************/
-/*  MMCUnMountDevice                                        */
-/************************************************************/
-int MMCUnMountDevice(BYTE bDevice)
-{
-    return(MMC_OK);
-} /* MMCUnMountDevice */
-
-/************************************************************/
-/*  MMCGetTotalSectors                                      */
-/************************************************************/
-DWORD MMCGetTotalSectors(BYTE bDevice)
-{
-    DWORD  dwTotalSectors;
-    DRIVE *pDrive;
-
-    dwTotalSectors = 0;
-
-    MMCLock();
-
-    if (bDevice >= MMC_MAX_SUPPORTED_DEVICE)
-    {
-        dwTotalSectors = 0;
-    }
-    else
-    {
-        pDrive = &sDrive[bDevice];
-        dwTotalSectors = pDrive->dTotalSectors;
-
-        //dwTotalSectors -= 64;
-    }
-
-    MMCFree();
-
-    return(dwTotalSectors);
-} /* MMCGetTotalSectors */
-
-/************************************************************/
-/*  MMCReadSectors                                          */
-/************************************************************/
-int MMCReadSectors(BYTE bDevice, void *pData, DWORD dwStartSector, WORD wSectorCount)
-{
-    int    nError;
-    WORD   wReadCount;
-    DRIVE *pDrive = 0;
-    BYTE  *pByte;
-
-    nError = MMC_OK;
-
-    MMCLock();
-
-    if (bDevice >= MMC_MAX_SUPPORTED_DEVICE)
-    {
-        nError = MMC_DRIVE_NOT_FOUND;
-    }
-    else
-    {
-        pDrive = &sDrive[bDevice];
-        if ((pDrive->wFlags & MMC_READY) == 0)
-        {
-            nError = MMC_DRIVE_NOT_FOUND;
-        }
-        else
-        {
-            if ((dwStartSector + wSectorCount) > pDrive->dTotalSectors)
-            {
-                nError = MMC_PARAM_ERROR;
-            }
-        }
-    }
-
-    if (nError == MMC_OK)
-    {
-        pByte = (BYTE *)pData;
-
-        if (wSectorCount != 1)
-        {
-            while (wSectorCount > 0)
-            {
-
-                if (wSectorCount < 256)
-                {
-                    wReadCount = wSectorCount;
-                }
-                else
-                {
-                    wReadCount = 256;
-                }
-
-                nError = ReadSectors(pDrive, pByte, dwStartSector, wReadCount);
-                if (nError != MMC_OK)
-                {
-                    break;
-                }
-
-                dwStartSector += wReadCount;
-                wSectorCount -= wReadCount;
-                pByte += (wReadCount * pDrive->wSectorSize);
-            }
-        }
-        else
-        {
-            nError = ReadSectors(pDrive, pByte, dwStartSector, 1);
-        }
-    }
-
-    MMCFree();
-
-    return(nError);
-} /* MMCReadSectors */
-
-#if (MMC_SUPPORT_WRITE == 1)
-/************************************************************/
-/*  MMCWriteSectors                                         */
-/************************************************************/
-int MMCWriteSectors(BYTE   bDevice,      void *pData,
-                    DWORD dwStartSector, WORD  wSectorCount)
-{
-    int    nError;
-    WORD   wWriteCount;
-    DRIVE *pDrive = 0;
-    BYTE  *pByte;
-
-    nError = MMC_OK;
-
-    MMCLock();
-
-    if (bDevice >= MMC_MAX_SUPPORTED_DEVICE)
-    {
-        nError = MMC_DRIVE_NOT_FOUND;
-    }
-    else
-    {
-        pDrive = &sDrive[bDevice];
-
-        if ((dwStartSector + wSectorCount) > pDrive->dTotalSectors)
-        {
-            nError = MMC_PARAM_ERROR;
-        }
-        if ((pDrive->wFlags & MMC_READY) == 0)
-        {
-            nError = MMC_DRIVE_NOT_FOUND;
-        }
-        if (pDrive->wFlags & MMC_READ_ONLY)
-        {
-            nError = MMC_NOT_SUPPORTED;
-        }
-    }
-
-    if (nError == MMC_OK)
-    {
-        pByte = (BYTE *) pData;
-        while (wSectorCount > 0)
-        {
-
-            if (wSectorCount < 256)
-            {
-                wWriteCount = wSectorCount;
-            }
-            else
-            {
-                wWriteCount = 256;
-            }
-
-            nError = WriteSectors(pDrive, pByte, dwStartSector, wWriteCount);
-            if (nError != MMC_OK)
-            {
-                break;
-            }
-
-            dwStartSector += wWriteCount;
-            wSectorCount  -= wWriteCount;
-            pByte         += (wWriteCount * MMC_SECTOR_SIZE);
-        }
-    }
-
-    MMCFree();
-
-    return(nError);
-} /* MMCWriteSectors */
-#endif
-
-
-
-

+ 0 - 100
mmcdrv.h

@@ -1,100 +0,0 @@
-/****************************************************************************
-*  This file is part of the MMC device driver.
-*
-*  Copyright (c) 2002-2004 by Michael Fischer. All rights reserved.
-*
-*  Redistribution and use in source and binary forms, with or without 
-*  modification, are permitted provided that the following conditions 
-*  are met:
-*  
-*  1. Redistributions of source code must retain the above copyright 
-*     notice, this list of conditions and the following disclaimer.
-*  2. Redistributions in binary form must reproduce the above copyright
-*     notice, this list of conditions and the following disclaimer in the 
-*     documentation and/or other materials provided with the distribution.
-*  3. Neither the name of the author nor the names of its contributors may 
-*     be used to endorse or promote products derived from this software 
-*     without specific prior written permission.
-*
-*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
-*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
-*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
-*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
-*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
-*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
-*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
-*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
-*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
-*  SUCH DAMAGE.
-*
-****************************************************************************
-*  History:
-*
-*  10.10.04  mifi   First Version
-****************************************************************************/
-#ifndef __MMCDRV_H__
-#define __MMCDRV_H__
-
-#include "typedefs.h"
-
-/*-------------------------------------------------------------------------*/
-/* global defines                                                          */
-/*-------------------------------------------------------------------------*/
-//
-// Here we can switch on/off some
-// feature of the software
-//
-#define MMC_SUPPORT_WRITE               1
-
-#define MMC_OK                          0x00
-#define MMC_ERROR                       0x01
-#define MMC_DRIVE_NOT_FOUND             0x02
-#define MMC_PARAM_ERROR                 0x03
-#define MMC_BUSY                        0x04
-#define MMC_NOT_SUPPORTED               0x08
-
-#define MMC_DRIVE_C                     0
-
-//
-// Sector size
-//
-#define MMC_SECTOR_SIZE                 512
-#define MAX_SECTOR_SIZE                 MMC_SECTOR_SIZE
-
-/*-------------------------------------------------------------------------*/
-/* global types                                                            */
-/*-------------------------------------------------------------------------*/
-typedef void MMC_MOUNT_FUNC(int nDevice);
-
-/*-------------------------------------------------------------------------*/
-/* global macros                                                           */
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/* Prototypes                                                              */
-/*-------------------------------------------------------------------------*/
-int MMCInit(int nMMCMode, MMC_MOUNT_FUNC * pMountFunc, MMC_MOUNT_FUNC * pUnMountFunc);
-
-int MMCMountAllDevices(int nMMCMode, BYTE *pSectorBuffer);
-
-int MMCGetSectorSize(BYTE bDevice);
-
-int MMCIsCDROMDevice(BYTE bDevice);
-
-int MMCIsZIPDevice(BYTE bDevice);
-
-int MMCUnMountDevice(BYTE bDevice);
-
-DWORD MMCGetTotalSectors(BYTE bDevice);
-
-int MMCReadSectors(BYTE bDevice, void *pData, DWORD dwStartSector, WORD wSectorCount);
-
-#if (MMC_SUPPORT_WRITE == 1)
-
-int MMCWriteSectors(BYTE bDevice, void *pData, DWORD dwStartSector, WORD wSectorCount);
-
-#endif
-
-#endif /* !__MMCDRV_H__ */

+ 332 - 0
mp3stream.c

@@ -0,0 +1,332 @@
+//
+// Created by Jordy Sipkema on 28/03/16.
+//
+
+#include "mp3stream.h"
+
+#include <arpa/inet.h>
+#include <sys/bankmem.h>
+#include <sys/heap.h>
+#include <sys/thread.h>
+#include <sys/timer.h>
+
+#include "vs10xx.h"
+
+#define OK              1
+#define NOK             0
+#define DEFAULT_VOLUME  7
+#define MSIZE           1024
+#define NUTSEGBUFFER    4096
+
+typedef struct _StreamArgs {
+    FILE *stream;
+} TStreamArgs;
+
+// Prototypes - Functions for internal use only! (They wont be visible outside this file!)
+THREAD(Mp3Player, args);
+void stopMp3PlayerThread(void);
+int ProcessStreamMetaData(FILE *stream);
+
+// Variables
+static bool stream_isplaying = false;
+static bool stream_connected = false;
+static bool stream_stopped = false;
+
+static u_char VS_volume = DEFAULT_VOLUME; //[0-16]; (Default volume = 7/16
+static u_long metaInt = 0;
+
+FILE *stream;
+TCPSOCKET *socket;
+
+bool connectToStream(char *ipaddr, u_short port, char *radioUrl)
+{
+    if (stream_connected == true)
+        return false;
+
+    stream_connected = false;
+    bool result = true;
+    char* data;
+
+    socket = NutTcpCreateSocket();
+    printf("Connecting to %s:%d%s\r\n", ipaddr, port, radioUrl);
+    if (NutTcpConnect(socket, inet_addr(ipaddr), port))
+    {
+        // An error has occurred.
+        printf("ConnectToStream: Error creating tcp socket.\n");
+        NutSleep(5000);
+        result = false;
+        return result;
+    }
+
+    stream = _fdopen((int)socket, "r+b");
+
+    fprintf(stream, "GET %s HTTP/1.0\r\n", radioUrl);
+    fprintf(stream, "Host: %s\r\n", ipaddr);
+    fprintf(stream, "User-Agent: Ethernut\r\n");
+    fprintf(stream, "Accept: */*\r\n");
+    fprintf(stream, "Icy-MetaData: 1\r\n");
+    fprintf(stream, "Connection: close\r\n\r\n");
+    fflush(stream);
+
+    // Server will respond with a HTTP-header. Fetch it to the buffer.
+    stream_connected = true;
+    stream_stopped = false;
+
+    data = (char *)malloc(MSIZE * sizeof(char));
+
+    while (fgets(data, MSIZE, stream))
+    {
+        /*
+         * Chop off the carriage return at the end of the line. If none
+         * was found, then this line was probably too large for our buffer.
+         */
+        char *cp = strchr(data, '\r');
+        if (cp == 0) continue;             // Input buffer overflow.
+
+        *cp = 0;
+
+        /*
+         * The header is terminated by an empty line.
+         */
+        if (*data == 0) break;
+
+        if (strncmp(data, "icy-metaint:", 12) == 0)
+            metaInt = atol(data + 12);
+        printf("%s\n", data);
+    }
+
+    free(data);
+
+    return result;
+}
+
+bool play()
+{
+    if (stream_connected == false)
+        return false;
+
+    if (stream_isplaying == true)
+        return false;
+
+    // else:
+    stream_isplaying == true;
+
+    TStreamArgs *streamArgs = &(TStreamArgs){
+            .stream = stream,
+            //.metaint = metaInt
+    };
+
+    NutThreadCreate("Mp3Player", Mp3Player, streamArgs, 512);
+    printf("Mp3Player thread created. Device should start playing the stream.\n");
+
+    return true;
+}
+
+u_char volumeUp(void)
+{
+    if (VS_volume >= 16)
+        return VS_volume;
+
+    //else:
+    ++VS_volume;
+    VS_volume = VS_volume % 17;
+    setVolume();
+
+    return VS_volume;
+}
+
+u_char volumeDown(void)
+{
+    if (VS_volume <= 0)
+        return VS_volume;
+
+    //else:
+    --VS_volume;
+    VS_volume = VS_volume % 17;
+    setVolume();
+
+    return VS_volume;
+}
+
+void setVolume(void){
+    u_char volumeToSet = (128 - (VS_volume * 8)) % 129;
+    VsSetVolume(volumeToSet, volumeToSet);
+    printf("- VS_volume level: %d/16\n", VS_volume);
+}
+
+void killPlayerThread(void)
+{
+    printf("Signal to stop the stream sent.\n");
+    stream_stopped = true;
+}
+
+THREAD(Mp3Player, args)
+//void function(void* args) //TODO: REMOVE THIS, THIS IS ONLY TO TRICK CLION!
+{
+    // Unpack the args passed to the thread initializer.
+    TStreamArgs *streamArgs = (TStreamArgs *)args;
+    FILE *stream = streamArgs->stream;
+
+    int result = NOK;
+
+    size_t rbytes = 0;
+    char *mp3buf;
+    u_char ief;
+    int got = 0;
+    u_long mp3left = metaInt;
+
+    // Init MP3-buffer. NutSegBuf is a global system buffer.
+    if (0 != NutSegBufInit(NUTSEGBUFFER)){
+        // Reset the global buffer.
+        ief = VsPlayerInterrupts(0);
+        NutSegBufReset();
+        VsPlayerInterrupts(ief);
+
+        result = OK;
+    }
+
+    // Init the VS1003b hardware.
+    if (result == OK){
+        if (-1 == VsPlayerInit()) {
+            if (-1 == VsPlayerReset(0)){
+                result = NOK;
+            }
+        }
+    }
+
+    // Set the volume to the correct level
+    setVolume();
+
+    for(;;)
+    {
+        /*
+         * Query the number of bytes available in the MP3 buffer.
+         */
+        ief = VsPlayerInterrupts(0);
+        mp3buf = NutSegBufWriteRequest(&rbytes);
+        VsPlayerInterrupts(ief);
+
+        /*
+         * If the player is not running, kick it.
+         * This should only occur once.
+         */
+        if (VsGetStatus() != VS_STATUS_RUNNING) {
+            puts("Player not running.");
+            if (rbytes < 1024){
+                puts("Kick player in 3 2 1..:");
+                VsPlayerKick();
+            }
+        }
+
+
+
+        /*
+         * Do not read pass metadata.
+         * This causes ugly hiccups.
+         */
+        if (metaInt && rbytes > mp3left){
+            rbytes = mp3left;
+        }
+
+        /*
+         * Read directly into the MP3 buffer.
+         */
+        while (rbytes) {
+            if (stream_stopped == true) {
+                stopMp3PlayerThread();
+            }
+
+            if ((got = fread(mp3buf, 1, rbytes, stream)) > 0) {
+                ief = VsPlayerInterrupts(0);
+                mp3buf = NutSegBufWriteCommit(got);
+                VsPlayerInterrupts(ief);
+
+                if (metaInt) {
+                    mp3left -= got;
+                    if (mp3left == 0) {
+                        ProcessStreamMetaData(stream);
+                        mp3left = metaInt;
+                    }
+                }
+
+                if (got < rbytes && got < 512) {
+                    printf("%lu buffered\n", NutSegBufUsed());
+                    NutSleep(250);
+                }
+                else {
+                    NutThreadYield();
+                }
+            } else {
+                break;
+            }
+            rbytes -= got;
+        }
+
+        if (got <= 0) break;
+
+
+    } // end for(;;)
+
+    while (NutSegBufUsed() > 10){
+        NutSleep(250);
+    }
+
+    stopMp3PlayerThread();
+}
+
+void stopMp3PlayerThread(void)
+{
+    printf("Signal to stop the stream recieved\n.");
+    stream_connected = false;
+    stream_isplaying = false;
+    VsPlayerStop();
+    NutTcpCloseSocket(socket);
+    NutThreadExit();
+}
+
+int ProcessStreamMetaData(FILE *stream)
+{
+    u_char blks = 0;
+    u_short cnt;
+    int got;
+    int rc = 0;
+    u_char *mbuf;
+
+    /*
+     * Wait for the lenght byte.
+     */
+    got = fread(&blks, 1, 1, stream);
+    if(got != 1) {
+        return -1;
+    }
+    if (blks) {
+        if (blks > 32) {
+            printf("Error: Metadata too large, %u blocks\n", blks);
+            return -1;
+        }
+
+        cnt = blks * 16;
+        if ((mbuf = malloc(cnt + 1)) == 0) {
+            printf("Can't malloc memory for metadata parsing\n");
+            return -1;
+        }
+
+        /*
+         * Receive the metadata block.
+         */
+        for (;;) {
+            if ((got = fread(mbuf + rc, 1, cnt, stream)) <= 0) {
+                return -1;
+            }
+            if ((cnt -= got) == 0) {
+                break;
+            }
+            rc += got;
+            mbuf[rc] = 0;
+        }
+
+        printf("\nMeta='%s'\n", mbuf);
+        free(mbuf);
+    }
+    return 0;
+}

+ 25 - 0
mp3stream.h

@@ -0,0 +1,25 @@
+//
+// Created by Jordy Sipkema on 28/03/16.
+//
+
+#ifndef MUTLI_OS_BUILD_MP3STREAM_H
+#define MUTLI_OS_BUILD_MP3STREAM_H
+
+#include "typedefs.h"
+
+#include <netinet/tcp.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <string.h>
+
+bool play(void);
+bool connectToStream(char* ipaddr, u_short port, char *radioUrl);
+void killPlayerThread(void);
+
+u_char volumeUp(void);
+u_char volumeDown(void);
+void setVolume(void); // Do not use this one, this is invoked by volumeUp/Down
+
+
+#endif //MUTLI_OS_BUILD_MP3STREAM_H

+ 12 - 12
network.c

@@ -7,6 +7,7 @@
 #include <sys/confnet.h>
 #include <sys/socket.h>
 #include <netinet/tcp.h>
+#include <sys/types.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -17,6 +18,8 @@
 
 #include <stdio.h>
 #include <io.h>
+#include <sys/version.h>
+#include <dev/irqreg.h>
 #include <arpa/inet.h>
 #include <pro/dhcp.h>
 #include <pro/sntp.h>
@@ -47,7 +50,7 @@ void NetworkInit() {
 }
 
 char* getMacAdress(){
-    ether_ntoa(confnet.cdn_mac);
+    return ether_ntoa(confnet.cdn_mac);
 }
 
 void httpGet(char address[], void (*parser)(char*)){
@@ -58,7 +61,7 @@ void httpGet(char address[], void (*parser)(char*)){
     TCPSOCKET* sock = NutTcpCreateSocket();
 
     char buffer[2];
-    char* content = (char*) calloc(1 , 800);
+    char* content = (char*) malloc(900);
     char enters = 0;
     int t = 0;
 
@@ -67,7 +70,7 @@ void httpGet(char address[], void (*parser)(char*)){
     }else if (NutTcpConnect(sock, inet_addr("62.195.226.247"), 80)) {
         printf("Can't connect to server\n");
     }else if (NutTcpSetSockOpt(sock, SO_RCVTIMEO, &rx_to, sizeof(rx_to))){
-
+        printf("Can't set sock options\n");
     }else{
         FILE *stream;
         stream = _fdopen((int) sock, "r+b");
@@ -77,7 +80,6 @@ void httpGet(char address[], void (*parser)(char*)){
         fflush(stream);
 
         printf("Headers writed. Now reading.");
-        NutDelay(500);
         //Removing header:
         while(fgets(buffer, sizeof(buffer), stream) != NULL) {
             if(enters == 4) {
@@ -93,16 +95,14 @@ void httpGet(char address[], void (*parser)(char*)){
             }
         }
         fclose(stream);
+
+        content[t] = '\0';
+        printf("\nContent size: %d, Content: %s \n", t, content);
+        parser(content);
+        free(content);
     }
     NutTcpCloseSocket(sock);
-
-    content[t] = '\0';
-    printf("\nContent size: %d, Content: %s \n", t, content);
-    parser(content);
-    free(content);
-
     isReceiving = false;
-    return content;
 }
 
 bool NetworkIsReceiving(void){
@@ -111,4 +111,4 @@ bool NetworkIsReceiving(void){
 
 bool hasNetworkConnection(void){
     return hasNetwork;
-}
+}

+ 4 - 4
network.h

@@ -4,11 +4,11 @@
 
 #ifndef _Network_H
 #define _Network_H
-
-//bool hasNetworkConnection(void);
-//bool NetworkIsReceiving(void);
+#include "typedefs.h"
+bool hasNetworkConnection(void);
+bool NetworkIsReceiving(void);
 extern void NetworkInit(void);
 extern void httpGet(char address[], void (*parser)(char*));
-char* getMacAdress();
+char* getMacAdress(void);
 
 #endif /* _Network_H */

+ 4 - 22
ntp.c

@@ -21,6 +21,8 @@
 #include "log.h"
 #include "ntp.h"
 #include "contentparser.h"
+#include "alarm.h"
+#include "network.h"
 
 int TIME_ZONE = 1;
 #define LOG_MODULE  LOG_NTP_MODULE
@@ -68,7 +70,7 @@ void NtpCheckValidTime(void){
     tm current_tm;
     X12RtcGetClock(&current_tm);
 
-    validTime = NtpCompareTime(current_tm, stored_tm);
+    validTime = compareTime(current_tm, stored_tm);
     if (validTime){
         puts("NtpCheckValidTime(): Time was valid \n");
     }else {
@@ -76,26 +78,6 @@ void NtpCheckValidTime(void){
     }
 }
 
-//Tests if t1 is after t2.
-bool NtpCompareTime(tm t1, tm t2){
-
-    if (t1.tm_year > t2.tm_year)
-        return true;
-    if (t1.tm_mon > t2.tm_mon)
-        return true;
-    if (t1.tm_mday > t2.tm_mday)
-        return true;
-    if (t1.tm_hour > t2.tm_hour)
-        return true;
-    if (t1.tm_min > t2.tm_min)
-        return true;
-    if (t1.tm_sec > t2.tm_sec)
-        return true;
-
-    //else
-    return false;
-}
-
 bool NtpTimeIsValid(void){
     return validTime;
 }
@@ -105,7 +87,7 @@ void NtpSync(void){
     isSyncing = true;
     httpGet("/gettimezone.php", parsetimezone);
     _daylight = 0;
-    printf(TIME_ZONE);
+    printf("Timezone is: %d", TIME_ZONE);
     NutDelay(100);
     //puts("Tijd ophalen van pool.ntp.org (213.154.229.24)");
     timeserver = inet_addr("213.154.229.24");

+ 3 - 3
ntp.h

@@ -6,6 +6,7 @@
 #define _Ntp_H
 
 #include "typedefs.h"
+#include <time.h>
 
 extern bool NtpIsSyncing(void);
 extern void NtpInit(void);
@@ -14,9 +15,8 @@ extern void setTimeZone(int timezone);
 extern bool NtpTimeIsValid(void);
 
 void NtpCheckValidTime(void);
-void NtpWriteTimeToEeprom(tm);
-bool NtpCompareTime(tm, tm);
+void NtpWriteTimeToEeprom(tm time_struct);
 
 void setTimeZone(int timezone);
-int getTimeZone();
+int getTimeZone(void);
 #endif /* _Ntp_H */

+ 0 - 151
remcon.c

@@ -1,151 +0,0 @@
-/*! \file
- * remcon.c contains all interface- and low-level routines that
- * perform handling of the infrared bitstream
- * [COPYRIGHT]  Copyright (C) STREAMIT BV
- *  \version 1.0
- *  \date 26 september 2003
- */
-
-
-
-#define LOG_MODULE  LOG_REMCON_MODULE
-
-#include <stdlib.h>
-#include <fs/typedefs.h>
-#include <sys/heap.h>
-
-#include <sys/event.h>
-#include <sys/atom.h>
-#include <sys/types.h>
-#include <dev/irqreg.h>
-
-#include "system.h"
-#include "portio.h"
-#include "remcon.h"
-#include "display.h"
-#include "keyboard.h"
-#include "led.h"
-
-
-/*-------------------------------------------------------------------------*/
-/* local variable definitions                                              */
-/*-------------------------------------------------------------------------*/
-static HANDLE  hRCEvent;
-
-/*-------------------------------------------------------------------------*/
-/* local routines (prototyping)                                            */
-/*-------------------------------------------------------------------------*/
-static void RcInterrupt(void*);
-static void RcClearEvent(HANDLE*);
-
-
-/*!
- * \addtogroup RemoteControl
- */
-
-/*@{*/
-
-/*-------------------------------------------------------------------------*/
-/*                         start of code                                   */
-/*-------------------------------------------------------------------------*/
-
-
-
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-/*!
- * \brief ISR Remote Control Interrupt (ISR called by Nut/OS)
- *
- *  NEC-code consists of 5 parts:
- *
- *  - leader (9 msec high, 4,5 msec low)
- *  - address (8 bits)
- *  - inverted address (8 bits)
- *  - data (8 bits)
- *  - inverted data (8 bits)
- *
- *  The first sequence contains these 5 parts, next
- *  sequences only contain the leader + 1 '0' bit as long
- *  as the user holds down the button
- *  repetition time is 108 msec in that case
- *
- *  Resolution of the 16-bit timer we use here is 4,3 usec
- *
- *  13,5 msecs are 3109 ticks
- *  '0' is 1,25 msecs (260 ticks)
- *  '1' is 2,25 msecs (517 ticks)
- *
- * \param *p not used (might be used to pass parms from the ISR)
- */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-static void RcInterrupt(void *p)
-{
-	// Hier ISR implementeren voor bijv. NEC protocol
-}
-
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-/*!
- * \brief Clear the eventbuffer of this module
- *
- * This routine is called during module initialization.
- *
- * \param *pEvent pointer to the event queue
- */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-static void RcClearEvent(HANDLE *pEvent)
-{
-    NutEnterCritical();
-
-    *pEvent = 0;
-
-    NutExitCritical();
-}
-
-
-
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-/*!
- * \brief Initialise the Remote Control module
- *
- * - register the ISR in NutOS
- * - initialise the HW-timer that is used for this module (Timer1)
- * - initialise the external interrupt that inputs the infrared data
- * - flush the remote control buffer
- * - flush the eventqueue for this module
- */
-/* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-void RcInit()
-{
-    int nError = 0;
-
-    EICRB &= ~RC_INT_SENS_MASK;    // clear b0, b1 of EICRB
-
-    // Install Remote Control interrupt
-    nError = NutRegisterIrqHandler(&sig_INTERRUPT4, RcInterrupt, NULL);
-    if (nError == FALSE)
-    {
-/*
- *  ToDo: control External Interrupt following NutOS calls
-#if (NUTOS_VERSION >= 421)
-        NutIrqSetMode(&sig_INTERRUPT4, NUT_IRQMODE_FALLINGEDGE);
-#else
-        EICRB |= RC_INT_FALLING_EDGE;
-#endif
-        EIMSK |= 1<<IRQ_INT4;         // enable interrupt
- */
-        EICRB |= RC_INT_FALLING_EDGE;
-        EIMSK |= 1<<IRQ_INT4;         // enable interrupt
-    }
-
-    // Initialise 16-bit Timer (Timer1)
-    TCCR1B |= (1<<CS11) | (1<<CS10); // clockdivider = 64
-    TIFR   |= 1<<ICF1;
-    //TIMSK = 1<<TICIE1;
-
-    RcClearEvent(&hRCEvent);
-
-
-}
-
-/* ---------- end of module ------------------------------------------------ */
-
-/*@}*/

+ 0 - 52
remcon.h

@@ -1,52 +0,0 @@
-/* ========================================================================
- * [PROJECT]    SIR
- * [MODULE]     Remote Control
- * [TITLE]      remote control header file
- * [FILE]       remcon.h
- * [VSN]        1.0
- * [CREATED]    1 july 2003
- * [LASTCHNGD]  1 july 2003
- * [COPYRIGHT]  Copyright (C) STREAMIT BV 2010
- * [PURPOSE]    remote control routines for SIR
- * ======================================================================== */
-
-/*-------------------------------------------------------------------------*/
-/* global defines                                                          */
-/*-------------------------------------------------------------------------*/
-#define RC_OK                 0x00
-#define RC_ERROR              0x01
-#define RC_BUSY               0x04
-
-#define RCST_IDLE             0x00
-#define RCST_WAITFORLEADER    0x01
-#define RCST_SCANADDRESS      0x02
-#define RCST_SCANDATA         0x03
-
-#define RC_INT_SENS_MASK      0x03
-#define RC_INT_FALLING_EDGE   0x02
-#define RC_INT_RISING_EDGE    0x03
-
-#define IR_RECEIVE            4
-#define IR_BUFFER_SIZE        1
-
-
-/*-------------------------------------------------------------------------*/
-/* export global routines (interface)                                      */
-/*-------------------------------------------------------------------------*/
-void    RcInit(void);
-
-
-/*  ÍÍÍÍ  End Of File  ÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
-
-
-
-
-
-
-
-
-
-
-
-
-

+ 0 - 3
uart0driver.c

@@ -106,9 +106,6 @@ THREAD(Uart0KeyEvents, arg)
         result = fgets(result, 16, stream);
         short _reset_received = strcmp(rst, result);
 
-        *rst = "abcde\n";
-        *result = "";
-
         if (_reset_received == 0){
             LogMsg_P(LOG_INFO, PSTR(">>>>>> RESET COMMAND RECEIVED"));
             //RESET SIR!

+ 1 - 9
vs10xx.c

@@ -91,7 +91,6 @@
 /*-------------------------------------------------------------------------*/
 static volatile u_char vs_status = VS_STATUS_STOPPED;
 static u_short g_vs_type;
-static u_char VsPlayMode;
 
 
 static void VsLoadProgramCode(void);
@@ -505,7 +504,7 @@ int VsPlayerKick(void)
          *  for the VS1003 we need an extra reset
          *  here before we start playing a stream...
          */
-         VsPlayerSetMode(VS_SM_RESET);
+//        VsPlayerSetMode(VS_SM_RESET);
 //        NutDelay(10);
 //        LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
 //        LogMsg_P(LOG_DEBUG,PSTR("Kick: CLOCKF = [0x%02X]"),VsRegRead(VS_CLOCKF_REG));
@@ -787,13 +786,6 @@ u_short VsMemoryTest(void)
 int VsSetVolume(u_char left, u_char right)
 {
     u_char ief;
-    if(left < 0){
-        left = 0;
-    }
-    if(right < 0){
-        right = 0;
-    }
-    printf("%d %d", left, right);
 
     ief = VsPlayerInterrupts(0);