mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
Port MMC driver fixes & improvements (r18541, r18551, r18552) to the 3.0 branch.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_0@18579 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0805a82781
commit
7577e2f14b
1 changed files with 99 additions and 136 deletions
|
@ -145,7 +145,7 @@ static void read_transfer(unsigned char *buf, int len)
|
||||||
__attribute__ ((section(".icode")));
|
__attribute__ ((section(".icode")));
|
||||||
static unsigned char poll_byte(long timeout);
|
static unsigned char poll_byte(long timeout);
|
||||||
static unsigned char poll_busy(long timeout);
|
static unsigned char poll_busy(long timeout);
|
||||||
static int send_cmd(int cmd, unsigned long parameter, unsigned char *response);
|
static unsigned char send_cmd(int cmd, unsigned long parameter, void *data);
|
||||||
static int receive_cxd(unsigned char *buf);
|
static int receive_cxd(unsigned char *buf);
|
||||||
static int initialize_card(int card_no);
|
static int initialize_card(int card_no);
|
||||||
static int receive_block(unsigned char *inbuf, long timeout);
|
static int receive_block(unsigned char *inbuf, long timeout);
|
||||||
|
@ -172,6 +172,8 @@ static int select_card(int card_no)
|
||||||
led(true);
|
led(true);
|
||||||
last_disk_activity = current_tick;
|
last_disk_activity = current_tick;
|
||||||
|
|
||||||
|
mmc_enable_int_flash_clock(card_no == 0);
|
||||||
|
|
||||||
if (!card_info[card_no].initialized)
|
if (!card_info[card_no].initialized)
|
||||||
{
|
{
|
||||||
setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */
|
setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */
|
||||||
|
@ -316,30 +318,25 @@ static unsigned char poll_busy(long timeout)
|
||||||
return (dummy == 0xFF) ? data : 0;
|
return (dummy == 0xFF) ? data : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send MMC command and get response */
|
/* Send MMC command and get response. Returns R1 byte directly.
|
||||||
static int send_cmd(int cmd, unsigned long parameter, unsigned char *response)
|
* Returns further R2 or R3 bytes in *data (can be NULL for other commands) */
|
||||||
|
static unsigned char send_cmd(int cmd, unsigned long parameter, void *data)
|
||||||
{
|
{
|
||||||
unsigned char command[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 0xFF};
|
static struct {
|
||||||
|
unsigned char cmd;
|
||||||
|
unsigned long parameter;
|
||||||
|
const unsigned char crc7; /* fixed, valid for CMD0 only */
|
||||||
|
const unsigned char trailer;
|
||||||
|
} __attribute__((packed)) command = {0x40, 0, 0x95, 0xFF};
|
||||||
|
|
||||||
command[0] = cmd;
|
unsigned char ret;
|
||||||
|
|
||||||
if (parameter != 0)
|
|
||||||
{
|
|
||||||
command[1] = (parameter >> 24) & 0xFF;
|
|
||||||
command[2] = (parameter >> 16) & 0xFF;
|
|
||||||
command[3] = (parameter >> 8) & 0xFF;
|
|
||||||
command[4] = parameter & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_transfer(command, 7);
|
|
||||||
|
|
||||||
response[0] = poll_byte(20);
|
command.cmd = cmd;
|
||||||
|
command.parameter = htobe32(parameter);
|
||||||
|
|
||||||
if (response[0] != 0x00)
|
write_transfer((unsigned char *)&command, sizeof(command));
|
||||||
{
|
|
||||||
write_transfer(dummy, 1);
|
ret = poll_byte(20);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
|
@ -347,24 +344,21 @@ static int send_cmd(int cmd, unsigned long parameter, unsigned char *response)
|
||||||
case CMD_SEND_CID:
|
case CMD_SEND_CID:
|
||||||
case CMD_READ_SINGLE_BLOCK:
|
case CMD_READ_SINGLE_BLOCK:
|
||||||
case CMD_READ_MULTIPLE_BLOCK:
|
case CMD_READ_MULTIPLE_BLOCK:
|
||||||
break;
|
return ret;
|
||||||
|
|
||||||
case CMD_SEND_STATUS: /* R2 response, close with dummy */
|
case CMD_SEND_STATUS: /* R2 response, close with dummy */
|
||||||
read_transfer(response + 1, 1);
|
read_transfer(data, 1);
|
||||||
write_transfer(dummy, 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_OCR: /* R3 response, close with dummy */
|
case CMD_READ_OCR: /* R3 response, close with dummy */
|
||||||
read_transfer(response + 1, 4);
|
read_transfer(data, 4);
|
||||||
write_transfer(dummy, 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* R1 response, close with dummy */
|
default: /* R1 response, close with dummy */
|
||||||
write_transfer(dummy, 1);
|
|
||||||
break; /* also catches block writes */
|
break; /* also catches block writes */
|
||||||
}
|
}
|
||||||
|
write_transfer(dummy, 1);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive CID/ CSD data (16 bytes) */
|
/* Receive CID/ CSD data (16 bytes) */
|
||||||
|
@ -386,7 +380,6 @@ static int initialize_card(int card_no)
|
||||||
{
|
{
|
||||||
int rc, i;
|
int rc, i;
|
||||||
int blk_exp, ts_exp, taac_exp;
|
int blk_exp, ts_exp, taac_exp;
|
||||||
unsigned char response[5];
|
|
||||||
tCardInfo *card = &card_info[card_no];
|
tCardInfo *card = &card_info[card_no];
|
||||||
|
|
||||||
static const char mantissa[] = { /* *10 */
|
static const char mantissa[] = { /* *10 */
|
||||||
|
@ -400,43 +393,40 @@ static int initialize_card(int card_no)
|
||||||
|
|
||||||
if (card_no == 1)
|
if (card_no == 1)
|
||||||
mmc_status = MMC_TOUCHED;
|
mmc_status = MMC_TOUCHED;
|
||||||
|
|
||||||
/* switch to SPI mode */
|
/* switch to SPI mode */
|
||||||
send_cmd(CMD_GO_IDLE_STATE, 0, response);
|
if (send_cmd(CMD_GO_IDLE_STATE, 0, NULL) != 0x01)
|
||||||
if (response[0] != 0x01)
|
return -1; /* error or no response */
|
||||||
return -1; /* error response */
|
|
||||||
|
|
||||||
/* initialize card */
|
/* initialize card */
|
||||||
for (i = 0; i < 100; i++) /* timeout 1 sec */
|
for (i = HZ;;) /* try for 1 second*/
|
||||||
{
|
{
|
||||||
sleep(1);
|
sleep(1);
|
||||||
if (send_cmd(CMD_SEND_OP_COND, 0, response) == 0)
|
if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0)
|
||||||
break;
|
break;
|
||||||
|
if (--i <= 0)
|
||||||
|
return -2; /* timeout */
|
||||||
}
|
}
|
||||||
if (response[0] != 0x00)
|
|
||||||
return -2; /* not ready */
|
|
||||||
|
|
||||||
/* get OCR register */
|
/* get OCR register */
|
||||||
rc = send_cmd(CMD_READ_OCR, 0, response);
|
if (send_cmd(CMD_READ_OCR, 0, &card->ocr))
|
||||||
if (rc)
|
return -3;
|
||||||
return rc * 10 - 3;
|
card->ocr = betoh32(card->ocr); /* no-op on big endian */
|
||||||
card->ocr = (response[1] << 24) | (response[2] << 16)
|
|
||||||
| (response[3] << 8) | response[4];
|
|
||||||
|
|
||||||
/* check voltage */
|
/* check voltage */
|
||||||
if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */
|
if (!(card->ocr & 0x00100000)) /* 3.2 .. 3.3 V */
|
||||||
return -4;
|
return -4;
|
||||||
|
|
||||||
/* get CSD register */
|
/* get CSD register */
|
||||||
rc = send_cmd(CMD_SEND_CSD, 0, response);
|
if (send_cmd(CMD_SEND_CSD, 0, NULL))
|
||||||
if (rc)
|
return -5;
|
||||||
return rc * 10 - 5;
|
|
||||||
rc = receive_cxd((unsigned char*)card->csd);
|
rc = receive_cxd((unsigned char*)card->csd);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc * 10 - 6;
|
return rc * 10 - 5;
|
||||||
|
|
||||||
blk_exp = card_extract_bits(card->csd, 44, 4);
|
blk_exp = card_extract_bits(card->csd, 44, 4);
|
||||||
if (blk_exp < 9) /* block size < 512 bytes not supported */
|
if (blk_exp < 9) /* block size < 512 bytes not supported */
|
||||||
return -7;
|
return -6;
|
||||||
|
|
||||||
card->numblocks = (card_extract_bits(card->csd, 54, 12) + 1)
|
card->numblocks = (card_extract_bits(card->csd, 54, 12) + 1)
|
||||||
<< (card_extract_bits(card->csd, 78, 3) + 2 + blk_exp - 9);
|
<< (card_extract_bits(card->csd, 78, 3) + 2 + blk_exp - 9);
|
||||||
|
@ -461,29 +451,24 @@ static int initialize_card(int card_no)
|
||||||
|
|
||||||
/* r2w_factor, write timeout */
|
/* r2w_factor, write timeout */
|
||||||
card->r2w_factor = 1 << card_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 */
|
card->write_timeout = card->read_timeout * card->r2w_factor;
|
||||||
{
|
|
||||||
card->read_timeout *= 4; /* add safety factor */
|
if (card->r2w_factor > 32) /* Such cards often need extra read delay */
|
||||||
card->write_timeout = card->read_timeout * 8;
|
card->read_timeout *= 4;
|
||||||
}
|
|
||||||
else
|
|
||||||
card->write_timeout = card->read_timeout * card->r2w_factor;
|
|
||||||
|
|
||||||
/* switch to full speed */
|
/* switch to full speed */
|
||||||
setup_sci1(card->bitrate_register);
|
setup_sci1(card->bitrate_register);
|
||||||
|
|
||||||
/* always use 512 byte blocks */
|
/* always use 512 byte blocks */
|
||||||
rc = send_cmd(CMD_SET_BLOCKLEN, BLOCK_SIZE, response);
|
if (send_cmd(CMD_SET_BLOCKLEN, BLOCK_SIZE, NULL))
|
||||||
if (rc)
|
return -7;
|
||||||
return rc * 10 - 8;
|
|
||||||
|
|
||||||
/* get CID register */
|
/* get CID register */
|
||||||
rc = send_cmd(CMD_SEND_CID, 0, response);
|
if (send_cmd(CMD_SEND_CID, 0, NULL))
|
||||||
if (rc)
|
return -8;
|
||||||
return rc * 10 - 9;
|
|
||||||
rc = receive_cxd((unsigned char*)card->cid);
|
rc = receive_cxd((unsigned char*)card->cid);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc * 10 - 9;
|
return rc * 10 - 8;
|
||||||
|
|
||||||
card->initialized = true;
|
card->initialized = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -624,7 +609,6 @@ int ata_read_sectors(IF_MV2(int drive,)
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int lastblock = 0;
|
int lastblock = 0;
|
||||||
unsigned long end_block;
|
unsigned long end_block;
|
||||||
unsigned char response;
|
|
||||||
tCardInfo *card;
|
tCardInfo *card;
|
||||||
#ifndef HAVE_MULTIVOLUME
|
#ifndef HAVE_MULTIVOLUME
|
||||||
int drive = current_card;
|
int drive = current_card;
|
||||||
|
@ -653,21 +637,20 @@ int ata_read_sectors(IF_MV2(int drive,)
|
||||||
|
|
||||||
if (incount > 1)
|
if (incount > 1)
|
||||||
{
|
{
|
||||||
rc = send_cmd(CMD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, &response);
|
/* MMC4.2: make multiplication conditional */
|
||||||
/* MMC4.2: make multiplication conditional */
|
if (send_cmd(CMD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL))
|
||||||
if (rc)
|
|
||||||
{
|
{
|
||||||
rc = rc * 10 - 3;
|
rc = -3;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
while (incount-- > lastblock)
|
while (--incount >= lastblock)
|
||||||
{
|
{
|
||||||
rc = receive_block(inbuf, card->read_timeout);
|
rc = receive_block(inbuf, card->read_timeout);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
/* If an error occurs during multiple block reading, the
|
/* If an error occurs during multiple block reading, the
|
||||||
* host still needs to send CMD_STOP_TRANSMISSION */
|
* host still needs to send CMD_STOP_TRANSMISSION */
|
||||||
send_cmd(CMD_STOP_TRANSMISSION, 0, &response);
|
send_cmd(CMD_STOP_TRANSMISSION, 0, NULL);
|
||||||
rc = rc * 10 - 4;
|
rc = rc * 10 - 4;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -675,20 +658,18 @@ int ata_read_sectors(IF_MV2(int drive,)
|
||||||
start++;
|
start++;
|
||||||
/* ^^ necessary for the abovementioned last block special case */
|
/* ^^ necessary for the abovementioned last block special case */
|
||||||
}
|
}
|
||||||
rc = send_cmd(CMD_STOP_TRANSMISSION, 0, &response);
|
if (send_cmd(CMD_STOP_TRANSMISSION, 0, NULL))
|
||||||
if (rc)
|
|
||||||
{
|
{
|
||||||
rc = rc * 10 - 5;
|
rc = -5;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (incount > 0)
|
if (incount > 0)
|
||||||
{
|
{
|
||||||
rc = send_cmd(CMD_READ_SINGLE_BLOCK, start * BLOCK_SIZE, &response);
|
/* MMC4.2: make multiplication conditional */
|
||||||
/* MMC4.2: make multiplication conditional */
|
if (send_cmd(CMD_READ_SINGLE_BLOCK, start * BLOCK_SIZE, NULL))
|
||||||
if (rc)
|
|
||||||
{
|
{
|
||||||
rc = rc * 10 - 6;
|
rc = -6;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rc = receive_block(inbuf, card->read_timeout);
|
rc = receive_block(inbuf, card->read_timeout);
|
||||||
|
@ -714,7 +695,6 @@ int ata_write_sectors(IF_MV2(int drive,)
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int write_cmd;
|
int write_cmd;
|
||||||
unsigned char start_token;
|
unsigned char start_token;
|
||||||
unsigned char response;
|
|
||||||
tCardInfo *card;
|
tCardInfo *card;
|
||||||
#ifndef HAVE_MULTIVOLUME
|
#ifndef HAVE_MULTIVOLUME
|
||||||
int drive = current_card;
|
int drive = current_card;
|
||||||
|
@ -744,36 +724,27 @@ int ata_write_sectors(IF_MV2(int drive,)
|
||||||
write_cmd = CMD_WRITE_BLOCK;
|
write_cmd = CMD_WRITE_BLOCK;
|
||||||
start_token = DT_START_BLOCK;
|
start_token = DT_START_BLOCK;
|
||||||
}
|
}
|
||||||
rc = send_cmd(write_cmd, start * BLOCK_SIZE, &response);
|
/* MMC4.2: make multiplication conditional */
|
||||||
/* MMC4.2: make multiplication conditional */
|
if (send_cmd(write_cmd, start * BLOCK_SIZE, NULL))
|
||||||
if (rc)
|
|
||||||
{
|
{
|
||||||
rc = rc * 10 - 2;
|
rc = -2;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
while (--count >= 0)
|
||||||
while (--count > 0)
|
|
||||||
{
|
{
|
||||||
rc = send_block_send(start_token, card->write_timeout, true);
|
rc = send_block_send(start_token, card->write_timeout, count > 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
rc = rc * 10 - 3;
|
rc = rc * 10 - 3;
|
||||||
break;
|
break;
|
||||||
|
/* If an error occurs during multiple block writing,
|
||||||
|
* the STOP_TRAN token still needs to be sent. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rc == 0)
|
|
||||||
{
|
|
||||||
rc = send_block_send(start_token, card->write_timeout, false);
|
|
||||||
if (rc)
|
|
||||||
rc = rc * 10 - 4;
|
|
||||||
}
|
|
||||||
/* If an error occurs during multiple block writing, the STOP_TRAN token
|
|
||||||
* still needs to be sent, hence the special error handling above. */
|
|
||||||
|
|
||||||
if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK)
|
if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK)
|
||||||
{
|
{
|
||||||
response = DT_STOP_TRAN;
|
static const unsigned char stop_tran = DT_STOP_TRAN;
|
||||||
write_transfer(&response, 1);
|
write_transfer(&stop_tran, 1);
|
||||||
poll_busy(card->write_timeout);
|
poll_busy(card->write_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,13 +835,10 @@ bool mmc_touched(void)
|
||||||
{
|
{
|
||||||
if (mmc_status == MMC_UNKNOWN) /* try to detect */
|
if (mmc_status == MMC_UNKNOWN) /* try to detect */
|
||||||
{
|
{
|
||||||
unsigned char response;
|
|
||||||
|
|
||||||
mutex_lock(&mmc_mutex);
|
mutex_lock(&mmc_mutex);
|
||||||
setup_sci1(7); /* safe value */
|
setup_sci1(7); /* safe value */
|
||||||
and_b(~0x02, &PADRH); /* assert CS */
|
and_b(~0x02, &PADRH); /* assert CS */
|
||||||
send_cmd(CMD_SEND_OP_COND, 0, &response);
|
if (send_cmd(CMD_SEND_OP_COND, 0, NULL) == 0xFF)
|
||||||
if (response == 0xFF)
|
|
||||||
mmc_status = MMC_UNTOUCHED;
|
mmc_status = MMC_UNTOUCHED;
|
||||||
else
|
else
|
||||||
mmc_status = MMC_TOUCHED;
|
mmc_status = MMC_TOUCHED;
|
||||||
|
@ -943,18 +911,15 @@ int ata_soft_reset(void)
|
||||||
|
|
||||||
void ata_enable(bool on)
|
void ata_enable(bool on)
|
||||||
{
|
{
|
||||||
PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */
|
PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
|
||||||
PACR2 &= ~0x4000; /* use PA7 (bridge reset) as GPIO */
|
* if not modified below */
|
||||||
if (on)
|
if (on)
|
||||||
{
|
PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
|
||||||
PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
|
|
||||||
IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
|
and_b(~0x80, &PADRL); /* assert flash reset */
|
||||||
mmc_enable_int_flash_clock(true); /* always enabled in SPI mode */
|
sleep(HZ/100);
|
||||||
}
|
or_b(0x80, &PADRL); /* de-assert flash reset */
|
||||||
and_b(~0x80, &PADRL); /* assert reset */
|
sleep(HZ/100);
|
||||||
sleep(HZ/20);
|
|
||||||
or_b(0x80, &PADRL); /* de-assert reset */
|
|
||||||
sleep(HZ/20);
|
|
||||||
card_info[0].initialized = false;
|
card_info[0].initialized = false;
|
||||||
card_info[1].initialized = false;
|
card_info[1].initialized = false;
|
||||||
}
|
}
|
||||||
|
@ -971,36 +936,33 @@ int ata_init(void)
|
||||||
mutex_lock(&mmc_mutex);
|
mutex_lock(&mmc_mutex);
|
||||||
led(false);
|
led(false);
|
||||||
|
|
||||||
/* Port setup */
|
|
||||||
PACR1 &= ~0x0F00; /* GPIO function for PA12, /IRQ1 for PA13 */
|
|
||||||
PACR1 |= 0x0400;
|
|
||||||
PADR |= 0x0680; /* set all the selects + reset high (=inactive) */
|
|
||||||
PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */
|
|
||||||
|
|
||||||
PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high when GPIO CHECKME: mask */
|
|
||||||
PBIOR |= 0x2000; /* SCK1 output */
|
|
||||||
PBIOR &= ~0x0C00; /* TxD1, RxD1 input */
|
|
||||||
|
|
||||||
last_mmc_status = mmc_detect();
|
last_mmc_status = mmc_detect();
|
||||||
#ifndef HAVE_MULTIVOLUME
|
#ifndef HAVE_MULTIVOLUME
|
||||||
if (last_mmc_status)
|
/* Use MMC if inserted, internal flash otherwise */
|
||||||
{ /* MMC inserted */
|
current_card = last_mmc_status ? 1 : 0;
|
||||||
current_card = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* no MMC, use internal memory */
|
|
||||||
current_card = 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
|
if (!initialized)
|
||||||
ata_enable(true);
|
|
||||||
|
|
||||||
if ( !initialized )
|
|
||||||
{
|
{
|
||||||
if (!last_mmc_status)
|
if (!last_mmc_status)
|
||||||
mmc_status = MMC_UNTOUCHED;
|
mmc_status = MMC_UNTOUCHED;
|
||||||
|
|
||||||
|
/* Port setup */
|
||||||
|
PACR1 &= ~0x0F3C; /* GPIO function for PA13 (flash busy), PA12
|
||||||
|
* (clk gate), PA10 (flash CS), PA9 (MMC CS) */
|
||||||
|
PACR2 &= ~0x4000; /* GPIO for PA7 (flash reset) */
|
||||||
|
PADR |= 0x0680; /* set all the selects + reset high (=inactive) */
|
||||||
|
PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */
|
||||||
|
|
||||||
|
PBCR1 &= ~0x0CF0; /* GPIO function for PB13, PB11 and PB10 */
|
||||||
|
PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high in GPIO */
|
||||||
|
PBIOR |= 0x2000; /* SCK1 output */
|
||||||
|
PBIOR &= ~0x0C00; /* TxD1, RxD1 input */
|
||||||
|
|
||||||
|
IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
|
||||||
|
|
||||||
|
new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
|
||||||
|
|
||||||
create_thread(mmc_thread, mmc_stack,
|
create_thread(mmc_thread, mmc_stack,
|
||||||
sizeof(mmc_stack), 0, mmc_thread_name
|
sizeof(mmc_stack), 0, mmc_thread_name
|
||||||
IF_PRIO(, PRIORITY_SYSTEM)
|
IF_PRIO(, PRIORITY_SYSTEM)
|
||||||
|
@ -1008,6 +970,7 @@ int ata_init(void)
|
||||||
tick_add_task(mmc_tick);
|
tick_add_task(mmc_tick);
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
ata_enable(true);
|
||||||
|
|
||||||
mutex_unlock(&mmc_mutex);
|
mutex_unlock(&mmc_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue