aboutsummaryrefslogtreecommitdiffstats
path: root/Projects/TemperatureDataLogger
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2010-01-24 11:13:23 +0000
committerDean Camera <dean@fourwalledcubicle.com>2010-01-24 11:13:23 +0000
commitdd995683ea1f233b79724d524a9a3dbcdc171d30 (patch)
tree9488b6e69cc9457fade5c7d4050a8941ac6da836 /Projects/TemperatureDataLogger
parent03ee87b35abdb8b92e8b55ec040fa943f9a6786c (diff)
downloadlufa-dd995683ea1f233b79724d524a9a3dbcdc171d30.tar.gz
lufa-dd995683ea1f233b79724d524a9a3dbcdc171d30.tar.bz2
lufa-dd995683ea1f233b79724d524a9a3dbcdc171d30.zip
Enhance TemperatureDatalogger project -- add RTC capabilities so that data is logged along with the current time and date. Make logging interval configurable, set by a C# PC host application.
Diffstat (limited to 'Projects/TemperatureDataLogger')
-rw-r--r--Projects/TemperatureDataLogger/Descriptors.c87
-rw-r--r--Projects/TemperatureDataLogger/Descriptors.h48
-rw-r--r--Projects/TemperatureDataLogger/Lib/DS1307.c129
-rw-r--r--Projects/TemperatureDataLogger/Lib/DS1307.h111
-rw-r--r--Projects/TemperatureDataLogger/Lib/FATFs/diskio.c14
-rw-r--r--Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h2
-rw-r--r--Projects/TemperatureDataLogger/TempDataLogger.c165
-rw-r--r--Projects/TemperatureDataLogger/TempDataLogger.h25
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.sln20
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.suobin0 -> 17408 bytes
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.Designer.cs181
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.cs172
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.resx120
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Linux.dllbin0 -> 9216 bytes
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Net.dllbin0 -> 24576 bytes
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Win32.dllbin0 -> 94208 bytes
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Program.cs21
-rw-r--r--Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/TempLoggerHostApp.csproj95
-rw-r--r--Projects/TemperatureDataLogger/TemperatureDataLogger.txt29
-rw-r--r--Projects/TemperatureDataLogger/makefile3
20 files changed, 1141 insertions, 81 deletions
diff --git a/Projects/TemperatureDataLogger/Descriptors.c b/Projects/TemperatureDataLogger/Descriptors.c
index 40ce620a6..e4f5666e5 100644
--- a/Projects/TemperatureDataLogger/Descriptors.c
+++ b/Projects/TemperatureDataLogger/Descriptors.c
@@ -49,6 +49,32 @@
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
#endif
+/** HID class report descriptor. This is a special descriptor constructed with values from the
+ * USBIF HID class specification to describe the reports and capabilities of the HID device. This
+ * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
+ * the device will send, and what it may be sent back from the host. Refer to the HID specification for
+ * more details on HID report descriptors.
+ */
+USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] =
+{
+ 0x06, 0x9c, 0xff, /* Usage Page (Vendor Defined) */
+ 0x09, 0x01, /* Usage (Vendor Defined) */
+ 0xa1, 0x01, /* Collection (Vendor Defined) */
+ 0x09, 0x02, /* Usage (Vendor Defined) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
+ 0x15, 0x80, /* Logical Minimum (-128) */
+ 0x25, 0x7F, /* Logical Maximum (127) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x09, 0x03, /* Usage (Vendor Defined) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, GENERIC_REPORT_SIZE, /* Report Count (GENERIC_REPORT_SIZE) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0xff, /* Logical Maximum (255) */
+ 0x91, 0x02, /* Output (Data, Variable, Absolute) */
+ 0xc0 /* End Collection */
+};
+
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration
@@ -66,7 +92,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB,
- .ProductID = 0x2045,
+ .ProductID = 0x2063,
.ReleaseNumber = 0x0000,
.ManufacturerStrIndex = 0x01,
@@ -88,7 +114,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
- .TotalInterfaces = 1,
+ .TotalInterfaces = 2,
.ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR,
@@ -98,7 +124,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
},
- .Interface =
+ .MSInterface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -114,7 +140,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.InterfaceStrIndex = NO_DESCRIPTOR
},
- .DataInEndpoint =
+ .MSDataInEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
@@ -124,7 +150,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.PollingIntervalMS = 0x00
},
- .DataOutEndpoint =
+ .MSDataOutEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
@@ -132,7 +158,44 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
.PollingIntervalMS = 0x00
- }
+ },
+
+ .HIDInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = 0x03,
+ .SubClass = 0x00,
+ .Protocol = HID_NON_BOOT_PROTOCOL,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .HIDInfo =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_t), .Type = DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(01.11),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = DTYPE_Report,
+ .HIDReportLength = sizeof(GenericReport)
+ },
+
+ .HIDDataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | GENERIC_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = GENERIC_EPSIZE,
+ .PollingIntervalMS = 0x0A
+ },
};
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
@@ -163,9 +226,9 @@ USB_Descriptor_String_t PROGMEM ManufacturerString =
*/
USB_Descriptor_String_t PROGMEM ProductString =
{
- .Header = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},
+ .Header = {.Size = USB_STRING_LEN(10), .Type = DTYPE_String},
- .UnicodeString = L"LUFA Mass Storage Demo"
+ .UnicodeString = L"Datalogger"
};
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
@@ -210,6 +273,14 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex,
}
break;
+ case DTYPE_HID:
+ Address = (void*)&ConfigurationDescriptor.HIDInfo;
+ Size = sizeof(USB_HID_Descriptor_t);
+ break;
+ case DTYPE_Report:
+ Address = (void*)&GenericReport;
+ Size = sizeof(GenericReport);
+ break;
}
*DescriptorAddress = Address;
diff --git a/Projects/TemperatureDataLogger/Descriptors.h b/Projects/TemperatureDataLogger/Descriptors.h
index dcaaddaf7..a0f03c38d 100644
--- a/Projects/TemperatureDataLogger/Descriptors.h
+++ b/Projects/TemperatureDataLogger/Descriptors.h
@@ -5,33 +5,6 @@
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
-
-/*
- Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Header file for Descriptors.c.
- */
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
@@ -41,6 +14,9 @@
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h>
+ #include <LUFA/Drivers/USB/Class/HID.h>
+
+ #include "TempDataLogger.h"
/* Macros: */
/** Endpoint number of the Mass Storage device-to-host data IN endpoint. */
@@ -51,6 +27,15 @@
/** Size in bytes of the Mass Storage data endpoints. */
#define MASS_STORAGE_IO_EPSIZE 64
+
+ /** Endpoint number of the Generic HID reporting IN endpoint. */
+ #define GENERIC_IN_EPNUM 1
+
+ /** Size in bytes of the Generic HID reporting endpoint. */
+ #define GENERIC_EPSIZE 16
+
+ /** Size in bytes of the Generic HID reports (including report ID byte). */
+ #define GENERIC_REPORT_SIZE sizeof(Device_Report_t)
/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
@@ -60,9 +45,12 @@
typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
- USB_Descriptor_Interface_t Interface;
- USB_Descriptor_Endpoint_t DataInEndpoint;
- USB_Descriptor_Endpoint_t DataOutEndpoint;
+ USB_Descriptor_Interface_t MSInterface;
+ USB_Descriptor_Endpoint_t MSDataInEndpoint;
+ USB_Descriptor_Endpoint_t MSDataOutEndpoint;
+ USB_Descriptor_Interface_t HIDInterface;
+ USB_HID_Descriptor_t HIDInfo;
+ USB_Descriptor_Endpoint_t HIDDataInEndpoint;
} USB_Descriptor_Configuration_t;
/* Function Prototypes: */
diff --git a/Projects/TemperatureDataLogger/Lib/DS1307.c b/Projects/TemperatureDataLogger/Lib/DS1307.c
new file mode 100644
index 000000000..37817e97f
--- /dev/null
+++ b/Projects/TemperatureDataLogger/Lib/DS1307.c
@@ -0,0 +1,129 @@
+/*
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+#include "DS1307.h"
+
+void DS1307_Init(void)
+{
+ // Nothing to initialize
+}
+
+void DS1307_SetDate(uint8_t Day, uint8_t Month, uint8_t Year)
+{
+#if defined(DUMMY_RTC)
+ return;
+#endif
+
+ DS1307_DateRegs_t CurrentRTCDate;
+ CurrentRTCDate.Byte1.TenDay = (Day / 10);
+ CurrentRTCDate.Byte1.Day = (Day % 10);
+ CurrentRTCDate.Byte2.TenMonth = (Month / 10);
+ CurrentRTCDate.Byte2.Month = (Month % 10);
+ CurrentRTCDate.Byte3.TenYear = (Year / 10);
+ CurrentRTCDate.Byte3.Year = (Year % 10);
+
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))
+ {
+ TWI_SendByte(DS1307_DATEREG_START);
+ TWI_SendByte(CurrentRTCDate.Byte1.IntVal);
+ TWI_SendByte(CurrentRTCDate.Byte2.IntVal);
+ TWI_SendByte(CurrentRTCDate.Byte3.IntVal);
+
+ TWI_StopTransmission();
+ }
+}
+
+void DS1307_SetTime(uint8_t Hour, uint8_t Minute, uint8_t Second)
+{
+#if defined(DUMMY_RTC)
+ return;
+#endif
+
+ DS1307_TimeRegs_t CurrentRTCTime;
+ CurrentRTCTime.Byte1.TenSec = (Second / 10);
+ CurrentRTCTime.Byte1.Sec = (Second % 10);
+ CurrentRTCTime.Byte1.CH = false;
+ CurrentRTCTime.Byte2.TenMin = (Minute / 10);
+ CurrentRTCTime.Byte2.Min = (Minute % 10);
+ CurrentRTCTime.Byte3.TenHour = (Hour / 10);
+ CurrentRTCTime.Byte3.Hour = (Hour % 10);
+ CurrentRTCTime.Byte3.TwelveHourMode = false;
+
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))
+ {
+ TWI_SendByte(DS1307_TIMEREG_START);
+ TWI_SendByte(CurrentRTCTime.Byte1.IntVal);
+ TWI_SendByte(CurrentRTCTime.Byte2.IntVal);
+ TWI_SendByte(CurrentRTCTime.Byte3.IntVal);
+
+ TWI_StopTransmission();
+ }
+}
+
+void DS1307_GetDate(uint8_t* Day, uint8_t* Month, uint8_t* Year)
+{
+#if defined(DUMMY_RTC)
+ *Day = 1;
+ *Month = 1;
+ *Year = 1;
+ return;
+#endif
+
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))
+ {
+ TWI_SendByte(DS1307_DATEREG_START);
+
+ TWI_StopTransmission();
+ }
+
+ DS1307_DateRegs_t CurrentRTCDate;
+
+ if (TWI_StartTransmission(DS1307_ADDRESS_READ))
+ {
+ TWI_ReceiveByte(&CurrentRTCDate.Byte1.IntVal, false);
+ TWI_ReceiveByte(&CurrentRTCDate.Byte2.IntVal, false);
+ TWI_ReceiveByte(&CurrentRTCDate.Byte3.IntVal, true);
+
+ TWI_StopTransmission();
+ }
+
+ *Day = (CurrentRTCDate.Byte1.TenDay * 10) + CurrentRTCDate.Byte1.Day;
+ *Month = (CurrentRTCDate.Byte2.TenMonth * 10) + CurrentRTCDate.Byte2.Month;
+ *Year = (CurrentRTCDate.Byte3.TenYear * 10) + CurrentRTCDate.Byte3.Year;
+}
+
+void DS1307_GetTime(uint8_t* Hour, uint8_t* Minute, uint8_t* Second)
+{
+#if defined(DUMMY_RTC)
+ *Hour = 1;
+ *Minute = 1;
+ *Second = 1;
+ return;
+#endif
+
+ if (TWI_StartTransmission(DS1307_ADDRESS_WRITE))
+ {
+ TWI_SendByte(DS1307_TIMEREG_START);
+
+ TWI_StopTransmission();
+ }
+
+ DS1307_TimeRegs_t CurrentRTCTime;
+
+ if (TWI_StartTransmission(DS1307_ADDRESS_READ))
+ {
+ TWI_ReceiveByte(&CurrentRTCTime.Byte1.IntVal, false);
+ TWI_ReceiveByte(&CurrentRTCTime.Byte2.IntVal, false);
+ TWI_ReceiveByte(&CurrentRTCTime.Byte3.IntVal, true);
+
+ TWI_StopTransmission();
+ }
+
+ *Second = (CurrentRTCTime.Byte1.TenSec * 10) + CurrentRTCTime.Byte1.Sec;
+ *Minute = (CurrentRTCTime.Byte2.TenMin * 10) + CurrentRTCTime.Byte2.Min;
+ *Hour = (CurrentRTCTime.Byte3.TenHour * 10) + CurrentRTCTime.Byte3.Hour;
+}
diff --git a/Projects/TemperatureDataLogger/Lib/DS1307.h b/Projects/TemperatureDataLogger/Lib/DS1307.h
new file mode 100644
index 000000000..491836079
--- /dev/null
+++ b/Projects/TemperatureDataLogger/Lib/DS1307.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+#ifndef _DS1307_H_
+#define _DS1307_H_
+
+ /* Includes: */
+ #include <avr/io.h>
+
+ #include <LUFA/Drivers/Peripheral/TWI.h>
+
+ /* Type Defines: */
+ typedef struct
+ {
+ union
+ {
+ struct
+ {
+ unsigned int Sec : 4;
+ unsigned int TenSec : 3;
+ unsigned int CH : 1;
+ };
+
+ uint8_t IntVal;
+ } Byte1;
+
+ union
+ {
+ struct
+ {
+ unsigned int Min : 4;
+ unsigned int TenMin : 3;
+ unsigned int _RESERVED : 1;
+ };
+
+ uint8_t IntVal;
+ } Byte2;
+
+ union
+ {
+ struct
+ {
+ unsigned int Hour : 4;
+ unsigned int TenHour : 2;
+ unsigned int TwelveHourMode : 1;
+ unsigned int _RESERVED : 1;
+ };
+
+ uint8_t IntVal;
+ } Byte3;
+ } DS1307_TimeRegs_t;
+
+ typedef struct
+ {
+ union
+ {
+ struct
+ {
+ unsigned int Day : 4;
+ unsigned int TenDay : 2;
+ unsigned int _RESERVED : 2;
+ };
+
+ uint8_t IntVal;
+ } Byte1;
+
+ union
+ {
+ struct
+ {
+ unsigned int Month : 4;
+ unsigned int TenMonth : 1;
+ unsigned int _RESERVED : 3;
+ };
+
+ uint8_t IntVal;
+ } Byte2;
+
+ union
+ {
+ struct
+ {
+ unsigned int Year : 4;
+ unsigned int TenYear : 4;
+ };
+
+ uint8_t IntVal;
+ } Byte3;
+ } DS1307_DateRegs_t;
+
+ /* Macros: */
+ #define DS1307_TIMEREG_START 0x00
+ #define DS1307_DATEREG_START 0x04
+
+ #define DS1307_ADDRESS_READ 0b11010001
+ #define DS1307_ADDRESS_WRITE 0b11010000
+
+ /* Function Prototypes: */
+ void DS1307_Init(void);
+
+ void DS1307_SetDate(uint8_t Day, uint8_t Month, uint8_t Year);
+ void DS1307_SetTime(uint8_t Hour, uint8_t Minute, uint8_t Second);
+
+ void DS1307_GetDate(uint8_t* Day, uint8_t* Month, uint8_t* Year);
+ void DS1307_GetTime(uint8_t* Hour, uint8_t* Minute, uint8_t* Second);
+
+#endif
diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c
index e6be68734..0c0083bac 100644
--- a/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c
+++ b/Projects/TemperatureDataLogger/Lib/FATFs/diskio.c
@@ -83,5 +83,17 @@ DRESULT disk_ioctl (
DWORD get_fattime (void)
{
- return (1UL << 25) | (1UL << 21) | (1UL << 16) | (1UL << 11) | (1UL << 5) | (1UL << 0);
+ uint8_t Day, Month, Year;
+ uint8_t Hour, Minute, Second;
+
+ DS1307_GetDate(&Day, &Month, &Year);
+ DS1307_GetTime(&Hour, &Minute, &Second);
+
+
+ return ((DWORD)(20 + Year) << 25) |
+ ((DWORD)Month << 21) |
+ ((DWORD)Day << 16) |
+ ((DWORD)Hour << 11) |
+ ((DWORD)Minute << 5) |
+ (((DWORD)Second >> 1) << 0);
}
diff --git a/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h b/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h
index 18510157d..9b414e979 100644
--- a/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h
+++ b/Projects/TemperatureDataLogger/Lib/FATFs/ffconf.h
@@ -36,7 +36,7 @@
/ 3: f_lseek is removed in addition to level 2. */
-#define _USE_STRFUNC 1 /* 0, 1 or 2 */
+#define _USE_STRFUNC 0 /* 0, 1 or 2 */
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
diff --git a/Projects/TemperatureDataLogger/TempDataLogger.c b/Projects/TemperatureDataLogger/TempDataLogger.c
index b181ec2f8..538a6a5e8 100644
--- a/Projects/TemperatureDataLogger/TempDataLogger.c
+++ b/Projects/TemperatureDataLogger/TempDataLogger.c
@@ -58,52 +58,93 @@ USB_ClassInfo_MS_Device_t Disk_MS_Interface =
},
};
+/** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */
+uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE];
+
+/** LUFA HID Class driver interface configuration and state information. This structure is
+ * passed to all HID Class driver functions, so that multiple instances of the same class
+ * within a device can be differentiated from one another.
+ */
+USB_ClassInfo_HID_Device_t Generic_HID_Interface =
+ {
+ .Config =
+ {
+ .InterfaceNumber = 1,
+
+ .ReportINEndpointNumber = GENERIC_IN_EPNUM,
+ .ReportINEndpointSize = GENERIC_EPSIZE,
+ .ReportINEndpointDoubleBank = false,
+
+ .PrevReportINBuffer = PrevHIDReportBuffer,
+ .PrevReportINBufferSize = sizeof(PrevHIDReportBuffer),
+ },
+ };
+
+/** Non-volatile Logging Interval value in EEPROM, stored as a number of 500ms ticks */
+uint8_t EEMEM LoggingInterval500MS_EEPROM;
+
+/** SRAM Logging Interval value fetched from EEPROM, stored as a number of 500ms ticks */
+uint8_t LoggingInterval500MS_SRAM;
+
+/** Total number of 500ms logging ticks elapsed since the last log value was recorded */
+uint16_t CurrentLoggingTicks;
+
/** FAT Fs structure to hold the internal state of the FAT driver for the dataflash contents. */
FATFS DiskFATState;
/** FAT Fs structure to hold a FAT file handle for the log data write destination. */
FIL TempLogFile;
-/** Counter to count the number of 10 millisecond ticks that has elapsed since the last sample */
-uint16_t CurrentLogTick;
-
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
- if (CurrentLogTick++ != LOG_INTERVAL_10MS)
- return;
-
uint8_t LEDMask = LEDs_GetLEDs();
+ /* Check to see if the logging interval has expired */
+ if (CurrentLoggingTicks++ < LoggingInterval500MS_SRAM)
+ return;
+
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
- CurrentLogTick = 0;
-
+ /* Reset log tick counter to prepare for next logging interval */
+ CurrentLoggingTicks = 0;
+
if (USB_DeviceState == DEVICE_STATE_Unattached)
{
- f_printf(&TempLogFile, "%d Degrees\r\n", Temperature_GetTemperature());
+ uint8_t Day, Month, Year;
+ uint8_t Hour, Minute, Second;
+
+ DS1307_GetDate(&Day, &Month, &Year);
+ DS1307_GetTime(&Hour, &Minute, &Second);
+
+ char LineBuffer[100];
+ uint16_t BytesWritten;
+
+ BytesWritten = sprintf(LineBuffer, "%02d/%02d/20%04d, %02d:%02d:%02d, %d Degrees\r\n",
+ Day, Month, Year, Hour, Minute, Second, Temperature_GetTemperature());
+
+ f_write(&TempLogFile, LineBuffer, BytesWritten, &BytesWritten);
f_sync(&TempLogFile);
}
LEDs_SetAllLEDs(LEDMask);
}
-
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
*/
int main(void)
{
- SetupHardware();
+ /* Fetch logging interval from EEPROM */
+ LoggingInterval500MS_SRAM = eeprom_read_byte(&LoggingInterval500MS_EEPROM);
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+ SetupHardware();
+
/* Mount and open the log file on the dataflash FAT partition */
- f_mount(0, &DiskFATState);
- f_open(&TempLogFile, LOG_FILENAME, FA_OPEN_ALWAYS | FA_WRITE);
- f_lseek(&TempLogFile, TempLogFile.fsize);
- f_printf(&TempLogFile, "===========================\r\n");
-
+ OpenLogFile();
+
/* Discard the first sample from the temperature sensor, as it is generally incorrect */
uint8_t Dummy = Temperature_GetTemperature();
(void)Dummy;
@@ -111,10 +152,33 @@ int main(void)
for (;;)
{
MS_Device_USBTask(&Disk_MS_Interface);
+ HID_Device_USBTask(&Generic_HID_Interface);
USB_USBTask();
}
}
+void OpenLogFile(void)
+{
+ char LogFileName[12];
+
+ /* Get the current date for the filename as "DDMMYY.csv" */
+ uint8_t Day, Month, Year;
+ DS1307_GetDate(&Day, &Month, &Year);
+ sprintf(LogFileName, "%02d%02d%02d.csv", Day, Month, Year);
+
+ /* Mount the storage device, open the file */
+ f_mount(0, &DiskFATState);
+ f_open(&TempLogFile, LogFileName, FA_OPEN_ALWAYS | FA_WRITE);
+ f_lseek(&TempLogFile, TempLogFile.fsize);
+}
+
+void CloseLogFile(void)
+{
+ /* Sync any data waiting to be written, unmount the storage device */
+ f_sync(&TempLogFile);
+ f_close(&TempLogFile);
+}
+
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
@@ -133,9 +197,9 @@ void SetupHardware(void)
Dataflash_Init();
USB_Init();
- /* 10ms interval timer configuration */
- OCR1A = (((F_CPU / 1024) / 100) - 1);
- TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // CTC mode, Fcpu/1024 speed
+ /* 500ms logging interval timer configuration */
+ OCR1A = ((F_CPU / 1024) / 2);
+ TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
TIMSK1 = (1 << OCIE1A);
/* Clear Dataflash sector protections, if enabled */
@@ -148,7 +212,7 @@ void EVENT_USB_Device_Connect(void)
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
/* Close the log file so that the host has exclusive filesystem access */
- f_close(&TempLogFile);
+ CloseLogFile();
}
/** Event handler for the library USB Disconnection event. */
@@ -156,11 +220,8 @@ void EVENT_USB_Device_Disconnect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
- /* When disconnected from the host, re-open log file so we can resume logging */
- f_mount(0, &DiskFATState);
- f_open(&TempLogFile, LOG_FILENAME, FA_OPEN_ALWAYS | FA_WRITE);
- f_lseek(&TempLogFile, TempLogFile.fsize);
- f_printf(&TempLogFile, "===========================\r\n");
+ /* Mount and open the log file on the dataflash FAT partition */
+ OpenLogFile();
}
/** Event handler for the library USB Configuration Changed event. */
@@ -170,12 +231,16 @@ void EVENT_USB_Device_ConfigurationChanged(void)
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+
+ if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void)
{
MS_Device_ProcessControlRequest(&Disk_MS_Interface);
+ HID_Device_ProcessControlRequest(&Generic_HID_Interface);
}
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
@@ -192,3 +257,53 @@ bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfa
return CommandSuccess;
}
+
+/** HID class driver callback function for the creation of HID reports to the host.
+ *
+ * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
+ * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
+ * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature
+ * \param[out] ReportData Pointer to a buffer where the created report should be stored
+ * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent
+ *
+ * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent
+ */
+bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
+ const uint8_t ReportType, void* ReportData, uint16_t* ReportSize)
+{
+ Device_Report_t* ReportParams = (Device_Report_t*)ReportData;
+
+ DS1307_GetDate(&ReportParams->Day, &ReportParams->Month, &ReportParams->Year);
+ DS1307_GetTime(&ReportParams->Hour, &ReportParams->Minute, &ReportParams->Second);
+
+ ReportParams->LogInterval500MS = LoggingInterval500MS_SRAM;
+
+ *ReportSize = sizeof(Device_Report_t);
+ return true;
+}
+
+/** HID class driver callback function for the processing of HID reports from the host.
+ *
+ * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
+ * \param[in] ReportID Report ID of the received report from the host
+ * \param[in] ReportData Pointer to a buffer where the created report has been stored
+ * \param[in] ReportSize Size in bytes of the received HID report
+ */
+void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
+ const void* ReportData, const uint16_t ReportSize)
+{
+ Device_Report_t* ReportParams = (Device_Report_t*)ReportData;
+
+ GPIOR0 = ReportParams->Day;
+ GPIOR1 = ReportParams->Month;
+ GPIOR2 = ReportParams->Year;
+
+ DS1307_SetDate(ReportParams->Day, ReportParams->Month, ReportParams->Year);
+ DS1307_SetTime(ReportParams->Hour, ReportParams->Minute, ReportParams->Second);
+
+ if (LoggingInterval500MS_SRAM != ReportParams->LogInterval500MS)
+ {
+ LoggingInterval500MS_SRAM = ReportParams->LogInterval500MS;
+ eeprom_write_byte(&LoggingInterval500MS_EEPROM, LoggingInterval500MS_SRAM);
+ }
+}
diff --git a/Projects/TemperatureDataLogger/TempDataLogger.h b/Projects/TemperatureDataLogger/TempDataLogger.h
index b9d1b9114..ee10a0971 100644
--- a/Projects/TemperatureDataLogger/TempDataLogger.h
+++ b/Projects/TemperatureDataLogger/TempDataLogger.h
@@ -40,12 +40,14 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/power.h>
-
+ #include <stdio.h>
+
#include "Descriptors.h"
#include "Lib/SCSI.h"
#include "Lib/DataflashManager.h"
#include "Lib/FATFs/ff.h"
+ #include "Lib/DS1307.h"
#include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h>
@@ -53,6 +55,7 @@
#include <LUFA/Drivers/Peripheral/ADC.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h>
+ #include <LUFA/Drivers/USB/Class/HID.h>
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
@@ -76,8 +79,24 @@
/** Data log interval between samples, in tens of milliseconds */
#define LOG_INTERVAL_10MS 1000
+ /* Type Defines: */
+ typedef struct
+ {
+ uint8_t Day;
+ uint8_t Month;
+ uint8_t Year;
+
+ uint8_t Hour;
+ uint8_t Minute;
+ uint8_t Second;
+
+ uint8_t LogInterval500MS;
+ } Device_Report_t;
+
/* Function Prototypes: */
void SetupHardware(void);
+ void OpenLogFile(void);
+ void CloseLogFile(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
@@ -85,5 +104,9 @@
void EVENT_USB_Device_UnhandledControlRequest(void);
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
+ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
+ const uint8_t ReportType, void* ReportData, uint16_t* ReportSize);
+ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, const uint8_t ReportID,
+ const void* ReportData, const uint16_t ReportSize);
#endif
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.sln b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.sln
new file mode 100644
index 000000000..f3fbdb2cf
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TempLoggerHostApp", "TempLoggerHostApp\TempLoggerHostApp.csproj", "{A2D66069-8CF9-4104-828C-49A73D7DB5D1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A2D66069-8CF9-4104-828C-49A73D7DB5D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A2D66069-8CF9-4104-828C-49A73D7DB5D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A2D66069-8CF9-4104-828C-49A73D7DB5D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A2D66069-8CF9-4104-828C-49A73D7DB5D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.suo b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.suo
new file mode 100644
index 000000000..647c7e68a
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp.suo
Binary files differ
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.Designer.cs b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.Designer.cs
new file mode 100644
index 000000000..c6b106f98
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.Designer.cs
@@ -0,0 +1,181 @@
+namespace Project1HostApp
+{
+ partial class frmDataloggerSettings
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.btnSetValues = new System.Windows.Forms.Button();
+ this.dtpTime = new System.Windows.Forms.DateTimePicker();
+ this.lblTime = new System.Windows.Forms.Label();
+ this.lblLoggingInterval = new System.Windows.Forms.Label();
+ this.nudLogInterval = new System.Windows.Forms.NumericUpDown();
+ this.lblSeconds = new System.Windows.Forms.Label();
+ this.btnGetValues = new System.Windows.Forms.Button();
+ this.lblDate = new System.Windows.Forms.Label();
+ this.dtpDate = new System.Windows.Forms.DateTimePicker();
+ ((System.ComponentModel.ISupportInitialize)(this.nudLogInterval)).BeginInit();
+ this.SuspendLayout();
+ //
+ // btnSetValues
+ //
+ this.btnSetValues.Location = new System.Drawing.Point(168, 136);
+ this.btnSetValues.Name = "btnSetValues";
+ this.btnSetValues.Size = new System.Drawing.Size(90, 35);
+ this.btnSetValues.TabIndex = 0;
+ this.btnSetValues.Text = "Set Values";
+ this.btnSetValues.UseVisualStyleBackColor = true;
+ this.btnSetValues.Click += new System.EventHandler(this.btnSetValues_Click);
+ //
+ // dtpTime
+ //
+ this.dtpTime.CustomFormat = "";
+ this.dtpTime.Format = System.Windows.Forms.DateTimePickerFormat.Time;
+ this.dtpTime.Location = new System.Drawing.Point(148, 61);
+ this.dtpTime.Name = "dtpTime";
+ this.dtpTime.ShowUpDown = true;
+ this.dtpTime.Size = new System.Drawing.Size(110, 20);
+ this.dtpTime.TabIndex = 1;
+ //
+ // lblTime
+ //
+ this.lblTime.AutoSize = true;
+ this.lblTime.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblTime.Location = new System.Drawing.Point(51, 67);
+ this.lblTime.Name = "lblTime";
+ this.lblTime.Size = new System.Drawing.Size(82, 13);
+ this.lblTime.TabIndex = 2;
+ this.lblTime.Text = "Device Time:";
+ //
+ // lblLoggingInterval
+ //
+ this.lblLoggingInterval.AutoSize = true;
+ this.lblLoggingInterval.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblLoggingInterval.Location = new System.Drawing.Point(30, 101);
+ this.lblLoggingInterval.Name = "lblLoggingInterval";
+ this.lblLoggingInterval.Size = new System.Drawing.Size(103, 13);
+ this.lblLoggingInterval.TabIndex = 3;
+ this.lblLoggingInterval.Text = "Logging Interval:";
+ //
+ // nudLogInterval
+ //
+ this.nudLogInterval.Location = new System.Drawing.Point(148, 94);
+ this.nudLogInterval.Maximum = new decimal(new int[] {
+ 60,
+ 0,
+ 0,
+ 0});
+ this.nudLogInterval.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.nudLogInterval.Name = "nudLogInterval";
+ this.nudLogInterval.Size = new System.Drawing.Size(51, 20);
+ this.nudLogInterval.TabIndex = 5;
+ this.nudLogInterval.Value = new decimal(new int[] {
+ 5,
+ 0,
+ 0,
+ 0});
+ //
+ // lblSeconds
+ //
+ this.lblSeconds.AutoSize = true;
+ this.lblSeconds.Location = new System.Drawing.Point(209, 101);
+ this.lblSeconds.Name = "lblSeconds";
+ this.lblSeconds.Size = new System.Drawing.Size(49, 13);
+ this.lblSeconds.TabIndex = 6;
+ this.lblSeconds.Text = "Seconds";
+ //
+ // btnGetValues
+ //
+ this.btnGetValues.Location = new System.Drawing.Point(30, 136);
+ this.btnGetValues.Name = "btnGetValues";
+ this.btnGetValues.Size = new System.Drawing.Size(90, 35);
+ this.btnGetValues.TabIndex = 7;
+ this.btnGetValues.Text = "Get Values";
+ this.btnGetValues.UseVisualStyleBackColor = true;
+ this.btnGetValues.Click += new System.EventHandler(this.btnGetValues_Click);
+ //
+ // lblDate
+ //
+ this.lblDate.AutoSize = true;
+ this.lblDate.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblDate.Location = new System.Drawing.Point(51, 33);
+ this.lblDate.Name = "lblDate";
+ this.lblDate.Size = new System.Drawing.Size(82, 13);
+ this.lblDate.TabIndex = 8;
+ this.lblDate.Text = "Device Date:";
+ //
+ // dtpDate
+ //
+ this.dtpDate.CustomFormat = "dd/MM/yyyy";
+ this.dtpDate.Format = System.Windows.Forms.DateTimePickerFormat.Custom;
+ this.dtpDate.Location = new System.Drawing.Point(148, 27);
+ this.dtpDate.Name = "dtpDate";
+ this.dtpDate.Size = new System.Drawing.Size(110, 20);
+ this.dtpDate.TabIndex = 9;
+ //
+ // frmDataloggerSettings
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(300, 197);
+ this.Controls.Add(this.dtpDate);
+ this.Controls.Add(this.lblDate);
+ this.Controls.Add(this.btnGetValues);
+ this.Controls.Add(this.lblSeconds);
+ this.Controls.Add(this.nudLogInterval);
+ this.Controls.Add(this.lblLoggingInterval);
+ this.Controls.Add(this.lblTime);
+ this.Controls.Add(this.dtpTime);
+ this.Controls.Add(this.btnSetValues);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "frmDataloggerSettings";
+ this.Text = "DataLogger";
+ this.Load += new System.EventHandler(this.frmDataloggerSettings_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.nudLogInterval)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnSetValues;
+ private System.Windows.Forms.DateTimePicker dtpTime;
+ private System.Windows.Forms.Label lblTime;
+ private System.Windows.Forms.Label lblLoggingInterval;
+ private System.Windows.Forms.NumericUpDown nudLogInterval;
+ private System.Windows.Forms.Label lblSeconds;
+ private System.Windows.Forms.Button btnGetValues;
+ private System.Windows.Forms.Label lblDate;
+ private System.Windows.Forms.DateTimePicker dtpDate;
+ }
+}
+
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.cs b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.cs
new file mode 100644
index 000000000..370dfbd69
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using Hid;
+
+namespace Project1HostApp
+{
+ public partial class frmDataloggerSettings : Form
+ {
+ private const int DEVICE_VID = 0x03EB;
+ private const int DEVICE_PID = 0xFAFA;
+
+ private struct Device_Report_t
+ {
+ public Byte Day;
+ public Byte Month;
+ public Byte Year;
+
+ public Byte Hour;
+ public Byte Minute;
+ public Byte Second;
+
+ public Byte LogInterval500MS;
+
+ public Byte[] ToReport()
+ {
+ Byte[] Report = new Byte[7];
+
+ Report[0] = this.Day;
+ Report[1] = this.Month;
+ Report[2] = this.Year;
+ Report[3] = this.Hour;
+ Report[4] = this.Minute;
+ Report[5] = this.Second;
+ Report[6] = this.LogInterval500MS;
+
+ return Report;
+ }
+
+ public void FromReport(Byte[] Report)
+ {
+ this.Day = Report[0];
+ this.Month = Report[1];
+ this.Year = Report[2];
+ this.Hour = Report[3];
+ this.Minute = Report[4];
+ this.Second = Report[5];
+ this.LogInterval500MS = Report[6];
+ }
+ };
+
+ private IDevice GetDeviceConnection()
+ {
+ IDevice[] ConnectedDevices = DeviceFactory.Enumerate(DEVICE_VID, DEVICE_PID);
+ IDevice ConnectionHandle = null;
+
+ if (ConnectedDevices.Count() > 0)
+ ConnectionHandle = ConnectedDevices[0];
+ else
+ return null;
+
+ // Fix report handle under Windows
+ if (ConnectionHandle is Hid.Win32.Win32DeviceSet)
+ {
+ ((Hid.Win32.Win32DeviceSet)ConnectionHandle).AddDevice(0x00,
+ ((Hid.Win32.Win32DeviceSet)ConnectionHandle).UnallocatedDevices[0]);
+ }
+
+ return ConnectionHandle;
+ }
+
+ public frmDataloggerSettings()
+ {
+ InitializeComponent();
+ }
+
+ private void btnSetValues_Click(object sender, EventArgs e)
+ {
+ IDevice ConnectionHandle = GetDeviceConnection();
+
+ if (ConnectionHandle == null)
+ {
+ MessageBox.Show("Error: Cannot connect to DataLogger device.");
+ return;
+ }
+
+ Device_Report_t DeviceReport = new Device_Report_t();
+ DeviceReport.Day = (byte)dtpDate.Value.Day;
+ DeviceReport.Month = (byte)dtpDate.Value.Month;
+ DeviceReport.Year = (byte)((dtpDate.Value.Year < 2000) ? 0 : (dtpDate.Value.Year - 2000));
+ DeviceReport.Hour = (byte)dtpTime.Value.Hour;
+ DeviceReport.Minute = (byte)dtpTime.Value.Minute;
+ DeviceReport.Second = (byte)dtpTime.Value.Second;
+ DeviceReport.LogInterval500MS = (byte)(nudLogInterval.Value * 2);
+
+ try
+ {
+ ConnectionHandle.Write(0x00, DeviceReport.ToReport());
+ MessageBox.Show("Device parameters updated sucessfully.");
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error: " + ex.Message);
+ }
+ }
+
+ private void btnGetValues_Click(object sender, EventArgs e)
+ {
+ IDevice ConnectionHandle = GetDeviceConnection();
+
+ if (ConnectionHandle == null)
+ {
+ MessageBox.Show("Error: Cannot connect to DataLogger device.");
+ return;
+ }
+
+ Device_Report_t DeviceReport = new Device_Report_t();
+
+ try
+ {
+ Byte[] Report = new Byte[7];
+
+ ConnectionHandle.Read(0x00, Report);
+ DeviceReport.FromReport(Report);
+
+ try
+ {
+ dtpDate.Value = new DateTime(
+ (2000 + DeviceReport.Year),
+ DeviceReport.Month,
+ DeviceReport.Day);
+
+ dtpTime.Value = new DateTime(
+ DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,
+ DeviceReport.Hour,
+ DeviceReport.Minute,
+ DeviceReport.Second);
+ }
+ catch (Exception ex)
+ {
+ dtpDate.Value = DateTime.Now;
+ dtpTime.Value = DateTime.Now;
+ }
+
+ try
+ {
+ nudLogInterval.Value = (DeviceReport.LogInterval500MS / 2);
+ }
+ catch (Exception ex)
+ {
+ nudLogInterval.Value = nudLogInterval.Minimum;
+ }
+
+ MessageBox.Show("Device parameters retrieved sucessfully.");
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error: " + ex.Message);
+ }
+ }
+
+ private void frmDataloggerSettings_Load(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.resx b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.resx
new file mode 100644
index 000000000..ff31a6db5
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/DataLoggerSettings.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Linux.dll b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Linux.dll
new file mode 100644
index 000000000..4c19edd21
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Linux.dll
Binary files differ
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Net.dll b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Net.dll
new file mode 100644
index 000000000..2a7112fc0
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Net.dll
Binary files differ
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Win32.dll b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Win32.dll
new file mode 100644
index 000000000..3693c6ca0
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Hid.Win32.dll
Binary files differ
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Program.cs b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Program.cs
new file mode 100644
index 000000000..dc818c822
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Project1HostApp
+{
+ static class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new frmDataloggerSettings());
+ }
+ }
+}
diff --git a/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/TempLoggerHostApp.csproj b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/TempLoggerHostApp.csproj
new file mode 100644
index 000000000..e3b08928f
--- /dev/null
+++ b/Projects/TemperatureDataLogger/TempLoggerHostApp/TempLoggerHostApp/TempLoggerHostApp.csproj
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A2D66069-8CF9-4104-828C-49A73D7DB5D1}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>TemperatureLoggerHostApp</RootNamespace>
+ <AssemblyName>TemperatureLoggerHostApp</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Hid.Net, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>.\Hid.Net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Deployment" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="DataLoggerSettings.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="DataLoggerSettings.Designer.cs">
+ <DependentUpon>DataLoggerSettings.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="DataLoggerSettings.resx">
+ <DependentUpon>DataLoggerSettings.cs</DependentUpon>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ <DesignTime>True</DesignTime>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Projects/TemperatureDataLogger/TemperatureDataLogger.txt b/Projects/TemperatureDataLogger/TemperatureDataLogger.txt
index d31e24f36..3e13fd385 100644
--- a/Projects/TemperatureDataLogger/TemperatureDataLogger.txt
+++ b/Projects/TemperatureDataLogger/TemperatureDataLogger.txt
@@ -24,12 +24,14 @@
* <td>Device</td>
* </tr>
* <tr>
- * <td><b>USB Class:</b></td>
+ * <td><b>USB Classes:</b></td>
* <td>Mass Storage Device</td>
+ * <td>Human Interface Device</td>
* </tr>
* <tr>
- * <td><b>USB Subclass:</b></td>
+ * <td><b>USB Subclasses:</b></td>
* <td>Bulk-Only Transport</td>
+ * <td>Keyboard Subclass</td>
* </tr>
* <tr>
* <td><b>Relevant Standards:</b></td>
@@ -37,6 +39,7 @@
* <td>USB Bulk-Only Transport Standard</td>
* <td>SCSI Primary Commands Specification</td>
* <td>SCSI Block Commands Specification</td>
+ * <td>USBIF HID Specification, USBIF HID Usage Tables</td>
* </tr>
* <tr>
* <td><b>Usable Speeds:</b></td>
@@ -49,10 +52,12 @@
* Temperature Data Logger project. This project is a very basic USB data logger for the current temperature as reported by
* the board's temperature sensor, writing the temperature to a file stored on the board's Dataflash in a FAT filesystem
* each time a specified interval elapses. When inserted into a PC, the datalogger will appear as a standard USB Mass Storage
- * device with a single text file, which contains the logged data.
+ * device with a single text file, which contains the logged data. Files are named according to the current date when the
+ * logging commences.
*
- * Currently there is no timestamp associated with the logged data; this project can be extended by the addition of a Real
- * Time Clock chip to retain the current time/date which could be stored along with each sample.
+ * A DS1307 or compatible RTC IC is designed to be attached to the AVR's TWI bus, for the management of timestamps on the
+ * sampled data. This project will not function correctly if the RTC chip is omitted unless the DUMMY_RTC compile time token
+ * is specified - see \ref SSec_Options.
*
* Due to the host's need for exclusive access to the filesystem, the device will not log samples while connected to a host.
* For the logger to store data, the Dataflash must first be formatted by the host so that it contains a valid FAT filesystem.
@@ -68,16 +73,10 @@
* <td><b>Description:</b></td>
* </tr>
* <tr>
- * <td>LOG_FILENAME</td>
- * <td>TempDataLogger.h</td>
- * <td>Filename of the log file to write to on the device's FAT filesystem.</td>
- * </tr>
- * <tr>
- * <td>LOG_INTERVAL_10MS</td>
- * <td>TempDataLogger.h</td>
- * <td>Time between each data sample, in tens of milliseconds. Each time this period elapses, a
- * temperature sample is taken and the result stored to the Dataflash's FAT filesystem.
- * </td>
+ * <td>DUMMY_RTC</td>
+ * <td>Makefile CDEFS</td>
+ * <td>When a DS1307 RTC chip is not fitted, this token can be defined to make the demo assume a 1/1/1 01:01:01 date/time
+ * stamp at all times, effectively transforming the project into a basic data logger with no specified sample times.</td>
* </tr>
* </table>
*/
diff --git a/Projects/TemperatureDataLogger/makefile b/Projects/TemperatureDataLogger/makefile
index 1e495526c..ab29bb1be 100644
--- a/Projects/TemperatureDataLogger/makefile
+++ b/Projects/TemperatureDataLogger/makefile
@@ -130,6 +130,7 @@ SRC = $(TARGET).c \
Lib/SCSI.c \
Lib/FATFs/diskio.c \
Lib/FATFs/ff.c \
+ Lib/DS1307.c \
$(LUFA_PATH)/LUFA/Drivers/Board/Temperature.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
@@ -143,6 +144,8 @@ SRC = $(TARGET).c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MassStorage.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/MassStorage.c \
+ $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c \
+ $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/HID.c \
# List C++ source files here. (C dependencies are automatically generated.)