problemas al intentar comunicarse entre ATMEL mega169 y ATMEL flash

1

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 Butterfly.

He logrado leer el registro de estado y obtener los datos correctos, por lo que estoy seguro de que el flash funciona y se puede comunicar. Pero no he podido escribir y leer en flash, lo único que puedo leer es los ceros.

Lamentablemente, tampoco tengo ninguna posibilidad de detener el tráfico.

init:

 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))) {;}
}

recive:

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;
}

borrar bandera:

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 recibiendo las señales correctas en el momento adecuado?

Si desea aclaraciones o más descripciones, infórmelo.
Saludos
Gorgen

    
pregunta Gorgen

1 respuesta

2

Lo único que puedo detectar es que stop_transmission() no se encuentra en flash_ready() .

Tu secuencia de programación es:

  1. llenar el búfer
  2. esperar a que esté listo
  3. programa
  4. esperar a que esté listo

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

    
respondido por el Andy

Lea otras preguntas en las etiquetas