/* --------------------------------- MMC.C ---------------------------------------------- Rutinas C de acceso a una tarjeta MMC mediante el protocolo de operacion SPI. Han sido probadas en un microcontrolador AVR-8515 y desarrolladas mediante la plataforma gratuita para Atmel y AVR-ATmega, Win-AVR. Version 0.0 Jordi Bartolome www.tolaemon.com 6-2004 ---------------------------------------------------------------------------------------*/ int ciclos_pausa=0x00; /* RSI de la interrupción de desboradamiento del TIMER0 */ SIGNAL (SIG_OVERFLOW0) { /* control de la variable de pausa: si la variable ciclos_pausa esta activada se decrementa */ if (ciclos_pausa>0){ ciclos_pausa--; };/*if*/ }/* RSI del TIMER0 */ /* procedimiento que realiza la pausa activa*/ void TIEMPO_pausa(int ciclos_pausa_ini){ ciclos_pausa=ciclos_pausa_ini; while (ciclos_pausa!=0){ /* mientras ciclos_pausa no sea 0 se hace una espera activa */ /* es la RSI del timer quien decrementa la variable ciclos_pausa */ };/*while*/ }/*TIEMPO_pausa*/ /* procedimiento que envia un byte a la MMCard a traves de la SPI */ uint8_t MMC_envia_byte(char valor){ SPDR=valor; while (!bit_is_set(SPSR,7)); /* se espera hasta que no haya finalizado la transmision */ SPSR=SPSR&0x7F; return SPDR; /* se retorna el valor cargado en el registro de datos tras la transmision */ }/* MMC_envia_byte */ /* procedimiento que envia el comando recibido a la MMC a traves de la SPI */ void MMC_envia_comando( uint8_t byte_0,uint8_t byte_1,uint8_t byte_2,uint8_t byte_3,uint8_t byte_4,uint8_t byte_5 ){ PORTD = PORTD|0x20;/* el bit 5-CS MMCard a 1 (CS desactivado) : XX1X XXXX */ TIEMPO_pausa(2);/* TIEMPO_pausa */ MMC_envia_byte(0xFF); PORTD = PORTD&0xDF;/* el bit 5-CS MMCard a 0 (CS activado): XX0X XXXX */ TIEMPO_pausa(2);/* TIEMPO_pausa */ /* Se envia el COMANDO */ MMC_envia_byte(byte_0); MMC_envia_byte(byte_1); MMC_envia_byte(byte_2); MMC_envia_byte(byte_3); MMC_envia_byte(byte_4); MMC_envia_byte(byte_5); TIEMPO_pausa(2);/* TIEMPO_pausa */ }/*MMC_envia_comando*/ /* procedimiento que activa los puertos y perifericos necesarios para la comunicacion con la tarjeta MMCard */ void MMC_activa(){ uint8_t i; DDRD = DDRD|0x20;/* bit 5-CS MMCard del puerto D configurado como salida: XX1X XXXX */ SPCR=0x53;/* configuracion de la SPI: 0101 0011 */ PORTD = PORTD|0x20;/* el bit 5-CS MMCard a 1 (CS desactivado) : XX1X XXXX */ TIEMPO_pausa(4);/* TIEMPO_pausa */ for (i=0;i<20;i++){ MMC_envia_byte(0xFF); /* se dan los 80 clocks iniciales para activar la SPI del la MMC */ };/*for*/ PORTD = PORTD&0xDF;/* el bit 5-CS MMCard a 0 (CS activado): XX0X XXXX */ }/*MMC_desactiva*/ /* procedimiento que desactiva la interficie SPI usada para la comunicaicon con la MMC */ void MMC_desactiva(){ PORTD = PORTD|0x20;/* el bit 5-CS MMCard a 1 (CS desactivado) : XX1X XXXX */ SPCR=0x13;/* configuracion de la SPI: 0001 0011 */ }/*MMC_desactiva*/ /* funcion que retorna la respuesta de la MMCard al comando enviado */ uint8_t MMC_espera_respuesta ( ){ uint8_t i=0; uint8_t valor=0xFF; /* entre el comando y la respuesta existe un retardo que va de 1 a 8 bytes (yo pongo 32 (4x) para que haya tiempo segurisisisimo), la respuesta R1 tiene una longitud de un byte y siempre comienza con un 0 */ while ( (i<=32) && (valor==0xFF) ){ valor=MMC_envia_byte(0xFF); i++; };/*while*/ return valor; }/* MMC_espera_respuesta */ /* funcion que retorna la respuesta de la MMCard al comando enviado */ uint8_t MMC_espera_data_token( ){ uint8_t i=0; uint8_t valor=0x00; /* se mantiene esperando el Data Token enviado por la tarjeta */ while ( (i<=10) && (valor!=0xFE) ){ valor=MMC_envia_byte(0xFF); i++; };/*while*/ return valor; }/* MMC_espera_respuesta */ /* funcion que realiza la secuencia de arranque de la tarjeta, retorna 1 si todo va bien y 0 si va mal */ char MMC_prepara_tarjeta(){ char respuesta1; char respuesta2; char retorno; uint8_t intentos; intentos=6; respuesta1=0; while ( (intentos>0)&&(respuesta1!=1) ){ MMC_activa(); MMC_envia_comando(0x40,0x00,0x00,0x00,0x00,0x95); respuesta1=MMC_espera_respuesta(); MMC_desactiva(); intentos--; };/* while */ respuesta2=1; while ( (intentos>0)&&(respuesta2!=0) ){ MMC_activa(); MMC_envia_comando(0x41,0x00,0x00,0x00,0x00,0xFF); respuesta2=MMC_espera_respuesta(); MMC_desactiva(); intentos--; };/* while */ MMC_desactiva(); /* si las respuestas recibidas son las correctas se retorna 1 sino 0 */ if ((respuesta1==1)&&(respuesta2==0)){ retorno=1; }else{ retorno=0; };/*if*/ return retorno; }/* MMC_prepara_tarjeta */