Marlin 2.0 for Flying Bear 4S/5
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

175 lines
5.7 KiB

/****************
* dl_cache.cpp *
****************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
/* The Display List Cache mechanism stores the display list corresponding
* to a menu into RAM_G so that on subsequent calls drawing the menu does
* not require as much SPI traffic.
*
* Layout of Cache memory:
*
* The cache memory begins with a table at
* DL_CACHE_START: each table entry contains
* an address and size for a cached DL slot.
*
* Immediately following the table is the
* DL_FREE_ADDR, which points to free cache
* space; following this is occupied DL space,
* and after that free space that is yet to
* be used.
*
* location data sizeof
*
* DL_CACHE_START slot0_addr 4
* slot0_size 4
* slot1_addr 4
* slot1_size 4
* ...
* slotN_addr 4
* slotN_size 4
* DL_FREE_ADDR dl_free_ptr 4
* cached data
* ...
* dl_free_ptr empty space
* ...
*/
#define DL_CACHE_START MAP::RAM_G_SIZE - 0xFFFF
#define DL_FREE_ADDR DL_CACHE_START + DL_CACHE_SLOTS * 8
using namespace FTDI;
// The init function ensures all cache locations are marked as empty
void DLCache::init() {
CLCD::mem_write_32(DL_FREE_ADDR, DL_FREE_ADDR + 4);
for(uint8_t slot = 0; slot < DL_CACHE_SLOTS; slot++) {
save_slot(slot, 0, 0);
}
}
bool DLCache::has_data() {
return dl_size != 0;
}
bool DLCache::wait_until_idle() {
const unsigned long startTime = millis();
do {
if ((millis() - startTime) > 250) {
SERIAL_ECHO_MSG("Timeout on DL_Cache::Wait_Until_Idle()");
CLCD::CommandFifo::reset();
return false;
}
#ifdef __MARLIN_FIRMWARE__
ExtUI::yield();
#endif
} while (CLCD::CommandFifo::is_processing());
return true;
}
/* This caches the current display list in RAMG so
* that it can be appended later. The memory is
* dynamically allocated following DL_FREE_ADDR.
*
* If num_bytes is provided, then that many bytes
* will be reserved so that the cache may be re-written
* later with potentially a bigger DL.
*/
bool DLCache::store(uint32_t num_bytes /* = 0*/) {
CLCD::CommandFifo cmd;
// Execute any commands already in the FIFO
cmd.execute();
if (!wait_until_idle())
return false;
// Figure out how long the display list is
uint32_t new_dl_size = CLCD::mem_read_32(REG::CMD_DL) & 0x1FFF;
uint32_t free_space = 0;
uint32_t dl_alloc = 0;
if (dl_addr == 0) {
// If we are allocating new space...
dl_addr = CLCD::mem_read_32(DL_FREE_ADDR);
free_space = MAP::RAM_G_SIZE - dl_addr;
dl_alloc = num_bytes ?: new_dl_size;
dl_size = new_dl_size;
} else {
// Otherwise, we can only store as much space
// as was previously allocated.
free_space = num_bytes ?: dl_size;
dl_alloc = 0;
dl_size = new_dl_size;
}
if (dl_size > free_space) {
// Not enough memory to cache the display list.
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Not enough space in GRAM to cache display list, free space: ", free_space,
" Required: ", dl_size);
#endif
return false;
} else {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Saving DL to RAMG cache, bytes: ", dl_size,
" Free space: ", free_space);
#endif
cmd.memcpy(dl_addr, MAP::RAM_DL, dl_size);
cmd.execute();
save_slot(dl_slot, dl_addr, dl_size);
if (dl_alloc > 0) {
// If we allocated space dynamically, then adjust dl_free_addr.
CLCD::mem_write_32(DL_FREE_ADDR, dl_addr + dl_alloc);
}
return true;
}
}
void DLCache::save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size) {
CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 0, dl_addr);
CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 4, dl_size);
}
void DLCache::load_slot() {
dl_addr = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 0);
dl_size = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 4);
}
void DLCache::append() {
CLCD::CommandFifo cmd;
cmd.append(dl_addr, dl_size);
#if ENABLED(TOUCH_UI_DEBUG)
cmd.execute();
wait_until_idle();
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Appending to DL from RAMG cache, bytes: ", dl_size,
" REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL));
#endif
}
#endif // FTDI_EXTENDED