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