add SDHC support
rework PAR+BTT system to match the original P8000 behaviour
This commit is contained in:
parent
e098003f7d
commit
33783a4bb2
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_config.h,v 1.10 2012/06/08 10:40:39 olivleh1 Exp $
|
* $Id: wdc_config.h,v 1.11 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
#define MMC_MULTIBLOCK 1
|
#define MMC_MULTIBLOCK 1
|
||||||
|
|
||||||
|
#define MEASURE_SDCARD_TIME 1
|
||||||
#undef MEASURE_SDCARD_TIME
|
#undef MEASURE_SDCARD_TIME
|
||||||
|
|
||||||
#endif /* CONFIG_H_ */
|
#endif /* CONFIG_H_ */
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_drv_mmc.c,v 1.14 2012/06/08 11:11:26 olivleh1 Exp $
|
* $Id: wdc_drv_mmc.c,v 1.15 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#define CMD0 (0x40 + 0)
|
#define CMD0 (0x40 + 0)
|
||||||
#define CMD1 (0x40 + 1)
|
#define CMD1 (0x40 + 1)
|
||||||
|
#define CMD8 (0x40 + 8)
|
||||||
#define CMD12 (0x40 + 12)
|
#define CMD12 (0x40 + 12)
|
||||||
#define CMD17 (0x40 + 17)
|
#define CMD17 (0x40 + 17)
|
||||||
#define CMD18 (0x40 + 18)
|
#define CMD18 (0x40 + 18)
|
||||||
|
|
@ -61,6 +62,8 @@
|
||||||
uint8_t mmc_read_block ( uint8_t *, uint8_t *, uint16_t );
|
uint8_t mmc_read_block ( uint8_t *, uint8_t *, uint16_t );
|
||||||
uint8_t mmc_cmd ( uint8_t * );
|
uint8_t mmc_cmd ( uint8_t * );
|
||||||
|
|
||||||
|
uint8_t is_sdhc = 0;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint32_t value32;
|
uint32_t value32;
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -177,6 +180,7 @@ uint8_t mmc_enable_crc ( uint8_t on_off )
|
||||||
uint8_t mmc_init ()
|
uint8_t mmc_init ()
|
||||||
{
|
{
|
||||||
uint16_t t16 = 0;
|
uint16_t t16 = 0;
|
||||||
|
uint8_t a;
|
||||||
|
|
||||||
|
|
||||||
DDR_MMC &= ~ ( 1 << PIN_MMC_MISO );
|
DDR_MMC &= ~ ( 1 << PIN_MMC_MISO );
|
||||||
|
|
@ -184,7 +188,7 @@ uint8_t mmc_init ()
|
||||||
DDR_MMC |= ( 1 << PIN_MMC_MOSI );
|
DDR_MMC |= ( 1 << PIN_MMC_MOSI );
|
||||||
DDR_MMC |= ( 1 << PIN_MMC_CS );
|
DDR_MMC |= ( 1 << PIN_MMC_CS );
|
||||||
|
|
||||||
for ( uint8_t a = 0; a < 200; a++ ) {
|
for ( a = 0; a < 200; a++ ) {
|
||||||
nop();
|
nop();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -193,7 +197,7 @@ uint8_t mmc_init ()
|
||||||
|
|
||||||
MMC_Disable();
|
MMC_Disable();
|
||||||
|
|
||||||
for ( uint8_t b = 0; b < 0x0f; b++ ) {
|
for ( a = 0; a < 0x0f; a++ ) {
|
||||||
send_dummy_byte();
|
send_dummy_byte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,12 +216,41 @@ uint8_t mmc_init ()
|
||||||
|
|
||||||
send_dummy_byte();
|
send_dummy_byte();
|
||||||
|
|
||||||
|
cmd[0] = CMD8;
|
||||||
|
cmd[1] = 0x00;
|
||||||
|
cmd[2] = 0x00;
|
||||||
|
cmd[3] = 0x01;
|
||||||
|
cmd[4] = 0xaa;
|
||||||
|
cmd[5] = 0x86;
|
||||||
|
a = mmc_cmd ( cmd );
|
||||||
|
/* if SDHC Card */
|
||||||
|
if ( a <= 1 ) {
|
||||||
|
/* skip 6 bytes */
|
||||||
|
for ( a = 0; a < 6; a++ )
|
||||||
|
send_dummy_byte();
|
||||||
|
|
||||||
|
is_sdhc = 1;
|
||||||
|
|
||||||
|
/* prepare next cmd */
|
||||||
|
cmd[0] = CMD1;
|
||||||
|
cmd[1] = 0x40;
|
||||||
|
cmd[2] = cmd[3] = cmd[4] = 0x00;
|
||||||
|
cmd[5] = 0xFF;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
send_dummy_byte();
|
||||||
|
is_sdhc = 0;
|
||||||
|
|
||||||
|
/* prepare next cmd */
|
||||||
|
cmd[0] = CMD1;
|
||||||
|
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0x00;
|
||||||
|
cmd[5] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send CMD1
|
* send CMD1
|
||||||
*/
|
*/
|
||||||
t16 = 0;
|
t16 = 0;
|
||||||
cmd[0] = CMD1;
|
|
||||||
cmd[5] = 0xFF;
|
|
||||||
while ( mmc_cmd ( cmd ) != 0 ) {
|
while ( mmc_cmd ( cmd ) != 0 ) {
|
||||||
send_dummy_byte();
|
send_dummy_byte();
|
||||||
if ( t16++ > 1000 ) {
|
if ( t16++ > 1000 ) {
|
||||||
|
|
@ -281,11 +314,13 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer )
|
||||||
wait_till_card_ready();
|
wait_till_card_ready();
|
||||||
|
|
||||||
/* convert blocks to bytes */
|
/* convert blocks to bytes */
|
||||||
|
if ( !is_sdhc )
|
||||||
addr = addr * MMC_BLOCKLEN;
|
addr = addr * MMC_BLOCKLEN;
|
||||||
x.value32 = addr;
|
x.value32 = addr;
|
||||||
cmd[1] = x.value8.hh;
|
cmd[1] = x.value8.hh;
|
||||||
cmd[2] = x.value8.hl;
|
cmd[2] = x.value8.hl;
|
||||||
cmd[3] = x.value8.lh;
|
cmd[3] = x.value8.lh;
|
||||||
|
cmd[4] = x.value8.ll;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send CMD24
|
* send CMD24
|
||||||
|
|
@ -340,7 +375,7 @@ uint8_t mmc_write_sector ( uint32_t addr, uint8_t *buffer )
|
||||||
uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes )
|
uint8_t mmc_read_block ( uint8_t *cmd, uint8_t *buffer, uint16_t bytes )
|
||||||
{
|
{
|
||||||
uint16_t i = 1;
|
uint16_t i = 1;
|
||||||
uint8_t by;
|
uint8_t by;
|
||||||
#ifdef SPI_CRC
|
#ifdef SPI_CRC
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -373,7 +408,7 @@ uint8_t by;
|
||||||
wait_till_send_done();
|
wait_till_send_done();
|
||||||
by = recv_byte();
|
by = recv_byte();
|
||||||
xmit_byte ( 0xff );
|
xmit_byte ( 0xff );
|
||||||
} while ( i<bytes );
|
} while ( i < bytes );
|
||||||
|
|
||||||
*buffer = by;
|
*buffer = by;
|
||||||
|
|
||||||
|
|
@ -382,7 +417,7 @@ uint8_t by;
|
||||||
#ifdef SPI_CRC
|
#ifdef SPI_CRC
|
||||||
crc = recv_byte() << 8;
|
crc = recv_byte() << 8;
|
||||||
xmit_byte ( 0xff );
|
xmit_byte ( 0xff );
|
||||||
buffer = buffer - (bytes-1);
|
buffer = buffer - ( bytes - 1 );
|
||||||
wait_till_send_done();
|
wait_till_send_done();
|
||||||
crc |= recv_byte();
|
crc |= recv_byte();
|
||||||
if ( crc != crc16 ( buffer, bytes ) ) {
|
if ( crc != crc16 ( buffer, bytes ) ) {
|
||||||
|
|
@ -407,11 +442,13 @@ uint8_t mmc_read_sector ( uint32_t addr, uint8_t *buffer )
|
||||||
uint8_t cmd[] = {CMD17, 0x00, 0x00, 0x00, 0x00, 0xFF};
|
uint8_t cmd[] = {CMD17, 0x00, 0x00, 0x00, 0x00, 0xFF};
|
||||||
|
|
||||||
/* convert blocks to bytes */
|
/* convert blocks to bytes */
|
||||||
|
if ( !is_sdhc )
|
||||||
addr = addr * MMC_BLOCKLEN;
|
addr = addr * MMC_BLOCKLEN;
|
||||||
x.value32 = addr;
|
x.value32 = addr;
|
||||||
cmd[1] = x.value8.hh;
|
cmd[1] = x.value8.hh;
|
||||||
cmd[2] = x.value8.hl;
|
cmd[2] = x.value8.hl;
|
||||||
cmd[3] = x.value8.lh;
|
cmd[3] = x.value8.lh;
|
||||||
|
cmd[4] = x.value8.ll;
|
||||||
|
|
||||||
return mmc_read_block ( cmd, buffer, MMC_BLOCKLEN );
|
return mmc_read_block ( cmd, buffer, MMC_BLOCKLEN );
|
||||||
|
|
||||||
|
|
@ -452,14 +489,16 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* convert blocks to bytes */
|
/* convert blocks to bytes */
|
||||||
|
if ( !is_sdhc )
|
||||||
addr = addr * MMC_BLOCKLEN;
|
addr = addr * MMC_BLOCKLEN;
|
||||||
x.value32 = addr;
|
x.value32 = addr;
|
||||||
|
|
||||||
#ifdef MMC_MULTIBLOCK
|
#ifdef MMC_MULTIBLOCK
|
||||||
cmd[0] = CMD18;
|
cmd[0] = CMD18;
|
||||||
cmd[1] = x.value8.hh;
|
cmd[1] = x.value8.hh;
|
||||||
cmd[2] = x.value8.hl;
|
cmd[2] = x.value8.hl;
|
||||||
cmd[3] = x.value8.lh;
|
cmd[3] = x.value8.lh;
|
||||||
cmd[4] = 0;
|
cmd[4] = x.value8.ll;
|
||||||
|
|
||||||
wait_till_card_ready();
|
wait_till_card_ready();
|
||||||
|
|
||||||
|
|
@ -482,6 +521,7 @@ uint8_t mmc_read_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
|
||||||
cmd[1] = x.value8.hh;
|
cmd[1] = x.value8.hh;
|
||||||
cmd[2] = x.value8.hl;
|
cmd[2] = x.value8.hl;
|
||||||
cmd[3] = x.value8.lh;
|
cmd[3] = x.value8.lh;
|
||||||
|
cmd[4] = x.value8.ll;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send CMD17
|
* send CMD17
|
||||||
|
|
@ -592,6 +632,8 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/* convert blocks to bytes */
|
/* convert blocks to bytes */
|
||||||
|
/* convert blocks to bytes */
|
||||||
|
if ( !is_sdhc )
|
||||||
addr = addr * MMC_BLOCKLEN;
|
addr = addr * MMC_BLOCKLEN;
|
||||||
x.value32 = addr;
|
x.value32 = addr;
|
||||||
#ifdef MMC_MULTIBLOCK
|
#ifdef MMC_MULTIBLOCK
|
||||||
|
|
@ -599,7 +641,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
|
||||||
cmd[1] = x.value8.hh;
|
cmd[1] = x.value8.hh;
|
||||||
cmd[2] = x.value8.hl;
|
cmd[2] = x.value8.hl;
|
||||||
cmd[3] = x.value8.lh;
|
cmd[3] = x.value8.lh;
|
||||||
cmd[4] = 0;
|
cmd[4] = x.value8.ll;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send CMD25
|
* send CMD25
|
||||||
|
|
@ -619,6 +661,7 @@ uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t numblocks
|
||||||
cmd[1] = x.value8.hh;
|
cmd[1] = x.value8.hh;
|
||||||
cmd[2] = x.value8.hl;
|
cmd[2] = x.value8.hl;
|
||||||
cmd[3] = x.value8.lh;
|
cmd[3] = x.value8.lh;
|
||||||
|
cmd[4] = x.value8.ll;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send CMD24
|
* send CMD24
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_if_disk.c,v 1.9 2012/06/07 18:01:02 olivleh1 Exp $
|
* $Id: wdc_if_disk.c,v 1.10 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -34,8 +34,6 @@
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "wdc_par.h"
|
#include "wdc_par.h"
|
||||||
|
|
||||||
extern uint8_t par_table[];
|
|
||||||
|
|
||||||
uint8_t wdc_init_sdcard()
|
uint8_t wdc_init_sdcard()
|
||||||
{
|
{
|
||||||
uint8_t errorcode;
|
uint8_t errorcode;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
|
||||||
#ifdef MEASURE_SDCARD_TIME
|
#ifdef MEASURE_SDCARD_TIME
|
||||||
#define BLOCKNO 150000
|
#define BLOCKNO 300000
|
||||||
|
|
||||||
extern uint32_t overflow;
|
extern uint32_t overflow;
|
||||||
|
|
||||||
|
|
@ -108,13 +108,13 @@ void test_read512(uint8_t numblocks, uint8_t nr_of_tests)
|
||||||
uint32_t blockno = 0;
|
uint32_t blockno = 0;
|
||||||
uint8_t i8, errorcode;
|
uint8_t i8, errorcode;
|
||||||
|
|
||||||
uart_puts_p ( PSTR ( "Test Read 5000 512B-Blocks with Multiblock-Read (4KB Blocksize):" ) );
|
uart_puts_p ( PSTR ( "Test Read 5000 512B-Blocks with Singleblock-Read (512B Blocksize):" ) );
|
||||||
uart_putc ( '\n' );
|
uart_putc ( '\n' );
|
||||||
|
|
||||||
for ( i8 = 0; i8 < nr_of_tests; i8++ ) {
|
for ( i8 = 0; i8 < nr_of_tests; i8++ ) {
|
||||||
blockno = BLOCKNO;
|
blockno = BLOCKNO;
|
||||||
for ( starttime = overflow; blockno < ( BLOCKNO + 5000 ); blockno += numblocks ) {
|
for ( starttime = overflow; blockno < ( BLOCKNO + 5000 ); blockno++ ) {
|
||||||
errorcode = wdc_read_multiblock ( blockno, data_buffer, numblocks );
|
errorcode = wdc_read_sector ( blockno, data_buffer );
|
||||||
if ( errorcode ) {
|
if ( errorcode ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_if_p8000.h,v 1.6 2012/06/07 18:01:02 olivleh1 Exp $
|
* $Id: wdc_if_p8000.h,v 1.7 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WDC_IF_PIO_H_
|
#ifndef WDC_IF_PIO_H_
|
||||||
#define WDC_IF_PIO_H_
|
#define WDC_IF_PIO_H_
|
||||||
|
|
||||||
#define DELAY_PIO_US 500
|
#define DELAY_PIO_US 450
|
||||||
|
|
||||||
#define configure_port_data_read() DDR_DATA = 0x00 /* programs the DATA-Port as Input-only for reading from the P8000*/
|
#define configure_port_data_read() DDR_DATA = 0x00 /* programs the DATA-Port as Input-only for reading from the P8000*/
|
||||||
#define configure_port_data_write() DDR_DATA = 0xff /* programs the DATA-Port as Out-only for writing to the P8000*/
|
#define configure_port_data_write() DDR_DATA = 0xff /* programs the DATA-Port as Out-only for writing to the P8000*/
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
/*
|
/*
|
||||||
* P8000 WDC Emulator
|
* P8000 WDC Emulator
|
||||||
*
|
*
|
||||||
* $Id: wdc_main.c,v 1.22 2012/06/08 11:11:26 olivleh1 Exp $
|
* $Id: wdc_main.c,v 1.23 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*
|
*
|
||||||
* TODO: - Different Errorcodes in the MMC layer (use defines)
|
* TODO: - Different Errorcodes in the MMC layer (use defines)
|
||||||
* - errorchecking in several places
|
* - errorchecking in several places
|
||||||
|
|
@ -41,6 +41,8 @@
|
||||||
* - Prio 3: put the whole par_table handling from wdc_ram.[ch] into wdc_par.[ch]
|
* - Prio 3: put the whole par_table handling from wdc_ram.[ch] into wdc_par.[ch]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
|
@ -49,15 +51,15 @@
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <avr/sleep.h>
|
#include <avr/sleep.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#ifdef DEBUG
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
#endif
|
||||||
#include "wdc_ram.h"
|
#include "wdc_ram.h"
|
||||||
#include "wdc_par.h"
|
#include "wdc_par.h"
|
||||||
#include "wdc_if_pio.h"
|
#include "wdc_if_pio.h"
|
||||||
#include "wdc_if_sdcard.h"
|
#include "wdc_if_sdcard.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
|
||||||
|
|
||||||
void atmega_setup ( void );
|
void atmega_setup ( void );
|
||||||
|
|
||||||
#ifdef MEASURE_SDCARD_TIME
|
#ifdef MEASURE_SDCARD_TIME
|
||||||
|
|
@ -68,9 +70,13 @@ ISR ( TIMER0_OVF_vect )
|
||||||
overflow ++;
|
overflow ++;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* switched from local to global for keeping an eye on memory usage */
|
/* switched from local to global for keeping an eye on memory usage */
|
||||||
uint8_t data_buffer[4096];
|
uint8_t data_buffer[4096];
|
||||||
uint8_t cmd_buffer[9];
|
uint8_t cmd_buffer[9];
|
||||||
|
|
||||||
|
extern uint8_t valid_disk;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int __attribute__ ( ( OS_main ) )
|
int __attribute__ ( ( OS_main ) )
|
||||||
|
|
@ -92,19 +98,24 @@ main ( void )
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* load Parameter Table into RAM if valid */
|
/* load Parameter Table into RAM if valid */
|
||||||
|
if ( wdc_get_disk_valid() ) {
|
||||||
blockno = 0;
|
blockno = 0;
|
||||||
data_counter = WDC_BLOCKLEN;
|
data_counter = WDC_BLOCKLEN;
|
||||||
while ( wdc_read_sector ( blockno, data_buffer ) ) {
|
wdc_read_sector ( blockno, data_buffer );
|
||||||
#if DEBUG >= 1
|
|
||||||
uart_puts_p ( PSTR ( "Block 0 of SD-Card not readable" ) );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( data_buffer[0] == 'W' &&
|
if ( data_buffer[0] == 'W' &&
|
||||||
data_buffer[1] == 'D' &&
|
data_buffer[1] == 'D' &&
|
||||||
data_buffer[2] == 'C' ) {
|
data_buffer[2] == 'C' &&
|
||||||
|
data_buffer[3] == '_' &&
|
||||||
|
data_buffer[4] == '4' &&
|
||||||
|
data_buffer[5] == '.' &&
|
||||||
|
data_buffer[6] == '2' ) {
|
||||||
wdc_write_par_table ( data_buffer, data_counter );
|
wdc_write_par_table ( data_buffer, data_counter );
|
||||||
|
wdc_set_disk_valid();
|
||||||
|
} else {
|
||||||
|
wdc_set_disk_invalid();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
|
|
||||||
|
|
@ -132,6 +143,24 @@ main ( void )
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* if the disk is not valid, only maintenance commands are allowed */
|
||||||
|
if ( ! wdc_get_disk_valid()
|
||||||
|
&& cmd_buffer[0] != CMD_RD_WDC_RAM
|
||||||
|
&& cmd_buffer[0] != CMD_FMTRD_TRACK
|
||||||
|
&& cmd_buffer[0] != CMD_WR_WDC_RAM
|
||||||
|
&& cmd_buffer[0] != CMD_FMTBTT_TRACK
|
||||||
|
&& cmd_buffer[0] != CMD_RD_PARTAB
|
||||||
|
&& cmd_buffer[0] != CMD_RD_WDCERR
|
||||||
|
&& cmd_buffer[0] != CMD_VER_TRACK
|
||||||
|
&& cmd_buffer[0] != CMD_DL_BTTAB
|
||||||
|
&& cmd_buffer[0] != CMD_RD_BTTAB
|
||||||
|
&& cmd_buffer[0] != CMD_WR_BTTAB
|
||||||
|
&& cmd_buffer[0] != CMD_WR_PARTAB
|
||||||
|
&& cmd_buffer[0] != CMD_ST_PARBTT
|
||||||
|
) {
|
||||||
|
wdc_send_error();
|
||||||
|
} else {
|
||||||
|
|
||||||
switch ( cmd_buffer[0] ) {
|
switch ( cmd_buffer[0] ) {
|
||||||
case CMD_WR_BLOCK:
|
case CMD_WR_BLOCK:
|
||||||
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
|
data_counter = ( cmd_buffer[7] << 8 ) | cmd_buffer[6];
|
||||||
|
|
@ -218,6 +247,7 @@ main ( void )
|
||||||
|
|
||||||
wdc_write_wdc_par ( data_buffer
|
wdc_write_wdc_par ( data_buffer
|
||||||
, data_counter );
|
, data_counter );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DL_BTTAB:
|
case CMD_DL_BTTAB:
|
||||||
|
|
@ -246,7 +276,13 @@ main ( void )
|
||||||
, data_counter );
|
, data_counter );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_FMTRD_TRACK:
|
||||||
case CMD_FMTBTT_TRACK:
|
case CMD_FMTBTT_TRACK:
|
||||||
|
|
||||||
|
/* no cylinder 0 formatting if command is CMD_FMTBTT_TRACK */
|
||||||
|
if ( cmd_buffer[0] == CMD_FMTBTT_TRACK && ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ) ) == 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
data_counter = WDC_BLOCKLEN;
|
data_counter = WDC_BLOCKLEN;
|
||||||
|
|
||||||
memset ( &data_buffer[0], 0x00, data_counter );
|
memset ( &data_buffer[0], 0x00, data_counter );
|
||||||
|
|
@ -262,7 +298,11 @@ main ( void )
|
||||||
blockno++;
|
blockno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( errorcode ) {
|
if ( errorcode ) {
|
||||||
|
if ( cmd_buffer[0] == CMD_FMTRD_TRACK ) {
|
||||||
|
wdc_send_error();
|
||||||
|
} else {
|
||||||
if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) {
|
if ( wdc_add_btt_entry ( cmd_buffer[2] | ( cmd_buffer[3] << 8 ), cmd_buffer[4] ) ) {
|
||||||
wdc_send_error();
|
wdc_send_error();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -275,18 +315,21 @@ main ( void )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_ST_PARBTT:
|
case CMD_ST_PARBTT:
|
||||||
data_counter = WDC_BLOCKLEN;
|
data_counter = WDC_BLOCKLEN;
|
||||||
|
|
||||||
blockno = 0;
|
blockno = 0;
|
||||||
|
wdc_set_disk_valid();
|
||||||
wdc_read_par_table ( data_buffer
|
wdc_read_par_table ( data_buffer
|
||||||
, data_counter );
|
, data_counter );
|
||||||
|
|
||||||
errorcode = wdc_write_sector ( blockno, data_buffer );
|
errorcode = wdc_write_sector ( blockno, data_buffer );
|
||||||
if ( errorcode )
|
if ( errorcode )
|
||||||
wdc_send_error();
|
wdc_send_error();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_RD_WDCERR:
|
case CMD_RD_WDCERR:
|
||||||
|
|
@ -352,6 +395,7 @@ main ( void )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -361,10 +405,8 @@ void atmega_setup ( void )
|
||||||
set_sleep_mode ( SLEEP_MODE_IDLE );
|
set_sleep_mode ( SLEEP_MODE_IDLE );
|
||||||
uart_init();
|
uart_init();
|
||||||
wdc_init_ports();
|
wdc_init_ports();
|
||||||
while ( wdc_init_sdcard() ) {
|
if ( wdc_init_sdcard() ) {
|
||||||
#if DEBUG >= 1
|
wdc_set_no_disk();
|
||||||
uart_puts_p ( PSTR ( "SDCard initialisation failed!" ) );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_main.h,v 1.10 2012/06/07 18:01:02 olivleh1 Exp $
|
* $Id: wdc_main.h,v 1.11 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
#define CMD_RD_WDC_RAM 0x08 /* read data from WDC RAM */
|
#define CMD_RD_WDC_RAM 0x08 /* read data from WDC RAM */
|
||||||
#define ___CMD_RDBTT_SECTOR 0x11 /* read sector taking BTT into account */
|
#define ___CMD_RDBTT_SECTOR 0x11 /* read sector taking BTT into account */
|
||||||
#define ___CMD_WRBTT_SECTOR 0x12 /* write sector taking BTT into account */
|
#define ___CMD_WRBTT_SECTOR 0x12 /* write sector taking BTT into account */
|
||||||
#define ___CMD_FMTRD_TRACK 0x14 /* format and reread a track */
|
#define CMD_FMTRD_TRACK 0x14 /* format and reread a track */
|
||||||
#define CMD_WR_WDC_RAM 0x18 /* write data to WDC RAM */
|
#define CMD_WR_WDC_RAM 0x18 /* write data to WDC RAM */
|
||||||
#define CMD_RD_BLOCK 0x21 /* read data beginning at given block */
|
#define CMD_RD_BLOCK 0x21 /* read data beginning at given block */
|
||||||
#define CMD_WR_BLOCK 0x22 /* write data beginning at given block */
|
#define CMD_WR_BLOCK 0x22 /* write data beginning at given block */
|
||||||
|
|
|
||||||
|
|
@ -26,18 +26,77 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_par.c,v 1.2 2012/06/07 18:01:02 olivleh1 Exp $
|
* $Id: wdc_par.c,v 1.3 2012/06/09 00:22:28 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "wdc_par.h"
|
#include "wdc_par.h"
|
||||||
|
|
||||||
uint8_t par_table[512] = {'W', 'D', 'C', '_', '4', '.', '2', 0x00, 'R', 'O', 'B', ' ', 'K', '5', '5', '0',
|
/*
|
||||||
'4', '.', '5', '0', 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x12, 0x00, 0x04, 0x01, 0x00, 0x00,
|
* unformatted ST138
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x67, 0x01, 0x00, 0x01, 0x01,
|
*
|
||||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
* 57 44 43 5F 34 2E 32 81 81 81 81 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 81 81 64 00 02 12 64 00 01 81 81
|
||||||
|
* 81 81 81 81 81 81 81 81 81 81 EB 0D 00 00 41 00
|
||||||
|
* 01 01 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 EB 0D 00 00 24 00 00 81 81 81 81
|
||||||
|
* 00 81 00 80 FE 00 00 00 01 81 81 73 00 12 81 01
|
||||||
|
* 00 02 00 00 81 81 81 00 41 D7 28 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* fresh formatted ST138
|
||||||
|
*
|
||||||
|
* 57 44 43 5F 34 2E 32 81 53 54 32 35 31 2D 31 20
|
||||||
|
* 20 20 20 20 81 00 00 34 03 06 12 34 03 01 00 00
|
||||||
|
* 00 00 00 00 CB D1 FB FD F1 F3 83 59 01 00 01 09
|
||||||
|
* 00 01 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 83 59 01 00 6C 00 00 81 81 81 E5
|
||||||
|
* 00 81 00 80 FE 00 00 00 01 81 81 33 00 12 81 00
|
||||||
|
* 00 00 00 00 81 81 81 09 01 D7 28 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* no harddrive attached:
|
||||||
|
*
|
||||||
|
* 57 44 43 5F 34 2E 32 81 81 81 81 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 81 81 64 00 02 12 64 00 01 81 81
|
||||||
|
* 81 81 81 81 81 81 81 81 81 81 81 81 81 81 40 00
|
||||||
|
* 00 00 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
* 00 81 00 80 81 81 81 81 81 81 81 33 00 12 81 00
|
||||||
|
* 81 81 81 81 81 81 81 00 40 D7 81 81 81 81 81 81
|
||||||
|
* 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81 81
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t par_table[512];
|
||||||
|
const uint8_t
|
||||||
|
par_tab_new_dsk[128] = {'W', 'D', 'C', '_', '4', '.', '2', 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x64, 0x00, 0x02, 0x12, 0x64, 0x00, 0x01, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, /* init with sa.format ends here */
|
||||||
|
/* to be initiated by controller starts here */ 0xEB, 0x0D, 0x00, 0x00, 0x41, 0x00,
|
||||||
|
0x01, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0xEB, 0x0D, 0x00, 0x00, 0x24, 0x00, 0x00, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x00, 0x81, 0x00, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x81, 0x81, 0x73, 0x00, 0x12, 0x81, 0x01,
|
||||||
|
0x00, 0x02, 0x00, 0x00, 0x81, 0x81, 0x81, 0x00, 0x41, 0xd7, 0x28, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t
|
||||||
|
par_tab_no_dsk[128] = {'W', 'D', 'C', '_', '4', '.', '2', 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x64, 0x00, 0x02, 0x12, 0x64, 0x00, 0x01, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, /* init with sa.format ends here */
|
||||||
|
/* to be initiated by controller starts here */ 0x81, 0x81, 0x81, 0x81, 0x40, 0x00,
|
||||||
|
0x00, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x00, 0x81, 0x00, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x33, 0x00, 0x12, 0x81, 0x00,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x40, 0xd7, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t valid_disk = 1;
|
||||||
|
|
||||||
void wdc_read_par_table ( uint8_t *buffer, uint16_t count )
|
void wdc_read_par_table ( uint8_t *buffer, uint16_t count )
|
||||||
{
|
{
|
||||||
|
|
@ -136,3 +195,60 @@ uint8_t wdc_get_hdd_heads()
|
||||||
{
|
{
|
||||||
return ( par_table[17 + POS_PAR_WDC_PAR] );
|
return ( par_table[17 + POS_PAR_WDC_PAR] );
|
||||||
}
|
}
|
||||||
|
uint16_t wdc_get_hdd_cylinder()
|
||||||
|
{
|
||||||
|
return ( ( par_table[16 + POS_PAR_WDC_PAR] << 8 ) | par_table[15 + POS_PAR_WDC_PAR] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void wdc_set_disk_invalid()
|
||||||
|
{
|
||||||
|
valid_disk = 0;
|
||||||
|
uint8_t i;
|
||||||
|
for ( i = 0; i < 128; i++ )
|
||||||
|
par_table[i] = par_tab_new_dsk[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void wdc_set_disk_valid()
|
||||||
|
{
|
||||||
|
uint32_t blocks;
|
||||||
|
uint16_t zw0, zw1;
|
||||||
|
|
||||||
|
blocks = (uint32_t)wdc_get_hdd_sectors() * (uint32_t)wdc_get_hdd_heads() * (uint32_t) wdc_get_hdd_cylinder()
|
||||||
|
- (uint32_t)wdc_get_hdd_sectors() * (uint32_t)wdc_get_hdd_heads();
|
||||||
|
|
||||||
|
zw0 = blocks / 65536;
|
||||||
|
zw1 = ( blocks % 65536 ) - 1;
|
||||||
|
|
||||||
|
valid_disk = 1;
|
||||||
|
par_table[42] = zw1;
|
||||||
|
par_table[43] = zw1 >> 8;
|
||||||
|
par_table[44] = zw0;
|
||||||
|
par_table[45] = zw0 >> 8;
|
||||||
|
par_table[46] = 0x01;
|
||||||
|
par_table[47] = 0x09;
|
||||||
|
par_table[48] = 0x00;
|
||||||
|
par_table[69] = 0x83;
|
||||||
|
par_table[70] = 0x59;
|
||||||
|
par_table[71] = 0x01;
|
||||||
|
par_table[73] = 0x6c;
|
||||||
|
par_table[91] = 0x33;
|
||||||
|
par_table[95] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wdc_set_no_disk()
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
valid_disk = 0;
|
||||||
|
for ( i = 0; i < 128; i++ )
|
||||||
|
par_table[i] = par_tab_no_dsk[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t wdc_get_disk_valid()
|
||||||
|
{
|
||||||
|
return valid_disk;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t wdc_get_num_of_drvs()
|
||||||
|
{
|
||||||
|
return par_table[49];
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: wdc_par.h,v 1.2 2012/06/07 18:01:02 olivleh1 Exp $
|
* $Id: wdc_par.h,v 1.3 2012/06/09 00:22:29 olivleh1 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WDC_PAR_H_
|
#ifndef WDC_PAR_H_
|
||||||
|
|
@ -47,12 +47,19 @@ extern uint8_t wdc_add_btt_entry ( uint16_t cylinder, uint8_t head );
|
||||||
extern uint8_t wdc_get_hdd_sectors();
|
extern uint8_t wdc_get_hdd_sectors();
|
||||||
extern uint8_t wdc_get_hdd_heads();
|
extern uint8_t wdc_get_hdd_heads();
|
||||||
|
|
||||||
|
void wdc_set_disk_invalid();
|
||||||
|
void wdc_set_disk_valid();
|
||||||
|
uint8_t wdc_get_disk_valid();
|
||||||
|
|
||||||
|
void wdc_set_no_disk();
|
||||||
|
uint8_t wdc_get_num_of_drvs();
|
||||||
|
|
||||||
#define POS_PAR_VERSION 0
|
#define POS_PAR_VERSION 0
|
||||||
#define POS_PAR_WDC_PAR 8
|
#define POS_PAR_WDC_PAR 8
|
||||||
#define POS_PAR_WDC_BTT 88
|
#define POS_PAR_WDC_BTT 0x88
|
||||||
|
|
||||||
#define SIZE_PAR_VERSION 8
|
#define SIZE_PAR_VERSION 8
|
||||||
#define SIZE_PAR_WDC_PAR 80
|
#define SIZE_PAR_WDC_PAR 0x80
|
||||||
#define SIZE_PAR_WDC_BTT 125
|
#define SIZE_PAR_WDC_BTT 125
|
||||||
|
|
||||||
#endif /* WDC_PAR_H_ */
|
#endif /* WDC_PAR_H_ */
|
||||||
Loading…
Reference in New Issue