updatate source with Arduboy FX library to v1.0.5

This commit is contained in:
Mr.Blinky 2023-01-07 02:07:49 +01:00
parent c26e9dd8a6
commit 29dd60bb1c
10 changed files with 579 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

View File

@ -0,0 +1,142 @@
/* *****************************************************************************
* FX drawDrame example v1.00 by Mr.Blinky Jan 2023 licenced under CC0
* *****************************************************************************
*
* This is a example that shows how you can draw animations from the FX external
* flash memory using the drawframes function
*
* Before this example sketch is uploaded and run on the Arduboy FX, make sure
* the fxdata used by this sketch has been build and uploaded to the Arduboy FX.
*
* If the Arduboy FX Arduino plugin has been installed you can simply choose the
* 'Build and upload Arduboy FX data' from the Arduino IDE Tools menu.
*
* Alternatively the fxdata.txt script file can be build using the fxdata-build.py
* Python script. using the command:
*
* fxdata-upload.py fxdata.txt
The created fxdata.bin file can be uploaded to your Arduboy by using the
*uploader-gui.py Python script using the command:
* fxdata-upload.py fxdata.bin
*
* On some OS you may need to type python3 infront of the script name and supply
* the full path to the script and fxdata files.
*
******************************************************************************
*
* There are 3 functions to make drawing animations of multiple bitmap images
* easier:
*
* - uint24_t FX::drawFrame(uint24_t address)
* - FX::setFrame(uint24_t frame, uint8_t repeat);
* - uint8_t FX::drawFrame();
*
* FX::drawFrame(uint24_t address)
* -------------------------------
* drawFrame is a bit like FX::drawBitmap but instead of passing the parameters
* along with the function directly, they are stored in FX memory at the given
* address. In addition to that parameters of multiple bitmaps can be stored at
* the address to draw multiple bitmaps by this function.
* the list of bitmap parameters is called a frame. The parameters are the same
* as used with FX::drawBitmap except the mode parameter. An extra flag value
* can be added to mark the end of a frame or to mark the frame as the last in
* the list of frames.
*
* this functions return the address of the next frame unless the frame is
* flagged as a last frame. In that case the function returns 0
*
* using this function has no effect on using the other frame functions.
*
* FX::setFrame(uint24_t address, uint8_t repeat)
* --------------------------------------------
* setFrame sets the current frame address and repeat value for the drawFrame
* function below.
*
* - address is the address of a frame list in FX memory.
* - repeat is number of times each frame should be repeated.
* Each frame is drawn repeat + 1 times.
*
* uint8_t FX::drawFrame()
* ------------------------
*
* drawFrame without parameters draws the current frame in the frame list set
* by the setFrame function above. When the last frame of the framelist is
* drawn and is also the last repeated frame, the current frame pointer is
* reset to start of the frame list. This effectively loops the frame list.
* the function also returns 0 in that case. This can be usedto detect the
* end of the animation.
*
******************************************************************************/
#include <Arduboy2.h> // required to build for Arduboy
#include <ArduboyFX.h> // required to access the FX external flash
#include "fxdata/fxdata.h" // this file contains all references to FX data
Arduboy2 arduboy;
enum class State : uint8_t {
init,
logo,
wait,
main,
};
State state;
uint8_t timer;
void setup() {
arduboy.boot(); // boot is used instead of begin as we don't want the Arduboy startup logo
arduboy.display(CLEAR_BUFFER); // another way to clear the display
arduboy.systemButtons(); // also do system buttons as it's normally used by begin
//arduboy.setFrameRate(60); // Only needed for frameRates other than 60
FX::begin(FX_DATA_PAGE); // initialise FX chip
state = State::init;
}
void loop() {
if (!arduboy.nextFrame()) return; // Do nothing until it's time for the next display frame
arduboy.pollButtons(); // required here for arduboy.justPressed() below
switch (state) {
//initialise animation using setFrame
case State::init:
{
FX::setFrame(ArduboyLogo_Frame, 0); // set frame list for drawFrame() and 0 repeats
state = State::logo; // changing the 0 into an higher value will
} // slow down the animation
break;
// do logo animation
case State::logo:
{ // draw a frame from the frame list and test if it was the last frame
if(!FX::drawFrame()) { // without this test the animation would loop continiously
state = State::wait; // it was the last frame go for wait state
timer = 60; // wait for 60 frames
}
}
break;
//wait and display a single frame
case State::wait:
{
FX::drawFrame(ArduboyLogo_LastFrame);
if (--timer == 0) state = State::main;
}
break;
case State::main:
{
// No special code here so the screen will turn black after the wait period
// pressing A or B button will restart the animation
if (arduboy.justPressed(A_BUTTON | B_BUTTON)) state = State::init;
}
break;
}
FX::display(CLEAR_BUFFER); // Using CLEAR_BUFFER will clear the display buffer after it is displayed
}

View File

@ -0,0 +1,83 @@
ArduboyLogo_Frame[] = {
int16_t 20, -15, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -14, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -13, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -12, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -11, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -10, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -9, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -8, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -7, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -6, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -5, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -4, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -3, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -2, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, -1, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 0, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 1, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 2, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 3, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 4, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 5, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 6, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 7, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 8, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 9, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 10, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 11, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 12, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 13, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 14, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 15, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 16, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 17, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 18, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 19, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 20, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 21, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 22, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 23, int24_t ArduboyLogo, int8_t 0, dbmNormal_end
int16_t 20, 24, int24_t ArduboyLogo, int8_t 0, dbmNormal_last
}

View File

@ -0,0 +1,21 @@
#pragma once
/**** FX data header generated by fxdata-build.py tool version 1.12 ****/
using uint24_t = __uint24;
// Initialize FX hardware using FX::begin(FX_DATA_PAGE); in the setup() function.
constexpr uint16_t FX_DATA_PAGE = 0xfffd;
constexpr uint24_t FX_DATA_BYTES = 674;
constexpr uint24_t ArduboyLogo = 0x000000;
constexpr uint16_t ArduboyLogoWidth = 88;
constexpr uint16_t ArduboyLogoHeight = 16;
constexpr uint24_t FXLogo = 0x0000B4;
constexpr uint16_t FXLogoWidth = 28;
constexpr uint16_t FXLogoHeight = 16;
constexpr uint24_t ArduboyLogo_Frame = 0x000128;
constexpr uint24_t ArduboyLogo_LastFrame = 0x000290;

View File

@ -0,0 +1,95 @@
/*******************************************************************************
FX Data resource file.
********************************************************************************
Run this file through the fx-data.py Python script (drag and drop) to create
a c-style header file that can be included with your project.
a .bin file will also be created containing the actual resource data. This .bin
file can be uploaded to the FX flash chip using the Arduino plugin or using the
fxdata-upload.py or uploader-gui.py (Use Upload Development data button).
Note fxdata.txt file maybe split up into multiple parts and can be included
using the include directive.
Data types:
int8_t, uint8_t values will be stored as 8-bit bytes (unsigned char)
int16_t, uint16_t values will be stored as 16-bit (half)words (int)
int24_t,uint24_t values will be stored as 24-bit address that points to
a FX data resource
int32_t,uint32_t values will be stored as 32-bit long words
image_t a filename with a relative path to a .bmp or .png image file
raw_t a filename with a relative path to a raw file
to create a constant to point to a FX resource, a similar format as in C(++):
is used.
image_t FXlogo = "fx-logo.png";
image_t arduboyLogo = "FXSprite.png";
when data of the same format is used the data type may be ommited. The semicolon
may also be ommited in all cases.
image_t FXlogo = "FX-logo.png"
FxSprite = "FXSprite.png"
or even:
image_t FXlogo = "FX-logo.png", FxSprite = "FXSprite.png"
When specifying multiple data make sure they are seperated by at least a space
(comma is optional). A data array can be simplified. For examle:
uint8_t tilemap[] = {
0, 1, 2, 3, 4, 5, 6
};
can also be written simply as:
uint8_t tilemap = 0 1 2 3 4 5 6
data can be commented out using // for a single line or
using /* */ for a block comment
Symbols
For the drawFrames functions there are some predefined bitmap mode symbols:
dbmNormal
dbmOverwrite
dbmWhite
dbmReverse
dbmBlack
dbmInvert
dbmMasked
to mark the end of a frame _end is appended to the above symbols like
dbmNormal_end
to mark the end of the last frame in a frames list append _last to the above
symbols like
dbmNormal_last
********************************************************************************
drawFrame example :
*******************************************************************************/
// Arduboy FX logo image:
image_t ArduboyLogo = "../assets/arduboy-logo.png"
image_t FXLogo = "../assets/fx-logo.png"
include "ArduboyLogo_Frame.txt"
ArduboyLogo_LastFrame[] = { // create a reference to last frame
int16_t 12, 24, int24_t ArduboyLogo, int8_t 0, dbmNormal
int16_t 100, 24, int24_t FXLogo, int8_t 0, dbmMasked_last
}

View File

@ -1,5 +1,5 @@
name=ArduboyFX
version=1.0.4
version=1.0.5
author=Mr.Blinky
maintainer=mstr.blinky@gmail.com
sentence=The Arduboy FX library.

View File

@ -6,6 +6,8 @@ uint16_t FX::programSavePage; // program read and write data location in flash m
Font FX::font;
Cursor FX::cursor = {0,0,0,WIDTH};
FrameControl FX::frameControl;
uint8_t FX::writeByte(uint8_t data)
{
@ -124,10 +126,27 @@ void FX::writeEnable()
void FX::seekCommand(uint8_t command, uint24_t address)
{
enable();
#ifdef ARDUINO_ARCH_AVR
register uint8_t cmd asm("r24") = command; //assembly optimizer for AVR platform ~saves 12 bytes
asm volatile(
"call %x2 \n"
"mov r24, %C[addr] \n"
"call %x2 \n"
"mov r24, %B[addr] \n"
"call %x2 \n"
"mov r24, %A[addr] \n"
"call %x2 \n"
: [cmd] "+&r" (cmd)
: [addr] "r" (address),
[write] "i" (writeByte)
:
);
#else
writeByte(command);
writeByte(address >> 16);
writeByte(address >> 8);
writeByte(address);
#endif
}
@ -158,22 +177,22 @@ void FX::seekDataArray(uint24_t address, uint8_t index, uint8_t offset, uint8_t
" mul %[index], %[size] \n"
" brne .+2 \n" //treat size 0 as size 256
" mov r1, %[index] \n"
" clr r24 \n" //use as alternative zero reg
" clr r21 \n" //use as alternative zero reg
" add r0, %[offset] \n"
" adc r1, r24 \n"
" adc r1, r21 \n"
" add %A[address], r0 \n"
" adc %B[address], r1 \n"
" adc %C[address], r24 \n"
" adc %C[address], r21 \n"
" clr r1 \n"
: [address] "+r" (address)
: [address] "+&r" (address)
: [index] "r" (index),
[offset] "r" (offset),
[size] "r" (elementSize)
: "r24"
: "r21"
);
#else
address += size ? index * size + offset : index * 256 + offset;
#endif
#else
address += size ? index * size + offset : index * 256 + offset;
#endif
seekData(address);
}
@ -212,9 +231,6 @@ uint8_t FX::readPendingUInt8()
uint8_t FX::readPendingLastUInt8()
{
#ifdef ARDUINO_ARCH_AVR
asm volatile("ArduboyFX_cpp_readPendingLastUInt8:\n"); // create label for calls in FX::readPendingUInt16
#endif
return readEnd();
}
@ -227,7 +243,7 @@ uint16_t FX::readPendingUInt16()
( "ArduboyFX_cpp_readPendingUInt16: \n"
"call ArduboyFX_cpp_readPendingUInt8 \n"
"mov %B[val], r24 \n"
"call ArduboyFX_cpp_readPendingUInt8 \n"
"jmp ArduboyFX_cpp_readPendingUInt8 \n"
: [val] "=&r" (result)
: "" (readPendingUInt8)
:
@ -245,17 +261,17 @@ uint16_t FX::readPendingLastUInt16()
uint16_t result asm("r24"); // we want result to be assigned to r24,r25
asm volatile
( "ArduboyFX_cpp_readPendingLastUInt16: \n"
"call ArduboyFX_cpp_readPendingUInt8 \n"
"mov %B[val], r24 \n"
"call ArduboyFX_cpp_readPendingLastUInt8 \n"
"call %x1 \n"
"mov %B[val], r24 \n"
"jmp %x2 \n"
: [val] "=&r" (result)
: "" (readPendingUInt8),
"" (readPendingLastUInt8)
"" (readEnd)
:
);
return result;
#else //C++ implementation for non AVR platforms
return ((uint16_t)readPendingUint8() << 8) | (uint16_t)readPendingLastUInt8();
return ((uint16_t)readPendingUint8() << 8) | (uint16_t)readEnd();
#endif
}
@ -289,19 +305,19 @@ uint24_t FX::readPendingLastUInt24()
uint24_t result asm("r24"); // we want result to be assigned to r24,r25,r26
asm volatile
(
"call ArduboyFX_cpp_readPendingUInt16 \n"
"mov %B[val], r24 \n"
"call ArduboyFX_cpp_readPendingLastUInt8 \n"
"mov %A[val], r24 \n"
"mov %C[val], r25 \n"
"call %x1 \n"
"mov %B[val], r24 \n"
"call %x2 \n"
"mov %A[val], r24 \n"
"mov %C[val], r25 \n"
: [val] "=&r" (result)
: "" (readPendingUInt16),
"" (readPendingLastUInt8)
"" (readEnd)
:
);
return result;
#else //C++ implementation for non AVR platforms
return ((uint24_t)readPendingUInt16() << 8) | readPendingLastUInt8();
return ((uint24_t)readPendingUInt16() << 8) | readEnd();
#endif
}
@ -678,6 +694,167 @@ void FX::drawBitmap(int16_t x, int16_t y, uint24_t address, uint8_t frame, uint8
#endif
}
void FX::setFrame(uint24_t frame, uint8_t repeat) //~22 bytes
{
#ifdef ARDUINO_ARCH_AVR
FrameControl* ctrl = &frameControl;
asm volatile(
"ldi r30, lo8(%[ctrl]) \n"
"ldi r31, hi8(%[ctrl]) \n"
"st z, %A[frame] \n" // start
"std z+1, %B[frame] \n"
"std z+2, %C[frame] \n"
"std z+3, %A[frame] \n" // current
"std z+4, %B[frame] \n"
"std z+5, %C[frame] \n"
"std z+6, %A[repeat] \n" // repeat
"std z+7, %A[repeat] \n" // count
:
: [ctrl] "" (ctrl),
[frame] "r" (frame),
[repeat] "r" (repeat)
: //"r30", "r31"
);
#else
frameControl.start = frame;
frameControl.current = frame;
frameControl.repeat = repeat;
frameControl.count = repeat;
#endif
}
uint8_t FX::drawFrame() // ~66 bytes
{
uint24_t frame = drawFrame(frameControl.current);
uint8_t moreFrames;
#ifdef ARDUINO_ARCH_AVR
FrameControl* ctrl = &frameControl;
asm volatile(
"ldi r30, lo8(%[ctrl]) \n"
"ldi r31, hi8(%[ctrl]) \n"
"ldd r0, z+7 \n" // frameControl.count
"mov %[more], r0 \n" // moreFrames = (frame != 0) | frameControl.count;
"or %[more], %A[frame] \n"
"or %[more], %B[frame] \n"
"or %[more], %C[frame] \n"
"tst r0 \n"
"breq 1f \n" // skip frameControl.count == 0
" \n"
"dec r0 \n"
"std z+7, r0 \n" // frameControl.count--
"rjmp 3f \n" // return
"1: \n"
"ldd r0, z+6 \n" // frameControl.count = frameControl.repeat
"std z+7, r0 \n"
"tst %[more] \n" //
"brne 2f \n" // if if moreFrames skip
" \n"
"ld %A[frame], z \n" // frame = frameControl.start
"ldd %B[frame], z+1 \n"
"ldd %C[frame], z+2 \n"
"2: \n"
"std z+3, %A[frame] \n" // frameControl.current = frame
"std z+4, %B[frame] \n"
"std z+5, %C[frame] \n"
"3: \n"
: [more] "=&r" (moreFrames)
: [ctrl] "" (ctrl),
[frame] "r" (frame)
: "r0", "r30", "r31"
);
#else
moreFrames = (frame != 0) | frameControl.count;
if (frameControl.count > 0)
{
frameControl.count--;
}
else
{
frameControl.count = frameControl.repeat;
if (!moreFrames) frame = frameControl.start;
frameControl.current = frame;
}
#endif
return moreFrames;
}
uint24_t FX::drawFrame(uint24_t address) //~94 bytes
{
FrameData f;
#ifdef ARDUINO_ARCH_AVR
asm volatile (
"push r6 \n"
"push r7 \n"
"push r8 \n"
"push r14 \n"
"push r16 \n"
"0: \n"
"movw r6, %A[addr] \n" //save address for calls
"mov r8, %C[addr] \n"
"call %x6 \n"
"call %x1 \n"
"movw r30, r24 \n" //temporary save x
"call %x1 \n"
"movw r26, r24 \n" //temporary save y
"call %x2 \n"
"mov r20, r24 \n" // bmp address
"movw r18, r22 \n"
"call %x3 \n"
"movw r16, r24 \n" // frame
"call %x4 \n"
"mov r14, r24 \n" // mode
"movw r24, r30 \n" // x
"movw r22, r26 \n" // y
"call %x5 \n" // drawbitmap
"movw %A[addr], r6 \n" // restore address
"mov %C[addr], r8 \n"
"subi %A[addr], -%[size] \n"
"sbci %B[addr], 0xFF \n"
"sbci %C[addr], 0xFF \n"
" \n"
"sbrc r14, 6 \n" // test next frame
"rjmp 1f \n" // skip end of this frame
" \n"
"sbrs r14, 7 \n" // test last frame
"rjmp 0b \n" // loop not last frame
" \n"
"clr %A[addr] \n"
"clr %B[addr] \n"
"clr %C[addr] \n"
"1: \n"
"pop r16 \n"
"pop r14 \n"
"pop r8 \n"
"pop r7 \n"
"pop r6 \n"
: [addr] "+&r" (address)
: "" (readPendingUInt16),
"" (readPendingUInt24),
"" (readPendingUInt8),
"" (readEnd),
"" (drawBitmap),
"" (seekData),
[size] "" (sizeof(f))
: "r18","r19", "r20", "r21", "r25", "r26", "r27", "r30", "r31"
);
return address;
#else
seekData(address);
address += sizeof(f);
for(;;)
{
f.x = readPendingUInt16();
f.y = readPendingUInt16();
f.bmp = readPendingUInt24();
f.frame = readPendingUInt8();
f.mode = readEnd();
drawBitmap(f.x, f.y, f.bmp, f.frame, f.mode);
if (f.mode & dbmEndFrame) return address;
if (f.mode & dbmLastFrame) return 0;
}
#endif
}
void FX::readDataArray(uint24_t address, uint8_t index, uint8_t offset, uint8_t elementSize, uint8_t* buffer, size_t length)
{

View File

@ -38,6 +38,8 @@ constexpr uint8_t dbfBlack = 2; // bitmap will be blackened
constexpr uint8_t dbfReverseBlack = 3; // reverses bitmap data
constexpr uint8_t dbfMasked = 4; // bitmap contains mask data
constexpr uint8_t dbfExtraRow = 7; // ignored (internal use)
constexpr uint8_t dbfEndFrame = 6; // last bitmap image of a frame
constexpr uint8_t dbfLastFrame = 7; // last bitmap image of the last frame
// drawBitmap modes with same behaviour as Arduboy library drawBitmap modes
constexpr uint8_t dbmBlack = _BV(dbfReverseBlack) | // white pixels in bitmap will be drawn as black pixels on display
@ -62,6 +64,8 @@ constexpr uint8_t dbmReverse = _BV(dbfReverseBlack); // White pixels in bitma
constexpr uint8_t dbmMasked = _BV(dbfMasked); // The bitmap contains a mask that will determine which pixels are
// drawn and which pixels remain unchanged on display
// (same as sprites drawPlusMask)
constexpr uint8_t dbmEndFrame = _BV(dbfEndFrame); // last bitmap of a frame but more frames
constexpr uint8_t dbmLastFrame = _BV(dbfLastFrame); // last bitmap of a frame and at end of frames
// Note above modes may be combined like (dbmMasked | dbmReverse)
@ -132,6 +136,24 @@ struct Cursor
int16_t wrap;
};
struct FrameControl
{
uint24_t start;
uint24_t current;
uint8_t repeat;
uint8_t count;
};
struct FrameData
{
int16_t x;
int16_t y;
uint24_t bmp;
uint8_t frame;
uint8_t mode;
};
class FX
{
public:
@ -227,11 +249,11 @@ class FX
static uint8_t readPendingUInt8() __attribute__ ((noinline)); //read a prefetched byte from the current flash location
static uint8_t readPendingLastUInt8() __attribute__ ((noinline)); //read a prefetched byte from the current flash location
static uint8_t readPendingLastUInt8() __attribute__ ((noinline)); //depreciated use readEnd() instead (see below)
static uint16_t readPendingUInt16() __attribute__ ((noinline)); //read a partly prefetched 16-bit word from the current flash location
static uint16_t readPendingUInt16() __attribute__ ((noinline)) __attribute__ ((naked)); //read a partly prefetched 16-bit word from the current flash location
static uint16_t readPendingLastUInt16() __attribute__ ((noinline)); //read a partly prefetched 16-bit word from the current flash location
static uint16_t readPendingLastUInt16() __attribute__ ((noinline)) __attribute__ ((naked)); //read a partly prefetched 16-bit word from the current flash location
static uint24_t readPendingUInt24() ; //read a partly prefetched 24-bit word from the current flash location
@ -243,9 +265,9 @@ class FX
static void readBytes(uint8_t* buffer, size_t length);// read a number of bytes from the current flash location
static void readBytesEnd(uint8_t* buffer, size_t length); // read a number of bytes from the current flash location and end the read command
static void readBytesEnd(uint8_t* buffer, size_t length); // read a number of bytes from the current flash location and ends the read command
static uint8_t readEnd(); //read last pending byte and end read command
static uint8_t readEnd() __attribute__ ((noinline)); //read the last prefetched byte from the current flash location and ends the read command
static void readDataBytes(uint24_t address, uint8_t* buffer, size_t length);
@ -259,6 +281,12 @@ class FX
static void drawBitmap(int16_t x, int16_t y, uint24_t address, uint8_t frame, uint8_t mode) __attribute__((noinline));
static void setFrame(uint24_t frame, uint8_t repeat)__attribute__ ((noinline));
static uint8_t drawFrame();
static uint24_t drawFrame(uint24_t address) __attribute__((noinline)); // draw a list of bitmap images located at address
static void readDataArray(uint24_t address, uint8_t index, uint8_t offset, uint8_t elementSize, uint8_t* buffer, size_t length);
static uint8_t readIndexedUInt8(uint24_t address, uint8_t index);
@ -431,5 +459,7 @@ class FX
static uint16_t programSavePage; // program read and write data area in flash memory
static Font font;
static Cursor cursor;
static FrameControl frameControl;
};
#endif