1
0
Fork 0
forked from len0rd/rockbox

Accept FS#7134 - Sansa: external sd card support by Antonius Hellmann with some tweaks. All testers have given the green light. (Now for the RED ?? ;).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13741 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2007-06-30 02:08:27 +00:00
parent 189a5f812f
commit 1167e3c72f
22 changed files with 886 additions and 540 deletions

View file

@ -59,7 +59,7 @@
#include "fat.h" #include "fat.h"
#include "mas.h" #include "mas.h"
#include "eeprom_24cxx.h" #include "eeprom_24cxx.h"
#ifdef HAVE_MMC #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
#include "ata_mmc.h" #include "ata_mmc.h"
#endif #endif
#if CONFIG_TUNER #if CONFIG_TUNER
@ -1524,8 +1524,8 @@ static bool view_battery(void)
#endif #endif
#ifndef SIMULATOR #ifndef SIMULATOR
#ifdef HAVE_MMC #if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
static bool dbg_mmc_info(void) static bool dbg_card_info(void)
{ {
bool done = false; bool done = false;
int currval = 0; int currval = 0;
@ -1548,7 +1548,7 @@ static bool dbg_mmc_info(void)
while (!done) while (!done)
{ {
card = mmc_card_info(currval / 2); card = card_get_info(currval / 2);
line = 0; line = 0;
lcd_clear_display(); lcd_clear_display();
@ -1564,29 +1564,29 @@ static bool dbg_mmc_info(void)
strncpy(card_name, ((unsigned char*)card->cid) + 3, 6); strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
snprintf(pbuf, sizeof(pbuf), "%s Rev %d.%d", card_name, snprintf(pbuf, sizeof(pbuf), "%s Rev %d.%d", card_name,
(int) mmc_extract_bits(card->cid, 72, 4), (int) card_extract_bits(card->cid, 72, 4),
(int) mmc_extract_bits(card->cid, 76, 4)); (int) card_extract_bits(card->cid, 76, 4));
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "Prod: %d/%d", snprintf(pbuf, sizeof(pbuf), "Prod: %d/%d",
(int) mmc_extract_bits(card->cid, 112, 4), (int) card_extract_bits(card->cid, 112, 4),
(int) mmc_extract_bits(card->cid, 116, 4) + 1997); (int) card_extract_bits(card->cid, 116, 4) + 1997);
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "Ser#: 0x%08lx", snprintf(pbuf, sizeof(pbuf), "Ser#: 0x%08lx",
mmc_extract_bits(card->cid, 80, 32)); card_extract_bits(card->cid, 80, 32));
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "M=%02x, O=%04x", snprintf(pbuf, sizeof(pbuf), "M=%02x, O=%04x",
(int) mmc_extract_bits(card->cid, 0, 8), (int) card_extract_bits(card->cid, 0, 8),
(int) mmc_extract_bits(card->cid, 8, 16)); (int) card_extract_bits(card->cid, 8, 16));
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
temp = mmc_extract_bits(card->csd, 2, 4); temp = card_extract_bits(card->csd, 2, 4);
snprintf(pbuf, sizeof(pbuf), "MMC v%s", temp < 5 ? snprintf(pbuf, sizeof(pbuf), "MMC v%s", temp < 5 ?
spec_vers[temp] : "?.?"); spec_vers[temp] : "?.?");
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "Blocks: 0x%06lx", card->numblocks); snprintf(pbuf, sizeof(pbuf), "Blocks: 0x%06lx", card->numblocks);
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "Blksz.: %d P:%c%c", card->blocksize, snprintf(pbuf, sizeof(pbuf), "Blksz.: %d P:%c%c", card->blocksize,
mmc_extract_bits(card->csd, 48, 1) ? 'R' : '-', card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
mmc_extract_bits(card->csd, 106, 1) ? 'W' : '-'); card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
} }
else /* Technical details */ else /* Technical details */
@ -1606,12 +1606,12 @@ static bool dbg_mmc_info(void)
snprintf(pbuf, sizeof(pbuf), "R2W: *%d", card->r2w_factor); snprintf(pbuf, sizeof(pbuf), "R2W: *%d", card->r2w_factor);
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "IRmax: %d..%d mA", snprintf(pbuf, sizeof(pbuf), "IRmax: %d..%d mA",
i_vmin[mmc_extract_bits(card->csd, 66, 3)], i_vmin[card_extract_bits(card->csd, 66, 3)],
i_vmax[mmc_extract_bits(card->csd, 69, 3)]); i_vmax[card_extract_bits(card->csd, 69, 3)]);
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
snprintf(pbuf, sizeof(pbuf), "IWmax: %d..%d mA", snprintf(pbuf, sizeof(pbuf), "IWmax: %d..%d mA",
i_vmin[mmc_extract_bits(card->csd, 72, 3)], i_vmin[card_extract_bits(card->csd, 72, 3)],
i_vmax[mmc_extract_bits(card->csd, 75, 3)]); i_vmax[card_extract_bits(card->csd, 75, 3)]);
lcd_puts(0, line++, pbuf); lcd_puts(0, line++, pbuf);
} }
} }
@ -1642,7 +1642,7 @@ static bool dbg_mmc_info(void)
action_signalscreenchange(); action_signalscreenchange();
return false; return false;
} }
#else /* !HAVE_MMC */ #else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
static bool dbg_disk_info(void) static bool dbg_disk_info(void)
{ {
char buf[128]; char buf[128];
@ -1799,7 +1799,7 @@ static bool dbg_disk_info(void)
action_signalscreenchange(); action_signalscreenchange();
return false; return false;
} }
#endif /* !HAVE_MMC */ #endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
#endif /* !SIMULATOR */ #endif /* !SIMULATOR */
#ifdef HAVE_DIRCACHE #ifdef HAVE_DIRCACHE
@ -2278,8 +2278,10 @@ static const struct the_menu_item menuitems[] = {
{ "View partitions", dbg_partitions }, { "View partitions", dbg_partitions },
#endif #endif
#ifndef SIMULATOR #ifndef SIMULATOR
#ifdef HAVE_MMC #if defined(HAVE_MMC)
{ "View MMC info", dbg_mmc_info }, { "View MMC info", dbg_card_info },
#elif defined(HAVE_HOTSWAP)
{ "View microSD info", dbg_card_info },
#else #else
{ "View disk info", dbg_disk_info }, { "View disk info", dbg_disk_info },
#endif #endif

View file

@ -430,7 +430,8 @@ static void init(void)
/* enter USB mode early, before trying to mount */ /* enter USB mode early, before trying to mount */
if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED) if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
#ifdef HAVE_MMC #ifdef HAVE_MMC
if (!mmc_touched() || (mmc_remove_request() == SYS_MMC_EXTRACTED)) if (!mmc_touched() ||
(mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
#endif #endif
{ {
usb_screen(); usb_screen();

View file

@ -828,7 +828,8 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
if (callback != NULL) if (callback != NULL)
callback(parameter); callback(parameter);
#ifdef HAVE_MMC #ifdef HAVE_MMC
if (!mmc_touched() || (mmc_remove_request() == SYS_MMC_EXTRACTED)) if (!mmc_touched() ||
(mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
#endif #endif
{ {
scrobbler_flush_cache(); scrobbler_flush_cache();

View file

@ -163,8 +163,8 @@ int mmc_remove_request(void)
queue_wait_w_tmo(&button_queue, &ev, HZ/2); queue_wait_w_tmo(&button_queue, &ev, HZ/2);
switch (ev.id) switch (ev.id)
{ {
case SYS_MMC_EXTRACTED: case SYS_HOTSWAP_EXTRACTED:
return SYS_MMC_EXTRACTED; return SYS_HOTSWAP_EXTRACTED;
case SYS_USB_DISCONNECTED: case SYS_USB_DISCONNECTED:
return SYS_USB_DISCONNECTED; return SYS_USB_DISCONNECTED;

View file

@ -352,7 +352,7 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
unsigned long sum; unsigned long sum;
/* Read header to find out how long the mi4 file is. */ /* Read header to find out how long the mi4 file is. */
ata_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET, ata_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET,
PPMI_SECTORS, &ppmi_header); PPMI_SECTORS, &ppmi_header);
/* The first four characters at 0x80000 (sector 1024) should be PPMI*/ /* The first four characters at 0x80000 (sector 1024) should be PPMI*/
@ -362,7 +362,7 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
printf("BL mi4 size: %x", ppmi_header.length); printf("BL mi4 size: %x", ppmi_header.length);
/* Read mi4 header of the OF */ /* Read mi4 header of the OF */
ata_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS ata_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS
+ (ppmi_header.length/512), MI4_HEADER_SECTORS, &mi4header); + (ppmi_header.length/512), MI4_HEADER_SECTORS, &mi4header);
/* We don't support encrypted mi4 files yet */ /* We don't support encrypted mi4 files yet */
@ -385,7 +385,7 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
printf("Binary type: %.4s", mi4header.type); printf("Binary type: %.4s", mi4header.type);
/* Load firmware */ /* Load firmware */
ata_read_sectors(pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS ata_read_sectors(IF_MV2(0,) pinfo->start + PPMI_SECTOR_OFFSET + PPMI_SECTORS
+ (ppmi_header.length/512) + MI4_HEADER_SECTORS, + (ppmi_header.length/512) + MI4_HEADER_SECTORS,
(mi4header.mi4size-MI4_HEADER_SIZE)/512, buf); (mi4header.mi4size-MI4_HEADER_SIZE)/512, buf);
@ -404,7 +404,7 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
unsigned int i; unsigned int i;
/* check which known version we have */ /* check which known version we have */
/* These are taken from the PPPS section, 0x00780240 */ /* These are taken from the PPPS section, 0x00780240 */
ata_read_sectors(pinfo->start + 0x3C01, 1, block); ata_read_sectors(IF_MV2(0,) pinfo->start + 0x3C01, 1, block);
for (i=0; i<sizeof(OFDatabaseOffsets)/sizeof(*OFDatabaseOffsets); i++) for (i=0; i<sizeof(OFDatabaseOffsets)/sizeof(*OFDatabaseOffsets); i++)
{ {
if (!memcmp(&block[0x40], OFDatabaseOffsets[i].version, if (!memcmp(&block[0x40], OFDatabaseOffsets[i].version,
@ -417,9 +417,9 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
} }
if (sector && offset) if (sector && offset)
{ {
ata_read_sectors(sector, 1, block); ata_read_sectors(IF_MV2(0,) sector, 1, block);
block[offset] = 0; block[offset] = 0;
ata_write_sectors(sector, 1, block); ata_write_sectors(IF_MV2(0,) sector, 1, block);
} }
} }
return EOK; return EOK;
@ -428,12 +428,14 @@ int load_mi4_part(unsigned char* buf, struct partinfo* pinfo,
void* main(void) void* main(void)
{ {
#ifndef SANSA_E200
char buf[256]; char buf[256];
unsigned short* identify_info;
#endif
int i; int i;
int btn; int btn;
int rc; int rc;
int num_partitions; int num_partitions;
unsigned short* identify_info;
struct partinfo* pinfo; struct partinfo* pinfo;
#ifdef SANSA_E200 #ifdef SANSA_E200
int usb_retry = 0; int usb_retry = 0;
@ -475,6 +477,7 @@ void* main(void)
printf(MODEL_NAME); printf(MODEL_NAME);
i=ata_init(); i=ata_init();
#ifndef SANSA_E200
if (i==0) { if (i==0) {
identify_info=ata_get_identify(); identify_info=ata_get_identify();
/* Show model */ /* Show model */
@ -489,8 +492,9 @@ void* main(void)
} else { } else {
error(EATA, i); error(EATA, i);
} }
#endif
disk_init(); disk_init(IF_MV(0));
num_partitions = disk_mount_all(); num_partitions = disk_mount_all();
if (num_partitions<=0) if (num_partitions<=0)
{ {

View file

@ -116,6 +116,9 @@ drivers/ata.c
#endif /* HAVE_FLASH_DISK */ #endif /* HAVE_FLASH_DISK */
#endif /* HAVE_MMC */ #endif /* HAVE_MMC */
drivers/fat.c drivers/fat.c
#ifdef HAVE_HOTSWAP
hotswap.c
#endif
#endif /* SIMULATOR */ #endif /* SIMULATOR */
/* EEPROM */ /* EEPROM */

View file

@ -37,6 +37,9 @@ static DIR opendirs[MAX_OPEN_DIRS];
#ifdef HAVE_MMC #ifdef HAVE_MMC
static const char* vol_names = "<MMC%d>"; static const char* vol_names = "<MMC%d>";
#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */ #define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */
#elif defined(HAVE_HOTSWAP)
static const char* vol_names = "<microSD%d>";
#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */
#else #else
static const char* vol_names = "<HD%d>"; static const char* vol_names = "<HD%d>";
#define VOL_ENUM_POS 3 #define VOL_ENUM_POS 3

View file

@ -20,8 +20,8 @@
#include "ata.h" #include "ata.h"
#include "debug.h" #include "debug.h"
#include "fat.h" #include "fat.h"
#ifdef HAVE_MMC #ifdef HAVE_HOTSWAP
#include "ata_mmc.h" #include "hotswap.h"
#endif #endif
#include "file.h" /* for release_dirs() */ #include "file.h" /* for release_dirs() */
#include "dir.h" /* for release_files() */ #include "dir.h" /* for release_files() */
@ -101,8 +101,8 @@ int disk_mount_all(void)
int mounted; int mounted;
int i; int i;
#if defined(HAVE_MMC) && defined(HAVE_HOTSWAP) #ifdef HAVE_MMC
mmc_enable_monitoring(false); card_enable_monitoring(false);
#endif #endif
fat_init(); /* reset all mounted partitions */ fat_init(); /* reset all mounted partitions */
@ -110,13 +110,13 @@ int disk_mount_all(void)
vol_drive[i] = -1; /* mark all as unassigned */ vol_drive[i] = -1; /* mark all as unassigned */
mounted = disk_mount(0); mounted = disk_mount(0);
#ifdef HAVE_MMC #ifdef HAVE_HOTSWAP
if (mmc_detect()) /* for Ondio, only if card detected */ if (card_detect())
{ {
mounted += disk_mount(1); /* try 2nd "drive", too */ mounted += disk_mount(1); /* try 2nd "drive", too */
} }
#ifdef HAVE_HOTSWAP #ifdef HAVE_MMC
mmc_enable_monitoring(true); card_enable_monitoring(true);
#endif #endif
#endif #endif

View file

@ -397,26 +397,6 @@ static int receive_cxd(unsigned char *buf)
return 0; return 0;
} }
/* helper function to extract n (<=32) bits from an arbitrary position.
counting from MSB to LSB */
unsigned long mmc_extract_bits(
const unsigned long *p, /* the start of the bitfield array */
unsigned int start, /* bit no. to start reading */
unsigned int size) /* how many bits to read */
{
unsigned int long_index = start / 32;
unsigned int bit_index = start % 32;
unsigned long result;
result = p[long_index] << bit_index;
if (bit_index + size > 32) /* crossing longword boundary */
result |= p[long_index+1] >> (32 - bit_index);
result >>= 32 - size;
return result;
}
static int initialize_card(int card_no) static int initialize_card(int card_no)
{ {
@ -470,9 +450,9 @@ static int initialize_card(int card_no)
return rc * 10 - 6; return rc * 10 - 6;
/* check block sizes */ /* check block sizes */
card->block_exp = mmc_extract_bits(card->csd, 44, 4); card->block_exp = card_extract_bits(card->csd, 44, 4);
card->blocksize = 1 << card->block_exp; card->blocksize = 1 << card->block_exp;
if ((mmc_extract_bits(card->csd, 102, 4) != card->block_exp) if ((card_extract_bits(card->csd, 102, 4) != card->block_exp)
|| card->blocksize > MAX_BLOCK_SIZE) || card->blocksize > MAX_BLOCK_SIZE)
{ {
return -7; return -7;
@ -486,16 +466,16 @@ static int initialize_card(int card_no)
} }
/* max transmission speed, clock divider */ /* max transmission speed, clock divider */
temp = mmc_extract_bits(card->csd, 29, 3); temp = card_extract_bits(card->csd, 29, 3);
temp = (temp > 3) ? 3 : temp; temp = (temp > 3) ? 3 : temp;
card->speed = mantissa[mmc_extract_bits(card->csd, 25, 4)] card->speed = mantissa[card_extract_bits(card->csd, 25, 4)]
* exponent[temp + 4]; * exponent[temp + 4];
card->bitrate_register = (FREQ/4-1) / card->speed; card->bitrate_register = (FREQ/4-1) / card->speed;
/* NSAC, TSAC, read timeout */ /* NSAC, TSAC, read timeout */
card->nsac = 100 * mmc_extract_bits(card->csd, 16, 8); card->nsac = 100 * card_extract_bits(card->csd, 16, 8);
card->tsac = mantissa[mmc_extract_bits(card->csd, 9, 4)]; card->tsac = mantissa[card_extract_bits(card->csd, 9, 4)];
temp = mmc_extract_bits(card->csd, 13, 3); temp = card_extract_bits(card->csd, 13, 3);
card->read_timeout = ((FREQ/4) / (card->bitrate_register + 1) card->read_timeout = ((FREQ/4) / (card->bitrate_register + 1)
* card->tsac / exponent[9 - temp] * card->tsac / exponent[9 - temp]
+ (10 * card->nsac)); + (10 * card->nsac));
@ -503,7 +483,7 @@ static int initialize_card(int card_no)
card->tsac = card->tsac * exponent[temp] / 10; card->tsac = card->tsac * exponent[temp] / 10;
/* r2w_factor, write timeout */ /* r2w_factor, write timeout */
card->r2w_factor = 1 << mmc_extract_bits(card->csd, 99, 3); card->r2w_factor = 1 << card_extract_bits(card->csd, 99, 3);
if (card->r2w_factor > 32) /* dirty MMC spec violation */ if (card->r2w_factor > 32) /* dirty MMC spec violation */
{ {
card->read_timeout *= 4; /* add safety factor */ card->read_timeout *= 4; /* add safety factor */
@ -513,8 +493,8 @@ static int initialize_card(int card_no)
card->write_timeout = card->read_timeout * card->r2w_factor; card->write_timeout = card->read_timeout * card->r2w_factor;
/* card size */ /* card size */
card->numblocks = (mmc_extract_bits(card->csd, 54, 12) + 1) card->numblocks = (card_extract_bits(card->csd, 54, 12) + 1)
* (1 << (mmc_extract_bits(card->csd, 78, 3) + 2)); * (1 << (card_extract_bits(card->csd, 78, 3) + 2));
card->size = card->numblocks * card->blocksize; card->size = card->numblocks * card->blocksize;
/* switch to full speed */ /* switch to full speed */
@ -993,12 +973,12 @@ static void mmc_thread(void)
break; break;
#ifdef HAVE_HOTSWAP #ifdef HAVE_HOTSWAP
case SYS_MMC_INSERTED: case SYS_HOTSWAP_INSERTED:
disk_mount(1); /* mount MMC */ disk_mount(1); /* mount MMC */
queue_broadcast(SYS_FS_CHANGED, 0); queue_broadcast(SYS_FS_CHANGED, 0);
break; break;
case SYS_MMC_EXTRACTED: case SYS_HOTSWAP_EXTRACTED:
disk_unmount(1); /* release "by force" */ disk_unmount(1); /* release "by force" */
queue_broadcast(SYS_FS_CHANGED, 0); queue_broadcast(SYS_FS_CHANGED, 0);
break; break;
@ -1097,11 +1077,11 @@ static void mmc_tick(void)
{ {
if (current_status) if (current_status)
{ {
queue_broadcast(SYS_MMC_INSERTED, 0); queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
} }
else else
{ {
queue_broadcast(SYS_MMC_EXTRACTED, 0); queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
mmc_status = MMC_UNTOUCHED; mmc_status = MMC_UNTOUCHED;
card_info[1].initialized = false; card_info[1].initialized = false;
} }

View file

@ -18,34 +18,14 @@
****************************************************************************/ ****************************************************************************/
#ifndef __ATA_MMC_H__ #ifndef __ATA_MMC_H__
#define __ATA_MMC_H__ #define __ATA_MMC_H__
#include "hotswap.h"
typedef struct
{
bool initialized;
unsigned char bitrate_register;
unsigned long read_timeout; /* n * 8 clock cycles */
unsigned long write_timeout; /* n * 8 clock cycles */
unsigned long ocr; /* OCR register */
unsigned long csd[4]; /* CSD register, 16 bytes */
unsigned long cid[4]; /* CID register, 16 bytes */
unsigned long speed; /* bit/s */
unsigned int nsac; /* clock cycles */
unsigned long tsac; /* n * 0.1 ns */
unsigned int r2w_factor;
unsigned long size; /* size in bytes */
unsigned long numblocks; /* size in flash blocks */
unsigned int blocksize; /* block size in bytes */
unsigned int block_exp; /* block size exponent */
} tCardInfo;
void mmc_enable_int_flash_clock(bool on); void mmc_enable_int_flash_clock(bool on);
bool mmc_detect(void); bool mmc_detect(void);
unsigned long mmc_extract_bits(const unsigned long *p, unsigned int start,
unsigned int size);
tCardInfo *mmc_card_info(int card_no); tCardInfo *mmc_card_info(int card_no);
bool mmc_touched(void); bool mmc_touched(void);
bool mmc_usb_active(int delayticks); bool mmc_usb_active(int delayticks);
#ifdef HAVE_HOTSWAP #ifdef HAVE_HOTSWAP
void mmc_enable_monitoring(bool on); void mmc_enable_monitoring(bool on);
#endif #endif

View file

@ -33,6 +33,11 @@
/* define this if you have LCD enable function */ /* define this if you have LCD enable function */
#define HAVE_LCD_ENABLE #define HAVE_LCD_ENABLE
#ifndef SIMULATOR
#define HAVE_HOTSWAP
#define HAVE_MULTIVOLUME
#endif
#define HAVE_BACKLIGHT_BRIGHTNESS #define HAVE_BACKLIGHT_BRIGHTNESS
/* Main LCD backlight brightness range and defaults */ /* Main LCD backlight brightness range and defaults */
#define MIN_BRIGHTNESS_SETTING 1 #define MIN_BRIGHTNESS_SETTING 1

View file

@ -247,7 +247,7 @@
/* Enable the directory cache and tagcache in RAM if we have /* Enable the directory cache and tagcache in RAM if we have
* plenty of RAM. Both features can be enabled independently. */ * plenty of RAM. Both features can be enabled independently. */
#if ((defined(MEMORYSIZE) && (MEMORYSIZE > 8)) || MEM > 8) && \ #if ((defined(MEMORYSIZE) && (MEMORYSIZE > 8)) || MEM > 8) && \
!defined(BOOTLOADER) !defined(BOOTLOADER) && !defined(SANSA_E200)
#define HAVE_DIRCACHE #define HAVE_DIRCACHE
#ifdef HAVE_TAGCACHE #ifdef HAVE_TAGCACHE
#define HAVE_TC_RAMCACHE #define HAVE_TC_RAMCACHE

59
firmware/export/hotswap.h Normal file
View file

@ -0,0 +1,59 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2004 by Jens Arnold
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __HOTSWAP_H__
#define __HOTSWAP_H__
typedef struct
{
bool initialized;
unsigned char bitrate_register;
unsigned long read_timeout; /* n * 8 clock cycles */
unsigned long write_timeout; /* n * 8 clock cycles */
unsigned long ocr; /* OCR register */
unsigned long csd[4]; /* CSD register, 16 bytes */
unsigned long cid[4]; /* CID register, 16 bytes */
unsigned long speed; /* bit/s */
unsigned int nsac; /* clock cycles */
unsigned long tsac; /* n * 0.1 ns */
unsigned int r2w_factor;
unsigned long size; /* size in bytes */
unsigned long numblocks; /* size in flash blocks */
unsigned int blocksize; /* block size in bytes */
unsigned int block_exp; /* block size exponent */
} tCardInfo;
#ifdef TARGET_TREE
bool card_detect(void);
tCardInfo *card_get_info(int card_no);
#else /* HAVE_MMC */
#include "ata_mmc.h"
#define card_detect mmc_detect
#define card_get_info mmc_card_info
#define card_touched mmc_touched
#define card_enable_monitoring mmc_enable_monitoring
#endif
/* helper function to extract n (<=32) bits from an arbitrary position.
counting from MSB to LSB */
unsigned long card_extract_bits(
const unsigned long *p, /* the start of the bitfield array */
unsigned int start, /* bit no. to start reading */
unsigned int size); /* how many bits to read */
#endif

View file

@ -41,8 +41,8 @@
#define SYS_USB_DISCONNECTED ((SYS_EVENT | ((long)3 << 27))) #define SYS_USB_DISCONNECTED ((SYS_EVENT | ((long)3 << 27)))
#define SYS_USB_DISCONNECTED_ACK ((SYS_EVENT | ((long)4 << 27))) #define SYS_USB_DISCONNECTED_ACK ((SYS_EVENT | ((long)4 << 27)))
#define SYS_TIMEOUT ((SYS_EVENT | ((long)5 << 27))) #define SYS_TIMEOUT ((SYS_EVENT | ((long)5 << 27)))
#define SYS_MMC_INSERTED ((SYS_EVENT | ((long)6 << 27))) #define SYS_HOTSWAP_INSERTED ((SYS_EVENT | ((long)6 << 27)))
#define SYS_MMC_EXTRACTED ((SYS_EVENT | ((long)7 << 27))) #define SYS_HOTSWAP_EXTRACTED ((SYS_EVENT | ((long)7 << 27)))
#define SYS_POWEROFF ((SYS_EVENT | ((long)8 << 27))) #define SYS_POWEROFF ((SYS_EVENT | ((long)8 << 27)))
#define SYS_FS_CHANGED ((SYS_EVENT | ((long)9 << 27))) #define SYS_FS_CHANGED ((SYS_EVENT | ((long)9 << 27)))
#define SYS_CHARGER_CONNECTED ((SYS_EVENT | ((long)10 << 27))) #define SYS_CHARGER_CONNECTED ((SYS_EVENT | ((long)10 << 27)))

View file

@ -24,7 +24,7 @@
#include "pp5020.h" #include "pp5020.h"
#undef GPIO_IRQ #undef GPIO_IRQ
/* Ports A, ?? */ /* Ports A, B, ?? */
#define GPIO0_IRQ (32+0) #define GPIO0_IRQ (32+0)
/* Ports F, H, ?? */ /* Ports F, H, ?? */
#define GPIO1_IRQ (32+1) #define GPIO1_IRQ (32+1)

58
firmware/hotswap.c Normal file
View file

@ -0,0 +1,58 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2004 by Jens Arnold
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdbool.h>
#include "config.h"
#ifdef TARGET_TREE
#include "hotswap-target.h"
#else
#include "ata_mmc.h"
#endif
/* helper function to extract n (<=32) bits from an arbitrary position.
counting from MSB to LSB */
unsigned long card_extract_bits(
const unsigned long *p, /* the start of the bitfield array */
unsigned int start, /* bit no. to start reading */
unsigned int size) /* how many bits to read */
{
unsigned int long_index = start / 32;
unsigned int bit_index = start % 32;
unsigned long result;
result = p[long_index] << bit_index;
if (bit_index + size > 32) /* crossing longword boundary */
result |= p[long_index+1] >> (32 - bit_index);
result >>= 32 - size;
return result;
}
#ifdef TARGET_TREE
bool card_detect(void)
{
return card_detect_target();
}
tCardInfo *card_get_info(int card_no)
{
return card_get_info_target(card_no);
}
#endif

View file

@ -71,6 +71,10 @@ typedef struct {
#endif #endif
} DIR; } DIR;
#ifdef HAVE_HOTSWAP
char *get_volume_name(int volume);
#endif
#ifndef DIRFUNCTIONS_DEFINED #ifndef DIRFUNCTIONS_DEFINED
extern DIR* opendir(const char* name); extern DIR* opendir(const char* name);

File diff suppressed because it is too large Load diff

View file

@ -19,25 +19,4 @@
#ifndef ATA_TARGET_H #ifndef ATA_TARGET_H
#define ATA_TARGET_H #define ATA_TARGET_H
#include "inttypes.h"
typedef struct
{
bool initialized;
unsigned int ocr; /* OCR register */
unsigned int csd[4]; /* CSD register */
unsigned int cid[4]; /* CID register */
unsigned int rca;
uint64_t capacity; /* size in bytes */
unsigned long numblocks; /* size in flash blocks */
unsigned int block_size; /* block size in bytes */
unsigned int max_read_bl_len;/* max read data block length */
unsigned int block_exp; /* block size exponent */
} tSDCardInfo;
tSDCardInfo *sd_card_info(int card_no);
bool sd_touched(void);
#endif #endif

View file

@ -0,0 +1,45 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Antonius Hellmann
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef HOTSWAP_TARGET_H
#define HOTSWAP_TARGET_H
#include "inttypes.h"
#include "hotswap.h"
typedef struct
{
bool initialized;
unsigned int ocr; /* OCR register */
unsigned int csd[4]; /* CSD register */
unsigned int cid[4]; /* CID register */
unsigned int rca;
uint64_t capacity; /* size in bytes */
unsigned long numblocks; /* size in flash blocks */
unsigned int block_size; /* block size in bytes */
unsigned int max_read_bl_len;/* max read data block length */
unsigned int block_exp; /* block size exponent */
unsigned char current_bank; /* The bank that we are working with */
} tSDCardInfo;
tCardInfo *card_get_info_target(int card_no);
bool card_detect_target(void);
#endif

View file

@ -56,8 +56,11 @@ void irq(void)
/* TODO: this should really be in the target tree, but moving it there caused /* TODO: this should really be in the target tree, but moving it there caused
crt0.S not to find it while linking */ crt0.S not to find it while linking */
/* TODO: Even if it isn't in the target tree, this should be the default case */ /* TODO: Even if it isn't in the target tree, this should be the default case */
#ifdef SANSA_E200
extern void button_int(void); extern void button_int(void);
extern void clickwheel_int(void); extern void clickwheel_int(void);
extern void microsd_int(void);
#endif
void irq(void) void irq(void)
{ {
@ -65,11 +68,15 @@ void irq(void)
if (CPU_INT_STAT & TIMER1_MASK) { if (CPU_INT_STAT & TIMER1_MASK) {
TIMER1(); TIMER1();
} }
else if (CPU_INT_STAT & TIMER2_MASK) else if (CPU_INT_STAT & TIMER2_MASK) {
TIMER2(); TIMER2();
}
#ifdef SANSA_E200 #ifdef SANSA_E200
else if (CPU_HI_INT_STAT & GPIO1_MASK) else if (CPU_HI_INT_STAT & GPIO0_MASK) {
{ if (GPIOA_INT_STAT & 0x80)
microsd_int();
}
else if (CPU_HI_INT_STAT & GPIO1_MASK) {
if (GPIOF_INT_STAT & 0xff) if (GPIOF_INT_STAT & 0xff)
button_int(); button_int();
if (GPIOH_INT_STAT & 0xc0) if (GPIOH_INT_STAT & 0xc0)

View file

@ -255,8 +255,8 @@ static void usb_thread(void)
break; break;
#ifdef HAVE_MMC #ifdef HAVE_MMC
case SYS_MMC_INSERTED: case SYS_HOTSWAP_INSERTED:
case SYS_MMC_EXTRACTED: case SYS_HOTSWAP_EXTRACTED:
if(usb_state == USB_INSERTED) if(usb_state == USB_INSERTED)
{ {
usb_enable(false); usb_enable(false);