|
|
View previous topic :: View next topic |
Author |
Message |
CHRIS Guest
|
COMPACT FLASH PROBLEM!!!! |
Posted: Thu Jun 10, 2004 4:45 am |
|
|
I am working with a CF card and I can read and erase sectors, but I can't write a sector and I don't know why.
I belive that my code is correct.
Do somebody detect the fail?
Thank's.
#include <16F73.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOBROWNOUT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7)
//******************************************************************************
#byte cf_control = 0x05 // puerto a
#byte cf_data = 0x06 // puerto b
#byte cf_addr = 0x07 // puerto c Solo usaremos C0,C1 y C2 para direccionar
#byte tris_cf_control = 0x85 // puerto a (1=entrada, 0=salida)
#byte tris_cf_data = 0x86 // b
#byte tris_cf_addr = 0x87 // c
#bit CE1 = cf_control.0
#bit CD1 = cf_control.1
#bit RESET = cf_control.2
#bit OE = cf_control.3
#bit WE = cf_control.4
#bit RDY = cf_control.5
#bit bucle = cf_addr.4
#bit led = cf_addr.3
//******************************************************************************
//FOR UART
#byte SPBRG = 0x99 // BAUD RATE GENERATOR REGISTER
#byte TXREG = 0x19 // USART TRANSMIT DATA REGISTER
#byte RCREG = 0x1A // USART RECEIVE DATA REGISTER
#byte TXSTA = 0x98 // TRANSMIT STATUS AND CONTROL REGISTER
#bit CSRC = 0x98.7 // Clock Source (1=Master, 0=Slave) Modo SYNC
#bit TX9 = 0x98.6 //
#bit TXEN = 0x98.5
#bit SYNC = 0x98.4
//#bit--- = 0x98.3
#bit BRGH = 0x98.2
#bit TRMT = 0x98.1
#bit TX9D = 0x98.0
#byte RCSTA= 0x18
#bit SPEN = 0x18.7
#bit RX9 = 0x18.6
#bit SREN = 0x18.5
#bit CREN = 0x18.4
#bit ADDEN = 0x18.3
#bit FERR = 0x18.2
#bit OERR = 0x18.1
#bit RX9D = 0x18.0
// DIRECCION DE LOS REGISTROS DE LA COMPACT FLASH
//******************************************************************************
// SOLO SON NECESARIAS 3 LINEAS:
// (X,X,X,X,X,A2,A1,A0)
#define DATA_REG 0x00 // ADDRESS OF DATA REGISTER
#define ERROR_REG 0x01 // ADDRESS OF ERROR REGISTER
#define FEATURES_REG 0x01 // ADDRESS OF FEATURES REGISTER
#define SEC_CNT_REG 0x02 // ADDRESS OF SECTOR COUNT REGISTER
#define SEC_NUM_REG 0x03 // ADDRESS OF SECTOR NUMBER REGISTER
#define CYL_LO_REG 0x04 // ADDRESS OF LOW CYLINDER REGISTER
#define CYL_HI_REG 0x05 // ADDRESS OF HIGH CYLINDER REGISTER
#define HEAD_REG 0x06 // ADDRESS OF HEAD/DRIVE REGISTER
#define STATUS_REG 0x07 // ADDRESS OF STATUS REGISTER
#define COMMAND_REG 0x07 // ADDRESS OF COMMAND REGISTER
// VALORES EN HEXADECIMAL DE COMANDOS PARA LA COMPACT FLASH
#define IDENTIFY 0xEC // IDENTIFICA LOS PARAMETROS DE LA UNIDAD
#define WRITE_SEC 0x30 // ESCRIBIMOS TANTOS SECTORES COMO INDICA SEC_CNT_REG
#define WRITE_BUFF_SEC 0xE8 // ESCRIBIMOS EN EL BUFFER TANTOS SECTORES COMO INDICA SEC_CNT_REG
#define READ_SEC 0x20 // LEEMOS TANTOS SECTORES COMO INDICA SEC_CNT_REG
#define ERASE_SEC 0xC0 // BORRAMOS TANTOS SECTORES COMO INDICA SEC_CNT_REG
//-------------------------------funciones usadas
void inicializa(void);
void cfwrite(void);
void cfread(void);
void checkready(void);
void getdatafromcf(int32 lba);
void putdatatocf(int32 lba);
void readsector(void);
void writesector(void);
void erasesector(void);
void getLBA(void);
//--------------------------------------end prototypes
//******************************************************************************
char data_lo,data_hi,;
int32 LBA;
byte contador;
byte i;
char buffer_in;
//******************************************************************************************************************
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
inicializa();
for (i=0;i<4;i++)
{
led = 1;
delay_ms(500);
led = 0;
delay_ms(500);
}
while(1){
buffer_in=getc();
switch (buffer_in){
case 0xF8: //READ SECTOR
getLBA();
getdatafromcf(LBA);
readsector();
break;
case 0xF9: //WRITE SECTOR
getLBA();
putdatatocf(LBA);
writesector();
break;
case 0xFB: //ERASE SECTOR
getLBA();
getdatafromcf(LBA);
erasesector();
break;
}
delay_ms(10);
putc(buffer_in);
}
}
//******************************************************************************
void inicializa(){
contador=0;
//Configuramos la UART
//TXSTA
tx9=0; // Deshabilitamos el 9 bit
txen=1; // Habilitamos la transmision
sync=0; // Seleccionamos modo ASINCRONO
brgh=1; // Establecemos el baudrate para high speed
//RCSTA
spen=1; // Habilitamos las lineas del puerto serie
rx9=0; // Selccionamos recpeción de 8 bits
cren=1; // Habilitamos recepción contínua
//SPBRG
spbrg=129; // Miramos en tablas, para high speed a 9600 corresponde el valor 129, para 19200 es 64
//Compact Flash
tris_cf_control =0x22; // port a xxoi iioi para la compact, pero para el pic es al reves xxio ooio
tris_cf_data =0x00; // port b oooo oooo
tris_cf_addr =0x80; // port c ioxo oooo
cf_control =0x18; // (RDY /WE /OE RST /CD1 /CE1) 0 1 1 0 0 0 Las entradas las dejamos a 1, /WE y /CDE
cf_addr =0x00; // 0 1 1 0 0 0
}
//******************************************************************************************************************
void checkready(void){
do{;
}while(!RDY);
}
//******************************************************************************************************************
void cfread(){
checkready(); // Esperamos a que RDY de la tarjeta este en alto
tris_cf_data=0xFF; // COnfiguramos el cf_data como todo entradas
CF_DATA=0; // Inicializamos, por si acaso
OE=false; // Lectura de la parte baja del dato
data_lo=CF_DATA;
OE=true;
checkready(); // Despues de la primera lectura esperamos para hacer la segunda
OE=false; // Lectura de la parte alta del dato
data_hi=CF_DATA;
OE=true;
tris_cf_data=0x00; // Configuramos el cf_data como todo salidas
}
//******************************************************************************************************************
void cfwrite(void){
checkready(); // Nos aseguramos que la tarjeta esta preparada
delay_us(5);
WE=0;
delay_ms(1);
WE=1;
}
//******************************************************************************************************************
void getLBA(void){
int8 lba0,lba1,lba2,lba3;
lba3=getc();
lba2=getc();
lba1=getc();
lba0=getc();
LBA=((int32)lba0)+((int32) lba1<<8)+((int32) lba2<<16)+((int32)lba3<<24);
putc(make8(LBA,3));
delay_ms(10);
putc(make8(LBA,2));
delay_ms(10);
putc(make8(LBA,1));
delay_ms(10);
putc(make8(LBA,0));
delay_ms(10);
getc();
}
//******************************************************************************************************************
// Para manejar un registro de la compact flash se coloca el dato en el cf_data, luego se
// coloca la dirección del registro a escribir o leer en el cf_addr y luego se baja a 0
// la correspondiente linea OE o WE para leer o escribir dicho registro.
void getdatafromcf(int32 lba){
lba = lba & 0x0FFFFFFF; // El primer byte siempre debe ser 1110 = E
lba = lba | 0xE0000000;
cf_data=make8(lba,3); // HEAD_REG = lba[3] Siempre ponemos 0xE0
cf_addr=HEAD_REG;
cfwrite();
cf_data=make8(lba,2); // CYL_HI_REG = lba[2]
cf_addr=CYL_HI_REG;
cfwrite();
cf_data=make8(lba,1); // CYL_LO_REG = lba[1]
cf_addr=CYL_LO_REG;
cfwrite();
cf_data=make8(lba,0); // SEC_NUM_REG = lba[0]
cf_addr=SEC_NUM_REG;
cfwrite();
cf_data=0x01; // SEC_CNT_REG = 0x01
cf_addr=SEC_CNT_REG; // seleccionamos que lea solo un sector
cfwrite();
cf_data=READ_SEC; // COMMAND_REG = READ_SEC
cf_addr=COMMAND_REG; // Comando para leer tantos sectores como indica SEC_CNT_REG
cfwrite();
cf_addr=DATA_REG; // Dejamos la dirección del registro de datos lista para usar
}
//******************************************************************************************************************
void putdatatocf(int32 lba){
lba = lba & 0x0FFFFFFF; // El primer byte siempre debe ser 1110 = E
lba = lba | 0xE0000000;
cf_data=make8(lba,3); // HEAD_REG = lba[3] Siempre ponemos 0xE0
cf_addr=HEAD_REG;
cfwrite();
cf_data=make8(lba,2); // CYL_HI_REG = lba[2]
cf_addr=CYL_HI_REG;
cfwrite();
cf_data=make8(lba,1); // CYL_LO_REG = lba[1]
cf_addr=CYL_LO_REG;
cfwrite();
cf_data=make8(lba,0); // SEC_NUM_REG = lba[0]
cf_addr=SEC_NUM_REG;
cfwrite();
cf_data=0x01; // SEC_CNT_REG = 0x01
cf_addr=SEC_CNT_REG; // seleccionamos que lea solo un sector
cfwrite();
cf_data=WRITE_SEC; // COMMAND_REG = WRITE_SEC
cf_addr=COMMAND_REG; // Comando para leer tantos sectores como indica SEC_CNT_REG
cfwrite();
cf_addr=DATA_REG; // Dejamos la dirección del registro de datos lista para usar
}
//******************************************************************************************************************
void readsector(){
int16 c;
for (c=0;c<256;c++){ //Un sector son 512 bytes
cfread();
}
}
//******************************************************************************************************************
void writesector(){
int16 c;
for (c=0;c<512;c++){ // Un sector son 512 bytes
cf_data=0xAF;
cf_addr=DATA_REG;
cfwrite();
}
}
//******************************************************************************************************************
void erasesector(){
cf_data=ERASE_SEC; // COMMAND_REG = READ_SEC
cf_addr=COMMAND_REG; // Comando para leer tantos sectores como indica SEC_CNT_REG
cfwrite();
cf_addr=DATA_REG; // Dejamos la dirección del registro de datos lista para usar
} |
|
|
lucky
Joined: 12 Sep 2003 Posts: 46 Location: South Coast - England
|
CF Code |
Posted: Fri Jun 11, 2004 3:22 am |
|
|
Hi CHRIS,
I dont know the answe to your problem as I am only reading from my CF but my old CF code in my downloads area was able to write & read back using the CF(). Note that this is very old code & is not FAT16 aware. You should be able to compare them & spot the error tho. My new FAT 16 code will be on there soon but this only reads. _________________ Lucky
www.mpic3.com - MPIC3 player project, Forum, Downloads, Online Shop |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|