Hej there,
I am writing an application for a WyzBee board from Redpine Signals. They use the MB9MF568 from the FM4 MB9BFx6xM family. For my application I am trying to store account credentials and wireless lan configurations in the non-volatile work flash memory.
After a full or sector erase of the work flash writing to the flash is no problem. But if I try to write to the same memory addresses again the operation times out and the information is not stored correctly. Most of the time only the first byte of the half-word is written and the second is just garbage.
Is this a bug, or am I doing something wrong? Is there a working example (source code) somewhere?
I am using this code:
uint32_t write_to_nonvolatile( volatile uint16_t* p_start_address, uint16_t* p_data, uint16_t length_in_bytes){
int i,length;
int32_t status = WF_SUCCESS;
length = length_in_bytes/2;
for (i=0; i<length; i++)
status = write_half_word_to_nonvolatile(p_start_address+i, *(p_data+i));
return status;
}
uint32_t write_half_word_to_nonvolatile( volatile uint16_t* p_data_address, uint16_t data_half_word) {
int32_t operation_verified = 0;
volatile uint16_t *p_address;
uint16_t hw_seq_bits;
volatile uint8_t* reg_wfaszr;
char debug_message[64], dec_as_binary[9];
// Enable CPU programming mode
reg_wfaszr = &WFASZR;
*reg_wfaszr = 0x00;
WFASZR;
// Write command sequence
// prepare for true consecutive writes
// 1st write
p_address = (unsigned long)&WORKFLASH_CMD_BASE_ADDRESS | 0x00000AA8UL;
*p_address = 0x00AA;
// 2nd write
p_address = (unsigned long)&WORKFLASH_CMD_BASE_ADDRESS | 0x00000554UL;
*p_address = 0x0055;
// 3rd write
p_address = (unsigned long)&WORKFLASH_CMD_BASE_ADDRESS | 0x00000AA8UL;
*p_address = 0x00A0;
// write data
*p_data_address = data_half_word;
// dummy read
hw_seq_bits = *p_data_address;
// sprintf(debug_message, "First read of data address after write: b%s\n\r", dec2bin(dec_as_binary, hw_seq_bits, 8));
// WB_Debug(debug_message);
while ( !(WFSTR & WFSTR_RDY_MASK) && operation_verified < 2) {
// Perform read access on the address that was written to get the hw_seq_bits
hw_seq_bits = *p_data_address;
// sprintf(debug_message, "hw_seq_bits: b%s\n\r", dec2bin(dec_as_binary, hw_seq_bits, 8));
// WB_Debug(debug_message);
// if bit 7 of the data read (hw_seq_bits) is equal to bit 7 of the data written -> process complete
if ( (hw_seq_bits & HW_SEQ_BIT_DPOL_MASK) == (data_half_word & HW_SEQ_BIT_DPOL_MASK) ) {
break;
// WB_Debug("Write complete!\n\r"); break;// ToDo: abort!
}
// if write process is incomplete, check if max time exceeded
if ( hw_seq_bits & HW_SEQ_BIT_TLOV_MASK ) {
// operation_verified++;
sprintf(debug_message, "Write timed out writing address: %08X\n\r", p_data_address);
WB_Debug(debug_message); operation_verified++;// ToDo: abort!
}
}
// Return to CPU ROM mode
*reg_wfaszr = 0x01;
WFASZR;
// sprintf(debug_message, "Internal check WFASZR: %d\n\r", *reg_wfaszr);
// WB_Debug(debug_message);
return operation_verified;
}