from HAL.hpp:41
class HAL
{
public:
HAL(DMA_Interface& dmaInterface, LCD& display, TouchController& touchCtrl, uint16_t width, uint16_t height) :
dma(dmaInterface),
lcdRef(display),
touchController(touchCtrl),
mcuInstrumentation(0),
buttonController(0),
taskDelayFunc(0),
frameBuffer0(0),
frameBuffer1(0),
frameBuffer2(0),
refreshStrategy(REFRESH_STRATEGY_DEFAULT),
fingerSize(1),
lockDMAToPorch(true),
touchSampleRate(1),
mcuLoadPct(0),
vSyncCnt(0),
vSyncForFrame(1),
vSyncCompensationEnabled(false),
clientDirty(false),
swapRequested(false),
lastTouched(false),
updateMCULoad(0),
cc_begin(0),
displayOrientationChangeRequested(false)
{
instance = this;
DISPLAY_WIDTH = width;
DISPLAY_HEIGHT = height;
DISPLAY_ROTATION = rotate0;
FRAME_BUFFER_WIDTH = DISPLAY_WIDTH;
FRAME_BUFFER_HEIGHT = DISPLAY_HEIGHT;
nativeDisplayOrientation = ((width >= height) ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT);
}
virtual ~HAL() { }
static HAL* getInstance()
{
return instance;
}
virtual void setDisplayOrientation(DisplayOrientation orientation)
{
requestedOrientation = orientation;
displayOrientationChangeRequested = true;
}
DisplayOrientation getDisplayOrientation() const
{
if (DISPLAY_ROTATION == rotate0)
{
return nativeDisplayOrientation;
}
else
{
return (nativeDisplayOrientation == ORIENTATION_LANDSCAPE ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE);
}
}
void signalDMAInterrupt()
{
dma.signalDMAInterrupt();
}
void initialize();
virtual void taskEntry();
virtual void flushFrameBuffer();
virtual void flushFrameBuffer(const Rect& rect);
virtual void allowDMATransfers();
void frontPorchEntered()
{
allowDMATransfers();
}
virtual void flushDMA();
virtual uint16_t* lockFrameBuffer();
virtual void unlockFrameBuffer();
virtual uint16_t* getTFTFrameBuffer() const = 0;
static LCD& lcd()
{
return instance->lcdRef;
}
void lockDMAToFrontPorch(bool enableLock)
{
lockDMAToPorch = enableLock;
}
virtual void registerTextCache(Unicode::UnicodeChar* str, uint16_t length);
virtual const Unicode::UnicodeChar* cacheTextString(const Unicode::UnicodeChar* str);
virtual bool blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes);
virtual BlitOperations getBlitCaps()
{
return dma.getBlitCaps();
};
virtual void blitSetTransparencyKey(uint16_t key);
virtual void blitCopy(const uint16_t* pSrc, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t srcWidth, uint8_t alpha, bool hasTransparentPixels);
virtual void blitCopyARGB8888(const uint16_t* pSrc, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t srcWidth, uint8_t alpha);
virtual void blitCopyGlyph(const uint8_t* pSrc, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t srcWidth, colortype color, uint8_t alpha, BlitOperations operation);
virtual void blitFill(colortype color, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t alpha);
virtual void registerEventListener(UIEventListener& listener);
virtual uint16_t* copyFBRegionToMemory(Rect meAbs);
virtual uint16_t* copyFBRegionToMemory(Rect meAbs, uint16_t* dst, uint32_t stride);
uint16_t getDisplayWidth() const
{
return DISPLAY_WIDTH;
}
uint16_t getDisplayHeight() const
{
return DISPLAY_HEIGHT;
}
void swapFrameBuffers();
uint32_t getLCDRefreshCount()
{
return vSyncForFrame;
};
void setFrameRateCompensation(bool enabled)
{
vSyncCompensationEnabled = enabled;
};
void vSync()
{
vSyncCnt++;
};
virtual void backPorchExited()
{
swapFrameBuffers();
tick();
}
virtual void configureInterrupts() = 0;
virtual void enableInterrupts() = 0;
virtual void disableInterrupts() = 0;
virtual void enableLCDControllerInterrupt() = 0;
virtual bool sampleKey(uint8_t& key)
{
return false;
}
void setDragThreshold(uint8_t value)
{
gestures.setDragThreshold(value);
}
static uint16_t DISPLAY_WIDTH;
static uint16_t DISPLAY_HEIGHT;
static DisplayRotation DISPLAY_ROTATION;
static uint16_t FRAME_BUFFER_WIDTH;
static uint16_t FRAME_BUFFER_HEIGHT;
static bool USE_DOUBLE_BUFFERING;
static bool USE_ANIMATION_STORAGE;
virtual void setFrameBufferStartAddress(void* adr, uint16_t depth = 16, bool useDoubleBuffering = true, bool useAnimationStorage = true)
{
uint32_t bufferSizeInBytes = 0;
switch (depth)
{
case 32:
case 24:
case 16:
case 8:
bufferSizeInBytes = (DISPLAY_WIDTH * DISPLAY_HEIGHT) * (depth / 8);
break;
case 4:
case 2:
case 1:
bufferSizeInBytes = ((DISPLAY_WIDTH * depth + 7) / 8) * DISPLAY_HEIGHT;
break;
default:
assert(0 && "Unsupported bit depth");
break;
}
uint8_t* buffer = static_cast<uint8_t*>(adr);
frameBuffer0 = reinterpret_cast<uint16_t*>(buffer);
if (useDoubleBuffering)
{
buffer += bufferSizeInBytes;
frameBuffer1 = reinterpret_cast<uint16_t*>(buffer);
}
else
{
frameBuffer1 = 0;
}
if (useAnimationStorage)
{
buffer += bufferSizeInBytes;
frameBuffer2 = reinterpret_cast<uint16_t*>(buffer);
}
else
{
frameBuffer2 = 0;
}
USE_DOUBLE_BUFFERING = useDoubleBuffering;
USE_ANIMATION_STORAGE = useAnimationStorage;
}
virtual void setFrameBufferStartAddresses(void* frameBuffer, void* doubleBuffer, void* animationStorage)
{
assert(frameBuffer != 0 && "A framebuffer address must be set");
frameBuffer0 = reinterpret_cast<uint16_t*>(frameBuffer);
frameBuffer1 = reinterpret_cast<uint16_t*>(doubleBuffer);
frameBuffer2 = reinterpret_cast<uint16_t*>(animationStorage);
USE_DOUBLE_BUFFERING = doubleBuffer != 0;
USE_ANIMATION_STORAGE = animationStorage != 0;
}
void setTouchSampleRate(int8_t sampleRateInTicks)
{
if (sampleRateInTicks > 0)
{
touchSampleRate = sampleRateInTicks;
}
}
int8_t getTouchSampleRate() const
{
return touchSampleRate;
}
void setMCUActive(bool active);
uint32_t getCPUCycles();
void setMCUInstrumentation(MCUInstrumentation* mcuInstr)
{
mcuInstrumentation = mcuInstr;
}
void enableMCULoadCalculation(bool enabled)
{
updateMCULoad = enabled;
}
uint8_t getMCULoadPct() const
{
return mcuLoadPct;
}
void setButtonController(ButtonController* btnCtrl)
{
buttonController = btnCtrl;
}
ButtonController* getButtonController() const
{
return buttonController;
}
void setFingerSize(uint8_t size)
{
fingerSize = size;
}
uint8_t getFingerSize() const
{
return fingerSize;
}
uint16_t* getAnimationStorage() const
{
return frameBuffer2;
}
typedef enum
{
REFRESH_STRATEGY_DEFAULT,
REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL
} FrameRefreshStrategy;
bool setFrameRefreshStrategy(FrameRefreshStrategy s)
{
if (s == REFRESH_STRATEGY_DEFAULT)
{
refreshStrategy = s;
return true;
}
else if (s == REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL)
{
if (taskDelayFunc != 0 && getTFTCurrentLine() != 0xFFFF && !HAL::USE_DOUBLE_BUFFERING)
{
refreshStrategy = s;
return true;
}
return false;
}
return false;
}
FrameRefreshStrategy getFrameRefreshStrategy() const
{
return refreshStrategy;
}
void registerTaskDelayFunction(void(*delayF)(uint16_t))
{
taskDelayFunc = delayF;
}
virtual void taskDelay(uint16_t ms)
{
if (taskDelayFunc)
{
taskDelayFunc(ms);
}
}
virtual uint16_t getTFTCurrentLine()
{
return 0xFFFFu;
}
protected:
virtual void tick();
virtual bool beginFrame();
virtual void endFrame();
virtual void setTFTFrameBuffer(uint16_t* address) = 0;
uint16_t* getClientFrameBuffer()
{
if (USE_DOUBLE_BUFFERING && getTFTFrameBuffer() == frameBuffer0)
{
return frameBuffer1;
}
return frameBuffer0;
}
virtual void touch(int32_t x, int32_t y);
virtual void noTouch();
virtual void performDisplayOrientationChange()
{
if (requestedOrientation != nativeDisplayOrientation)
{
if (DISPLAY_ROTATION == rotate0)
{
FRAME_BUFFER_WIDTH = DISPLAY_WIDTH;
FRAME_BUFFER_HEIGHT = DISPLAY_HEIGHT;
DISPLAY_HEIGHT = FRAME_BUFFER_WIDTH;
DISPLAY_WIDTH = FRAME_BUFFER_HEIGHT;
DISPLAY_ROTATION = rotate90;
}
}
else if (DISPLAY_ROTATION != rotate0)
{
FRAME_BUFFER_WIDTH = DISPLAY_HEIGHT;
FRAME_BUFFER_HEIGHT = DISPLAY_WIDTH;
DISPLAY_HEIGHT = FRAME_BUFFER_HEIGHT;
DISPLAY_WIDTH = FRAME_BUFFER_WIDTH;
DISPLAY_ROTATION = rotate0;
}
}
DMA_Interface& dma;
LCD& lcdRef;
TouchController& touchController;
MCUInstrumentation* mcuInstrumentation;
ButtonController* buttonController;
static bool isDrawing;
Gestures gestures;
DisplayOrientation nativeDisplayOrientation;
void(*taskDelayFunc)(uint16_t);
uint16_t* frameBuffer0;
uint16_t* frameBuffer1;
uint16_t* frameBuffer2;
FrameRefreshStrategy refreshStrategy;
uint8_t fingerSize;
bool lockDMAToPorch;
bool frameBufferUpdatedThisFrame;
private:
UIEventListener* listener;
static HAL* instance;
int32_t lastX;
int32_t lastY;
int8_t touchSampleRate;
uint8_t mcuLoadPct;
uint8_t vSyncCnt;
uint8_t vSyncForFrame;
bool vSyncCompensationEnabled;
bool clientDirty;
bool swapRequested;
bool lastTouched;
bool updateMCULoad;
uint32_t cc_begin;
DisplayOrientation requestedOrientation;
bool displayOrientationChangeRequested;
friend class LCD1bpp;
friend class LCD2bpp;
friend class LCD4bpp;
friend class LCD16bpp;
friend class LCD24bpp;
uint16_t* getDstAddress(uint16_t x, uint16_t y, uint16_t* startAddress) const;
};