#include <18F4550.h>
#device adc=8
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

#use rs232(baud=9600,parity=N,xmit=PIN_A0,rcv=PIN_A1,bits=8, force_sw)

#use spi(MASTER,BITS=8,MODE=3,FORCE_HW,stream=SDCard)

#define SD_CS PIN_B3
#define CMD0 0       // Resetea la SD Card.-
#define CMD1 1       // Activa proceso de inicialización de SD Card.


void SDSelect(void){
   output_low(SD_CS);
   spi_xfer(SDCard,0xFF);
}
void SDDeselect(void){
   spi_xfer(SDCard,0xFF);
   output_high(SD_CS);
}

int1 SDCard_send_command(int cmd, int32 arg,int& res){ 

   int Trama[6]; // Comando, Argumento y CRC
   int i,ResTmp;
   // Construimos el paquete a enviar.-
   Trama[0] = cmd | 0x40;
   Trama[1] = make8(arg, 3);
   Trama[2] = make8(arg, 2);
   Trama[3] = make8(arg, 1);
   Trama[4] = make8(arg, 0);

   if(cmd==0){
      Trama[5]=0x95;
   }else{   
      Trama[5]=0xFF;
   }
   
   for( i=0;i<16;i++) spi_xfer(SDCard,0xFF);
   // Transfiere el paquete.-
   spi_xfer(SDCard, Trama[0]);
   spi_xfer(SDCard, Trama[1]);
   spi_xfer(SDCard, Trama[2]);
   spi_xfer(SDCard, Trama[3]);
   spi_xfer(SDCard, Trama[4]);
   spi_xfer(SDCard, Trama[5]);
      
   // // Se espera respuesta R1
   i=0;
   do{
      ResTmp=spi_xfer(SDCard,0xFF);
      putc(ResTmp);// Ver los hex de la respuesta.-
      i++;
   }while((ResTmp&0x80)!=0 && i<200);// mientras no corresponda con 0xxxxxxx.-
   if(i>=200){SDDeselect();return(0);}
   res=ResTmp;  
   printf("Repeticiones para respuesta de CmdXX: %u; Respuesta recibida:0x%X\r\n",i,res);
   return(1);
}

int1 SDCard_init(void){
int i,Respuesta;
   
   SETUP_SPI(SPI_MASTER|SPI_CLK_DIV_16|SPI_H_TO_L|SPI_XMIT_L_TO_H ); 
   
   
   printf("\r\n--> Se inicia sincronizacion\r\n");
   
   output_high(SD_CS);
   delay_ms(20);
   for(i=0;i<20;i++) spi_xfer(SDCard,0xFF);   // Para sincronización.
   output_low(SD_CS);
   delay_ms(20);
   printf("\r\n--> Se envia CMD0 (Se desactiva SD Card)\r\n\r\n");

   i=0;
   do{
      if(SDCard_send_command(CMD0,0x00,Respuesta)==0){
         return(0);        // Si se recibe 0 error por timeout.-
      }else{i++;}   
   }while(((Respuesta&0x01)==0x00) && i<200);
   if(i>=200){return(0);} // Timeout esperando desactivación de SD Card.
   
   // Pasamos a esperar condición de SD Card activa.
   // Si R1=0x01, SD Card en estado desactivado.
   printf("\r\n--> Se envia CMD1 (Se activa SD Card)\r\n\r\n");
      i=0;
   do{
      if(SDCard_send_command(CMD1,0x00,Respuesta)==0){
         return(0);     // Si se recibe 0 error por timeout.-
      }else{i++;}
   }while(((Respuesta&0x01)==0x01) && (i<100)); // Mientras se reciba R1=0x01
   if(i>=100){return(0);} // Timeout esperando activación de SD Card.

   
   SDDeselect();
   return(1);
}
/* *************************************************************************** */
void main()
{
char i;
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED|T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   output_high(PIN_C0);
   //delay_ms(1000);
   printf("Iniciando SD Card\r\n");

   SDCard_init();
   
   printf("Listo\r\n");

   while(1){
      
   }
   
}


