diff options
Diffstat (limited to 'lib/lufa/Projects/TempDataLogger/TempDataLogger.c')
| -rw-r--r-- | lib/lufa/Projects/TempDataLogger/TempDataLogger.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/lib/lufa/Projects/TempDataLogger/TempDataLogger.c b/lib/lufa/Projects/TempDataLogger/TempDataLogger.c new file mode 100644 index 000000000..1dc267a6f --- /dev/null +++ b/lib/lufa/Projects/TempDataLogger/TempDataLogger.c | |||
| @@ -0,0 +1,331 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * | ||
| 33 | * Main source file for the TemperatureDataLogger project. This file contains the main tasks of | ||
| 34 | * the project and is responsible for the initial application hardware configuration. | ||
| 35 | */ | ||
| 36 | |||
| 37 | #include "TempDataLogger.h" | ||
| 38 | |||
| 39 | /** LUFA Mass Storage Class driver interface configuration and state information. This structure is | ||
| 40 | * passed to all Mass Storage Class driver functions, so that multiple instances of the same class | ||
| 41 | * within a device can be differentiated from one another. | ||
| 42 | */ | ||
| 43 | USB_ClassInfo_MS_Device_t Disk_MS_Interface = | ||
| 44 | { | ||
| 45 | .Config = | ||
| 46 | { | ||
| 47 | .InterfaceNumber = INTERFACE_ID_MassStorage, | ||
| 48 | .DataINEndpoint = | ||
| 49 | { | ||
| 50 | .Address = MASS_STORAGE_IN_EPADDR, | ||
| 51 | .Size = MASS_STORAGE_IO_EPSIZE, | ||
| 52 | .Banks = 1, | ||
| 53 | }, | ||
| 54 | .DataOUTEndpoint = | ||
| 55 | { | ||
| 56 | .Address = MASS_STORAGE_OUT_EPADDR, | ||
| 57 | .Size = MASS_STORAGE_IO_EPSIZE, | ||
| 58 | .Banks = 1, | ||
| 59 | }, | ||
| 60 | .TotalLUNs = 1, | ||
| 61 | }, | ||
| 62 | }; | ||
| 63 | |||
| 64 | /** Buffer to hold the previously generated HID report, for comparison purposes inside the HID class driver. */ | ||
| 65 | static uint8_t PrevHIDReportBuffer[GENERIC_REPORT_SIZE]; | ||
| 66 | |||
| 67 | /** LUFA HID Class driver interface configuration and state information. This structure is | ||
| 68 | * passed to all HID Class driver functions, so that multiple instances of the same class | ||
| 69 | * within a device can be differentiated from one another. | ||
| 70 | */ | ||
| 71 | USB_ClassInfo_HID_Device_t Generic_HID_Interface = | ||
| 72 | { | ||
| 73 | .Config = | ||
| 74 | { | ||
| 75 | .InterfaceNumber = INTERFACE_ID_HID, | ||
| 76 | .ReportINEndpoint = | ||
| 77 | { | ||
| 78 | .Address = GENERIC_IN_EPADDR, | ||
| 79 | .Size = GENERIC_EPSIZE, | ||
| 80 | .Banks = 1, | ||
| 81 | }, | ||
| 82 | .PrevReportINBuffer = PrevHIDReportBuffer, | ||
| 83 | .PrevReportINBufferSize = sizeof(PrevHIDReportBuffer), | ||
| 84 | }, | ||
| 85 | }; | ||
| 86 | |||
| 87 | /** Non-volatile Logging Interval value in EEPROM, stored as a number of 500ms ticks */ | ||
| 88 | static uint8_t EEMEM LoggingInterval500MS_EEPROM = DEFAULT_LOG_INTERVAL; | ||
| 89 | |||
| 90 | /** SRAM Logging Interval value fetched from EEPROM, stored as a number of 500ms ticks */ | ||
| 91 | static uint8_t LoggingInterval500MS_SRAM; | ||
| 92 | |||
| 93 | /** Total number of 500ms logging ticks elapsed since the last log value was recorded */ | ||
| 94 | static uint16_t CurrentLoggingTicks; | ||
| 95 | |||
| 96 | /** FAT Fs structure to hold the internal state of the FAT driver for the Dataflash contents. */ | ||
| 97 | static FATFS DiskFATState; | ||
| 98 | |||
| 99 | /** FAT Fs structure to hold a FAT file handle for the log data write destination. */ | ||
| 100 | static FIL TempLogFile; | ||
| 101 | |||
| 102 | |||
| 103 | /** ISR to handle the 500ms ticks for sampling and data logging */ | ||
| 104 | ISR(TIMER1_COMPA_vect, ISR_BLOCK) | ||
| 105 | { | ||
| 106 | /* Signal a 500ms tick has elapsed to the RTC */ | ||
| 107 | RTC_Tick500ms(); | ||
| 108 | |||
| 109 | /* Check to see if the logging interval has expired */ | ||
| 110 | if (++CurrentLoggingTicks < LoggingInterval500MS_SRAM) | ||
| 111 | return; | ||
| 112 | |||
| 113 | /* Reset log tick counter to prepare for next logging interval */ | ||
| 114 | CurrentLoggingTicks = 0; | ||
| 115 | |||
| 116 | uint8_t LEDMask = LEDs_GetLEDs(); | ||
| 117 | LEDs_SetAllLEDs(LEDMASK_USB_BUSY); | ||
| 118 | |||
| 119 | /* Only log when not connected to a USB host */ | ||
| 120 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
| 121 | { | ||
| 122 | TimeDate_t CurrentTimeDate; | ||
| 123 | RTC_GetTimeDate(&CurrentTimeDate); | ||
| 124 | |||
| 125 | char LineBuffer[100]; | ||
| 126 | uint16_t BytesWritten; | ||
| 127 | |||
| 128 | BytesWritten = sprintf(LineBuffer, "%02d/%02d/20%02d, %02d:%02d:%02d, %d Degrees\r\n", | ||
| 129 | CurrentTimeDate.Day, CurrentTimeDate.Month, CurrentTimeDate.Year, | ||
| 130 | CurrentTimeDate.Hour, CurrentTimeDate.Minute, CurrentTimeDate.Second, | ||
| 131 | Temperature_GetTemperature()); | ||
| 132 | |||
| 133 | f_write(&TempLogFile, LineBuffer, BytesWritten, &BytesWritten); | ||
| 134 | f_sync(&TempLogFile); | ||
| 135 | } | ||
| 136 | |||
| 137 | LEDs_SetAllLEDs(LEDMask); | ||
| 138 | } | ||
| 139 | |||
| 140 | /** Main program entry point. This routine contains the overall program flow, including initial | ||
| 141 | * setup of all components and the main program loop. | ||
| 142 | */ | ||
| 143 | int main(void) | ||
| 144 | { | ||
| 145 | SetupHardware(); | ||
| 146 | |||
| 147 | /* Fetch logging interval from EEPROM */ | ||
| 148 | LoggingInterval500MS_SRAM = eeprom_read_byte(&LoggingInterval500MS_EEPROM); | ||
| 149 | |||
| 150 | /* Check if the logging interval is invalid (0xFF) indicating that the EEPROM is blank */ | ||
| 151 | if (LoggingInterval500MS_SRAM == 0xFF) | ||
| 152 | LoggingInterval500MS_SRAM = DEFAULT_LOG_INTERVAL; | ||
| 153 | |||
| 154 | /* Mount and open the log file on the Dataflash FAT partition */ | ||
| 155 | OpenLogFile(); | ||
| 156 | |||
| 157 | LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | ||
| 158 | GlobalInterruptEnable(); | ||
| 159 | |||
| 160 | for (;;) | ||
| 161 | { | ||
| 162 | MS_Device_USBTask(&Disk_MS_Interface); | ||
| 163 | HID_Device_USBTask(&Generic_HID_Interface); | ||
| 164 | USB_USBTask(); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | /** Opens the log file on the Dataflash's FAT formatted partition according to the current date */ | ||
| 169 | void OpenLogFile(void) | ||
| 170 | { | ||
| 171 | char LogFileName[12]; | ||
| 172 | |||
| 173 | /* Get the current date for the filename as "DDMMYY.csv" */ | ||
| 174 | TimeDate_t CurrentTimeDate; | ||
| 175 | RTC_GetTimeDate(&CurrentTimeDate); | ||
| 176 | sprintf(LogFileName, "%02d%02d%02d.csv", CurrentTimeDate.Day, CurrentTimeDate.Month, CurrentTimeDate.Year); | ||
| 177 | |||
| 178 | /* Mount the storage device, open the file */ | ||
| 179 | f_mount(0, &DiskFATState); | ||
| 180 | f_open(&TempLogFile, LogFileName, FA_OPEN_ALWAYS | FA_WRITE); | ||
| 181 | f_lseek(&TempLogFile, TempLogFile.fsize); | ||
| 182 | } | ||
| 183 | |||
| 184 | /** Closes the open data log file on the Dataflash's FAT formatted partition */ | ||
| 185 | void CloseLogFile(void) | ||
| 186 | { | ||
| 187 | /* Sync any data waiting to be written, unmount the storage device */ | ||
| 188 | f_sync(&TempLogFile); | ||
| 189 | f_close(&TempLogFile); | ||
| 190 | } | ||
| 191 | |||
| 192 | /** Configures the board hardware and chip peripherals for the demo's functionality. */ | ||
| 193 | void SetupHardware(void) | ||
| 194 | { | ||
| 195 | #if (ARCH == ARCH_AVR8) | ||
| 196 | /* Disable watchdog if enabled by bootloader/fuses */ | ||
| 197 | MCUSR &= ~(1 << WDRF); | ||
| 198 | wdt_disable(); | ||
| 199 | |||
| 200 | /* Disable clock division */ | ||
| 201 | clock_prescale_set(clock_div_1); | ||
| 202 | #endif | ||
| 203 | |||
| 204 | /* Hardware Initialization */ | ||
| 205 | LEDs_Init(); | ||
| 206 | ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_128); | ||
| 207 | Temperature_Init(); | ||
| 208 | Dataflash_Init(); | ||
| 209 | USB_Init(); | ||
| 210 | TWI_Init(TWI_BIT_PRESCALE_4, TWI_BITLENGTH_FROM_FREQ(4, 50000)); | ||
| 211 | RTC_Init(); | ||
| 212 | |||
| 213 | /* 500ms logging interval timer configuration */ | ||
| 214 | OCR1A = (((F_CPU / 256) / 2) - 1); | ||
| 215 | TCCR1B = (1 << WGM12) | (1 << CS12); | ||
| 216 | TIMSK1 = (1 << OCIE1A); | ||
| 217 | |||
| 218 | /* Check if the Dataflash is working, abort if not */ | ||
| 219 | if (!(DataflashManager_CheckDataflashOperation())) | ||
| 220 | { | ||
| 221 | LEDs_SetAllLEDs(LEDMASK_USB_ERROR); | ||
| 222 | for(;;); | ||
| 223 | } | ||
| 224 | |||
| 225 | /* Clear Dataflash sector protections, if enabled */ | ||
| 226 | DataflashManager_ResetDataflashProtections(); | ||
| 227 | } | ||
| 228 | |||
| 229 | /** Event handler for the library USB Connection event. */ | ||
| 230 | void EVENT_USB_Device_Connect(void) | ||
| 231 | { | ||
| 232 | LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); | ||
| 233 | |||
| 234 | /* Close the log file so that the host has exclusive file system access */ | ||
| 235 | CloseLogFile(); | ||
| 236 | } | ||
| 237 | |||
| 238 | /** Event handler for the library USB Disconnection event. */ | ||
| 239 | void EVENT_USB_Device_Disconnect(void) | ||
| 240 | { | ||
| 241 | LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); | ||
| 242 | |||
| 243 | /* Mount and open the log file on the Dataflash FAT partition */ | ||
| 244 | OpenLogFile(); | ||
| 245 | } | ||
| 246 | |||
| 247 | /** Event handler for the library USB Configuration Changed event. */ | ||
| 248 | void EVENT_USB_Device_ConfigurationChanged(void) | ||
| 249 | { | ||
| 250 | bool ConfigSuccess = true; | ||
| 251 | |||
| 252 | ConfigSuccess &= HID_Device_ConfigureEndpoints(&Generic_HID_Interface); | ||
| 253 | ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface); | ||
| 254 | |||
| 255 | LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); | ||
| 256 | } | ||
| 257 | |||
| 258 | /** Event handler for the library USB Control Request reception event. */ | ||
| 259 | void EVENT_USB_Device_ControlRequest(void) | ||
| 260 | { | ||
| 261 | MS_Device_ProcessControlRequest(&Disk_MS_Interface); | ||
| 262 | HID_Device_ProcessControlRequest(&Generic_HID_Interface); | ||
| 263 | } | ||
| 264 | |||
| 265 | /** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed. | ||
| 266 | * | ||
| 267 | * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced | ||
| 268 | */ | ||
| 269 | bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) | ||
| 270 | { | ||
| 271 | bool CommandSuccess; | ||
| 272 | |||
| 273 | LEDs_SetAllLEDs(LEDMASK_USB_BUSY); | ||
| 274 | CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo); | ||
| 275 | LEDs_SetAllLEDs(LEDMASK_USB_READY); | ||
| 276 | |||
| 277 | return CommandSuccess; | ||
| 278 | } | ||
| 279 | |||
| 280 | /** HID class driver callback function for the creation of HID reports to the host. | ||
| 281 | * | ||
| 282 | * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced | ||
| 283 | * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID | ||
| 284 | * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature | ||
| 285 | * \param[out] ReportData Pointer to a buffer where the created report should be stored | ||
| 286 | * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) | ||
| 287 | * | ||
| 288 | * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent | ||
| 289 | */ | ||
| 290 | bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, | ||
| 291 | uint8_t* const ReportID, | ||
| 292 | const uint8_t ReportType, | ||
| 293 | void* ReportData, | ||
| 294 | uint16_t* const ReportSize) | ||
| 295 | { | ||
| 296 | Device_Report_t* ReportParams = (Device_Report_t*)ReportData; | ||
| 297 | |||
| 298 | RTC_GetTimeDate(&ReportParams->TimeDate); | ||
| 299 | |||
| 300 | ReportParams->LogInterval500MS = LoggingInterval500MS_SRAM; | ||
| 301 | |||
| 302 | *ReportSize = sizeof(Device_Report_t); | ||
| 303 | return true; | ||
| 304 | } | ||
| 305 | |||
| 306 | /** HID class driver callback function for the processing of HID reports from the host. | ||
| 307 | * | ||
| 308 | * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced | ||
| 309 | * \param[in] ReportID Report ID of the received report from the host | ||
| 310 | * \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature | ||
| 311 | * \param[in] ReportData Pointer to a buffer where the received report has been stored | ||
| 312 | * \param[in] ReportSize Size in bytes of the received HID report | ||
| 313 | */ | ||
| 314 | void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, | ||
| 315 | const uint8_t ReportID, | ||
| 316 | const uint8_t ReportType, | ||
| 317 | const void* ReportData, | ||
| 318 | const uint16_t ReportSize) | ||
| 319 | { | ||
| 320 | Device_Report_t* ReportParams = (Device_Report_t*)ReportData; | ||
| 321 | |||
| 322 | RTC_SetTimeDate(&ReportParams->TimeDate); | ||
| 323 | |||
| 324 | /* If the logging interval has changed from its current value, write it to EEPROM */ | ||
| 325 | if (LoggingInterval500MS_SRAM != ReportParams->LogInterval500MS) | ||
| 326 | { | ||
| 327 | LoggingInterval500MS_SRAM = ReportParams->LogInterval500MS; | ||
| 328 | eeprom_update_byte(&LoggingInterval500MS_EEPROM, LoggingInterval500MS_SRAM); | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
