RG351P
修正STM32F103手柄吞鍵問題
參考資料:
1. PedalButtonController
2. pedal-button-controller
程式碼如下:
#include <linux/types.h> #include <linux/input.h> #include <linux/hidraw.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdint.h> #include <errno.h> #include <time.h> #include <sys/time.h> #include <SDL.h> #include <SDL_ttf.h> #include <SDL_image.h> #ifndef PC #include "hex_font.h" #endif #include "hex_splash.h" TTF_Font *font=NULL; SDL_Surface *real=NULL; SDL_Surface *screen=NULL; SDL_Surface *splash=NULL; uint8_t mycfg[] = { 0x04, 0x01, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x16, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x16, 0x16, 0x16, 0x00, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x32, 0x04, 0x05, 0x04, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x78, 0xf9, 0x8c, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x7f, 0x38, 0xd8, 0xf4, 0x58, 0xf9, 0x74, 0x00, 0xb2, 0x15, 0x01, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x50, 0xf9, 0x74, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x69, 0x00, 0x2d, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x04, 0x04, 0x00, 0x01, 0x7f, 0x00, 0x6e, 0x00, 0x2d, 0x00, 0x73, 0x00, 0x68, 0x00, 0x01, 0x7f, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x2d, 0x00, 0x6f, 0x01, 0x7f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x01, 0x7f, 0x65, 0x00, 0x2d, 0x00, 0x6c, 0x00, 0x31, 0x00, 0x2d, 0x01, 0x7f, 0x00, 0x2d, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x64, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x05, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xee, 0xed, 0xec, 0xeb, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0x74, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x40, 0xcd, 0x8b, 0x77, 0xd0, 0x38, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xd2, 0x8b, 0x77, 0xed, 0x3a, 0xd8, 0xf4, 0x00, 0x00, 0x8c, 0x00, 0x04, 0x06, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xff, 0xff, 0x30, 0xfa, 0x74, 0x00, 0x2b, 0x17, 0x8b, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xfa, 0x74, 0x00, 0x04, 0x07, 0x00, 0x00, 0xd0, 0x01, 0xa0, 0x03, 0x50, 0x05, 0x20, 0x07, 0xc0, 0x08, 0xa0, 0x0a, 0x40, 0x0c, 0x40, 0x0e, 0xff, 0x0f, 0x00, 0x00, 0x80, 0x05, 0xc0, 0x09, 0x40, 0x0c, 0x10, 0x0e, 0x10, 0x0f, 0x80, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x30, 0x01, 0x70, 0x02, 0x40, 0x04, 0x60, 0x08, 0xff, 0x0f, 0xb0, 0x75, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xa0, 0x01, 0xb0, 0x04, 0x70, 0x0b, 0x40, 0x0e, 0xb0, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x00, 0x00, 0x40, 0x04, 0x50, 0x06, 0x80, 0x07, 0xc0, 0x07, 0xf0, 0x07, 0x60, 0x08, 0x60, 0x09, 0xd0, 0x0b, 0xff, 0x0f, 0xff, 0x0f, 0x40, 0x0e, 0x40, 0x0c, 0xa0, 0x0a, 0xc0, 0x08, 0x20, 0x07, 0x50, 0x05, 0xa0, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x00, 0x00, 0x00, 0x00, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x31, 0x00, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x32, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x31, 0x00, 0x00, 0x00, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x32, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, }; int upgrade(void) { char buf[255]={0}; struct hidraw_devinfo info={0}; struct hidraw_report_descriptor rpt_desc={0}; int fd=-1, x=0, r=0, desc_size=0, err_cnt=0; fd = open("/dev/hidraw0", O_RDWR | O_NONBLOCK); if(fd < 0){ printf("failed to open device\n"); return -1; } ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); rpt_desc.size = desc_size; ioctl(fd, HIDIOCGRDESC, &rpt_desc); ioctl(fd, HIDIOCGRAWNAME(sizeof(buf)), buf); if(strcmp(buf, "OpenSimHardware OSH PB Controller") != 0){ printf("failed to open rg351p device\n"); close(fd); return -1; } ioctl(fd, HIDIOCGRAWPHYS(sizeof(buf)), buf); ioctl(fd, HIDIOCGRAWINFO, &info); buf[0] = 0x9; buf[1] = 0xff; buf[2] = 0xff; buf[3] = 0xff; ioctl(fd, HIDIOCSFEATURE(4), buf); buf[0] = 0x9; ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf); err_cnt = 0; for(x=0; x<9; x++){ mycfg[64 * x] = 2; r = write(fd, &mycfg[64 * x], 64); if(r < 0){ err_cnt+=1; } printf("wrote: %d\n", r); usleep(100000); } close(fd); return err_cnt; } void flip_screen(void) { int x=0, y=0; uint16_t *s = screen->pixels; uint16_t *d = real->pixels; for(y=0; y<320; y++){ for(x=0; x<480; x++){ d[y+((480-x)*320)] = s[x + (y*480)]; } } SDL_Flip(real); } void text(char *msg, uint8_t r, uint8_t g, uint8_t b) { int w, h; SDL_Rect rt={0}; SDL_Surface *t=NULL; SDL_Color col={r, g, b}; t = TTF_RenderUTF8_Blended(font, msg, col); if(t){ TTF_SizeUTF8(font, msg, &w, &h); rt.x = (480 - w) / 2; rt.y = 260; SDL_BlitSurface(splash, NULL, screen, NULL); SDL_BlitSurface(t, NULL, screen, &rt); SDL_FreeSurface(t); } flip_screen(); } int main(int argc, char **argv) { int ok=0; SDL_Surface *t=NULL; if(SDL_Init(SDL_INIT_VIDEO) != 0) { printf("failed to init sdl\n"); return -1; } real = SDL_SetVideoMode(320, 480, 16, SDL_HWSURFACE); if(real == NULL) { printf("failed to set video mode\n"); return -1; } SDL_ShowCursor(SDL_FALSE); if(TTF_Init() == -1) { printf("failed to init ttf\n"); return -1; } #ifndef PC font = TTF_OpenFontRW(SDL_RWFromMem(hex_font, sizeof(hex_font)), 1, 38); #else font = TTF_OpenFont("font.ttf", 38); #endif screen = SDL_CreateRGBSurface(SDL_SWSURFACE, 480, 320, 16, 0, 0, 0, 0); SDL_FillRect(real, &real->clip_rect, SDL_MapRGB(real->format, 0, 0, 0)); SDL_RWops *rw=NULL; rw = SDL_RWFromMem(hex_splash, sizeof(hex_splash)); t = IMG_Load_RW(rw, 1); splash = SDL_ConvertSurface(t, real->format, 0); SDL_FreeSurface(t); text("手柄固件更新中...", 0x00, 0x00, 0xa0); ok = upgrade(); SDL_Delay(1000); if(ok < 0){ text("更新失败, 系统关机中...", 0xa0, 0x00, 0x00); } else{ text("更新完成, 系统关机中...", 0x00, 0xa0, 0x00); } SDL_Delay(1500); TTF_Quit(); SDL_FreeSurface(splash); SDL_Quit(); #ifndef PC system("poweroff"); #endif return 0; }