5
mirror of https://gitlab.com/zephray/glider.git synced 2025-12-30 12:47:27 +00:00
glider/fw/User/caster.c
2025-11-23 11:34:37 +08:00

130 lines
4.7 KiB
C

//
// Grimoire
// Copyright 2025 Wenting Zhang
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "platform.h"
#include "board.h"
#include "app.h"
static size_t last_update;
static size_t last_update_duration;
static uint8_t waveform_frames;
static uint8_t get_update_frames(void) {
// Should be worst case time to clear/ update a frame
//uint8_t min_time = 10; // Minimum time for non-LUT modes
// actually, just always return 0.5s
return 16;
}
static void wait(void) {
// Reading is not implemented in the simulator
}
void caster_init(void) {
waveform_frames = 38; // Need to sync with the RTL code
fpga_write_reg8(CSR_CFG_V_FP, config.tcon_vfp);
fpga_write_reg8(CSR_CFG_V_SYNC, config.tcon_vsync);
fpga_write_reg8(CSR_CFG_V_BP, config.tcon_vbp);
fpga_write_reg16(CSR_CFG_V_ACT, config.tcon_vact);
fpga_write_reg8(CSR_CFG_H_FP, config.tcon_hfp);
fpga_write_reg8(CSR_CFG_H_SYNC, config.tcon_hsync);
fpga_write_reg8(CSR_CFG_H_BP, config.tcon_hbp);
fpga_write_reg16(CSR_CFG_H_ACT, config.tcon_hact);
uint32_t frame_bytes = config.tcon_hact * 4 * config.tcon_vact * 2;
fpga_write_reg8(CSR_CFG_FBYTES_B0, frame_bytes & 0xff);
fpga_write_reg8(CSR_CFG_FBYTES_B1, (frame_bytes >> 8) & 0xff);
fpga_write_reg8(CSR_CFG_FBYTES_B2, (frame_bytes >> 16) & 0xff);
fpga_write_reg8(CSR_CFG_MINDRV, 2);
fpga_write_reg8(CSR_LUT_FRAME, 38);
fpga_write_reg16(CSR_OSD_LEFT, 0);
fpga_write_reg16(CSR_OSD_RIGHT, 256/4);
fpga_write_reg16(CSR_OSD_TOP, 0);
fpga_write_reg16(CSR_OSD_BOTTOM, 128);
fpga_write_reg8(CSR_OSD_EN, 0);
fpga_write_reg8(CSR_CFG_MIRROR, config.mirror);
fpga_write_reg8(CSR_ENABLE, 1); // Enable refresh
}
static uint8_t is_busy() {
uint8_t status = fpga_write_reg8(CSR_STATUS, 0x00);
return !!(status & STATUS_OP_QUEUE);
}
uint8_t caster_load_waveform(uint8_t *waveform, uint8_t frames) {
fpga_write_reg8(CSR_LUT_FRAME, 0); // Reset value before loading
fpga_write_reg16(CSR_LUT_ADDR, 0);
fpga_write_bulk(CSR_LUT_WR, waveform, WAVEFORM_SIZE);
waveform_frames = frames;
return 0;
}
uint8_t caster_redraw(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
//if (is_busy()) return 1;
fpga_write_reg16(CSR_OP_LEFT, x0);
fpga_write_reg16(CSR_OP_TOP, y0);
fpga_write_reg16(CSR_OP_RIGHT, x1);
fpga_write_reg16(CSR_OP_BOTTOM, y1);
fpga_write_reg8(CSR_OP_LENGTH, get_update_frames());
fpga_write_reg8(CSR_OP_CMD, OP_EXT_REDRAW);
return 0;
}
uint8_t caster_setmode(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
update_mode_t mode) {
//if (is_busy()) return 1;
fpga_write_reg16(CSR_OP_LEFT, x0);
fpga_write_reg16(CSR_OP_TOP, y0);
fpga_write_reg16(CSR_OP_RIGHT, x1);
fpga_write_reg16(CSR_OP_BOTTOM, y1);
fpga_write_reg8(CSR_OP_LENGTH, get_update_frames());
fpga_write_reg8(CSR_OP_PARAM, (uint8_t)mode);
fpga_write_reg8(CSR_OP_CMD, OP_EXT_SETMODE);
return 0;
}
uint8_t caster_setinput(uint8_t input_src) {
// if (is_busy()) return 1;
// fpga_write_reg8(CSR_CFG_IN_SRC, input_src);
return 0;
}
void caster_redraw_blank(void) {
fpga_write_reg16(CSR_OP_LEFT, 0);
fpga_write_reg16(CSR_OP_TOP, 0);
fpga_write_reg16(CSR_OP_RIGHT, config.hact);
fpga_write_reg16(CSR_OP_BOTTOM, config.vact);
fpga_write_reg8(CSR_OP_LENGTH, get_update_frames());
fpga_write_reg8(CSR_ENABLE, 0x3); // Enable blanking
fpga_write_reg8(CSR_OP_CMD, OP_EXT_REDRAW);
}
uint8_t caster_osd_send_buf(uint8_t *buf) {
fpga_write_reg16(CSR_OSD_ADDR, 0);
fpga_write_bulk(CSR_OSD_WR, buf, 4096);
return 0;
}
uint8_t caster_osd_set_enable(bool en) {
fpga_write_reg8(CSR_OSD_EN, en);
return 0;
}