problemas al intentar comunicarse entre ATMEL mega169 y ATMEL flash

Hola a todos

Estoy escribiendo un programa en C que accederá a un flash AT45DB041B desde el controlador ATmega169. Estoy usando un kit de desarrollo de Butterfly.

Logré leer el registro de estado y obtener los datos correctos, por lo que estoy bastante seguro de que el flash funciona y puede comunicarse. Pero no he podido escribir y leer en flash, lo único que puedo leer son ceros.

Desafortunadamente, tampoco tengo ninguna posibilidad de espiar el tráfico.

en eso:

 void init_flash_as_master(void)
 {

// double speed, p 150 mega169 manual
SPSR = 0x01; // the other bits are don't care or set by hardware

//      MOSI        SCK         !SS    are outputs
DDRB |= _BV(PB2) | _BV(PB1) | _BV(PB0);


// p 148 in mega169 manual
/* bit 7, 0 interrupt not enabled
 * bit 6, 1 SPI enable,
 * bit 5, 0, MSB first, ch 5 flash datasheet
 * bit 4, 1, Master
 * bit 3,2, 00, CPOL,CPHA, SPI mode 0, p 5 flash datasheet
 * bit 1,0, 10, /32, flash max operating frequency 20 MHz p 1 flash datasheet
 */

SPCR = 0x52;

}

enviar:

inline void send_byte(uint8_t byte)
{
    SPDR = byte;
    while (!(SPSR & _BV(SPIF))) {;}
}

recibir:

inline uint8_t recieve_byte(void) 
{
SPDR = 'A'; //load SPDR to start clock generation
while (!(SPSR & _BV(SPIF))) {;}
return SPDR;
}

iniciar transmisión:

inline void start_transmission(void) 
{
    // set chip select for sending data
    PORTB &= 0xFE; // setting bit 0 on port B low
}

detener la transmisión:

inline void stop_transmission(void) 
{
    // finish transmission
    PORTB |= 0x01;
}

bandera clara:

inline void clear_SPIF(void)
{
    uint8_t temp = 0;

    // clear SPIF
    if(SPSR & _BV(SPIF)) { temp = SPDR; }
}

operación de escritura:

// write a struct song_t to specified page in the flash memory
void flash_write_song(uint16_t page, const song_t * song)
{
    if (direction != master) init_flash_as_master();

    clear_SPIF();
    start_transmission();
    // ch. 12.2 flash datasheet 
    send_byte(0x84); // write to buffer 1, 84h
    send_byte(0x00); // three address bytes, starting at byte 0
    send_byte(0x00); // table 7, flash application note
    send_byte(0x00);

    // push name
    for (int i = 0; i != NAME_LEN; i++)
    {
        send_byte(song->name[i]);
    }
    int j = 0;
    while (j < TUNE_LEN) 
    {
        send_byte(song->tune[j]);
        j++;
}
stop_transmission();

flash_ready();

start_transmission();
// ch. 12.3 flash datasheet

    // Buffer 1 to Main Memory Page Program with Built-in Erase
send_byte(0x83); 

    // first byte contains the 4 uppermost bits
send_byte(get_high_byte(page));

    // second byte contains the 7 lowest bits, starting at bit 1
send_byte(get_low_byte(page)); 
send_byte(0x00); // table 7, flash application note

stop_transmission();
flash_ready();

}

operación de lectura:

// read a struct song_t from specified page in the flash memory
void flash_read_song(uint16_t page, song_t * song)
{

if (direction != master) init_flash_as_master();

clear_SPIF();

// flash datasheet 16.2
start_transmission();

// table 7, flash application note
send_byte(0xD2); // read page from main memory,
// first byte contains the 4 uppermost bits
send_byte(get_high_byte(page)); 
// second byte contains the 7 lowest bits, starting at bit 1
send_byte(get_low_byte(page)); 
send_byte(0x00); // controller says, read from byte 0

send_byte(0x00); // 4 don't care bytes
send_byte(0x00);
send_byte(0x00);
send_byte(0x00);

// read name
for (int i = 0; i != NAME_LEN; i++)
{
    song->name[i] = recieve_byte(); 
}
/*  // and now we will read the data until we find a 0
int j = 0;
uint8_t byte_popped = recieve_byte();
while (j < 4) //TODO
{
    song->tune[j] = byte_popped;
    j++;
    byte_popped = recieve_byte();
}
*/
stop_transmission();

}

La pregunta

Estoy bastante seguro de que el error está en mi código, ya que puedo leer el registro de estado. Pero no puedo ver ningún problema en mi código. ¿Estoy dando las señales correctas en el momento adecuado?

Si desea alguna aclaración o más descripciones, por favor díganos.
Saludos
Gorgen

¿Puedes dar sondas de señales? ¿Puede publicar su código en este sitio en lugar de pastebin? Realmente no podemos ayudar fácilmente sin más información. Estoy cerrando esto y cuando esté listo para hacer actualizaciones, hágamelo saber y volveré a abrir (solo marque para la atención del moderador).
parece que alguien ya te ayudó. He vuelto a abrir, pero parece que la pregunta está bastante resuelta. Lo que quiero señalar es que alguien realmente podría usar un esquema y señales probadas para un problema más complicado. Como la solución parece ser relativamente fácil y muy específica para su situación, la cerré. Con el código, alguien ahora tiene una guía completa para interactuar con este flash. Buena suerte y diviertete.
@Kortuk: Lo haré... :)

Respuestas (1)

Lo único que puedo detectar es que stop_transmission()falta en flash_ready().

Su secuencia de programación es:

  1. búfer de relleno
  2. espera listo
  3. programa
  4. espera listo

El comando del programa puede perderse ya que no está precedido por un borde descendente de $\overline{\text{CS}}$.