#include #include #include static int flash_block_size; static int flash_blocks; //static cyg_uint8 *flash_buffer = 0; /* Buffer for one Flash-Sector */ static cyg_uint8 *current_flash_segment = 0; static bool memory_write_init_done = false; /* Allocation of the flash-sector size RAM-buffer is done */ static bool memory_write_init_flash_written = false; /* memory_write() has at least one call in the flash speace */ static int dbg_f_c; /* debug counters */ static int dbg_w_c; #define flash_buffer memory_write_flash_buffer int dummy_printf(const char *fmt, ...){ /* The Flash should shut up! */ return 0; } static cyg_uint32 *flash_block_begin(cyg_uint32 *addr){ return (cyg_uint32 *)((((cyg_uint32) addr) / flash_block_size) * flash_block_size); } bool flash_valid_address(cyg_uint8 *addr){ return flash_verify_addr((cyg_uint32 *) addr) == FLASH_ERR_OK; } cyg_uint32 memory_write_init(void){ dbg_f_c = 0; dbg_w_c = 0; flash_init(dummy_printf); flash_get_block_info(&flash_block_size, &flash_blocks); // if (!flash_buffer){ // flash_buffer = zcalloc(0, flash_block_size, sizeof(cyg_uint8)); // } memory_write_init_done = true; memory_write_init_flash_written = false; return flash_block_size; } bool memory_write_valid_address(cyg_uint8 *addr){ if (!memory_write_init_done){ diag_printf("ERROR: memory_write_valid_address(): !memory_write_init_done\n"); /* ERROR */ return false; } return valid_address(addr) || flash_valid_address(addr); } bool memory_write(cyg_uint8 *addr, cyg_uint8 value){ cyg_uint32 retcode = FLASH_ERR_OK; cyg_uint32 err_addr; if (!memory_write_init_done || !flash_buffer){ diag_printf("ERROR: memory_write(): !memory_write_init_done || !flash_buffer\n"); /* ERROR */ return false; } if (valid_address(addr)){ /* If the target address is in RAM */ *addr = value; } else if (flash_valid_address((cyg_uint32 *) addr)){ /* If it's in Flash */ if (!memory_write_init_flash_written){ /* First Byte for the flash-space */ memcpy(flash_buffer, flash_block_begin((cyg_uint32 *) addr), flash_block_size); /* Init buffer with defaults */ current_flash_segment = addr; memory_write_init_flash_written = true; dbg_f_c++; } else { if (flash_block_begin((cyg_uint32 *) addr) != flash_block_begin((cyg_uint32 *) current_flash_segment)){ /* If we are in the next segment */ retcode = flash_erase(flash_block_begin(current_flash_segment), flash_block_size, &err_addr); if (retcode != FLASH_ERR_OK){ /* Flash ERROR */ diag_printf("ERROR: memory_write(): flash_erase(): %08x; addr: %08x\n", retcode, err_addr);/* ERROR */ return false; } retcode = flash_program(flash_block_begin(current_flash_segment), flash_buffer, flash_block_size, &err_addr); /* Write buffer to flash */ if (retcode != FLASH_ERR_OK){ /* Flash ERROR */ diag_printf("ERROR: memory_write(): flash_program(): %08x; addr: %08x\n", retcode, err_addr);/* ERROR */ return false; } memcpy(flash_buffer, flash_block_begin((cyg_uint32 *) addr), flash_block_size); /* Init buffer with defaults */ current_flash_segment = addr; dbg_w_c++; } } *(cyg_uint8 *)((cyg_uint32) flash_buffer + ((cyg_uint32) addr) % flash_block_size) = value; } else { /* Wrong Address */ diag_printf("ERROR: memory_write(): Wrong Address: %08x\n", addr); /* ERROR */ return false; } return true; } void memory_write_fini(void){ cyg_uint32 retcode = FLASH_ERR_OK; cyg_uint32 err_addr; if (memory_write_init_done && memory_write_init_flash_written && flash_buffer){ retcode = flash_erase(flash_block_begin(current_flash_segment), flash_block_size, &err_addr); if (retcode != FLASH_ERR_OK){ /* Flash ERROR */ diag_printf("ERROR: memory_write_fini(): flash_erase(): %08x; addr: %08x\n", retcode, err_addr);/* ERROR */ } retcode = flash_program(flash_block_begin(current_flash_segment), flash_buffer, flash_block_size, &err_addr); /* Write buffer to flash */ if (retcode != FLASH_ERR_OK){ /* Flash ERROR */ diag_printf("ERROR: memory_write_fini(): flash_program(): %08x; addr: %08x\n", retcode, err_addr);/* ERROR */ } } memory_write_init_done = false; memory_write_init_flash_written = false; // if (flash_buffer){ // zcfree(0, flash_buffer); // flash_buffer = 0; // } flash_init(diag_printf); }