Pre episode review
Single chip microcomputer HLK-W801 transplanted Nes simulator (I)
I've finished the transplantation of the program. Today, I'll try the key operation. At least I can jump and eat a mushroom
Key recognition
For the identification of keys on w801, I use an omni-directional key keyboard I used before,
The keys are collected through GPIO. In order to eliminate jitter, the mode of interrupt timer cyclic scanning is adopted. It is considered to be pressed after 8 times of continuous scanning to high level.
Method reference from blog "#51 single chip microcomputer # interrupt to realize key shaking elimination"
First define the macro
#define GPIO_UP WM_IO_PA_01 #define GPIO_DOWN WM_IO_PA_02 #define GPIO_LFT WM_IO_PA_08 #define GPIO_RHT WM_IO_PA_04 #define GPIO_START WM_IO_PA_05 #define GPIO_A WM_IO_PA_06 #define GPIO_B WM_IO_PA_07
Then register GPIO,
#ifdef GPIO_UP tls_gpio_cfg(GPIO_UP, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING); #endif #ifdef GPIO_DOWN tls_gpio_cfg(GPIO_DOWN, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING); #endif ...... #ifdef GPIO_B tls_gpio_cfg(GPIO_B, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING); #endif
Then define a timer to scan the keys every 2 milliseconds
void timer_demo(void) { u8 timer_id; struct tls_timer_cfg timer_cfg; timer_cfg.unit = TLS_TIMER_UNIT_MS; timer_cfg.timeout = 2; timer_cfg.is_repeat = 1; timer_cfg.callback = (tls_timer_irq_callback)demo_timer_irq; timer_cfg.arg = NULL; timer_id = tls_timer_create(&timer_cfg); tls_timer_start(timer_id); printf("timer start\n"); }
Finally, the circular scanning interrupt function is realized. Here, only one key is written as an example
static void demo_timer_irq(u8 *arg) { #ifdef GPIO_UP { static unsigned char keybuf_UP = 0XFF; //Scan buffer to save the scan value for a period of time. u8 KEY_UP; KEY_UP=tls_gpio_read(GPIO_UP); keybuf_UP = (keybuf_UP<<1)|KEY_UP; //Shift the buffer one bit to the left and move the current scan value to the lowest bit. if(keybuf_UP == 0X00) { //If the value of 8 consecutive scans is 0, that is, only the pressed state is detected within 16ms, it can be considered that the key has been pressed. up_key = 0; } else if(keybuf_UP == 0XFF) { //If the value of 8 consecutive scans is 1, that is, only the pop-up state is detected within 16ms, it can be considered that the key has popped up. up_key = 1; } } #endif }
Finally, through the variable up_key, notify the simulator. The simulator circularly scans the key changes through the following functions
void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
The three parameters are 1P,2P and on / off button respectively. The default comment is
//The handle control definition is represented by a DWORD type data, and the definitions of handle 1 and handle 2 are the same // case Key_Right: // pdwPad1 |= (1<<7); The seventh digit indicates right // break; // case Key_Left: // *pdwPad1 |= (1<<6); The sixth digit indicates left // break; // case Key_Down: // *pdwPad1 |= (1<<5); The fifth digit indicates next // break; // case Key_Up: // *pdwPad1 |= (1<<4); The fourth digit means up // break; // case Key_S: // *pdwPad1 |= (1<<3); The third digit indicates Start // break; // case Key_A: // *pdwPad1 |= (1<<2); A key // break; // case Key_Z: // *pdwPad1 |= (1<<1); Z key // break; // case Key_X: // *pdwPad1 |= (1<<0); X key
Here is the above key as an example
#define PAD_JOY_UP 0x10
*pdwPad1 = 0; #ifdef GPIO_UP if(up_key) { *pdwPad1 |= PAD_JOY_UP; printf("up\n"); } #endif
Super Mary this game, add the left and right start and A key, you can play it without acceleration. After adding, show the effect
Although it is too laggy, and the color is not right, it is the first step.
Color problem
It is estimated that when writing SPI, the color of the point is related to the byte order. The guess is correct. After reversing the order, the color is much more pure
void ILI9341_DrawLineOne(u16 y,u16* data) { int i=0; u16* dat=data; ILI9341_Address_Set(0,y,240,y);//Set cursor position GPIO_DATA();//Write data for(i=0;i<240;i++) { uint8_t data[2]; data[0] = (*dat)>>8; data[1] = (*dat); tls_spi_write((uint8_t *)data,2); dat++; } }
But the subsequent rate is slower... Because every time you draw a point, you need to calculate and reverse the data, and then write the SPI.
But I got another idea right away,
If it wants to display AB;
I made a mistake and displayed AB as BA;
So when I ask nes to calculate the point, I also make a mistake. If it wants AB, I'll give it BA, add error to error
So when I draw BA, I will draw AB, so
The purpose of drawing AB is achieved!!!
This is called negative positive!!!
The results really showed normal.
The modification method is to change SPI back to the original and write a line directly
void ILI9341_DrawLineOne(u16 y,u16* data) { int i=0; ILI9341_Address_Set(0,y,240,y);//Set cursor position GPIO_DATA();//Write data tls_spi_write((uint8_t *)data,480); }
Then switch the high and low positions of the palette
/*-------------------------------------------------------------------*/ /* Palette data */ /*-------------------------------------------------------------------*/ WORD NesPalette[64]={ #if 0 0x738E,0x20D1,0x0015,0x4013,0x880E,0xA802,0xA000,0x7840, 0x4140,0x0200,0x0280,0x01C2,0x19CB,0x0000,0x0000,0x0000, 0xBDD7,0x039D,0x21DD,0x801E,0xB817,0xE00B,0xD940,0xCA41, 0x8B80,0x0480,0x0540,0x0487,0x0411,0x0000,0x0000,0x0000, 0xFFDF,0x3DDF,0x5C9F,0x445F,0xF3DF,0xFB96,0xFB8C,0xFCC7, 0xF5C7,0x8682,0x4EC9,0x5FD3,0x075B,0x0000,0x0000,0x0000, 0xFFDF,0xAF1F,0xC69F,0xD65F,0xFE1F,0xFE1B,0xFDD6,0xFED5, 0xFF14,0xE7D4,0xAF97,0xB7D9,0x9FDE,0x0000,0x0000,0x0000, #else 0x8E73,0xD120,0x1500,0x1340,0x0E88,0x02A8,0x00A0,0x4078, 0x4041,0x0002,0x8002,0xC201,0xCB19,0x0000,0x0000,0x0000, 0xD7BD,0x9D03,0xDD21,0x1E80,0x17B8,0x0BE0,0x40D9,0x41CA, 0x808B,0x8004,0x4005,0x8704,0x1104,0x0000,0x0000,0x0000, 0xDFFF,0xDF3D,0x9F5C,0x5F44,0xDFF3,0x96FB,0x8CFB,0xC7FC, 0xC7F5,0x8286,0xC94E,0xD35F,0x5B07,0x0000,0x0000,0x0000, 0xDFFF,0x1FAF,0x9FC6,0x5FD6,0x1FFE,0x1BFE,0xD6FD,0xD5FE, 0x14FF,0xD4E7,0x97AF,0xD9B7,0xDE9F,0x0000,0x0000,0x0000, #endif };
I'm a genius
Refresh rate
This is still under study
Concluding remarks
On the last day of work years ago, I didn't have any desire for a holiday. I heard that the leader and pressed the North nose divorced. Maybe someone persuaded one of them not to divorce and keep it for the new year? I hope you don't have to go to the hot search because of your family property. You've seen enough of these people.