summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/common/timefuncs.c39
-rw-r--r--firmware/include/timefuncs.h2
-rw-r--r--firmware/usbstack/usb_storage.c42
3 files changed, 81 insertions, 2 deletions
diff --git a/firmware/common/timefuncs.c b/firmware/common/timefuncs.c
index 6fdc0b7240..f5097c8e52 100644
--- a/firmware/common/timefuncs.c
+++ b/firmware/common/timefuncs.c
@@ -193,3 +193,42 @@ time_t mktime(struct tm *t)
193 return(result); 193 return(result);
194} 194}
195#endif 195#endif
196
197int day_of_week(int m, int d, int y)
198{
199 char mo[12] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
200
201 if(m == 0 || m == 1) y--;
202 return (d + mo[m] + y + y/4 - y/100 + y/400) % 7;
203}
204
205void yearday_to_daymonth(int yd, int y, int *d, int *m)
206{
207 short t[12] = { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
208 int i;
209
210 if((y%4 == 0 && y%100 != 0) || y%400 == 0)
211 {
212 for(i=1;i<12;i++)
213 t[i]++;
214 }
215
216 yd++;
217 if(yd <= 31)
218 {
219 *d = yd;
220 *m = 0;
221 }
222 else
223 {
224 for(i=1;i<12;i++)
225 {
226 if(yd <= t[i])
227 {
228 *d = yd - t[i-1];
229 *m = i;
230 break;
231 }
232 }
233 }
234}
diff --git a/firmware/include/timefuncs.h b/firmware/include/timefuncs.h
index 45978f4e2e..52d4608287 100644
--- a/firmware/include/timefuncs.h
+++ b/firmware/include/timefuncs.h
@@ -29,6 +29,8 @@
29struct tm *get_time(void); 29struct tm *get_time(void);
30int set_time(const struct tm *tm); 30int set_time(const struct tm *tm);
31bool valid_time(const struct tm *tm); 31bool valid_time(const struct tm *tm);
32int day_of_week(int m, int d, int y);
33void yearday_to_daymonth(int yd, int y, int *d, int *m);
32#if CONFIG_RTC 34#if CONFIG_RTC
33time_t mktime(struct tm *t); 35time_t mktime(struct tm *t);
34#endif 36#endif
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index d29e731d5a..a6c960422d 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -31,6 +31,7 @@
31/* Needed to get at the audio buffer */ 31/* Needed to get at the audio buffer */
32#include "audio.h" 32#include "audio.h"
33#include "usb_storage.h" 33#include "usb_storage.h"
34#include "timefuncs.h"
34 35
35 36
36/* Enable the following define to export only the SD card slot. This 37/* Enable the following define to export only the SD card slot. This
@@ -68,8 +69,8 @@
68#define USB_BULK_RESET_REQUEST 0xff 69#define USB_BULK_RESET_REQUEST 0xff
69#define USB_BULK_GET_MAX_LUN 0xfe 70#define USB_BULK_GET_MAX_LUN 0xfe
70 71
71#define DIRECT_ACCESS_DEVICE 0x00 /* disks */ 72#define DIRECT_ACCESS_DEVICE 0x00 /* disks */
72#define DEVICE_REMOVABLE 0x80 73#define DEVICE_REMOVABLE 0x80
73 74
74#define CBW_SIGNATURE 0x43425355 75#define CBW_SIGNATURE 0x43425355
75#define CSW_SIGNATURE 0x53425355 76#define CSW_SIGNATURE 0x53425355
@@ -86,6 +87,7 @@
86#define SCSI_WRITE_10 0x2a 87#define SCSI_WRITE_10 0x2a
87#define SCSI_START_STOP_UNIT 0x1b 88#define SCSI_START_STOP_UNIT 0x1b
88#define SCSI_REPORT_LUNS 0xa0 89#define SCSI_REPORT_LUNS 0xa0
90#define SCSI_WRITE_BUFFER 0x3b
89 91
90#define UMS_STATUS_GOOD 0x00 92#define UMS_STATUS_GOOD 0x00
91#define UMS_STATUS_FAIL 0x01 93#define UMS_STATUS_FAIL 0x01
@@ -270,6 +272,7 @@ static void send_command_result(void *data,int size);
270static void send_command_failed_result(void); 272static void send_command_failed_result(void);
271static void send_block_data(void *data,int size); 273static void send_block_data(void *data,int size);
272static void receive_block_data(void *data,int size); 274static void receive_block_data(void *data,int size);
275static void receive_time(void);
273static void fill_inquiry(IF_MD_NONVOID(int lun)); 276static void fill_inquiry(IF_MD_NONVOID(int lun));
274static void send_and_read_next(void); 277static void send_and_read_next(void);
275static bool ejected[NUM_DRIVES]; 278static bool ejected[NUM_DRIVES];
@@ -288,6 +291,7 @@ static enum {
288 SENDING_RESULT, 291 SENDING_RESULT,
289 SENDING_FAILED_RESULT, 292 SENDING_FAILED_RESULT,
290 RECEIVING_BLOCKS, 293 RECEIVING_BLOCKS,
294 RECEIVING_TIME,
291 SENDING_CSW 295 SENDING_CSW
292} state = WAITING_FOR_COMMAND; 296} state = WAITING_FOR_COMMAND;
293 297
@@ -459,6 +463,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
459{ 463{
460 (void)ep; 464 (void)ep;
461 struct command_block_wrapper* cbw = (void*)cbw_buffer; 465 struct command_block_wrapper* cbw = (void*)cbw_buffer;
466 struct tm tm;
462 467
463 //logf("transfer result %X %d", status, length); 468 //logf("transfer result %X %d", status, length);
464 switch(state) { 469 switch(state) {
@@ -602,6 +607,19 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
602 cur_sense_data.ascq=0; 607 cur_sense_data.ascq=0;
603 } 608 }
604 break; 609 break;
610 case RECEIVING_TIME:
611 tm.tm_year=(tb.transfer_buffer[0]<<8)+tb.transfer_buffer[1];
612 tm.tm_yday=(tb.transfer_buffer[2]<<8)+tb.transfer_buffer[3];
613 tb.transfer_buffer[8];
614 tm.tm_hour=tb.transfer_buffer[5];
615 tm.tm_min=tb.transfer_buffer[6];
616 tm.tm_sec=tb.transfer_buffer[7];
617 yearday_to_daymonth(tm.tm_yday,tm.tm_year,&tm.tm_mday,&tm.tm_mon);
618 tm.tm_wday=day_of_week(tm.tm_mon,tm.tm_mday,tm.tm_year);
619 tm.tm_year -= 1900;
620 set_time(&tm);
621 send_csw(UMS_STATUS_GOOD);
622 break;
605 } 623 }
606} 624}
607 625
@@ -1063,6 +1081,21 @@ static void handle_scsi(struct command_block_wrapper* cbw)
1063 } 1081 }
1064 break; 1082 break;
1065 1083
1084 case SCSI_WRITE_BUFFER:
1085 if(cbw->command_block[1]==1
1086 && cbw->command_block[2]==0
1087 && cbw->command_block[3]==0x0c
1088 && cbw->command_block[4]==0
1089 && cbw->command_block[5]==0
1090 && cbw->command_block[6]==0
1091 && cbw->command_block[7]==0
1092 /* Some versions of itunes set the next byte to 0. Technically
1093 * it should be 0x0c */
1094 && (cbw->command_block[8]==0 || cbw->command_block[8]==0x0c)
1095 && cbw->command_block[9]==0)
1096 receive_time();
1097 break;
1098
1066 default: 1099 default:
1067 logf("scsi unknown cmd %x",cbw->command_block[0x0]); 1100 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
1068 send_csw(UMS_STATUS_FAIL); 1101 send_csw(UMS_STATUS_FAIL);
@@ -1091,6 +1124,11 @@ static void send_command_failed_result(void)
1091 state = SENDING_FAILED_RESULT; 1124 state = SENDING_FAILED_RESULT;
1092} 1125}
1093 1126
1127static void receive_time(void)
1128{
1129 usb_drv_recv(ep_out, tb.transfer_buffer, 12);
1130 state = RECEIVING_TIME;
1131}
1094static void receive_block_data(void *data,int size) 1132static void receive_block_data(void *data,int size)
1095{ 1133{
1096 usb_drv_recv(ep_out, data, size); 1134 usb_drv_recv(ep_out, data, size);