Advertisement
Guest User

Untitled

a guest
May 24th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.05 KB | None | 0 0
  1. #include <stdio.h>
  2. #include "NUC100Series.h"
  3. #include "MCU_init.h"
  4. #include "SYS_init.h"
  5. #include "LCD.h"
  6. #include "Draw2D.h"
  7. #include "picture.h"
  8. #define SYSTICK_DLAY_us 1000000
  9. #define Xmax 128
  10. #define Ymax 64
  11. #define Xmin 1
  12. #define Ymin 1
  13.  
  14. #define BLOCK_HEIGHT 6
  15. #define BLOCK_WIDTH 6
  16. #define GOAL 20
  17.  
  18. //------------------------------------------------------------------------------------------------------------------------------------
  19. // Functions declaration
  20. //------------------------------------------------------------------------------------------------------------------------------------
  21. void System_Config(void);
  22. void SPI3_Config(void);
  23. void LCD_start(void);
  24. void LCD_command(unsigned char temp);
  25. void LCD_data(unsigned char temp);
  26. void LCD_clear(void);
  27. void LCD_SetAddress(uint8_t PageAddr, uint8_t ColumnAddr);
  28. void KeyPadEnable(void);
  29. uint8_t KeyPadScanning(void);
  30.  
  31. uint8_t collision(uint8_t x, uint8_t y, uint8_t tx, uint8_t ty);
  32. uint8_t rand(uint8_t axis, uint8_t current);
  33. void addLast(uint8_t x, uint8_t y);
  34. void shift(uint8_t nx, uint8_t ny);
  35.  
  36. //------------------------------------------------------------------------------------------------------------------------------------
  37. // Main program
  38. //------------------------------------------------------------------------------------------------------------------------------------
  39. typedef enum {welcome_screen, game_rules, game_background, main_game, end_game} STATES;
  40.  
  41. typedef struct {
  42.         uint8_t x, y;
  43. } Coordinate;
  44.  
  45. Coordinate coords[GOAL];                //global snake coords
  46. uint8_t ate = 0, size = 1;
  47.  
  48. int main(void)
  49. {
  50.     STATES game_state;
  51.     uint8_t i, key_pressed=0, game_pad=0;
  52.     uint8_t x=64, y=32, dx=0, dy=0;
  53.     uint8_t x_steps, y_steps;
  54.     uint8_t x_reset, y_reset;
  55.     char score_txt[]="0";
  56.    
  57.     uint8_t tx = 8, ty = 8;                 //target
  58.     uint8_t nx, ny;
  59.     uint8_t reset_counter;
  60.  
  61.     //--------------------------------
  62.     //System initialization
  63.     //--------------------------------
  64.     System_Config();
  65.     KeyPadEnable();
  66.  
  67.     //--------------------------------
  68.     //SPI3 initialization
  69.     //--------------------------------
  70.     SPI3_Config();
  71.     //--------------------------------
  72.     //LCD initialization
  73.     //--------------------------------
  74.     LCD_start();
  75.     LCD_clear();
  76.     //--------------------------------
  77.     //LCD static content
  78.     //--------------------------------
  79.  
  80.     //--------------------------------
  81.     //LCD dynamic content
  82.     //--------------------------------
  83.     game_state = welcome_screen;
  84.     x_steps = 2; y_steps = 2;//x_steps = BLOCK_WIDTH; y_steps = BLOCK_HEIGHT;
  85.     x_reset = 64; y_reset = 32;
  86.    
  87.     //initially map all coords to (-1,-1) and dx,dy to (0,0);
  88.     for (i=0; i<GOAL; i++) {
  89.         coords[i].x = -BLOCK_WIDTH;     //makes it hidden outside of viewport
  90.         coords[i].y = -BLOCK_HEIGHT;
  91.     }
  92.  
  93.     while (1) {
  94.         switch(game_state){
  95.             case welcome_screen:
  96.                 //welcome state code here
  97.                 draw_LCD(monster_128x64);
  98.                 for (i=0;i<3;i++) CLK_SysTickDelay(SYSTICK_DLAY_us);
  99.                 LCD_clear();
  100.                
  101.                 game_state = game_rules; // state transition
  102.                 break;
  103.  
  104.             case game_rules:
  105.                 // game_rules state code here
  106.                 printS_5x7(1, 0, "Use Keypad to control");
  107.                 printS_5x7(1, 8, "2: UP 4: LEFT");
  108.                 printS_5x7(1, 16, "6: RIGHT 8: DOWN");
  109.                 printS_5x7(1, 32, "Eat all boxes to win");
  110.                 printS_5x7(1, 39, "press any key to continue!");
  111.  
  112.                 while(key_pressed==0) key_pressed = KeyPadScanning();
  113.                 key_pressed=0;
  114.                 LCD_clear();
  115.                 game_state = game_background;
  116.             break;
  117.  
  118.             case game_background:
  119.                 // static display information should be here
  120.                 sprintf(score_txt, "%d", ate);
  121.                 printS_5x7(48, 0, score_txt);
  122.                 fill_Rectangle(tx, ty, tx+BLOCK_WIDTH, ty+BLOCK_HEIGHT, 1, 0);
  123.                 game_state = main_game;
  124.  
  125.             case main_game:
  126.                 //main_game state code here
  127.                
  128.                 //display snake
  129.                 for (i=0; i<size; i++) {
  130.                         fill_Rectangle(coords[i].x, coords[i].y, coords[i].x+BLOCK_WIDTH, coords[i].y+BLOCK_HEIGHT, 1, 0); 
  131.                         /*
  132.                         if (collision(x, y, coords[i].x, coords[i].y))  { //steppped on ourselves
  133.                                 ate = 0;       
  134.                                 size = 1;       // start again with 1 block
  135.                         }
  136.                         */
  137.                 }
  138.            
  139.                 game_pad = KeyPadScanning();       
  140.                 CLK_SysTickDelay(170000);  //delay for vision
  141.                
  142.                 //hide snake
  143.                 for (i=0; i<size; i++)
  144.                         fill_Rectangle(coords[i].x, coords[i].y, coords[i].x+BLOCK_WIDTH, coords[i].y+BLOCK_HEIGHT, 0, 0); 
  145.                
  146.                 //check changes
  147.                 switch(game_pad) {
  148.                     case 1:
  149.                         dx =-1; dy =-1;
  150.                         break;
  151.                     case 2:
  152.                         dx = 0; dy = -1;
  153.                         break;
  154.                     case 3:
  155.                         dx = +1; dy =-1;
  156.                         break;
  157.                     case 4:
  158.                         dx = -1; dy = 0;
  159.                         break;
  160.                     case 5:
  161.                         dx = dy = 0;
  162.                         reset_counter++;
  163.                         if (reset_counter >= 5)
  164.                             game_state = end_game;
  165.                         break;
  166.                     case 6:
  167.                         dx = +1; dy = 0;
  168.                         break;
  169.                     case 7:
  170.                         dx = -1; dy= +1;
  171.                         break;
  172.                     case 8:
  173.                         dx = 0; dy= +1;
  174.                         break;
  175.                     case 9:
  176.                         dx=+1; dy=+1;
  177.                         break;
  178.                     default:
  179.                         reset_counter = 0;
  180.                         break;
  181.                 }
  182.                 game_pad = 0;
  183.                
  184.                 //update object’s information (position, etc.)
  185.                 nx = x + dx * x_steps;
  186.                 ny = y + dy * y_steps;
  187.                
  188.                 //update head
  189.                 shift(x,y);
  190.                
  191.                 //boundary condition
  192.                 //wrap around on X
  193.                 if (x<=Xmin)
  194.                     nx=Xmax-BLOCK_WIDTH-1;
  195.  
  196.                 if (x>Xmax-BLOCK_WIDTH-1)
  197.                     nx=Xmin;
  198.                 //wrap around on Y
  199.                 if (y<=Ymin)
  200.                     ny=Ymax-BLOCK_HEIGHT-1;
  201.  
  202.                 if (y>Ymax-BLOCK_HEIGHT-1)
  203.                     ny=Ymin;
  204.    
  205.                 //if eats target block
  206.                 if (collision(nx,ny,tx,ty)) {      
  207.                     //erase target
  208.                     fill_Rectangle(tx, ty, tx+BLOCK_WIDTH, ty+BLOCK_HEIGHT, 0, 0); 
  209.                    
  210.                     //increase snake size
  211.                     size++; ate++;          //increase before
  212.                     nx = x+dx*BLOCK_WIDTH;
  213.                     ny = y+dy*BLOCK_HEIGHT;
  214.                     shift(nx,ny);
  215.                    
  216.                     //generate new target
  217.                     tx = rand(1, nx);
  218.                     ty = rand(0, ny);
  219.                 }
  220.  
  221.                 //update pos
  222.                 x = nx;
  223.                 y = ny;
  224.                
  225.                 if (ate > GOAL) {
  226.                     ate = 0;
  227.                     LCD_clear();
  228.                     game_state = end_game;
  229.                 } else
  230.                     game_state = game_background;
  231.                 break;
  232.  
  233.             case end_game:      //end_game code here
  234.                 printS_5x7(1, 25, "       Good Job !");
  235.                 printS_5x7(1, 32, "press any key to replay!");
  236.  
  237.                 for (i=0;i<2;i++)
  238.                     CLK_SysTickDelay(SYSTICK_DLAY_us);
  239.                 while(key_pressed==0)
  240.                     key_pressed = KeyPadScanning();
  241.                 key_pressed=0;
  242.                 LCD_clear();
  243.                 game_state = welcome_screen;
  244.                 break;
  245.  
  246.             default:
  247.                 break;
  248.         }
  249.     }
  250. }
  251.  
  252. //  i           0 1 2 3 4
  253. //  arr[i]  2 3 4 5 6
  254. //  shifted ? 2 3 4 5 (6)
  255.  
  256. void shift(uint8_t x, uint8_t y) {
  257.         uint8_t i;
  258.         for(i=1; i<GOAL; i++)
  259.                 coords[i] = coords[i-1];
  260.         coords[0].x = x;
  261.         coords[0].y = y;
  262. }
  263.  
  264. void addLast(uint8_t x, uint8_t y) {
  265.         if (size+1 < GOAL) {
  266.                 coords[size+1].x = x;
  267.                 coords[size+1].y = y;
  268.         }
  269. }
  270.  
  271. // Uses bounding boxes collision detection algorithm
  272. uint8_t collision(uint8_t x, uint8_t y, uint8_t tx, uint8_t ty) {
  273.         //should these be eval'd with |abs| ?
  274.         return ((x+BLOCK_WIDTH >= tx) &&    // tx-x <= BW  <=>  x+BW >= tx
  275.                     (x <= tx+BLOCK_WIDTH) &&       
  276.                     (y+BLOCK_HEIGHT >= ty) &&
  277.                     (y <= ty+BLOCK_HEIGHT));   
  278. }
  279.  
  280. uint8_t rand(uint8_t axis, uint8_t current) {
  281.         if (axis)   //default is x
  282.                 return (current + 4*BLOCK_WIDTH) % (Xmax - BLOCK_WIDTH);    //stay far from borders cause collision fails ?
  283.         else
  284.                 return (current + 2*BLOCK_HEIGHT) % (Ymax - BLOCK_HEIGHT);
  285. }
  286.  
  287. //------------------------------------------------------------------------------------------------------------------------------------
  288. // Functions definition
  289. //------------------------------------------------------------------------------------------------------------------------------------
  290. void LCD_start(void)
  291. {
  292. LCD_command(0xE2); // Set system reset
  293. LCD_command(0xA1); // Set Frame rate 100 fps
  294. LCD_command(0xEB); // Set LCD bias ratio E8~EB for 6~9 (min~max)
  295. LCD_command(0x81); // Set V BIAS potentiometer
  296. LCD_command(0xA0); // Set V BIAS potentiometer: A0 ()
  297. LCD_command(0xC0);
  298. LCD_command(0xAF); // Set Display Enable
  299. }
  300. void LCD_command(unsigned char temp)
  301. {
  302. SPI3->SSR |= 1ul << 0;
  303. SPI3->TX[0] = temp;
  304. SPI3->CNTRL |= 1ul << 0;
  305. while(SPI3->CNTRL & (1ul << 0));
  306. SPI3->SSR &= ~(1ul << 0);
  307. }
  308. void LCD_data(unsigned char temp)
  309. {
  310. SPI3->SSR |= 1ul << 0;
  311. SPI3->TX[0] = 0x0100+temp;
  312. SPI3->CNTRL |= 1ul << 0;
  313. while(SPI3->CNTRL & (1ul << 0));
  314. SPI3->SSR &= ~(1ul << 0);
  315. }
  316. void LCD_clear(void)
  317. {
  318. int16_t i;
  319. LCD_SetAddress(0x0, 0x0);
  320.  
  321. for (i = 0; i < 132 *8; i++)
  322. {
  323. LCD_data(0x00);
  324. }
  325.  
  326.  
  327.  
  328. }
  329. void LCD_SetAddress(uint8_t PageAddr, uint8_t ColumnAddr) {
  330. LCD_command(0xB0 | PageAddr);
  331. LCD_command(0x10 | (ColumnAddr>>4)&0xF);
  332. LCD_command(0x00 | (ColumnAddr & 0xF)); }
  333. void KeyPadEnable(void){
  334. GPIO_SetMode(PA, BIT0, GPIO_MODE_QUASI);
  335. GPIO_SetMode(PA, BIT1, GPIO_MODE_QUASI);
  336. GPIO_SetMode(PA, BIT2, GPIO_MODE_QUASI);
  337. GPIO_SetMode(PA, BIT3, GPIO_MODE_QUASI);
  338. GPIO_SetMode(PA, BIT4, GPIO_MODE_QUASI);
  339. GPIO_SetMode(PA, BIT5, GPIO_MODE_QUASI);
  340.  
  341. }
  342. uint8_t KeyPadScanning(void){
  343. PA0=1; PA1=1; PA2=0; PA3=1; PA4=1; PA5=1;
  344. if (PA3==0) return 1;
  345. if (PA4==0) return 4;
  346. if (PA5==0) return 7;
  347. PA0=1; PA1=0; PA2=1; PA3=1; PA4=1; PA5=1;
  348. if (PA3==0) return 2;
  349. if (PA4==0) return 5;
  350. if (PA5==0) return 8;
  351. PA0=0; PA1=1; PA2=1; PA3=1; PA4=1; PA5=1;
  352. if (PA3==0) return 3;
  353. if (PA4==0) return 6;
  354. if (PA5==0) return 9;
  355. return 0;
  356.  
  357. }
  358. void System_Config (void){
  359. SYS_UnlockReg(); // Unlock protected registers
  360. // Enable clock sources
  361. //LXT - External Low frequency Crystal 32 kHz
  362. CLK->PWRCON |= (0x01ul << 1);
  363. while(!(CLK->CLKSTATUS & (1ul << 1)));
  364. CLK->PWRCON |= (0x01ul << 0);
  365. while(!(CLK->CLKSTATUS & (1ul << 0)));
  366.  
  367. //PLL configuration starts
  368. CLK->PLLCON &= ~(1ul<<19); //0: PLL input is HXT
  369. CLK->PLLCON &= ~(1ul<<16); //PLL in normal mode
  370. CLK->PLLCON &= (~(0x01FFul << 0));
  371. CLK->PLLCON |= 48;
  372. CLK->PLLCON &= ~(1ul<<18); //0: enable PLLOUT
  373. while(!(CLK->CLKSTATUS & (0x01ul << 2)));
  374. //PLL configuration ends
  375.  
  376. //clock source selection
  377. CLK->CLKSEL0 &= (~(0x07ul << 0));
  378. CLK->CLKSEL0 |= (0x02ul << 0);
  379. //clock frequency division
  380. CLK->CLKDIV &= (~0x0Ful << 0);
  381.  
  382.  
  383.  
  384. //enable clock of SPI3
  385. CLK->APBCLK |= 1ul << 15;
  386.  
  387. SYS_LockReg(); // Lock protected registers
  388. }
  389.  
  390. void SPI3_Config (void){
  391. SYS->GPD_MFP |= 1ul << 11; //1: PD11 is configured for alternative function
  392. SYS->GPD_MFP |= 1ul << 9; //1: PD9 is configured for alternative function
  393. SYS->GPD_MFP |= 1ul << 8; //1: PD8 is configured for alternative function
  394.  
  395. SPI3->CNTRL &= ~(1ul << 23); //0: disable variable clock feature
  396. SPI3->CNTRL &= ~(1ul << 22); //0: disable two bits transfer mode
  397. SPI3->CNTRL &= ~(1ul << 18); //0: select Master mode
  398. SPI3->CNTRL &= ~(1ul << 17); //0: disable SPI interrupt
  399. SPI3->CNTRL |= 1ul << 11; //1: SPI clock idle high
  400. SPI3->CNTRL &= ~(1ul << 10); //0: MSB is sent first
  401. SPI3->CNTRL &= ~(3ul << 8); //00: one transmit/receive word will be executed in one data transfer
  402.  
  403. SPI3->CNTRL &= ~(31ul << 3); //Transmit/Receive bit length
  404. SPI3->CNTRL |= 9ul << 3; //9: 9 bits transmitted/received per data transfer
  405.  
  406. SPI3->CNTRL |= (1ul << 2); //1: Transmit at negative edge of SPI CLK
  407. SPI3->DIVIDER = 0; // SPI clock divider. SPI clock = HCLK / ((DIVIDER+1)*2). HCLK = 50 MHz
  408. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement