blob: f4f12c5b4a8551ce006a20fa40b6e432f65f4134 [file] [log] [blame]
// Copyright 2023 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "pw_mipi_dsi_mcuxpresso/framebuffer_device.h"
#include "common.h"
#include "pw_assert/assert.h"
#include "pw_status/try.h"
namespace pw::mipi::dsi {
FramebufferDevice::FramebufferDevice(uint8_t layer)
: dc_(nullptr), layer_(layer), enabled_(false) {
VIDEO_MEMPOOL_InitEmpty(&video_mempool_);
}
Status FramebufferDevice::Init(
const dc_fb_t* dc, const pw::framebuffer::pool::PoolData& pool_data) {
PW_TRY(InitDisplayController(dc));
return InitVideoMemPool(pool_data);
}
Status FramebufferDevice::InitDisplayController(const dc_fb_t* dc) {
PW_ASSERT(!dc_);
dc_ = dc;
status_t status = dc_->ops->init(dc);
if (status != kStatus_Success) {
return MCUXpressoToPigweedStatus(status);
}
dc_fb_info_t buff_info;
status = dc_->ops->getLayerDefaultConfig(dc_, layer_, &buff_info);
if (status != kStatus_Success) {
return MCUXpressoToPigweedStatus(status);
}
dc_->ops->setCallback(dc_, layer_, BufferSwitchOffCallback, this);
status = dc_->ops->setLayerConfig(dc_, layer_, &buff_info);
if (status != kStatus_Success) {
return MCUXpressoToPigweedStatus(status);
}
return OkStatus();
}
Status FramebufferDevice::InitVideoMemPool(
const pw::framebuffer::pool::PoolData& pool_data) {
if (enabled_) {
return Status::FailedPrecondition();
}
for (uint8_t i = 0; i < pool_data.num_fb; i++) {
VIDEO_MEMPOOL_Put(&video_mempool_, pool_data.fb_addr[i]);
}
return OkStatus();
}
Status FramebufferDevice::Close() {
if (!dc_)
return Status::FailedPrecondition();
status_t status = dc_->ops->deinit(dc_);
dc_ = nullptr;
return MCUXpressoToPigweedStatus(status);
}
Status FramebufferDevice::Enable() {
if (enabled_)
return OkStatus();
status_t status = kStatus_Success;
if ((dc_->ops->getProperty(dc_) & (uint32_t)kDC_FB_ReserveFrameBuffer) ==
0U) {
status = dc_->ops->enableLayer(dc_, layer_);
if (status != kStatus_Success) {
enabled_ = true;
}
}
return MCUXpressoToPigweedStatus(status);
}
Status FramebufferDevice::Disable() {
if (!enabled_)
return OkStatus();
status_t status = dc_->ops->disableLayer(dc_, layer_);
enabled_ = false;
return MCUXpressoToPigweedStatus(status);
}
Status FramebufferDevice::WriteFramebuffer(void* frameBuffer) {
return MCUXpressoToPigweedStatus(
dc_->ops->setFrameBuffer(dc_, layer_, frameBuffer));
}
void* FramebufferDevice::GetFramebuffer() {
return VIDEO_MEMPOOL_Get(&video_mempool_);
}
void FramebufferDevice::BufferSwitchOff(void* buffer) {
VIDEO_MEMPOOL_Put(&video_mempool_, buffer);
}
// static
void FramebufferDevice::BufferSwitchOffCallback(void* param, void* buffer) {
PW_ASSERT(param != nullptr);
static_cast<FramebufferDevice*>(param)->BufferSwitchOff(buffer);
}
} // namespace pw::mipi::dsi