gint-with-thread/src/r61524/r61524.c

315 lines
5.4 KiB
C

//---
// gint:r61524 - Renesas R61524 driver
//---
#include <gint/drivers.h>
#include <gint/defs/types.h>
#ifdef FXCG50
//---
// Device specification sheet
//---
/* Registers and operations */
enum {
device_code_read = 0x000,
driver_output_control = 0x001,
entry_mode = 0x003,
display_control_2 = 0x008,
low_power_control = 0x00b,
ram_address_horizontal = 0x200,
ram_address_vertical = 0x201,
write_data = 0x202,
horizontal_ram_start = 0x210,
horizontal_ram_end = 0x211,
vertical_ram_start = 0x212,
vertical_ram_end = 0x213,
};
typedef word_union(entry_mode_t,
uint TRI :1;
uint DFM :1;
uint :1;
uint BGR :1;
uint :2;
uint HWM :1;
uint :1;
uint ORG :1;
uint :1;
uint ID :2;
uint AM :1;
uint :1;
uint EPF :2;
);
//---
// Device communication primitives
//---
#define synco() __asm__ volatile ("synco":::"memory")
/* Interface with the controller */
GDATA static volatile uint16_t *intf = (void *)0xb4000000;
/* Bit 4 of Port R controls the RS bit of the display driver */
GDATA static volatile uint8_t *PRDR = (void *)0xa405013c;
GINLINE static void select(uint16_t reg)
{
/* Clear RS and write the register number */
*PRDR &= ~0x10;
synco();
*intf = reg;
synco();
/* Set RS back. We don't do this in read()/write() because the display
driver is optimized for consecutive GRAM access. LCD-transfers will
be faster when executing select() followed by several calls to
write(). (Although most applications should use the DMA instead.) */
*PRDR |= 0x10;
synco();
}
GINLINE static uint16_t read(void)
{
return *intf;
}
GINLINE static void write(uint16_t data)
{
*intf = data;
}
//---
// Driver functions
//---
void pixel(int ha, int va, int color)
{
select(ram_address_horizontal);
write(ha);
select(ram_address_vertical);
write(va);
select(write_data);
write(color);
}
void r61524_test(void)
{
uint16_t device_name;
uint16_t doc;
int SM, SS;
entry_mode_t em;
uint16_t dc2;
int FP, BP;
uint16_t lpc;
int VEM, COL;
uint32_t AD;
uint16_t HSA, HEA;
uint16_t VSA, VEA;
//---
select(device_code_read);
device_name = read();
Bdisp_AllClr_VRAM();
print(1, 1, "Name=????");
print_hex(6, 1, device_name, 4);
if(device_name != 0x1524)
{
print(1, 2, "Aborting.");
Bdisp_PutDisp_DD();
delay(40);
return;
}
//---
select(driver_output_control);
doc = read();
SM = (doc >> 10) & 1;
SS = (doc >> 8) & 1;
select(entry_mode);
em.word = read();
select(display_control_2);
dc2 = read();
FP = (dc2 >> 8) & 0xf;
BP = dc2 & 0xf;
select(low_power_control);
lpc = read();
VEM = (lpc >> 4) & 1;
COL = lpc & 1;
/* Shift by 9, not 8, because of horizontal/vertical range inversion */
select(ram_address_horizontal);
AD = read();
select(ram_address_vertical);
AD |= read() << 9;
select(horizontal_ram_start);
HSA = read();
select(horizontal_ram_end);
HEA = read();
select(vertical_ram_start);
VSA = read();
select(vertical_ram_end);
VEA = read();
//---
print(15, 4, " SM=?");
print_hex(19, 4, SM, 1);
print(15, 5, " SS=?");
print_hex(19, 5, SS, 1);
print(1, 2, "TRI=? DFM=? BGR=?");
print_hex(5, 2, em.TRI, 1);
print_hex(12, 2, em.DFM, 1);
print_hex(19, 2, em.BGR, 1);
print(1, 3, "HWM=? ORG=? ID=?");
print_hex(5, 3, em.HWM, 1);
print_hex(12, 3, em.DFM, 1);
print_hex(19, 3, em.ID, 1);
print(1, 4, " AM=? EPF=?");
print_hex(5, 4, em.AM, 1);
print_hex(12, 4, em.EPF, 1);
print(1, 5, " FP=? BP=?");
print_hex(5, 5, FP, 1);
print_hex(12, 5, BP, 1);
print(1, 6, "VEM=? COL=?");
print_hex(5, 6, VEM, 1);
print_hex(12, 6, COL, 1);
Bdisp_PutDisp_DD();
delay(50);
//---
Bdisp_AllClr_VRAM();
print(1, 1, "Address=?????");
print_hex(9, 1, AD, 5);
print(1, 2, "HSA=??? HEA=???");
print_hex(5, 2, HSA, 3);
print_hex(14, 2, HEA, 3);
print(1, 3, "VSA=??? VEA=???");
print_hex(5, 3, VSA, 3);
print_hex(14, 3, VEA, 3);
Bdisp_PutDisp_DD();
delay(50);
//
Bdisp_AllClr_VRAM();
Bdisp_PutDisp_DD();
//---
select(horizontal_ram_start);
write(0);
select(horizontal_ram_end);
write(395);
select(vertical_ram_start);
write(0);
select(vertical_ram_end);
write(223);
//---
select(ram_address_horizontal);
write(HEA);
select(ram_address_vertical);
write(VSA);
select(write_data);
uint16_t color;
for(int v = 0; v < 224; v++)
for(int h = 0; h < 396; h++)
{
// int offset = 396 * v + h;
// uint8_t *src = gimp_image.pixel_data + 2 * offset;
color = 0x3eb7; // (src[1] << 8) | src[0];
write(color);
}
delay(200);
}
//---
// Context system for this driver
//---
typedef struct
{
/* Graphics RAM range */
uint16_t HSA, HEA, VSA, VEA;
} GPACKED(2) ctx_t;
/* Allocate one buffer in gint's storage section */
GBSS static ctx_t sys_ctx;
static void ctx_save(void *buf)
{
ctx_t *ctx = buf;
select(horizontal_ram_start);
ctx->HSA = read();
select(horizontal_ram_end);
ctx->HEA = read();
select(vertical_ram_start);
ctx->VSA = read();
select(vertical_ram_end);
ctx->VEA = read();
}
static void ctx_restore(void *buf)
{
ctx_t *ctx = buf;
select(horizontal_ram_start);
write(ctx->HSA);
select(horizontal_ram_end);
write(ctx->HEA);
select(vertical_ram_start);
write(ctx->VSA);
select(vertical_ram_end);
write(ctx->VEA);
}
//---
// Driver structure definition
//---
gint_driver_t drv_r61524 = {
.name = "R61524",
.init = NULL,
.ctx_size = sizeof(ctx_t),
.sys_ctx = &sys_ctx,
.ctx_save = ctx_save,
.ctx_restore = ctx_restore,
};
GINT_DECLARE_DRIVER(5, drv_r61524);
#endif /* FXCG50 */