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
Lo único que puedo detectar es que stop_transmission()
falta en flash_ready()
.
Su secuencia de programación es:
El comando del programa puede perderse ya que no está precedido por un borde descendente de $\overline{\text{CS}}$.
Kortuk
Kortuk
usuario3882