Creative ZVM:

* Re-enable USB
 * Acknowledge EP0SETUP packets
 * Spin disk down when no files get loaded in the bootloader
 * Clean up/fix some other stuff


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19931 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Maurus Cuelenaere 2009-02-05 21:47:54 +00:00
parent e1aee31878
commit ee1e8be37f
12 changed files with 196 additions and 155 deletions

View file

@ -203,7 +203,7 @@ static unsigned long cfs_start;
static unsigned long *sectors;
#define CFS_START ( ((hdr->partitions[1].start*hdr->sector_size) & ~0xFFFF) + 0x10000 )
#define CFS_CLUSTER2CLUSTER(x) ( CFS_START+((x)-1)*64 )
#define CFS_CLUSTER2CLUSTER(x) ( (CFS_START/512)+((x)-1)*64 )
/* Limited version of UCS -> ASCII */
static char* ucs2letostring(unsigned char* s)
@ -211,7 +211,7 @@ static char* ucs2letostring(unsigned char* s)
static char res[256];
int i;
for(i=0; (s[i] == 0 && s[i+1] == 0); i++)
for(i=0; (s[i] == 0 && s[i+1] == 0 && i<256); i++)
res[i] = s[i*2];
return (char*)&res;
@ -236,111 +236,134 @@ static void cfs_init(void)
_ata_read_sectors(0, 1, &sector);
hdr = (struct main_header*)&sector;
//printf("CFS is at 0x%x", CFS_START);
logf("CFS is at 0x%x [0x%x]", CFS_START, CFS_START/512);
/* Read CFS header */
_ata_read_sectors(CFS_START/512, 64, &sector2);
cfs = (struct cfs_header*)&sector2;
//printf("First inode = %d", cfs->first_inode);
logf("First inode = 0x%x", cfs->first_inode);
/* Read root inode */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2);
root_inode = (struct cfs_inode*)&sector2;
logf("Root inode = 0x%x", root_inode);
logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]);
/* Read root inode's first sector */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), 64, &sector2);
root_direntry = (struct cfs_direntry*)&sector2;
root_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry));
logf("0x%x", root_direntry->identifier);
logf("%d", root_direntry->items);
/* Search VFAT inode */
for(i=0; i < root_direntry->items; i++)
{
//printf(" * [%s] at 0x%x\n", ucs2letostring(&root_direntry_items[i].string[0]), root_direntry_items[i].inode_number);
if(strcmp(ucs2letostring(&root_direntry_items[i].string[0]), "VFAT") == 0)
vfat_inode_nr = root_direntry_items[i].inode_number;
if(root_direntry_items[i].inode_number != 0)
{
//logf(" * [%s] at 0x%x", ucs2letostring(&root_direntry_items[i].string[0]), root_direntry_items[i].inode_number);
if(strcmp(ucs2letostring(&root_direntry_items[i].string[0]), "VFAT") == 0)
vfat_inode_nr = root_direntry_items[i].inode_number;
}
}
/* Read VFAT inode */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode_nr), 64, &sector2);
vfat_inode = (struct cfs_inode*)&sector2;
/* Read VFAT inode's first sector */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode->first_class_chain[0]), 64, &sector2);
vfat_direntry = (struct cfs_direntry*)&sector2;
vfat_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry));
/* Search for VFAT's subinodes */
for(i=0; i < vfat_direntry->items; i++)
logf("VFAT inode = 0x%x", vfat_inode_nr);
if(vfat_inode_nr != 0)
{
//printf(" * [%s] at 0x%x\n", ucs2letostring(&vfat_direntry_items[i].string[0]), vfat_direntry_items[i].inode_number);
if(i > 0)
vfat_inodes_nr[i-1] = vfat_direntry_items[i].inode_number;
}
/* Read VFAT inode */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode_nr), 64, &sector2);
vfat_inode = (struct cfs_inode*)&sector2;
/* Determine size of VFAT file */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[1]), 1, &sector);
inode = (struct cfs_inode*)&sector;
sectors = (unsigned long*)buffer_alloc(VFAT_SECTOR_SIZE(inode->filesize));
/* Read VFAT inode's first sector */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode->first_class_chain[0]), 64, &sector2);
vfat_direntry = (struct cfs_direntry*)&sector2;
vfat_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry));
//printf("VFAT file size: 0x%x", inode->filesize);
/* Search for VFAT's subinodes */
for(i=0; i < vfat_direntry->items; i++)
{
logf(" * [%s] at 0x%x\n", ucs2letostring(&vfat_direntry_items[i].string[0]), vfat_direntry_items[i].inode_number);
if(i > 0)
vfat_inodes_nr[i-1] = vfat_direntry_items[i].inode_number;
}
/* Clear data sectors */
memset(&sectors, 0, VFAT_SECTOR_SIZE(inode->filesize)*sizeof(unsigned long));
/* Read all data sectors' addresses in memory */
vfat_sector_count = 0;
for(i=0; vfat_inodes_nr[i] != 0; i++)
{
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[i]), 1, &sector);
/* Determine size of VFAT file */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[1]), 1, &sector);
inode = (struct cfs_inode*)&sector;
#ifndef BOOTLOADER
sectors = (unsigned long*)buffer_alloc(VFAT_SECTOR_SIZE(inode->filesize));
#else
static unsigned long _sector[VFAT_SECTOR_SIZE(1024*1024*1024)]; /* 1GB guess */
sectors = _sector;
#endif
/* Read second & third class chain */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_first_cluster), 64, &vfat_data[0]);
_ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_second_cluster), 64, &vfat_data[1]);
logf("VFAT file size: 0x%x", inode->filesize);
/* First class chain */
for(j=0; j<12; j++)
/* Clear data sectors */
memset(&sectors, 0, VFAT_SECTOR_SIZE(inode->filesize)*sizeof(unsigned long));
/* Read all data sectors' addresses in memory */
vfat_sector_count = 0;
for(i=0; vfat_inodes_nr[i] != 0; i++)
{
if( (inode->first_class_chain[j] & 0xFFFF) != 0xFFFF &&
inode->first_class_chain[j] != 0
)
sectors[vfat_sector_count++] = inode->first_class_chain[j];
}
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[i]), 1, &sector);
inode = (struct cfs_inode*)&sector;
/* Second class chain */
for(j=0; j<0x8000/4; j++)
{
if( (vfat_data[0][j] & 0xFFFF) != 0xFFFF &&
vfat_data[0][j] != 0
)
sectors[vfat_sector_count++] = vfat_data[0][j];
}
/* Read second & third class chain */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_first_cluster), 64, &vfat_data[0]);
_ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_second_cluster), 64, &vfat_data[1]);
/* Third class chain */
for(j=0; j<0x8000/4; j++)
{
if( (vfat_data[1][j] & 0xFFFF) != 0xFFFF &&
vfat_data[1][j] != 0
)
/* First class chain */
for(j=0; j<12; j++)
{
memset(&vfat_data[0], 0, 0x8000*sizeof(unsigned int));
if( (inode->first_class_chain[j] & 0xFFFF) != 0xFFFF &&
inode->first_class_chain[j] != 0
)
sectors[vfat_sector_count++] = inode->first_class_chain[j];
}
/* Read third class subchain(s) */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_data[1][j]), 64, &vfat_data[0]);
/* Second class chain */
for(j=0; j<0x8000/4; j++)
{
if( (vfat_data[0][j] & 0xFFFF) != 0xFFFF &&
vfat_data[0][j] != 0
)
sectors[vfat_sector_count++] = vfat_data[0][j];
}
for(k=0; k<0x8000/4; k++)
/* Third class chain */
for(j=0; j<0x8000/4; j++)
{
if( (vfat_data[1][j] & 0xFFFF) != 0xFFFF &&
vfat_data[1][j] != 0
)
{
if( (vfat_data[0][k] & 0xFFFF) != 0xFFFF &&
vfat_data[0][k] != 0
)
sectors[vfat_sector_count++] = vfat_data[0][k];
memset(&vfat_data[0], 0, 0x8000*sizeof(unsigned int));
/* Read third class subchain(s) */
_ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_data[1][j]), 64, &vfat_data[0]);
for(k=0; k<0x8000/4; k++)
{
if( (vfat_data[0][k] & 0xFFFF) != 0xFFFF &&
vfat_data[0][k] != 0
)
sectors[vfat_sector_count++] = vfat_data[0][k];
}
}
}
}
}
//printf("Sector count: %d 0x%x", vfat_sector_count, vfat_sector_count);
logf("Sector count: %d 0x%x", vfat_sector_count, vfat_sector_count);
}
else
logf("Cannot find virtual FAT filesystem!"); //TODO: panicf
cfs_inited = true;
}
@ -386,6 +409,7 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const v
if(!cfs_inited)
cfs_init();
#if 0 /* Disabled for now */
/* Check if count is lesser than or equal to 1 native CFS sector */
if(count <= 64)
return _ata_write_sectors(IF_MV2(drive,) map_sector(start), count, buf);
@ -406,8 +430,16 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const v
return ret;
}
#else
(void)start;
(void)count;
(void)buf;
return 0;
#endif
}
#ifdef BOOTLOADER
/*
---------------------------------------------------------------------------
MiniFileSystem parsing code
@ -487,3 +519,5 @@ int load_minifs_file(char* filename, unsigned char* location)
return files[found].size;
}
#endif

View file

@ -82,6 +82,8 @@ void ata_reset(void);
void ata_device_init(void);
bool ata_is_coldstart(void);
void ide_power_enable(bool on);
#ifdef BOOTLOADER
int load_minifs_file(char* filename, unsigned char* location);
#endif
#endif

View file

@ -27,6 +27,7 @@
#include "button-target.h"
#include "i2c-dm320.h"
#include "sprintf.h"
#include "logf.h"
#ifdef BUTTON_DEBUG
#include "lcd-target.h"
@ -36,22 +37,22 @@
#ifndef ZEN_VISION
/* Creative Zen Vision:M */
#define BTN_LEFT 0x5F00
#define BTN_RIGHT 0x4F00
#define BTN_BACK 0xBF00
#define BTN_CUSTOM 0x8F00
#define BTN_PLAY 0x2F00
#define BTN_POWER 0x0F00
#define BTN_MENU 0x9F00
#define BTN_HOLD 0x9F06
#define BTN_UNHOLD 0xAF06
#define BTN_LEFT 0xAF00
#define BTN_RIGHT 0xA700
#define BTN_BACK 0xDF00
#define BTN_CUSTOM 0xC700
#define BTN_PLAY 0x9700
#define BTN_POWER 0x8700
#define BTN_MENU 0xCF00
#define BTN_HOLD 0xCF07
#define BTN_UNHOLD 0xD707
#define BTN_REL 1
#define BTN_TOUCHPAD_PRESS 0x1F00
#define BTN_TOUCHPAD_PRESS 0x8F00
#define BTN_TOUCHPAD_SCROLL_DOWN 0x0F03
#define BTN_TOUCHPAD_CORNER_DOWN 0xAF00
#define BTN_TOUCHPAD_CORNER_UP 0x3F00
#define BTN_TOUCHPAD_CORNER_DOWN 0xD700
#define BTN_TOUCHPAD_CORNER_UP 0x9F00
#define BTN_TOUCHPAD_SCROLL_UP 0x0F04
#define HEADPHONE_PLUGIN_A 0x5707
@ -63,8 +64,8 @@
#define DOCK_UNPLUG 0xDF06
#define DOCK_USB_INSERT 0x2F06
#define DOCK_USB_UNPLUG 0x3F06
#define DOCK_POWER_INSERT 0x2707
#define DOCK_POWER_UNPLUG 0x2F07
#define DOCK_POWER_INSERT 0x1707
#define DOCK_POWER_UNPLUG 0x1F07
#else
/* Creative Zen Vision */
@ -272,6 +273,8 @@ void GIO0(void)
lcd_update();
sw = !sw;
#endif
logf("PIC: 0x%x", (unsigned int)((msg[3] << 24) |
(msg[2] << 16) | (msg[1] << 8) | msg[0]));
}
static void send_command_to_pic(const unsigned char in, unsigned char* out,
@ -335,7 +338,8 @@ bool button_usb_connected(void)
{
return (bool)(nonbtn & NONBUTTON_USB);
}
#ifndef BOOTLOADER
int pic_dbg_num_items(void)
{
return 13;
@ -376,3 +380,4 @@ char* pic_dbg_item(int selected_item, void *data, char *buffer, size_t buffer_le
}
return NULL;
}
#endif

View file

@ -37,7 +37,7 @@ bool usb_drv_connected(void)
int usb_detect(void)
{
if(button_usb_connected())
if(usb_drv_connected())
return USB_INSERTED;
else
return USB_EXTRACTED;

View file

@ -65,11 +65,11 @@
b = value >> 16;
#define ZVM_SPECIFIC asm volatile( \
/*#define ZVM_SPECIFIC asm volatile( \
"LDR R12, =0x50FFC000\n" \
"LDRH R12, [R12]\n" \
: : : "r12")
//#define ZVM_SPECIFIC
: : : "r12");*/
#define ZVM_SPECIFIC
#define USE_IRAM

View file

@ -235,7 +235,7 @@ data_abort_handler:
mov r1, #2
b UIE
#if defined(STUB) || defined(BOOTLOADER)
#ifdef STUB
UIE:
b UIE
#endif

View file

@ -146,7 +146,7 @@ int i2c_read(unsigned short address, unsigned char* buf, int count)
void i2c_init(void)
{
#if 0 //TODO: mimic OF I2C clock settings; currently this is done by the bootloader
#ifdef CREATIVE_ZVx //TODO: mimic OF I2C clock settings; currently this is done by the bootloader
IO_CLK_MOD2 &= ~CLK_MOD2_I2C; // turn I²C clock off (just to be sure)
IO_CLK_LPCTL1 &= ~1; // set Powerdown mode to off
IO_CLK_SEL0 &= ~0x800; // set I²C clock to PLLA