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.

pull/1469/head
Dean Camera 15 years ago
parent 03ee87b35a
commit dd995683ea

File diff suppressed because one or more lines are too long

@ -17,6 +17,8 @@
* -# Add ability to get number of bytes not written with pipe/endpoint write routines after an error
* -# Add standardized descriptor names to class driver structures
* -# Correct mishandling of error cases in Mass Storage demos
* -# FIX BROKEN RNDIS HOST CLASS DRIVER (BLOCKING)
* -# TEST AND CORRECT TPI PROGRAMMING SUPPORT IN THE AVRISP-MKII PROJECT (BLOCKING)
* - Documentation/Support
* -# Remake AVRStudio project files
* -# Add detailed overviews of how each demo works
@ -32,6 +34,7 @@
* -# Finish MIDI class Bootloader
* -# Finish SideShow demo
* -# Finish StandaloneProgrammer project
* -# Finish Webserver project
* - Ports
* -# AVR32 UC3B series microcontrollers
* -# Atmel ARM7 series microcontrollers

@ -265,7 +265,7 @@
* 0x2063
* </td>
* <td>
* <i>Currently Unallocated</i>
* Mass Storage/HID Interface Datalogger Project
* </td>
* </tr>
*

@ -197,6 +197,7 @@ CDEFS += -DAUX_LINE_MASK="(1 << 4)"
CDEFS += -DVTARGET_ADC_CHANNEL=2
CDEFS += -DENABLE_ISP_PROTOCOL
CDEFS += -DENABLE_XPROG_PROTOCOL
#CDEFS += -DXPROG_VIA_HARDWARE_USART
# Place -D or -U options here for ASM sources

@ -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"
@ -209,6 +272,14 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex,
break;
}
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;
}

@ -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: */

@ -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;
}

@ -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

@ -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);
}

@ -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. */

@ -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);
}
}

@ -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

@ -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

@ -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;
}
}

@ -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)
{
}
}
}

@ -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>

@ -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());
}
}
}

@ -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>

@ -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>
*/

@ -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.)

Loading…
Cancel
Save