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


返回上一頁