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;
}