Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //{ Defines
- //{ Port E
- #define GPIO_E 0x40021000
- #define GPIO_E_MODER ((volatile unsigned int *) (GPIO_E))
- #define GPIO_E_OTYPER ((volatile unsigned short *) (GPIO_E+0x4))
- #define GPIO_E_OSPEEDR ((volatile unsigned short *) (GPIO_E+0x8))
- #define GPIO_E_PUPDR ((volatile unsigned int *) (GPIO_E+0xC))
- #define GPIO_E_IDRLOW ((volatile unsigned char *) (GPIO_E+0x10))
- #define GPIO_E_IDRHIGH ((volatile unsigned char *) (GPIO_E+0x11))
- #define GPIO_E_ODRLOW ((volatile unsigned char *) (GPIO_E+0x14))
- #define GPIO_E_ODRHIGH ((volatile unsigned char *) (GPIO_E+0x15))
- //}
- //{ Port D
- #define GPIO_D 0x40020C00
- #define GPIO_D_MODER ((volatile unsigned int *) (GPIO_D))
- #define GPIO_D_OTYPER ((volatile unsigned short *) (GPIO_D+0x4))
- #define GPIO_D_OSPEEDR ((volatile unsigned short *) (GPIO_D+0x8))
- #define GPIO_D_PUPDR ((volatile unsigned int *) (GPIO_D+0xC))
- #define GPIO_D_IDRLOW ((volatile unsigned char *) (GPIO_D+0x10))
- #define GPIO_D_IDRHIGH ((volatile unsigned char *) (GPIO_D+0x11))
- #define GPIO_D_ODRLOW ((volatile unsigned char *) (GPIO_D+0x14))
- #define GPIO_D_ODRHIGH ((volatile unsigned char *) (GPIO_D+0x15))
- //}
- //{ LCD
- #define B_E 0x40 // Enable
- #define B_RST 0x20 // Reset
- #define B_CS2 0x10 // Controller Select 2
- #define B_CS1 8 // Controller Select 1
- #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
- //}
- //{ Typedef uint8
- typedef unsigned char uint8_t;
- //}
- //{ STK (Systick)
- #define STK_CTRL ((volatile unsigned int *)(0xE000E010))
- #define STK_LOAD ((volatile unsigned int *)(0xE000E014))
- #define STK_VAL ((volatile unsigned int *)(0xE000E018))
- //}
- //{ Typedef Struct
- typedef struct tPoint
- {
- uint8_t x;
- uint8_t y;
- }POINT;
- #define MAX_POINTS 20
- typedef struct tGeometry
- {
- int numPoints;
- int sizex;
- int sizey;
- POINT px[ MAX_POINTS];
- } GEOMETRY, *PGEOMETRY;
- typedef struct tObj{
- PGEOMETRY geo;
- int dirx,diry;
- int posx,posy;
- void (* draw) (struct tObj *);
- void (* clear) (struct tObj *);
- void (* move) (struct tObj *, struct tObj *,struct tObj * );
- void (* set_speed) (struct tObj *, int, int);
- } OBJECT, *POBJECT;
- //}
- //}
- //{ Keyboard Handler
- unsigned char keyb(void){
- unsigned char key[]={1,2,3,0xA,4,5,6,0xB,7,8,9,0xC,0xE,0,0xF,0xD};
- int row, col;
- for (row=1; row <=4 ; row++ ) {
- kbdActivate( row );
- if( (col = kbdGetCol () ) )
- {
- kbdActivate( 0 );
- return key [4*(row-1)+(col-1) ];
- }
- }
- kbdActivate( 0 );
- return 0xFF;
- }
- int kbdGetCol ( void ){
- /* Om någon tangent (i aktiverad rad)
- * är nedtryckt, returnera dess kolumnnummer,
- * annars, returnera 0 */
- unsigned char c;
- c = *GPIO_D_IDRHIGH;
- if ( c & 0x8 ) return 4;
- if ( c & 0x4 ) return 3;
- if ( c & 0x2 ) return 2;
- if ( c & 0x1 ) return 1;
- return 0;
- }
- void kbdActivate(unsigned int row){
- switch(row)
- {
- case 1: *GPIO_D_ODRHIGH = 0x10; break;
- case 2: *GPIO_D_ODRHIGH = 0x20; break;
- case 3: *GPIO_D_ODRHIGH = 0x40; break;
- case 4: *GPIO_D_ODRHIGH = 0x80; break;
- case 0: *GPIO_D_ODRHIGH = 0x00; break;
- }
- }
- //}
- //{ Startups
- 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 */
- ) ;
- }
- //}
- //{ Delay
- void delay_250ns( void )
- {
- #ifdef SIMULATOR
- return;
- #endif
- /* SystemCoreClock = 168000000 */
- *STK_CTRL = 0;
- *STK_LOAD = ( (168/4) -1 );
- *STK_VAL = 0;
- *STK_CTRL = 5;
- while( (*STK_CTRL & 0x10000 )== 0 );
- *STK_CTRL = 0;
- }
- void delay_500ns( void )
- {
- #ifdef SIMULATOR
- return;
- #endif
- delay_250ns();
- delay_250ns();
- }
- void delay_micro(unsigned int us)
- {
- #ifdef SIMULATOR
- return;
- #endif
- #ifdef SIMULATOR
- us = us / 1000;//1000;
- us++;
- #endif
- while( us > 0 )
- {
- delay_250ns();
- delay_250ns();
- delay_250ns();
- delay_250ns();
- us--;
- }
- }
- void delay_milli(unsigned int ms)
- {
- #ifdef SIMULATOR
- return;
- #endif
- #ifdef SIMULATOR
- ms = ms / 1000;// 1000;
- ms++;
- #endif
- delay_micro(ms*1000);
- }
- //}
- //{ LCD
- void graphic_ctrl_bit_set(unsigned char x)
- {
- unsigned char c;
- c = *GPIO_E_ODRLOW;
- c |= x;
- c &= ~B_SELECT;
- *GPIO_E_ODRLOW = c;
- }
- void graphic_ctrl_bit_clear(unsigned char x)
- {
- unsigned char c;
- c=*GPIO_E_ODRLOW;
- c&=(~B_SELECT & ~x);
- *GPIO_E_ODRLOW = c;
- }
- void select_controller(unsigned char 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()
- {
- graphic_ctrl_bit_clear(B_E);
- *GPIO_E_MODER = 0x00005555;
- graphic_ctrl_bit_clear(B_RS);
- graphic_ctrl_bit_set(B_RW);
- delay_500ns();
- while(1)
- {
- graphic_ctrl_bit_set(B_E);
- delay_500ns();
- uint8_t c = *GPIO_E_IDRHIGH & LCD_BUSY;
- graphic_ctrl_bit_clear(B_E);
- delay_500ns();
- if(c == 0) //& LCD_BUSY)
- break;
- }
- *GPIO_E_MODER = 0x55555555;;
- }
- uint8_t graphic_read(unsigned char controller)
- {
- graphic_ctrl_bit_clear(B_E);
- *GPIO_E_MODER = 0x00005555;
- select_controller(controller);
- graphic_ctrl_bit_set(B_RS |B_RW);
- delay_500ns();
- graphic_ctrl_bit_set(B_E);
- delay_500ns();
- uint8_t rv = *GPIO_E_IDRHIGH;
- *GPIO_E_MODER = 0x55555555;
- if(controller == B_CS1)
- {
- select_controller(B_CS1);
- graphic_wait_ready();
- }
- if(controller == B_CS2)
- {
- select_controller(B_CS2);
- graphic_wait_ready();
- }
- return rv;
- }
- void graphic_write(unsigned char value, unsigned char controller)
- {
- *GPIO_E_ODRHIGH = value;
- select_controller(controller);
- delay_500ns();
- graphic_ctrl_bit_set(B_E);
- delay_500ns();
- graphic_ctrl_bit_clear(B_E);
- if(controller == B_CS1)
- {
- select_controller(B_CS1);
- graphic_wait_ready();
- }
- if(controller == B_CS2)
- {
- select_controller(B_CS2);
- graphic_wait_ready();
- }
- *GPIO_E_ODRHIGH = 0;
- graphic_ctrl_bit_set(B_E);
- select_controller(0);
- }
- void graphic_write_command(unsigned char command,unsigned char controller)
- {
- graphic_ctrl_bit_clear(B_E);
- select_controller(controller);
- graphic_ctrl_bit_clear(B_RW);
- graphic_ctrl_bit_clear(B_RS);
- graphic_write(command,controller);
- }
- void graphic_write_data(unsigned char data,unsigned char controller)
- {
- graphic_ctrl_bit_clear(B_E);
- select_controller(controller);
- graphic_ctrl_bit_clear(B_RW);
- graphic_ctrl_bit_set(B_RS);
- graphic_write(data,controller);
- }
- unsigned char graphic_read_data(unsigned char controller)
- {
- (void) graphic_read(controller); /* returnerar nonses */
- return graphic_read(controller); // returnerar det riktiga värdet
- }
- void graphic_init()
- {
- graphic_ctrl_bit_set(B_E);
- delay_micro(10);
- graphic_ctrl_bit_clear(B_CS1 | B_CS2 | B_RST | B_E);
- delay_milli(30);
- graphic_ctrl_bit_set(B_RST);
- 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); //deatktiverar båda cs signalerna
- }
- void graphic_clear_screen()
- {
- for(int i = 0; i <= 7; i ++)
- {
- graphic_write_command(LCD_SET_PAGE|i, B_CS1|B_CS2);
- graphic_write_command(LCD_SET_ADD| 0, B_CS1|B_CS2);
- for(int y = 0; y<= 63; y++)
- {
- graphic_write_data(0, B_CS1|B_CS2);
- }
- }
- }
- /* Display methods */
- void pixel(unsigned x, unsigned y, unsigned set)
- {
- if(x < 1 || x > 128 || y < 1 || y > 64) return 0;
- uint8_t mask,c,index,controller;
- index = (y-1)/8;
- switch((y-1)%8)
- {
- case 0:mask = 1;break;
- case 1:mask = 2;break;
- case 2:mask = 4;break;
- case 3:mask = 8;break;
- case 4:mask = 0x10;break;
- case 5:mask = 0x20;break;
- case 6:mask = 0x40;break;
- case 7:mask = 0x80;break;
- }
- if(!set)
- mask = ~mask;
- /* bestäm de fysiska kordinaterna och välj styrkrets */
- if(x > 64){
- controller = B_CS2;
- x = x-65;
- }
- else{
- controller = B_CS1;
- x = x-1;
- }
- graphic_write_command(LCD_SET_ADD| x,controller);
- graphic_write_command(LCD_SET_PAGE| index,controller);
- c = graphic_read_data(controller);
- graphic_write_command(LCD_SET_ADD| x,controller);
- if(set ==1)
- mask |= c;
- else
- mask &= c;
- graphic_write_data(mask,controller);
- }
- //} LCD END
- //{ ASCII
- void ascii_ctrl_bit_set( unsigned char x )
- {
- unsigned char c;
- c = *GPIO_E_ODRLOW;
- c |= ( B_SELECT | x );
- *GPIO_E_ODRLOW = c;
- }
- void ascii_ctrl_bit_clear( unsigned char x )
- {
- unsigned char c;
- c = *GPIO_E_ODRLOW;
- c &= ( B_SELECT | ~x );
- *GPIO_E_ODRLOW = c;
- }
- void ascii_write_controller( unsigned char c )
- {
- ascii_ctrl_bit_set( B_E );
- *GPIO_E_ODRHIGH = c;
- delay_250ns();
- ascii_ctrl_bit_clear( B_E );
- }
- unsigned char ascii_read_controller( void )
- {
- unsigned char c;
- ascii_ctrl_bit_set( B_E );
- delay_250ns();
- delay_250ns();
- c = *GPIO_E_IDRHIGH;
- ascii_ctrl_bit_clear( B_E );
- return c;
- }
- unsigned char ascii_read_status()
- {
- unsigned char c;
- *GPIO_E_MODER = 0x00005555;
- ascii_ctrl_bit_set( B_RW );
- ascii_ctrl_bit_clear( B_RS );
- c = ascii_read_controller( );
- *GPIO_E_MODER = 0x55555555;
- return c;
- }
- unsigned char ascii_read_data()
- {
- unsigned char c;
- *GPIO_E_MODER = 0x00005555;
- ascii_ctrl_bit_set( B_RW );
- ascii_ctrl_bit_set( B_RS );
- c = ascii_read_controller();
- *GPIO_E_MODER = 0x55555555;
- return c;
- }
- void ascii_write_cmd(unsigned char command)
- {
- ascii_ctrl_bit_clear(B_RS);
- ascii_ctrl_bit_clear(B_RW);
- ascii_write_controller(command);
- }
- void ascii_write_data(unsigned char data)
- {
- ascii_ctrl_bit_set(B_RS);
- ascii_ctrl_bit_clear(B_RW);
- ascii_write_controller(data);
- }
- void ascii_init()
- {
- //set reader och tecken storlek
- while((ascii_read_status() & 0x80) == 0x80);
- //tänd display, markör och konstant visning
- delay_micro(8);
- ascii_write_cmd(0x38);
- delay_micro(40);
- while((ascii_read_status() & 0x80) == 0x80);
- delay_micro(8);
- ascii_write_cmd(0xC);
- delay_micro(40);
- //clear display
- while((ascii_read_status() & 0x80) == 0x80);
- delay_micro(8);
- ascii_write_cmd(1);
- delay_milli(2);
- //adressing med increment
- while((ascii_read_status() & 0x80) == 0x80);
- delay_micro(8);
- ascii_write_cmd(0x6);
- delay_micro(40);
- }
- void ascii_write_char(unsigned char c)
- {
- while((ascii_read_status() & 0x80) == 0x80)
- {}
- delay_micro(8);
- ascii_write_data(c);
- delay_micro(43);
- }
- void ascii_gotoxy(int x,int y)
- {
- char c = x-1;
- if(y == 2)
- {
- c = c + 0x40;
- }
- ascii_write_cmd(0x80 | c);
- }
- //} Ascii end
- //{ Objects
- GEOMETRY ball_geometry =
- {
- 12, /* numpoints */
- 4,4, /* sizex, sizey */
- {/* px[0,1,2 ...] */
- {0,1},{0,2},{1,0}, {1,1}, {1,2},
- {1,3},{2,0},{2,1},{2,2},{2,3},
- {3,2}
- }
- };
- GEOMETRY paddle_geometry =
- {
- 18, /* numpoints */
- 2,9, /* sizex, sizey */
- {/* px[0,1,2 ...] */
- {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},
- {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8}
- }
- };
- void move_paddle(POBJECT o, POBJECT pl, POBJECT pr)
- {
- o->clear(o);
- o->posy += o->diry;
- if(o->posy < 1) //påväg ovanför skärmen
- o->diry = 0;
- if((o->posy+o->geo->sizey)>64)
- o->diry = 0;
- o->draw(o);
- }
- void move_ball(POBJECT o, POBJECT pl, POBJECT pr)
- {
- o->clear(o);
- o->posx += o->dirx;
- o->posy += o->diry;
- //kollar kanterna
- if(o->posx < 1) //objektet är påväg ut vänster kanten
- o->dirx *= -1;
- if((o->posx+o->geo->sizex) > 128)//påväg ut ur höger kanten, det är objektets pos + obj storlek
- o->dirx *= -1;
- if(o->posy < 1) //påväg ovanför skärmen
- o->diry*=-1;
- if((o->posy+o->geo->sizey)>64)
- o->diry*=-1;
- //testa vänster paddeln
- if(o->posx <= (pl->posx+pl->geo->sizex) && (o->posy +o->geo->sizey) >= pl->posy && (pl->posy + pl->geo->sizey) >= o->posy)
- {
- o->dirx*=-1;
- }
- //testa höger paddeln
- if((o->posx+o->geo->sizex) >= pr->posx && (o->posy+o->geo->sizey) >= pr->posy && o->posy < (pr->posy+pr->geo->sizey))
- {
- o->dirx*=-1;
- }
- o->draw(o);
- }
- void set_object_speed(POBJECT o, int speedx, int speedy)
- {
- o->dirx = speedx;
- o->diry = speedy;
- }
- void draw_object(POBJECT o)
- {
- int pixels = o->geo->numPoints;
- int posx = o->posx;
- int posy = o->posy;
- for(int i = 0; i <pixels; i++)
- {
- POINT p = o->geo->px[i];
- pixel((posx + p.x), posy +p.y,1);
- }
- }
- void clear_object(POBJECT o)
- {
- int pixels = o->geo->numPoints;
- int posx = o->posx;
- int posy = o->posy;
- for(int i = 0; i <pixels; i++)
- {
- pixel((posx + o->geo->px[i].x), posy + o->geo->px[i].y,0);
- }
- }
- static OBJECT ball =
- {
- &ball_geometry,
- 1,1,
- 64,32,
- draw_object,
- clear_object,
- move_ball,
- set_object_speed
- };
- static OBJECT padL =
- {
- &paddle_geometry,
- 0,0,
- 10,10,
- draw_object,
- clear_object,
- move_paddle,
- set_object_speed
- };
- static OBJECT padR =
- {
- &paddle_geometry,
- 0,0,
- 118,10,
- draw_object,
- clear_object,
- move_paddle,
- set_object_speed
- };
- //} Objects end
- //{ Collision Handler
- void setPaddleSpeed(POBJECT pd,int dir)
- {
- if(pd->posy > 1 && (pd->posy + pd->geo->sizey) < 63 )
- pd->set_speed(pd,0,dir);
- else if(pd->posy < 1 && dir < 0)
- pd->set_speed(pd,0,0);
- else if(pd->posy < 1 && dir > 0)
- pd->set_speed(pd,0,dir);
- else if(pd->posy+pd->geo->sizey >= 63 && dir > 0)
- pd->set_speed(pd,0,0);
- else if(pd->posy+pd->geo->sizey >= 63 && dir < 0)
- pd->set_speed(pd,0,dir);
- }
- //}
- void print_winner(int winner)
- {
- char *s;
- char test2[]="2k19";
- ascii_gotoxy(1,1);
- if(winner){ //höger vinner
- char test1[] ="Player 2 wins!";
- s=test1;
- while(*s){
- ascii_write_char(*s++);
- }
- }
- else{ //vänster vinner
- char test1[] ="Player 1 wins!";
- s=test1;
- while(*s){
- ascii_write_char(*s++);
- }
- }
- ascii_gotoxy(1,2);
- s=test2;
- while(*s){
- ascii_write_char(*s++);
- }
- }
- void app_init(){
- *((unsigned long*) 0x40023830) = 0x18;
- *((unsigned long*) 0x40023844) |= 0x4000;
- *((unsigned long*) 0xE000ED08) = 0x2001C000;
- *GPIO_D_MODER = 0x55005555;
- *GPIO_E_MODER = 0x55555555;
- *GPIO_D_OTYPER &= 0x00FF;
- *GPIO_D_OTYPER |= 0x0000;
- *GPIO_D_PUPDR &= 0x0000FFFF;
- *GPIO_D_PUPDR |= 0X55AA0000;
- }
- void main(void)
- {
- char c,d;
- int i = 0;
- POBJECT p = &ball;
- POBJECT pl = &padL;
- POBJECT pr = &padR;
- app_init();
- ascii_init();
- graphic_init();
- #ifndef SIMULATOR
- graphic_clear_screen();
- #endif
- while(1)
- {
- pl->diry = 0;
- pr->diry = 0;
- delay_milli(40);
- c = keyb();
- switch(c)
- {
- case 1: setPaddleSpeed(pl,-2);break;
- case 7: setPaddleSpeed(pl,2);break;
- case 3: setPaddleSpeed(pr,-2);break;
- case 9: setPaddleSpeed(pr,2);break;
- }
- pl->move(pl,pl,pl);
- pr->move(pr,pr,pr);
- p->move(p,pl,pr);
- if(p->posx < 1){ //objektet är påväg ut vänster kanten
- print_winner(1);
- p->posy = 32;
- p->posx = 64;
- p->dirx = p->dirx *2;
- p->diry = p->diry *2;
- }
- if((p->posx+p->geo->sizex) > 128){//påväg ut ur höger kanten, det är objektets pos + obj storlek
- print_winner(0);
- p->posy = 32;
- p->posx = 64;
- p->dirx = p->dirx *2;
- p->diry = p->diry *2;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement