void ADC_Init(){
//Modulo ADC a 12 Bits~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ADCON1bits.ADON = 0;
//ConfigIntADC12(ADC_INT_DISABLE);
#define config1ADC ADC_MODULE_OFF & ADC_IDLE_CONTINUE & ADC_FORMAT_INTG & ADC_CLK_AUTO & ADC_AUTO_SAMPLING_OFF & ADC_SAMP_OFF
#define config2ADC ADC_VREF_AVDD_AVSS & ADC_SCAN_OFF & ADC_SAMPLES_PER_INT_1 & ADC_ALT_BUF_OFF & ADC_ALT_INPUT_OFF
#define config3ADC ADC_SAMPLE_TIME_8 & ADC_CONV_CLK_INTERNAL_RC & ADC_CONV_CLK_Tcy
#define configport ENABLE_AN5_ANA & ENABLE_AN4_ANA & ENABLE_AN3_ANA & ENABLE_AN8_ANA & ENABLE_AN9_ANA & ENABLE_AN10_ANA
#define configscan SCAN_NONE
OpenADC12(config1ADC,config2ADC,config3ADC,configport,configscan);
//SetChanADC12(ADC_CH0_POS_SAMPLEA_AN4 & ADC_CH0_NEG_SAMPLEA_NVREF); // Canal A
// ConfigIntADC12(ADC_INT_PRI_3 & ADC_INT_ENABLE);
// DisableIntADC;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
void sdSpiInit(unsigned int u){
CloseSPI1();
# define config1SPI FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT & ENABLE_SDO_PIN & SPI_MODE16_OFF & SPI_SMP_OFF & SPI_CKE_OFF & SLAVE_ENABLE_OFF & CLK_POL_ACTIVE_LOW & MASTER_ENABLE_ON& SEC_PRESCAL_2_1 & u
# define config2SPI SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR
OpenSPI1(config1SPI, config2SPI);
}
uint8_t sdSpiByte(uint8_t data){
SPI1BUF = data;
while(!(SPI1STATbits.SPIRBF));
return SPI1BUF;
}
uint8_t sdCrc7(uint8_t* chr,uint8_t cnt,uint8_t crc){
uint8_t i, a;
uint8_t Data;
for(a = 0; a < cnt; a++){
Data = chr[a];
for(i = 0; i < 8; i++){
crc <<= 1;
if( (Data & 0x80) ^ (crc & 0x80) ) {crc ^= 0x09;}
Data <<= 1;
}
}
return crc & 0x7F;
}
bool sdSendCommand(uint8_t cmd, uint32_t param){
uint8_t send[6];
send[0] = cmd | 0x40;
send[1] = param >> 24;
send[2] = param >> 16;
send[3] = param >> 8;
send[4] = param;
send[5] = (sdCrc7(send, 5, 0) << 1) | 1;
for(cmd = 0; cmd < sizeof(send); cmd++){
sdSpiByte(send[cmd]);
}
return true;
}
uint8_t sdReadResp(void){
uint8_t v;
uint16_t i = 0;
do{
v = sdSpiByte(0xFF);
}while((i++ < 128) & (v == 0xFF));
return v;
}
uint8_t sdCommandAndResponse(uint8_t cmd, uint32_t param){
uint8_t ret;
sdSpiByte(0xFF);
sdSendCommand(cmd, param);
ret = sdReadResp();
return ret;
}
void sdClockSpeed(bool fast){
CloseSPI1();
if(fast)
{
sdSpiInit(PRI_PRESCAL_1_1);
}
else
{
sdSpiInit(PRI_PRESCAL_64_1);
}
}
void sdChipSelect(bool active){
LATFbits.LATF0 = !active;
}
void fatal(uint8_t val){ // Usado para deteccion de errores
uint8_t k;
for(k = 0; k < val; k++)
{ __delay_ms(100);
UART_Write_Text("Error");
WriteUART2(13);
WriteUART2(10);
}
while(1)
{
Sleep();
}
}
bool sdInit(){
uint8_t v =1;
sdSpiInit(PRI_PRESCAL_16_1);
sdSpiByte(0xFF); // Envio basura para mover el reloj
sdClockSpeed(false); // slow clock
sdChipSelect(0); // CS inactive
for(v = 0; v < 20; v++)
{ // 80 ciclos de reloj 20 x 4 ciclos por instruccion = 80 ciclos de reloj
sdSpiByte(0xFF); //tren de pulsos de reloj para que inicialice modo SPI
}
sdChipSelect(1); // CS active
v = sdCommandAndResponse(0, 0); // reset de la uSD CMD0
if(!v){fatal(2);} // compruebo que haya respondido ok la uSD. si es 0 es error
v = sdCommandAndResponse(8, 0x000001AA); // Indico a la SD que trabaje con voltaje entre 2.7 y 3.6 voltios (Tarjetas SDHC y SDXC))
if(!v){fatal(3);}//Devuelve el valor de 1 si eeta todo bien
do{ __delay_ms(50);
sdCommandAndResponse(55, 0); // activo los comandos alternativos ACMD41
v = sdCommandAndResponse(41,0x40000000); // reset de la uSD CMD1 (Le asigno el HCS=1) (Tarjetas SDHC y SDXC))
}while(v);
if(v){fatal(4);}
v = sdCommandAndResponse(16, 512);//sec sector size
if(v){fatal(5);}
v = sdCommandAndResponse(59, 0);//crc off
if(v){fatal(6);}
// now set the sd card up for full speed
sdClockSpeed(true);
/* UART_Write_Text("SD Modo SPI");
WriteUART2(13);
WriteUART2(10); */
return true;
}
void sdSecReadStop(){
uint8_t v;
// read back the two CRC bytes
v = sdSpiByte(0xFF);
v = sdSpiByte(0xFF);
}
bool sdReadBlock(uint32_t sec, uint8_t *Buff){
uint8_t v;
uint16_t cy=0,cv=0,i=0;
v = sdCommandAndResponse (17, ((uint32_t)sec) << 9);
if (!v)
{
do{
v = sdSpiByte(0xFF);
}while((v == 0xFF));
if (v!=0xFE)
{
fatal(2);
return false;
}
else{
do
{
v = sdSpiByte(0xFF);
*Buff++= v;
cy++;
}while(cy<512);
sdSecReadStop();
}
return true;
}
}
bool sdWriteByteToSector(uint8_t b){
uint8_t r;
r=sdSpiByte(b);
bytesWritten++;
return true;
}
bool sdWriteBlockStart(uint32_t sec,uint8_t *Buff){
uint8_t v,r;
uint16_t iy;
v = sdCommandAndResponse(24, ((uint32_t)sec) << 9);
if(!v) {
// keep track of how many bytes we've written in this sector
// (when we hit 512 we should expect some extra bytes in the packet data)
bytesWritten=0;
// send the correct token for CMD17/18/24 (0xFE)
// REMEMBER the token for CMD25 is 0xFC
r=sdSpiByte(0xFE);
for(iy=0; iy<512; iy++){
sdWriteByteToSector(*Buff++);
}
// send two CRC bytes
while(bytesWritten<512){
sdSpiByte(0xFF);
bytesWritten++;
}
sdSpiByte(0x00);
sdSpiByte(0x00);
// response should immediately follow
// (for writing, we're looking for 0bXXX00101 data accepted)
r=sdSpiByte(0x00);
//WriteUART2(r);
r=(r>>1)&0b00000111;
if(r!=2)
{
fatal(5);
}
while (r!=0xFF){
r=sdSpiByte(0xFF);
}
return true;
}
return false;
}