mirror of
https://gitlab.com/zephray/glider.git
synced 2024-12-22 13:43:16 +00:00
Update firmware for lite version
This commit is contained in:
parent
b15cee3316
commit
f50bc6edc6
9 changed files with 30331 additions and 30056 deletions
|
@ -25,6 +25,7 @@ pico_sdk_init()
|
|||
|
||||
add_executable(fw
|
||||
bitstream.c
|
||||
caster.c
|
||||
edid.c
|
||||
fpga.c
|
||||
fusb302.c
|
||||
|
|
60042
fw/bitstream.c
60042
fw/bitstream.c
File diff suppressed because it is too large
Load diff
87
fw/caster.c
Normal file
87
fw/caster.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// Glider
|
||||
// Copyright 2024 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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "config.h"
|
||||
#include "caster.h"
|
||||
#include "fpga.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 1s
|
||||
return 60;
|
||||
}
|
||||
|
||||
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, TCON_VFP);
|
||||
// fpga_write_reg8(CSR_CFG_V_SYNC, TCON_VSYNC);
|
||||
// fpga_write_reg8(CSR_CFG_V_BP, TCON_VBP);
|
||||
// fpga_write_reg16(CSR_CFG_V_ACT, TCON_VACT);
|
||||
// fpga_write_reg8(CSR_CFG_H_FP, TCON_HFP);
|
||||
// fpga_write_reg8(CSR_CFG_H_SYNC, TCON_HSYNC);
|
||||
// fpga_write_reg8(CSR_CFG_H_BP, TCON_HBP);
|
||||
// fpga_write_reg16(CSR_CFG_H_ACT, TCON_HACT);
|
||||
// fpga_write_reg8(CSR_CONTROL, 1); // Enable refresh
|
||||
}
|
||||
|
||||
void caster_load_waveform(uint8_t *waveform, uint8_t frames) {
|
||||
wait();
|
||||
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;
|
||||
}
|
||||
|
||||
void caster_redraw(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
wait();
|
||||
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);
|
||||
}
|
||||
|
||||
void caster_setmode(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
||||
UPDATE_MODE mode) {
|
||||
wait();
|
||||
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);
|
||||
}
|
95
fw/caster.h
Normal file
95
fw/caster.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// Caster simulator
|
||||
// Copyright 2023 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.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
// Register map
|
||||
#define CSR_LUT_FRAME 0
|
||||
#define CSR_LUT_ADDR_HI 1
|
||||
#define CSR_LUT_ADDR_LO 2
|
||||
#define CSR_LUT_WR 3
|
||||
#define CSR_OP_LEFT_HI 4
|
||||
#define CSR_OP_LEFT_LO 5
|
||||
#define CSR_OP_RIGHT_HI 6
|
||||
#define CSR_OP_RIGHT_LO 7
|
||||
#define CSR_OP_TOP_HI 8
|
||||
#define CSR_OP_TOP_LO 9
|
||||
#define CSR_OP_BOTTOM_HI 10
|
||||
#define CSR_OP_BOTTOM_LO 11
|
||||
#define CSR_OP_PARAM 12
|
||||
#define CSR_OP_LENGTH 13
|
||||
#define CSR_OP_CMD 14
|
||||
#define CSR_CONTROL 15
|
||||
#define CSR_CFG_V_FP 16
|
||||
#define CSR_CFG_V_SYNC 17
|
||||
#define CSR_CFG_V_BP 18
|
||||
#define CSR_CFG_V_ACT_HI 19
|
||||
#define CSR_CFG_V_ACT_LO 20
|
||||
#define CSR_CFG_H_FP 21
|
||||
#define CSR_CFG_H_SYNC 22
|
||||
#define CSR_CFG_H_BP 23
|
||||
#define CSR_CFG_H_ACT_HI 24
|
||||
#define CSR_CFG_H_ACT_LO 25
|
||||
#define CSR_CFG_FBYTES_B2 27
|
||||
#define CSR_CFG_FBYTES_B1 28
|
||||
#define CSR_CFG_FBYTES_B0 29
|
||||
// Alias for 16bit registers
|
||||
#define CSR_LUT_ADDR CSR_LUT_ADDR_HI
|
||||
#define CSR_OP_LEFT CSR_OP_LEFT_HI
|
||||
#define CSR_OP_RIGHT CSR_OP_RIGHT_HI
|
||||
#define CSR_OP_TOP CSR_OP_TOP_HI
|
||||
#define CSR_OP_BOTTOM CSR_OP_BOTTOM_HI
|
||||
#define CSR_CFG_V_ACT CSR_CFG_V_ACT_HI
|
||||
#define CSR_CFG_H_ACT CSR_CFG_H_ACT_HI
|
||||
|
||||
// Commands
|
||||
#define OP_EXT_REDRAW 0
|
||||
#define OP_EXT_SETMODE 1
|
||||
|
||||
// Status bits
|
||||
#define STATUS_MIG_ERROR 7
|
||||
#define STATUS_MIF_ERROR 6
|
||||
#define STATUS_SYS_READY 5
|
||||
#define STATUS_OP_BUSY 4
|
||||
#define STATUS_OP_QUEUE 3
|
||||
#define CTRL_ENABLE 0
|
||||
|
||||
#define WAVEFORM_SIZE (4*1024)
|
||||
|
||||
#define FRAME_RATE_HZ (60)
|
||||
|
||||
typedef enum {
|
||||
UM_MANUAL_LUT_NO_DITHER = 0,
|
||||
UM_MANUAL_LUT_ERROR_DIFFUSION = 1,
|
||||
UM_FAST_MONO_NO_DITHER = 2,
|
||||
UM_FAST_MONO_BAYER = 3,
|
||||
UM_FAST_MONO_BLUE_NOISE = 4,
|
||||
UM_FAST_GREY = 5,
|
||||
UM_AUTO_LUT_NO_DITHER = 6,
|
||||
UM_AUTO_LUT_ERROR_DIFFUSION = 7
|
||||
} UPDATE_MODE;
|
||||
|
||||
void caster_init(void);
|
||||
void caster_load_waveform(uint8_t *waveform, uint8_t frames);
|
||||
void caster_redraw(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||
void caster_setmode(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
||||
UPDATE_MODE mode);
|
18
fw/config.h
18
fw/config.h
|
@ -118,6 +118,15 @@
|
|||
#define SCREEN_VBLK 29
|
||||
#define SCREEN_VFP 3
|
||||
#define SCREEN_VSYNC 10
|
||||
|
||||
#define TCON_HACT 256
|
||||
#define TCON_HBP 2
|
||||
#define TCON_HSYNC 2
|
||||
#define TCON_HFP 72
|
||||
#define TCON_VACT 758
|
||||
#define TCON_VBP 3
|
||||
#define TCON_VSYNC 1
|
||||
#define TCON_VFP 12
|
||||
#elif defined(SCREEN_1448_1072)
|
||||
// 1448x1072 @ 60, 128.5MHz CVT
|
||||
#define SCREEN_CLK 128500
|
||||
|
@ -150,6 +159,15 @@
|
|||
#define SCREEN_VBLK 35
|
||||
#define SCREEN_VFP 21
|
||||
#define SCREEN_VSYNC 8
|
||||
|
||||
#define TCON_HACT 400
|
||||
#define TCON_HBP 2
|
||||
#define TCON_HSYNC 2
|
||||
#define TCON_HFP 16
|
||||
#define TCON_VACT 1200
|
||||
#define TCON_VBP 2
|
||||
#define TCON_VSYNC 1
|
||||
#define TCON_VFP 12
|
||||
#elif defined(SCREEN_1872_1404)
|
||||
// 1872x1404 @ 60, 162MHz Custom
|
||||
#define SCREEN_CLK 162000
|
||||
|
|
71
fw/fpga.c
71
fw/fpga.c
|
@ -20,6 +20,8 @@
|
|||
// SOFTWARE.
|
||||
//
|
||||
#include "pico/stdlib.h"
|
||||
#include <stdio.h>
|
||||
#include "utils.h"
|
||||
#include "fpga.h"
|
||||
#include "bitstream.h"
|
||||
|
||||
|
@ -58,22 +60,66 @@ static void fpga_send_byte(uint8_t byte) {
|
|||
}
|
||||
}
|
||||
|
||||
static void fpga_send_byte_slow(uint8_t byte) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
gpio_put(FPGA_MOSI, byte & 0x80);
|
||||
delay_loop(20);
|
||||
gpio_put(FPGA_SCLK, 1);
|
||||
delay_loop(20);
|
||||
byte <<= 1;
|
||||
gpio_put(FPGA_SCLK, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void fpga_write_reg8(uint8_t addr, uint8_t val) {
|
||||
gpio_put(FPGA_CS, 0);
|
||||
fpga_send_byte_slow(addr);
|
||||
fpga_send_byte_slow(val);
|
||||
gpio_put(FPGA_CS, 1);
|
||||
}
|
||||
|
||||
void fpga_write_reg16(uint8_t addr, uint16_t val) {
|
||||
gpio_put(FPGA_CS, 0);
|
||||
fpga_send_byte_slow(addr);
|
||||
fpga_send_byte_slow(val >> 8);
|
||||
fpga_send_byte_slow(val & 0xff);
|
||||
gpio_put(FPGA_CS, 1);
|
||||
}
|
||||
|
||||
void fpga_write_bulk(uint8_t addr, uint8_t *buf, int length) {
|
||||
gpio_put(FPGA_CS, 0);
|
||||
fpga_send_byte_slow(addr);
|
||||
for (int i = 0; i < length; i++) {
|
||||
fpga_send_byte_slow(buf[i]);
|
||||
}
|
||||
gpio_put(FPGA_CS, 1);
|
||||
}
|
||||
|
||||
static void fpga_load_bitstream(uint8_t *stream, int size) {
|
||||
gpio_put(FPGA_CS, 0);
|
||||
for (int i = 0; i < size; i++) {
|
||||
fpga_send_byte(stream[i]);
|
||||
}
|
||||
gpio_put(FPGA_CS, 1);
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (gpio_get(FPGA_DONE) == 1)
|
||||
break;
|
||||
sleep_ms(1);
|
||||
}
|
||||
if (gpio_get(FPGA_DONE) == 0) {
|
||||
fatal("FPGA done does not go high after 1s");
|
||||
printf("FPGA bitstream load done.\n");
|
||||
}
|
||||
|
||||
static void fpga_wait_done(bool timeout) {
|
||||
if (timeout) {
|
||||
int i;
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (gpio_get(FPGA_DONE) == 1)
|
||||
break;
|
||||
sleep_ms(1);
|
||||
}
|
||||
if (gpio_get(FPGA_DONE) == 0) {
|
||||
fatal("FPGA done does not go high after 1s");
|
||||
}
|
||||
printf("FPGA is up after %d ms.\n", i);
|
||||
}
|
||||
else {
|
||||
printf("FPGA bitstream load done.");
|
||||
while (gpio_get(FPGA_DONE) != 1);
|
||||
printf("FPGA is up.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +133,8 @@ void fpga_init(void) {
|
|||
gpio_init_ipu(FPGA_DONE);
|
||||
gpio_init_out(FPGA_SUSP, 0);
|
||||
|
||||
gpio_put(FPGA_CS, 1);
|
||||
|
||||
// FPGA Reset
|
||||
gpio_put(FPGA_PROG, 0);
|
||||
sleep_ms(100);
|
||||
|
@ -94,7 +142,14 @@ void fpga_init(void) {
|
|||
sleep_ms(100);
|
||||
|
||||
// Load bitstream
|
||||
#if 1
|
||||
fpga_load_bitstream(fpga_bitstream, fpga_bitstream_length);
|
||||
fpga_wait_done(true);
|
||||
#else
|
||||
fpga_wait_done(false);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
void fpga_suspend(void) {
|
||||
|
|
|
@ -24,3 +24,6 @@
|
|||
void fpga_init(void);
|
||||
void fpga_suspend(void);
|
||||
void fpga_resume(void);
|
||||
void fpga_write_reg8(uint8_t addr, uint8_t val);
|
||||
void fpga_write_reg16(uint8_t addr, uint16_t val);
|
||||
void fpga_write_bulk(uint8_t addr, uint8_t *buf, int length);
|
45
fw/fw.c
45
fw/fw.c
|
@ -32,6 +32,7 @@
|
|||
#include "power.h"
|
||||
#include "fpga.h"
|
||||
#include "edid.h"
|
||||
#include "caster.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -52,8 +53,52 @@ int main()
|
|||
//sleep_goto_dormant_until_edge_high(8);
|
||||
// https://ghubcoder.github.io/posts/awaking-the-pico/
|
||||
|
||||
fpga_init();
|
||||
|
||||
//sleep_ms(5000);
|
||||
//caster_init();
|
||||
|
||||
gpio_init(2);
|
||||
gpio_set_dir(2, GPIO_IN);
|
||||
gpio_pull_up(2);
|
||||
|
||||
int mode_max = 6;
|
||||
int mode = 1;
|
||||
UPDATE_MODE modes[6] = {
|
||||
UM_FAST_MONO_NO_DITHER,
|
||||
UM_FAST_MONO_BAYER,
|
||||
UM_FAST_MONO_BLUE_NOISE,
|
||||
UM_FAST_GREY,
|
||||
UM_AUTO_LUT_NO_DITHER,
|
||||
UM_AUTO_LUT_ERROR_DIFFUSION
|
||||
};
|
||||
|
||||
while (1) {
|
||||
//
|
||||
if (gpio_get(2) == 0) {
|
||||
sleep_ms(20);
|
||||
if (gpio_get(2) == 0) {
|
||||
int i = 0;
|
||||
while (gpio_get(2) == 0) {
|
||||
i++;
|
||||
sleep_ms(1);
|
||||
if (i > 500)
|
||||
break;
|
||||
}
|
||||
if (i > 500) {
|
||||
// Long press, clear screen
|
||||
caster_redraw(0,0,1600,1200);
|
||||
}
|
||||
else {
|
||||
// Short press, switch mode
|
||||
mode++;
|
||||
if (mode >= mode_max) mode = 0;
|
||||
caster_setmode(0,0,1600,1200,modes[mode]);
|
||||
}
|
||||
while (gpio_get(2) == 0);
|
||||
}
|
||||
while (gpio_get(2) == 0);
|
||||
}
|
||||
}
|
||||
#elif defined(INPUT_TYPEC)
|
||||
int result = tcpm_init(0);
|
||||
|
|
25
fw/power.c
25
fw/power.c
|
@ -25,8 +25,14 @@
|
|||
#include "config.h"
|
||||
|
||||
#if defined(POWER_GPIO)
|
||||
#define PWR_EN_GPIO 21
|
||||
#define PWR_VCOM_GPIO 22
|
||||
#define PWR_EN_GPIO 21
|
||||
#define PWR_VCOM_GPIO 22
|
||||
|
||||
#if defined(POWER_GPIO_VCOM_MEASURE)
|
||||
#define PWR_VCOM_EN_GPIO 28
|
||||
#define PWR_VCOM_MEN_GPIO 26
|
||||
#define PWR_VCOM_MEA_GPIO 27
|
||||
#endif
|
||||
|
||||
void power_init(void) {
|
||||
gpio_put(PWR_EN_GPIO, 0);
|
||||
|
@ -37,6 +43,21 @@ void power_init(void) {
|
|||
// Set period to 256 cycles
|
||||
pwm_set_wrap(slice_num, 255);
|
||||
pwm_set_gpio_level(PWR_VCOM_GPIO, 127);
|
||||
|
||||
// 0 -3.421V
|
||||
// 127 -2.145V
|
||||
// 255 -0.987V
|
||||
|
||||
#if defined(POWER_GPIO_VCOM_MEASURE)
|
||||
gpio_init(PWR_VCOM_EN_GPIO);
|
||||
gpio_put(PWR_VCOM_EN_GPIO, 0);
|
||||
gpio_set_dir(PWR_VCOM_EN_GPIO, GPIO_OUT);
|
||||
|
||||
gpio_init(PWR_VCOM_MEN_GPIO);
|
||||
gpio_put(PWR_VCOM_MEN_GPIO, 1);
|
||||
gpio_set_dir(PWR_VCOM_MEN_GPIO, GPIO_OUT);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void power_enable(bool en) {
|
||||
|
|
Loading…
Reference in a new issue