2015年11月23日月曜日

Raspberry Pi 2 で RadioShark2(その2)

Raspberry Pi 2 で RadioShark2(その1)からの続き。

libhidapiに関して検索すると、HID API for Linux, Mac OS X, and Windowsを発見した。
 #というか、日本語で書かれたページが出てこない(^^;
上記ページと、hidapi APIを見ながら、しばし後悔(^^;

サンプルプログラムも付いているのでなんとかなるだろうと、久々にviでCのソースをいじる。
 #これまた、5年以上振りだと思う(^o^;

悪戦苦闘すること数時間。
なんとかコンパイルエラーがなくなるところまできたが、linkするファイルがわからない。
以前のバージョンのshark2.c
gcc -g -o shark2 -lhid shark2.c
でコンパイルできたが、
今回は-lhidapiではダメだった。

インストールされたパッケージ名をもう一度よく見て、-lhidapi-libusbにしたところ、
なんとかコンパイルが通った(^^;;

その後、ちょこちょこ実行時エラーを修正し、なんとかLEDの制御が出来るレベルまできたのが下記。
/* This souce code written my Michael Rolig (email: michael_rolig@alumni.macalester.edu)
* This can be considered to be in the public domain
*/

/* Modified for Radio Shark2 2007-05-11
* This source code is written by Hisaaki Shibata (email: shibata@luky.org)
* Original Shark2 controll code in Delphi is written by
* Kawabe (email: mail.kwb@gmail.com)
* This can be considered to be in the public domain.
*/

/* Modified for Radio Shark2 on Raspberry Pi 2 with hidapi.h 2015-11-22
* This source code is written by Hisaaki Shibata (email: shibata@luky.org)
* This can be considered to be in the public domain.
*/

#define DEBUG false /* Set true for copious debugging output */
#define SHARK_VENDID 0x077d /* Griffin's Vendor ID */
#define SHARK_DEVID 0x627a /* The radioSHARK2's Device ID */

#define READ_EP 0x5 /* libhidapi read command? */
#define WRITE_EP 0x5 /* libhidapi write command? */
#define SEND_PACKET_LENGTH 7 /* size of an instruction packet: shark2=7 */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hidapi/hidapi.h"

void usage(int argc, const char** argv) {
printf("%s <command> <arg>\n\tchange state of radioSHARK2\n\n", argv[0]);
printf("commands:\n"
" -fm <freqeuncy> : set FM frequency, e.g. '-fm 80.7'\n"
" -am <frequency> : set AM frequency, e.g. '-am 730'\n"
" -blue <intensity> : turn on blue LED (0-127) '-blue 127'\n"
" -red <0/1> : turn on/off red LED '-red 1'\n");

/* Declare variables used later */
hid_device *handle;
struct hid_device_info *devs, *cur_dev;

devs = hid_enumerate(0x0, 0x0);
cur_dev = devs;
while (cur_dev) {
printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls",
cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
printf("\n");
printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
printf(" Product: %ls\n", cur_dev->product_string);
printf("\n");
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);

}

int main(int argc, const char** argv) {

/* Declare variables used later */
int ret;
hid_device *handle;
struct hid_device_info *dev;

/* Build the instruction packet to send to the shark */
unsigned char PACKET[SEND_PACKET_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned short encodedFreq;
float freq;
unsigned int intensity;

if (argc == 3) {
if (strcmp(argv[1], "-fm") == 0) {
/* Tune to an FM frequency */
PACKET[0] = 0x81;
encodedFreq = 0;
freq = atof(argv[2]);
encodedFreq = ((freq * 10 * 2) - 3 );
PACKET[1] = (encodedFreq >> 8) & 0xFF;
PACKET[2] = encodedFreq & 0xFF;
PACKET[3] = 0x33;
PACKET[4] = 0x04;
PACKET[5] = 0x00;
PACKET[6] = 0x28;
if (DEBUG) {
printf("band = fm\n");
printf("freq = %.1f\n", freq);
printf("encoded freq = 0x%x\n", (unsigned int)encodedFreq);
}
} else if (strcmp(argv[1], "-am") == 0) {
/* Tune to an AM frequency */
PACKET[0] = 0x81;
encodedFreq = 0;
freq = (float)atoi(argv[2]);
encodedFreq = ((unsigned short)freq * 4 ) + 16300;
PACKET[1] = (encodedFreq >> 8) & 0xFF;
PACKET[2] = encodedFreq & 0xFF;
PACKET[3] = 0xF3;
PACKET[4] = 0x36;
PACKET[5] = 0x00;
PACKET[6] = 0x24;
if (DEBUG) {
printf("band = am\n");
printf("freq = %d\n", (unsigned int)freq);
printf("encoded freq = 0x%x\n", (unsigned int)encodedFreq);
}
} else if (strcmp(argv[1], "-blue") == 0) {
/* Adjust the blue LED */
intensity = atoi(argv[2]);
PACKET[0] = 0x83;
PACKET[1] = (char)intensity;
} else if (strcmp(argv[1], "-bblue") == 0) {
/* Adjust the blue LED's pulsing rate */
intensity = atoi(argv[2]);
PACKET[0] = 0xA1;
PACKET[1] = (char)intensity;
} else if (strcmp(argv[1], "-red") == 0) {
/* Toggle the red LED */
intensity = atoi(argv[2]);
if (intensity) PACKET[0] = 0x84;
else PACKET[0] = 0x84;
PACKET[1] = (char)intensity;
} else {
/* Bad command - display the program's usage instructions */
usage(argc, argv);
exit(1);
}
} else {
usage(argc, argv);
exit(1);
}

/* Initialize the hid library */
ret = hid_init();
if (ret != 0) {
fprintf(stderr, "hid_init failed with return code %d\n", ret);
return 1;
}

/* Open the shark */
dev = hid_enumerate(SHARK_VENDID, SHARK_DEVID);
handle = hid_open(SHARK_VENDID, SHARK_DEVID, 0);
if (handle == NULL) {
fprintf(stderr, "hid_open failed with return code %d\n", handle);
return 1;
}

/* Send the instruction packet constructed above to the Shark */
ret = hid_write(handle, (char*)PACKET, SEND_PACKET_LENGTH);
if (ret == -1) fprintf(stderr, "hid_write failed with return code %d\n", ret);

/* Close the shark */
hid_close(handle);

/* Close the hid object */
hid_free_enumeration(dev);

return 0;
}

上記をshark2-hidapi.cに置いている。
 #サンプルコードからまるっともらってきたりしてゴミが残っていたり、
 #見直しも何もできていないけど(^^;

これを
gcc -g -o shark2-hidapi -lhidapi-libusb shark2-hidapi.c

でコンパイルし、
shark2-hidapi -red 1

とやると、赤いLEDが点灯した(^O^)

サウンド出力はまだ確認していないけど、、LEDが制御できたのなら、チューナーも動いているはず。

もう今日は寝る!

続く。

0 件のコメント:

コメントを投稿