180 lines
3.9 KiB
C
180 lines
3.9 KiB
C
/*
|
|
* Copyright (c) 2020 Hubert Miś
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <drivers/misc/ft8xx/ft8xx_copro.h>
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <drivers/misc/ft8xx/ft8xx_common.h>
|
|
#include <drivers/misc/ft8xx/ft8xx_memory.h>
|
|
#include "ft8xx_drv.h"
|
|
|
|
#define FT800_RAM_CMD_SIZE 4096UL
|
|
|
|
enum {
|
|
CMD_DLSTART = 0xffffff00,
|
|
CMD_SWAP = 0xffffff01,
|
|
CMD_TEXT = 0xffffff0c,
|
|
CMD_NUMBER = 0xffffff2e,
|
|
CMD_CALIBRATE = 0xffffff15,
|
|
} ft8xx_cmd;
|
|
|
|
static uint16_t reg_cmd_read;
|
|
static uint16_t reg_cmd_write;
|
|
|
|
static uint16_t ram_cmd_fullness(void)
|
|
{
|
|
return (reg_cmd_write - reg_cmd_read) % 4096UL;
|
|
}
|
|
|
|
static uint16_t ram_cmd_freespace(void)
|
|
{
|
|
return (FT800_RAM_CMD_SIZE - 4UL) - ram_cmd_fullness();
|
|
}
|
|
|
|
static void refresh_reg_cmd_read(void)
|
|
{
|
|
reg_cmd_read = ft8xx_rd32(FT800_REG_CMD_READ);
|
|
}
|
|
|
|
static void flush_reg_cmd_write(void)
|
|
{
|
|
ft8xx_wr32(FT800_REG_CMD_WRITE, reg_cmd_write);
|
|
}
|
|
|
|
static void increase_reg_cmd_write(uint16_t value)
|
|
{
|
|
reg_cmd_write = (reg_cmd_write + value) % FT800_RAM_CMD_SIZE;
|
|
}
|
|
|
|
void ft8xx_copro_cmd(uint32_t cmd)
|
|
{
|
|
while (ram_cmd_freespace() < sizeof(cmd)) {
|
|
refresh_reg_cmd_read();
|
|
}
|
|
|
|
ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, cmd);
|
|
increase_reg_cmd_write(sizeof(cmd));
|
|
|
|
flush_reg_cmd_write();
|
|
}
|
|
|
|
void ft8xx_copro_cmd_dlstart(void)
|
|
{
|
|
ft8xx_copro_cmd(CMD_DLSTART);
|
|
}
|
|
|
|
void ft8xx_copro_cmd_swap(void)
|
|
{
|
|
ft8xx_copro_cmd(CMD_SWAP);
|
|
}
|
|
|
|
void ft8xx_copro_cmd_text(int16_t x,
|
|
int16_t y,
|
|
int16_t font,
|
|
uint16_t options,
|
|
const char *s)
|
|
{
|
|
const uint16_t str_bytes = strlen(s) + 1;
|
|
const uint16_t padding_bytes = (4 - (str_bytes % 4)) % 4;
|
|
const uint16_t cmd_size = sizeof(CMD_TEXT) +
|
|
sizeof(x) +
|
|
sizeof(y) +
|
|
sizeof(font) +
|
|
sizeof(options) +
|
|
str_bytes +
|
|
padding_bytes;
|
|
|
|
while (ram_cmd_freespace() < cmd_size) {
|
|
refresh_reg_cmd_read();
|
|
}
|
|
|
|
ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_TEXT);
|
|
increase_reg_cmd_write(sizeof(CMD_TEXT));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, x);
|
|
increase_reg_cmd_write(sizeof(x));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, y);
|
|
increase_reg_cmd_write(sizeof(y));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, font);
|
|
increase_reg_cmd_write(sizeof(font));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, options);
|
|
increase_reg_cmd_write(sizeof(options));
|
|
|
|
(void)ft8xx_drv_write(FT800_RAM_CMD + reg_cmd_write, s, str_bytes);
|
|
increase_reg_cmd_write(str_bytes + padding_bytes);
|
|
|
|
flush_reg_cmd_write();
|
|
}
|
|
|
|
void ft8xx_copro_cmd_number(int16_t x,
|
|
int16_t y,
|
|
int16_t font,
|
|
uint16_t options,
|
|
int32_t n)
|
|
{
|
|
const uint16_t cmd_size = sizeof(CMD_NUMBER) +
|
|
sizeof(x) +
|
|
sizeof(y) +
|
|
sizeof(font) +
|
|
sizeof(options) +
|
|
sizeof(n);
|
|
|
|
while (ram_cmd_freespace() < cmd_size) {
|
|
refresh_reg_cmd_read();
|
|
}
|
|
|
|
ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_NUMBER);
|
|
increase_reg_cmd_write(sizeof(CMD_NUMBER));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, x);
|
|
increase_reg_cmd_write(sizeof(x));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, y);
|
|
increase_reg_cmd_write(sizeof(y));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, font);
|
|
increase_reg_cmd_write(sizeof(font));
|
|
|
|
ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, options);
|
|
increase_reg_cmd_write(sizeof(options));
|
|
|
|
ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, n);
|
|
increase_reg_cmd_write(sizeof(n));
|
|
|
|
flush_reg_cmd_write();
|
|
}
|
|
|
|
void ft8xx_copro_cmd_calibrate(uint32_t *result)
|
|
{
|
|
const uint16_t cmd_size = sizeof(CMD_CALIBRATE) + sizeof(uint32_t);
|
|
uint32_t result_address;
|
|
|
|
while (ram_cmd_freespace() < cmd_size) {
|
|
refresh_reg_cmd_read();
|
|
}
|
|
|
|
ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_CALIBRATE);
|
|
increase_reg_cmd_write(sizeof(CMD_CALIBRATE));
|
|
|
|
result_address = FT800_RAM_CMD + reg_cmd_write;
|
|
ft8xx_wr32(result_address, 1UL);
|
|
increase_reg_cmd_write(sizeof(uint32_t));
|
|
|
|
flush_reg_cmd_write();
|
|
|
|
/* Wait until calibration is finished. */
|
|
while (ram_cmd_fullness() > 0) {
|
|
refresh_reg_cmd_read();
|
|
}
|
|
|
|
*result = ft8xx_rd32(result_address);
|
|
}
|