diff --git a/spi.c b/spi.c index e7d1c8d..e195101 100644 --- a/spi.c +++ b/spi.c @@ -128,18 +128,42 @@ void spi_block_write(char *addr) { spi_write(addr, 512); } +static unsigned char spi_speed; + void spi_slow() { AT91C_SPI_CSR[0] = AT91C_SPI_CPOL | (SPI_SLOW_CLK_VALUE << 8) | (2 << 24); // init clock 100-400 kHz + spi_speed = SPI_SLOW_CLK_VALUE; } void spi_fast() { // set appropriate SPI speed for SD/SDHC card (max 25 Mhz) AT91C_SPI_CSR[0] = AT91C_SPI_CPOL | (SPI_SDC_CLK_VALUE << 8); // 24 MHz SPI clock + spi_speed = SPI_SDC_CLK_VALUE; } void spi_fast_mmc() { // set appropriate SPI speed for MMC card (max 20Mhz) AT91C_SPI_CSR[0] = AT91C_SPI_CPOL | (SPI_MMC_CLK_VALUE << 8); // 16 MHz SPI clock + spi_speed = SPI_MMC_CLK_VALUE; +} + +unsigned char spi_get_speed() { + return spi_speed; +} + +void spi_set_speed(unsigned char speed) { + switch (speed) { + case SPI_SLOW_CLK_VALUE: + spi_slow(); + break; + + case SPI_SDC_CLK_VALUE: + spi_fast(); + break; + + default: + spi_fast_mmc(); + } } /* generic helper */ diff --git a/spi.h b/spi.h index 45faf48..095d115 100644 --- a/spi.h +++ b/spi.h @@ -14,6 +14,8 @@ void spi_slow(); void spi_fast(); void spi_fast_mmc(); RAMFUNC void spi_wait4xfer_end(); +unsigned char spi_get_speed(); +void spi_set_speed(unsigned char speed); /* chip select functions */ void EnableFpga(void); diff --git a/tos.c b/tos.c index a58ef26..79d2ec5 100644 --- a/tos.c +++ b/tos.c @@ -46,6 +46,9 @@ unsigned long hdd_direct = 0; static unsigned char dma_buffer[512]; +unsigned char spi_speed; +unsigned char spi_newspeed; + static const char *acsi_cmd_name(int cmd) { static const char *cmdname[] = { "Test Drive Ready", "Restore to Zero", "Cmd $2", "Request Sense", @@ -139,7 +142,14 @@ static void mist_memory_read(char *data, unsigned long words) { DisableFpga(); } +static void mist2_spi_set_speed(unsigned char speed) +{ + if (user_io_core_type() == CORE_TYPE_MIST2) spi_set_speed(speed); +} + static void mist_memory_write(char *data, unsigned long words) { + spi_speed = spi_get_speed(); + mist2_spi_set_speed(spi_newspeed); EnableFpga(); SPI(MIST_WRITE_MEMORY); @@ -149,24 +159,31 @@ static void mist_memory_write(char *data, unsigned long words) { } DisableFpga(); + mist2_spi_set_speed(spi_speed); } static void mist_memory_read_block(char *data) { + spi_speed = spi_get_speed(); + mist2_spi_set_speed(spi_newspeed); EnableFpga(); SPI(MIST_READ_MEMORY); spi_block_read(data); DisableFpga(); + mist2_spi_set_speed(spi_speed); } static void mist_memory_write_block(char *data) { + spi_speed = spi_get_speed(); + mist2_spi_set_speed(spi_newspeed); EnableFpga(); SPI(MIST_WRITE_MEMORY); spi_block_write(data); DisableFpga(); + mist2_spi_set_speed(spi_speed); } void mist_memory_set(char data, unsigned long words) { @@ -551,12 +568,15 @@ static void mist_get_dmastate() { DisableFpga(); // check if acsi is busy - if(buffer[19] & 0x01) + if(buffer[19] & 0x01) { + spi_newspeed = SPI_MMC_CLK_VALUE; handle_acsi(buffer); - + } // check if fdc is busy - if(buffer[8] & 0x01) + if(buffer[8] & 0x01) { + spi_newspeed = SPI_SLOW_CLK_VALUE; handle_fdc(buffer); + } } // color test, used to test the shifter without CPU/TOS