Commit b2801cba authored by Matěj Kopecký's avatar Matěj Kopecký
Browse files

New codes

parent c30cdc0f
# typedef struct knobs_t
This structure contains values from every one of three knobs
* uint8_t R;
* uint8_t G;
* uint8_t B;
# typedef struct point_t
This structure contains vertical and horizontal coordinates of draw pointer
* uint16_t x;
* uint16_t y;
# void loadKnobs(volatile knobs_t *knobs)
* gets values from each knob
# void setPoint(point_t *newPoint, uint16_t x, uint16_t y)
* prepares new point for draw
# void show_color_on_led(uint64_t color)
* set LED´s colors to input value
# void drawPoint(point_t *oldPoint, point_t *newPoint, volatile uint16_t *lcd, uint16_t color_16b)
* draw new point into the lcd display
# void set_draw_color(uint16_t *color16b, uint64_t *color64b, int wait_time)
* gets color from input and changes the draw color and led color to it
# int main()
* main of the code, loops it to draw on lcd
**LCD_FB_START 0xffe00000** - start address of lcd display
**LCD_FB_END 0xffe4afff** - end address of lcd display
**GAB 2** - gab between two characters, size two
**LCD_WIDTH 480** - width of lcd display
**LCD_HEIGHT 320** - height of lcd display
**DRAW_BORDER 255** - border in pixels for drawing
uint16_t text_field[LCD_WIDTH * LCD_HEIGHT] - lcd buffer
# structure Gcolor16b
This structure contains colors in 16 bites.
uint16_t red;
uint16_t blue;
uint16_t green;
uint16_t black;
uint16_t white;
uint16_t yellow;
# structure Gcolor64b
This structure contains colors in 64 bites.
uint64_t red;
uint64_t blue;
uint64_t green;
uint64_t black;
uint64_t white;
uint64_t yellow;
# int get_width_of_char(font_descriptor_t *file_des, int ch_char)
* Function for getting the width of a char from a fond for lcd display
# void erase_text_field(void)
* Erase whole text field (buffer) to black (zero)
# void color_pixels(uint16_t pix_color, int start_pos, int block_size)
* Colors pixels in field according to inputs
# void make_draw_frame(uint16_t pix_color)
* Makes draw frame in field
# int get_text_lenght(font_descriptor_t *file_des, int *text_size, char *str_text)
* Returns text length according to file descriptor
# void write_character(int ch_size, int start, uint16_t char_color, font_descriptor_t *file_des, char character, int line_number)
* Writes one character into the text field
# void draw_line(int size_of_font, int line_number, uint16_t text_color, font_descriptor_t *file_des, int idx, char *str_text)
* Writes one line of a string according to inputs
# void draw_to_lcd(void)
* Redraws whole text field into the lcd
# void init_lcd_message(int size_of_font, uint16_t text_color, font_descriptor_t *file_des)
* Draws initialization message to lcd display
# void pick_color(int size_of_font, uint16_t text_color, font_descriptor_t *file_des)
* Draw color options to lcd
# void black_the_lcd(void)
* Erases the whole lcd display
# void black_the_draw_frame(void)
* Erases just the draw frame for new drawing
# volatile int terminalIn()
* Gets one character from terminal input
# volatile int my_terminalIn(int wait_time)
* Gets one character from terminal input but with a timeout
# void terminalOut(volatile int print)
* Writes data to terminal output
# void print_str_on_terminal(char *str)
* Write string to terminal output
# unsigned long myStrLen(const char *str)
* Return length of a string
# void print_coordinates(uint16_t x, uint16_t y)
* Prints out vertical and horizontal coordinate from input
# char *my_int_to_str_convert(int number, char *outStr)
* Converts number into string
# void print_num_terminal(int num)
* Prints number into terminal
# volatile int pick_color_trm(uint16_t *color16b, uint64_t *color64b, int wait_time)
* Gets color choice from terminal input with and without timeout
## GRAFO USER MANUAL
User manual for the game GRAFO, made as a semestral project for computer architectures in the summer semester of 2020.
The code is written without any C library. Just plain C code.
Made by: Matej Kopecky and Vit Ramba
# Installation
1. Download the code:
1. Install QTMips from this site: https://github.com/cvut/QtMips/releases/
1. Set up your QTMips to see LCD Display, terminal with input, LED’s and knobs like the picture shows.
![qtmips_setup]
(qtmips_setup.png?raw=true "QTMips Setup")
1. Build the game using included Makefile.
1. In your folder now should be ‘main’ file.
1. Run that file in QTMips to start Grafo.
# Controls
After you start the code, wait around half a minute before LCD loades. Keep an eye on the terminal. There will instructions for you. After the LCD loads, you can start pressing some buttons to set color of your drawing.
# Color options – press button:
1. ‘r’ for color red
1. ‘g’ for color green
1. ‘b’ for color blue
1. ‘y’ for color yellow
1. ‘w’ for color white
Press ‘p’ for clear of draw field.
Press ‘q’ to end the game.
After you pick color, you will start drawing in the draw screen. Both LED’s will show you the chosen color.
To change color when you start drawing, hold the button for a moment for the code to pick it up.
# Terminal
Terminal will show you every now and then coordinates of the cursor.
To change color when you start drawing, hold the button for a moment for the code to pick it up.
# Drawing
* Use red and green knob to move the cursor
The drawing is controlled by red and green knob. Red knob value is horizontal coordinate of the cursor. Green knob value is vertical coordinate of the cursor. In the moment when you change some of the two values, the cursor will start to move for that new coordinate that you just set. Line of the drawing will be continuous and whenever you change the values, it will move to new coordinate.
ARCH=mips-elf
#ARCH=mips-linux-gnu
SOURCES = main.c my_terminal.c my_lcd_text.c font_prop14x16.c
TARGET_EXE = main
CC=$(ARCH)-gcc
CXX=$(ARCH)-g++
AS=$(ARCH)-as
LD=$(ARCH)-ld
OBJCOPY=$(ARCH)-objcopy
#ARCHFLAGS += -march=mips3
#ARCHFLAGS += -fno-lto
#ARCHFLAGS += -mno-shared
CFLAGS += -ggdb -Os -Wall
CXXFLAGS+= -ggdb -Os -Wall
AFLAGS += -ggdb
LDFLAGS += -ggdb
LDFLAGS += -nostartfiles
LDFLAGS += -static
#LDFLAGS += -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs
CFLAGS += $(ARCHFLAGS)
CXXFLAGS+= $(ARCHFLAGS)
AFLAGS += $(ARCHFLAGS)
LDFLAGS += $(ARCHFLAGS)
OBJECTS += $(filter %.o,$(SOURCES:%.S=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
all : default
.PHONY : default clean dep all
%.o:%.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@
%.o:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
%.o:%.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
%.s:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@
default : $(TARGET_EXE)
$(TARGET_EXE) : $(OBJECTS)
$(CC) $(LDFLAGS) $^ -o $@
dep: depend
depend: $(SOURCES) $(glob *.h)
echo '# autogenerated dependencies' > depend
ifneq ($(filter %.S,$(SOURCES)),)
$(CC) -D__ASSEMBLY__ $(AFLAGS) -w -E -M $(filter %.S,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) depend
#mips-elf-objdump --source -M no-aliases,reg-names=numeric qtmips_binrep
-include depend
This diff is collapsed.
This diff is collapsed.
/*******************************************************************
font_types.h - simple bitmap fonts type definition
Simplified font type descriptor based on
Microwindows/Nano-X library by Greg Haerr
https://github.com/ghaerr/microwindows
Copyright (c) 1999, 2000, 2001, 2002, 2003, 2005, 2010, 2011 Greg Haerr <greg@censoft.com>
Portions Copyright (c) 2002 by Koninklijke Philips Electronics N.V.
Simplification by Pavel Pisa for Czech Technical University
Computer Architectures course
*******************************************************************/
#ifndef FONT_TYPES_H
#define FONT_TYPES_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint16_t font_bits_t;
/* builtin C-based proportional/fixed font structure*/
typedef struct {
char * name; /* font name*/
int maxwidth; /* max width in pixels*/
unsigned int height; /* height in pixels*/
int ascent; /* ascent (baseline) height*/
int firstchar; /* first character in bitmap*/
int size; /* font size in characters*/
const font_bits_t *bits; /* 16-bit right-padded bitmap data*/
const uint32_t *offset; /* offsets into bitmap data*/
const unsigned char *width; /* character widths or 0 if fixed*/
int defaultchar;/* default char (not glyph index)*/
int32_t bits_size; /* # words of MWIMAGEBITS bits*/
} font_descriptor_t;
extern font_descriptor_t font_winFreeSystem14x16;
extern font_descriptor_t font_rom8x16;
#ifdef __cplusplus
} /* extern "C"*/
#endif
#endif /*FONT_TYPES_H*/
#define SERIAL_PORT_BASE 0xffffc000
#define SERP_RX_ST_REG_o 0x00
#define SERP_RX_ST_REG_READY_m 0x1
#define SERP_RX_ST_REG_IE_m 0x2
#define SERP_RX_DATA_REG_o 0x04
#define SERP_TX_ST_REG_o 0x08
#define SERP_TX_ST_REG_READY_m 0x1
#define SERP_TX_ST_REG_IE_m 0x2
#define SERP_TX_DATA_REG_o 0x0c
/* ~ */
#define SPILED_REG_BASE 0xffffc100
#define SPILED_REG_LED_LINE_o 0x004
#define SPILED_REG_LED_RGB1_o 0x010
#define SPILED_REG_LED_RGB2_o 0x014
#define SPILED_REG_LED_KBDWR_DIRECT_o 0x018
#define SPILED_REG_KBDRD_KNOBS_DIRECT_o 0x020
#define SPILED_REG_KNOBS_8BIT_o 0x024
/**/
#define LCD_FB_START 0xffe00000
#define LCD_FB_END 0xffe4afff
#define LCD_WIDTH 480
#define LCD_HEIGHT 320
#define X_K (480 / 255)
#define Y_K (320 / 255)
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "my_terminal.h"
#include "my_lcd_text.h"
#include "font_types.h"
rgb_color_16b_t Gcolor16b;
font_descriptor_t font_winFreeSystem14x16;
/*struct px_t
{
unsigned R : 5;
unsigned G : 6;
unsigned B : 5;
} __attribute((packed)) __;
typedef struct px_t px;*/
typedef struct
{
uint8_t R;
uint8_t G;
uint8_t B;
} knobs_t;
void loadKnobs(volatile knobs_t *knobs)
{
volatile uint32_t *knobs_ptr = (uint32_t *)(SPILED_REG_BASE + SPILED_REG_KNOBS_8BIT_o);
knobs->B = 0xFF & *knobs_ptr;
knobs->G = 0xFF & (*knobs_ptr >> 8);
knobs->R = 0xFF & (*knobs_ptr >> 16);
}
typedef struct
{
uint16_t x;
uint16_t y;
} point_t;
void setPoint(point_t *newPoint, uint16_t x, uint16_t y)
{
newPoint->x = x;
newPoint->y = y;
}
void show_color_on_led(uint64_t color)
{
unsigned char *mem_base = (unsigned char *)SPILED_REG_BASE;
*(volatile uint32_t *)(mem_base + SPILED_REG_LED_RGB1_o) = color;
*(volatile uint32_t *)(mem_base + SPILED_REG_LED_RGB2_o) = color;
}
void drawPoint(point_t *oldPoint, point_t *newPoint, volatile uint16_t *lcd, uint16_t color_16b)
{
int ii = newPoint->x > oldPoint->x ? 1 : -1;
int ji = newPoint->y > oldPoint->y ? 1 : -1;
int i = 0;
int j = 0;
if (oldPoint->x + i != newPoint->x)
{
i += ii;
}
if (oldPoint->y + j != newPoint->y)
{
j += ji;
}
lcd[(oldPoint->y + j) * LCD_WIDTH + (oldPoint->x + i)] = color_16b;
oldPoint->x += i;
oldPoint->y += j;
}
void set_draw_color(uint16_t *color16b, uint64_t *color64b, int wait_time)
{
pick_color_trm(color16b, color64b, wait_time);
show_color_on_led(*color64b);
}
int main()
{
int small_font = 1;
int wait_time = 100; //number of cycles to wait
int inf_time = -1;
volatile uint16_t *lcd_t = (typeof(lcd_t))LCD_FB_START;
volatile knobs_t *knobs;
uint16_t color16b;
uint64_t color64b;
//Init position
loadKnobs(knobs);
point_t oldPoint;
setPoint(&oldPoint, knobs->R, knobs->G);
point_t newPoint;
setPoint(&newPoint, knobs->R, knobs->G);
init_lcd_message(small_font, Gcolor16b.yellow, &font_winFreeSystem14x16);
set_draw_color(&color16b, &color64b, inf_time);
int print_c = 0;
while (1)
{
loadKnobs(knobs);
setPoint(&newPoint, knobs->R, knobs->G);
drawPoint(&oldPoint, &newPoint, lcd_t, color16b);
set_draw_color(&color16b, &color64b, wait_time);
if (print_c % 100 == 0)
{
print_coordinates(newPoint.x, newPoint.y);
print_str_on_terminal("HOLD BUTTON TO CHANGE COLOR\n");
print_c = 0;
}
++print_c;
}
return 0;
}
#include "my_lcd_text.h"
#define LCD_FB_START 0xffe00000
#define LCD_FB_END 0xffe4afff
#define GAB 2
//gab between two characters, size two
#define LCD_WIDTH 480
#define LCD_HEIGHT 320
#define DRAW_BORDER 255
uint16_t text_field[LCD_WIDTH * LCD_HEIGHT];
rgb_color_16b_t Gcolor16b =
{
.red = 0xF800,
.blue = 0x1F,
.green = 0x7E0,
.black = 0x0000,
.white = 0xFFFF,
.yellow = 0xFF00,
};
rgb_color_64b_t Gcolor64b =
{
.red = 0xFF0000,
.blue = 0x0000FF,
.green = 0x00FF00,
.black = 0x000000,
.white = 0xFFFFFF,
.yellow = 0xFFFF00,
};
int get_width_of_char(font_descriptor_t *file_des, int ch_char)
{
int ch_width = 0;
int cond1 = file_des->firstchar <= ch_char;
int cond2 = file_des->size > (ch_char - file_des->firstchar);
if (cond1 && cond2)
{
ch_char = ch_char - file_des->firstchar;
if (!file_des->width)
{
ch_width = file_des->maxwidth;
}
else
{
ch_width = file_des->width[ch_char];
}
}
return ch_width;
}
void erase_text_field(void)
{
for (int i = 0; i < LCD_WIDTH * LCD_HEIGHT; ++i)
{
text_field[i] = 0;
}
}
void color_pixels(uint16_t pix_color, int start_pos, int block_size)
{
for (int m = 0; m < block_size; ++m)
{
for (int k = 0; k < block_size; ++k)
{
text_field[start_pos + m * LCD_WIDTH + k] = pix_color;
}
}
}
void make_draw_frame(uint16_t pix_color)
{
int size_of_num = 1;
int side_num = DRAW_BORDER + 10;
//vertical line
int x = DRAW_BORDER + 5;
int lower_line = x + 2;
for (int y = 0; y < x; ++y)
{
text_field[x + y * LCD_WIDTH] = pix_color;
}
//horizontal line
for (int y = 0; y < x; ++y)
{
text_field[y + x * LCD_WIDTH] = pix_color;
}
draw_line(size_of_num, 1, Gcolor16b.white, &font_winFreeSystem14x16, side_num, "0");
draw_line(size_of_num, 127, Gcolor16b.white, &font_winFreeSystem14x16, side_num, "127");
draw_line(size_of_num, lower_line, Gcolor16b.white, &font_winFreeSystem14x16, side_num, "255");
draw_line(size_of_num, lower_line, Gcolor16b.white, &font_winFreeSystem14x16, 2, "0");
draw_line(size_of_num, lower_line, Gcolor16b.white, &font_winFreeSystem14x16, 127, "127");
}
int get_text_lenght(font_descriptor_t *file_des, int *text_size, char *str_text)
{
int ret = 0;
int lenght = 0;
*text_size = 0;
while (str_text[lenght] != '\0')
{
lenght = lenght + 1;
text_size = text_size + get_width_of_char(file_des, str_text[lenght]);
if (LCD_WIDTH < lenght)
{
ret = LCD_WIDTH + 1;
return ret;
}
}
ret = lenght;
return ret;
}
void write_character(int ch_size, int start, uint16_t char_color, font_descriptor_t *file_des, char character,
int line_number)
{
int char_width = get_width_of_char(file_des, character);
for (int i = 0; i < file_des->height; ++i)
{
int index = (character - file_des->firstchar) * file_des->height + i;
uint16_t letter_of_bit = file_des->bits[index];
uint16_t bit_mask = 0x8000;
for (int j = 0; j < char_width; ++j)
{
int cond = (letter_of_bit & bit_mask);
int start_idx = 0;
if (cond)
{
start_idx = start + (line_number + i * ch_size) * LCD_WIDTH + j * ch_size;
color_pixels(char_color, start_idx, ch_size);
}
else
{
start_idx = start + (line_number + i * ch_size) * LCD_WIDTH + j * ch_size;
color_pixels(0x0, start_idx, ch_size);
}
bit_mask = bit_mask >> 1;
}
}
}
void draw_line(int size_of_font, int line_number, uint16_t text_color, font_descriptor_t *file_des, int idx,
char *str_text)
{
int text_size = 0;
int str_lenght = get_text_lenght(file_des, &text_size, str_text);
int length = text_size * size_of_font + (str_lenght - 1) * size_of_font * GAB;
int cond = (file_des->height * size_of_font + line_number) >= LCD_HEIGHT;
if (length > LCD_WIDTH)
{
print_str_on_terminal("ERROR: LINE TOO LONG!\n");
}
else if (cond)
{
print_str_on_terminal("ERROR: BIG LINE NUM OR SIZE!\n");
}
else
{
int index = 0;
if (idx == -1)
{
index = (LCD_WIDTH - length) / 4;
}
else
{
index = idx;
}
for (int j = 0; j < str_lenght; ++j)
{
write_character(size_of_font, index, text_color, file_des, str_text[j], line_number);
index = index + (get_width_of_char(file_des, str_text[j]) + GAB) * size_of_font;
}
}
}
void draw_to_lcd(void)
{
volatile uint16_t *lcd_t = (typeof(lcd_t))LCD_FB_START;
for (int e = 0; e < LCD_WIDTH * LCD_HEIGHT; ++e)
{
lcd_t[e] = text_field[e];
}
}
void init_lcd_message(int size_of_font, uint16_t text_color, font_descriptor_t *file_des)
{
int bigger_font = 2;
int left_side = DRAW_BORDER + 40;
int middle = -1;
print_str_on_terminal("HELLO!\n");
print_str_on_terminal("WAIT FOR LCD TO LOAD!\n");
print_str_on_terminal("I AM SLOW!\n");
make_draw_frame(Gcolor16b.white);
draw_line(bigger_font, 1, text_color, file_des, left_side, " GRAFO");
draw_line(size_of_font, 36, text_color, &font_winFreeSystem14x16, left_side, " <-- DRAW SCREEN");
draw_line(size_of_font, 56, text_color, &font_winFreeSystem14x16, left_side, " PICK COLOR");
pick_color(size_of_font, text_color, file_des);
draw_line(size_of_font, 176, text_color, &font_winFreeSystem14x16, left_side, " TYPE 'P' TO ERASE");
//tady to nekompiluje
draw_line(size_of_font, 196, text_color, &font_winFreeSystem14x16, left_side, " TYPE 'Q' TO QUIT");
draw_line(size_of_font, 290, Gcolor16b.green, &font_winFreeSystem14x16, middle, "BY: MATEJ KOPECKY AND VIT RAMBA");
draw_to_lcd();
print_str_on_term