mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Add support for setting the clock using a special SCSI command. This is the same method that itunes uses, and there are host-side tools for it (e.g. libgpod)
Flyspray: FS#10514 Author: Laurent Papier and myself git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22255 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
6cea3308d0
commit
ed73a3274c
3 changed files with 81 additions and 2 deletions
|
|
@ -193,3 +193,42 @@ time_t mktime(struct tm *t)
|
|||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
int day_of_week(int m, int d, int y)
|
||||
{
|
||||
char mo[12] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
|
||||
|
||||
if(m == 0 || m == 1) y--;
|
||||
return (d + mo[m] + y + y/4 - y/100 + y/400) % 7;
|
||||
}
|
||||
|
||||
void yearday_to_daymonth(int yd, int y, int *d, int *m)
|
||||
{
|
||||
short t[12] = { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
|
||||
int i;
|
||||
|
||||
if((y%4 == 0 && y%100 != 0) || y%400 == 0)
|
||||
{
|
||||
for(i=1;i<12;i++)
|
||||
t[i]++;
|
||||
}
|
||||
|
||||
yd++;
|
||||
if(yd <= 31)
|
||||
{
|
||||
*d = yd;
|
||||
*m = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=1;i<12;i++)
|
||||
{
|
||||
if(yd <= t[i])
|
||||
{
|
||||
*d = yd - t[i-1];
|
||||
*m = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
struct tm *get_time(void);
|
||||
int set_time(const struct tm *tm);
|
||||
bool valid_time(const struct tm *tm);
|
||||
int day_of_week(int m, int d, int y);
|
||||
void yearday_to_daymonth(int yd, int y, int *d, int *m);
|
||||
#if CONFIG_RTC
|
||||
time_t mktime(struct tm *t);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
/* Needed to get at the audio buffer */
|
||||
#include "audio.h"
|
||||
#include "usb_storage.h"
|
||||
#include "timefuncs.h"
|
||||
|
||||
|
||||
/* Enable the following define to export only the SD card slot. This
|
||||
|
|
@ -68,8 +69,8 @@
|
|||
#define USB_BULK_RESET_REQUEST 0xff
|
||||
#define USB_BULK_GET_MAX_LUN 0xfe
|
||||
|
||||
#define DIRECT_ACCESS_DEVICE 0x00 /* disks */
|
||||
#define DEVICE_REMOVABLE 0x80
|
||||
#define DIRECT_ACCESS_DEVICE 0x00 /* disks */
|
||||
#define DEVICE_REMOVABLE 0x80
|
||||
|
||||
#define CBW_SIGNATURE 0x43425355
|
||||
#define CSW_SIGNATURE 0x53425355
|
||||
|
|
@ -86,6 +87,7 @@
|
|||
#define SCSI_WRITE_10 0x2a
|
||||
#define SCSI_START_STOP_UNIT 0x1b
|
||||
#define SCSI_REPORT_LUNS 0xa0
|
||||
#define SCSI_WRITE_BUFFER 0x3b
|
||||
|
||||
#define UMS_STATUS_GOOD 0x00
|
||||
#define UMS_STATUS_FAIL 0x01
|
||||
|
|
@ -270,6 +272,7 @@ static void send_command_result(void *data,int size);
|
|||
static void send_command_failed_result(void);
|
||||
static void send_block_data(void *data,int size);
|
||||
static void receive_block_data(void *data,int size);
|
||||
static void receive_time(void);
|
||||
static void fill_inquiry(IF_MD_NONVOID(int lun));
|
||||
static void send_and_read_next(void);
|
||||
static bool ejected[NUM_DRIVES];
|
||||
|
|
@ -288,6 +291,7 @@ static enum {
|
|||
SENDING_RESULT,
|
||||
SENDING_FAILED_RESULT,
|
||||
RECEIVING_BLOCKS,
|
||||
RECEIVING_TIME,
|
||||
SENDING_CSW
|
||||
} state = WAITING_FOR_COMMAND;
|
||||
|
||||
|
|
@ -459,6 +463,7 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
|
|||
{
|
||||
(void)ep;
|
||||
struct command_block_wrapper* cbw = (void*)cbw_buffer;
|
||||
struct tm tm;
|
||||
|
||||
//logf("transfer result %X %d", status, length);
|
||||
switch(state) {
|
||||
|
|
@ -602,6 +607,19 @@ void usb_storage_transfer_complete(int ep,int dir,int status,int length)
|
|||
cur_sense_data.ascq=0;
|
||||
}
|
||||
break;
|
||||
case RECEIVING_TIME:
|
||||
tm.tm_year=(tb.transfer_buffer[0]<<8)+tb.transfer_buffer[1];
|
||||
tm.tm_yday=(tb.transfer_buffer[2]<<8)+tb.transfer_buffer[3];
|
||||
tb.transfer_buffer[8];
|
||||
tm.tm_hour=tb.transfer_buffer[5];
|
||||
tm.tm_min=tb.transfer_buffer[6];
|
||||
tm.tm_sec=tb.transfer_buffer[7];
|
||||
yearday_to_daymonth(tm.tm_yday,tm.tm_year,&tm.tm_mday,&tm.tm_mon);
|
||||
tm.tm_wday=day_of_week(tm.tm_mon,tm.tm_mday,tm.tm_year);
|
||||
tm.tm_year -= 1900;
|
||||
set_time(&tm);
|
||||
send_csw(UMS_STATUS_GOOD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1063,6 +1081,21 @@ static void handle_scsi(struct command_block_wrapper* cbw)
|
|||
}
|
||||
break;
|
||||
|
||||
case SCSI_WRITE_BUFFER:
|
||||
if(cbw->command_block[1]==1
|
||||
&& cbw->command_block[2]==0
|
||||
&& cbw->command_block[3]==0x0c
|
||||
&& cbw->command_block[4]==0
|
||||
&& cbw->command_block[5]==0
|
||||
&& cbw->command_block[6]==0
|
||||
&& cbw->command_block[7]==0
|
||||
/* Some versions of itunes set the next byte to 0. Technically
|
||||
* it should be 0x0c */
|
||||
&& (cbw->command_block[8]==0 || cbw->command_block[8]==0x0c)
|
||||
&& cbw->command_block[9]==0)
|
||||
receive_time();
|
||||
break;
|
||||
|
||||
default:
|
||||
logf("scsi unknown cmd %x",cbw->command_block[0x0]);
|
||||
send_csw(UMS_STATUS_FAIL);
|
||||
|
|
@ -1091,6 +1124,11 @@ static void send_command_failed_result(void)
|
|||
state = SENDING_FAILED_RESULT;
|
||||
}
|
||||
|
||||
static void receive_time(void)
|
||||
{
|
||||
usb_drv_recv(ep_out, tb.transfer_buffer, 12);
|
||||
state = RECEIVING_TIME;
|
||||
}
|
||||
static void receive_block_data(void *data,int size)
|
||||
{
|
||||
usb_drv_recv(ep_out, data, size);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue