//--- // gint:r61524 - Renesas R61524 driver //--- #include #include #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 */