- // ode
- /*
- * startup.c
- *
- */
- typedef unsigned char uint8_t;
- typedef unsigned int uint32_t;
- #define GPIO_E 0x40021000
- #define GPIO_MODER ((volatile uint32_t *) (GPIO_E))
- #define GPIO_OTYPER ((volatile unsigned short *) (GPIO_E+0x4))
- #define GPIO_OSPEEDR ((volatile uint32_t *) (GPIO_E+0x8))
- #define GPIO_PUPDR ((volatile uint32_t *) (GPIO_E+0xC))
- #define GPIO_IDR_LOW ((volatile uint8_t *) (GPIO_E+0x10))
- #define GPIO_IDR_HIGH ((volatile uint8_t *) (GPIO_E+0x11))
- #define GPIO_ODR_LOW ((volatile uint8_t *) (GPIO_E+0x14))
- #define GPIO_ODR_HIGH ((volatile uint8_t *) (GPIO_E+0x15))
- #define STK_CTRL ((volatile int *) 0xE000E010)
- #define STK_LOAD ((volatile int *) 0xE000E014)
- #define STK_VAL ((volatile int *) 0xE000E018)
- #define B_E 0x40 //Enable
- #define B_RST 0x20 //Reset
- #define B_CS2 0x10 //CS2 - Skärmdel till höger
- #define B_CS1 0x8 // CS1 - Skärmdel till vänster
- #define B_SELECT 4 // 0 Graphics, 1 Ascii
- #define B_RW 2 // 0 Write, 1 Read
- #define B_RS 1 // 0 Command, 1 Data
- #define LCD_ON 0x3F // Display on
- #define LCD_OFF 0x3E // Display off
- #define LCD_SET_ADD 0x40 // Set horizontal coordinate
- #define LCD_SET_PAGE 0xB8 // Set vertical coordinate
- #define LCD_DISP_START 0xC0 // Start address
- #define LCD_BUSY 0x80 // Read busy status
- #define SIMULATOR
- typedef struct tpoint{
- uint8_t x;
- uint8_t y;
- }POINT;
- #define MAX_POINTS 20
- typedef struct tGeometry{
- uint32_t numpoints;
- uint32_t sizex;
- uint32_t sixey;
- POINT px[MAX_POINTS];
- }GEOMETRY, *PGEOMETRY;
- typedef struct tObj{
- PGEOMETRY geo;
- signed int dirx;
- signed int diry;
- signed int posx;
- signed int posy;
- void (* draw)(struct tObj*);
- void (* clear)(struct tObj*);
- void (* move)(struct tObj*);
- void (* set_speed)(struct tObj*, signed int, signed int);
- }OBJECT, *POBJECT;
- void startup(void) __attribute__((naked)) __attribute__((section (".start_section")) );
- void startup ( void )
- {
- __asm volatile(
- " LDR R0,=0x2001C000\n" /* set stack */
- " MOV SP,R0\n"
- " BL main\n" /* call main */
- "_exit: B .\n" /* never return */
- ) ;
- }
- //------------ObjectFunktioner----//
- void set_object_speed(POBJECT o, uint32_t speedx, uint32_t speedy){
- o->dirx = speedx;
- o->diry = speedy;
- }
- void draw_object (POBJECT object){
- for(uint8_t p = 0; p < object->geo->numpoints; p++){
- POINT centerPoint = object->geo->px[p];
- pixel((object->posx + centerPoint.x),(object->posy + centerPoint.y), 1);
- }
- }
- void clear_object (POBJECT object){
- for(uint8_t p = 0; p < object->geo->numpoints; p++){
- POINT centerPoint = object->geo->px[p];
- pixel((object->posx + centerPoint.x),(object->posy + centerPoint.y), 0);
- }
- }
- void move_object (POBJECT object){
- clear_object(object);
- object->posx += object->dirx;
- object->posy += object->diry;
- if(object->posx < 1){
- object->posx = 1;
- object->dirx *= -1;
- }
- if(object->posx > 128){
- object->posx = 127;
- object->dirx *= -1;
- }
- if(object->posy < 1){
- object->posy = 1;
- object->diry *= -1;
- }
- if(object->posy > 64){
- object->posy = 63;
- object->diry *= -1;
- }
- draw_object(object);
- }
- //------------Drivrutiner---------//
- void graphic_ctrl_bit_set(uint8_t x){
- uint8_t c;
- c = *GPIO_ODR_LOW;
- c|=(~B_SELECT & x);
- *GPIO_ODR_LOW = c;
- }
- void graphic_ctrl_bit_clear(uint8_t x){
- uint8_t c;
- c = *GPIO_ODR_LOW;
- c &= (~B_SELECT & ~x);
- *GPIO_ODR_LOW = c;
- }
- void select_controller(uint8_t controller){
- switch(controller){
- case 0:
- graphic_ctrl_bit_clear(B_CS1|B_CS2);
- break;
- case B_CS1 :
- graphic_ctrl_bit_set(B_CS1);
- graphic_ctrl_bit_clear(B_CS2);
- break;
- case B_CS2 :
- graphic_ctrl_bit_set(B_CS2);
- graphic_ctrl_bit_clear(B_CS1);
- break;
- case B_CS1|B_CS2 :
- graphic_ctrl_bit_set(B_CS1|B_CS2);
- break;
- }
- }
- void graphic_wait_ready(void){
- uint32_t c;
- graphic_ctrl_bit_clear(B_E);
- c = 0x00005555;
- *GPIO_MODER = c;
- graphic_ctrl_bit_clear(B_RS);
- graphic_ctrl_bit_set(B_RW);
- delay_500();
- do{
- graphic_ctrl_bit_set(B_E);
- delay_500();
- c = *GPIO_IDR_HIGH & LCD_BUSY;
- graphic_ctrl_bit_clear(B_E);
- delay_500();
- }while (c);
- graphic_ctrl_bit_set(B_E);
- c = 0x55555555;
- *GPIO_MODER = c;
- }
- uint8_t graphic_read (uint8_t controller){
- graphic_ctrl_bit_clear(B_E);
- uint32_t c = 0x00005555;
- *GPIO_MODER = c;
- graphic_ctrl_bit_set(B_RS);
- graphic_ctrl_bit_set(B_RW);
- select_controller(controller);
- delay_500();
- graphic_ctrl_bit_set(B_E);
- delay_500();
- uint32_t rv = *GPIO_IDR_HIGH;
- graphic_ctrl_bit_clear(B_E);
- c = 0x55555555;
- *GPIO_MODER = c;
- help_select_controller(controller);
- return rv;
- }
- void graphic_write(uint8_t value, uint8_t controller){
- //uint32_t c = *GPIO_MODER;
- *GPIO_ODR_HIGH = value;
- select_controller(controller);
- delay_500();
- graphic_ctrl_bit_set(B_E);
- delay_500();
- graphic_ctrl_bit_clear(B_E);
- help_select_controller(controller);
- *GPIO_ODR_HIGH = value;
- graphic_ctrl_bit_set(B_E);
- select_controller(0);
- }
- void graphic_write_command(uint8_t cmd, uint8_t controller){
- graphic_ctrl_bit_clear(B_E);
- select_controller(controller);
- graphic_ctrl_bit_clear(B_RS);
- graphic_ctrl_bit_clear(B_RW);
- graphic_write(cmd, controller);
- }
- void graphic_write_data(uint8_t data, uint8_t controller){
- graphic_ctrl_bit_clear(B_E);
- select_controller(controller);
- graphic_ctrl_bit_set(B_RS);
- graphic_ctrl_bit_clear(B_RW);
- graphic_write(data, controller);
- }
- uint8_t graphic_read_data(uint8_t controller){
- graphic_read(controller);
- return graphic_read(controller);
- }
- void help_select_controller(uint8_t controller){
- if(controller == B_CS1){
- select_controller(B_CS1);
- graphic_wait_ready();
- }
- if (controller == B_CS2){
- select_controller(B_CS2);
- graphic_wait_ready();
- }
- }
- // ------------------INIT-------------//
- void app_init(void){
- //Display Data ut E15-8
- *GPIO_MODER = (*GPIO_MODER & 0) | 0x55555555;
- //Styrregister ut E7-0
- }
- void graphic_initalize(void){
- graphic_ctrl_bit_set(B_E);
- delay_micro(10);
- graphic_ctrl_bit_clear(B_CS1);
- graphic_ctrl_bit_clear(B_CS2);
- graphic_ctrl_bit_clear(B_RST);
- graphic_ctrl_bit_clear(B_E);
- delay_milli(30);
- graphic_ctrl_bit_set(B_RST);
- //Utelämna vid simulator?
- graphic_write_command(LCD_OFF, B_CS1|B_CS2);
- graphic_write_command(LCD_ON, B_CS1|B_CS2);
- graphic_write_command(LCD_DISP_START, B_CS1|B_CS2);
- graphic_write_command(LCD_SET_ADD, B_CS1|B_CS2);
- graphic_write_command(LCD_SET_PAGE, B_CS1|B_CS2);
- select_controller(0);
- }
- void graphic_clear_screen(void){
- for (uint8_t page = 0; page < 8; page++){
- graphic_write_command(LCD_SET_PAGE | page, B_CS1|B_CS2);
- graphic_write_command(LCD_SET_ADD| 0, B_CS1|B_CS2);
- for (uint8_t add = 0; add < 64; add++){
- graphic_write_data(0, B_CS1|B_CS2);
- }
- }
- }
- void pixel (uint8_t x, uint8_t y, uint8_t set){
- if(x >= 1 && x <= 128 && y >= 1 && y <= 64){}else{return;}
- uint8_t index = (y-1)/8;
- uint8_t mask = 1<<((y-1)%8);
- if (set == 0){
- mask = ~mask;
- }
- uint8_t controller = B_CS1;
- uint8_t x_fysisk = x-1;
- if(x>64){
- controller = B_CS2;
- x_fysisk = x-65;
- }
- graphic_write_command(LCD_SET_ADD | x_fysisk, controller);
- graphic_write_command(LCD_SET_PAGE | index, controller);
- uint8_t temp = graphic_read_data(controller);
- graphic_write_command(LCD_SET_ADD | x_fysisk, controller);
- if(set){
- mask |= temp;
- }else{
- mask &= temp;
- }
- graphic_write_data(mask, controller);
- }
- // ------------------DELAY------------//
- void delay_500(void){
- #ifndef SIMULATOR
- delay_250();
- delay_250();
- #endif
- }
- void delay_250(void){
- *STK_CTRL = 0; //Återställer räknaren
- *STK_LOAD = (168/4)-1;
- *STK_VAL = 0;
- *STK_CTRL = 5; //Starta räknaren
- while ((*STK_CTRL & 0x10000) == 0){
- }
- *STK_CTRL = 0;
- }
- void delay_micro(uint32_t us){
- us *=4;
- while (us>0){
- delay_250();
- us--;
- }
- }
- void delay_milli(uint32_t ms){
- #ifdef SIMULATOR
- ms = ms/1000;
- ms++;
- #endif
- while(ms>0){
- delay_micro(1000);
- ms--;
- }
- }
- void main(void)
- {
- uint8_t i;
- app_init();
- graphic_initalize();
- #ifndef SIMULATOR
- graphic_clear_screen();
- #endif
- GEOMETRY ball_geometry = {
- 12,
- 4,4,
- {
- {0,1}, {0,2}, {1,0}, {1,1}, {1,2}, {1,3}, {2,0}, {2,1}, {2,2}, {2,3}, {3,2}
- }
- };
- PGEOMETRY pball_geometry = &ball_geometry;
- OBJECT ball =
- {
- pball_geometry,
- 0,0,
- 1,1,
- draw_object,
- clear_object,
- move_object,
- set_object_speed
- };
- POBJECT p = &ball;
- p->set_speed(p, 0, 4);
- while(1){
- p->move(p);
- delay_milli(10);
- }
- /*
- graphic_write_command(LCD_SET_ADD | 10, B_CS1|B_CS2);
- graphic_write_command(LCD_SET_PAGE | 1, B_CS1|B_CS2);
- graphic_write_data(0xFF, B_CS1|B_CS2);
- */
- /*
- for (i = 1; i <= 128; i++){
- pixel(i, 10, 1);
- }
- for(i = 1; i <= 64; i++){
- pixel(10, i, 1);
- }
- //delay_milli(500);
- for (i = 1; i <= 128; i++){
- pixel(i, 10, 0);
- }
- for(i = 1; i <= 64; i++){
- pixel(10, i, 0);
- }
- */
- }