есть ихсодникиmain.c
/*Windows
#include <cstdlib>
#include <iostream>
#include <usb.h>
*/
/*
Linux*/
/* #include "usb.h" */
#include </usr/include/libusb-1.0/libusb.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <string.h>#define VERSION "0.1.0"
#define VENDOR_ID 0x16c0
#define PRODUCT_ID 0x05df
#define INTFACE 0
#define ONEWIRE_REPEAT 5
#define USB_REPEAT 5
#define USB_PAUSE_CONST 50000
unsigned char USB_BUFI[8];
unsigned char USB_BUFO[8];
unsigned long long ONEWIRE_ROM[40];
float ONEWIRE_TEMP[40];
int ONEWIRE_COUNT;
float T;
const static int timeout=5000; /* timeout in ms */
usb_dev_handle *find_lvr_winusb();
usb_dev_handle* setup_libusb_access() {
usb_dev_handle *lvr_winusb;
usb_set_debug(0);
usb_init();
usb_find_busses();
usb_find_devices();if(!(lvr_winusb = find_lvr_winusb())) {
return NULL;
}
/* Linux */
usb_detach_kernel_driver_np(lvr_winusb,0);
if (usb_set_configuration(lvr_winusb, 1) < 0) {
printf("Could not set configuration 1 : \n");
return NULL;
}
if (usb_claim_interface(lvr_winusb, INTFACE) < 0) {
printf("Could not claim interface: \n");
return NULL;
}
return lvr_winusb;
}usb_dev_handle *find_lvr_winusb()
{
struct usb_bus *bus;
struct usb_device *dev;
for (bus = usb_busses; bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == VENDOR_ID &&
dev->descriptor.idProduct == PRODUCT_ID ) {
usb_dev_handle *handle;
if (!(handle = usb_open(dev))) {
printf("Could not open USB device\n");
return NULL;
}
return handle;
}
}
}
return NULL;
}usb_dev_handle *lvr_winusb = NULL;
void USB_PAUSE(unsigned long long MS)
{ // MS - задержка в милисекундах
// блокирует всё
for (unsigned long long i=0; i<MS*USB_PAUSE_CONST; i++);
}void USB_BUF_CLEAR()
{ // очистка буферов приёма и передачи
for (int i=0; i<9; i++) { USB_BUFI[i]=0; USB_BUFO[i]=0; }
}bool USB_GET_FEATURE()
{ // чтение в буфер из устройстваbool RESULT=false;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
try {
RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);
}
catch (...) { RESULT=false; };
if (!RESULT) printf("Error reading from device\n");
/*
printf("read ");
for(int i=0;i<8;i++) printf("%x ",USB_BUFI[i]);
printf("\n");
*/
return RESULT;
}
bool USB_SET_FEATURE()
{ // запись из буфера в устройство
bool RESULT=false;
try {
RESULT = usb_control_msg(lvr_winusb, 0x21, 0x09, 0x300, 0, (char *)USB_BUFO, 0x8, timeout);
}
catch (...) { RESULT=false; };
if (!RESULT) printf("Error writing to device\n");
/*
printf("write ");
for(int i=0;i<8;i++) printf("%x ",USB_BUFO[i]);
printf("\n");
*/
return RESULT;
}bool USB_GET_PORT(unsigned char &PS)
{ // чтение состояния порта, 2ms
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0x7E;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
if (USB_GET_FEATURE())
if (USB_BUFI[0]==0x7E) { PS=USB_BUFI[1]; RESULT=USB_BUFI[2]==PS; }
else RESULT=false;
if (!RESULT) printf("Error reading PORT\n");
return RESULT;
}bool USB_SET_PORT(unsigned char PS)
{ // запись состояния порта, 2ms
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0xE7;
USB_BUFO[1]=PS;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
if (USB_GET_FEATURE())
{ RESULT=(USB_BUFI[0]==0xE7)&(USB_BUFI[1]==PS)&(USB_BUFI[2]==PS); }
if (!RESULT) printf("Error writing PORT\n");
return RESULT;
}bool USB_GET_FAMILY(unsigned char &FAMILY)
{ // чтение группового кода устройства, 2ms
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0x1D;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
if (USB_GET_FEATURE())
if (USB_BUFI[0]==0x1D) { RESULT=true; FAMILY=USB_BUFI[1]; }
else RESULT=false;
if (!RESULT) printf("Error reading FAMILY\n");
return RESULT;
}bool USB_GET_SOFTV(unsigned int &SV)
{ // чтение номера версии прошивки, 2ms
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0x1D;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
if (USB_GET_FEATURE())
if (USB_BUFI[0]==0x1D) { RESULT=true; SV=USB_BUFI[2]+(USB_BUFI[3]>>8); }
else RESULT=false;
if (!RESULT) printf("Error reading firmware version\n");
return RESULT;
}bool USB_GET_ID(unsigned int &ID)
{ // чтение ID устройства, 2ms
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0x1D;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
if (USB_GET_FEATURE())
if (USB_BUFI[0]==0x1D) { RESULT=true; ID=(USB_BUFI[4]<<24)+(USB_BUFI[5]<<16)+(USB_BUFI[6]<<8)+USB_BUFI[7]; }
else RESULT=false;
if (!RESULT) printf("Error reading device ID\n");
return RESULT;
}bool USB_EE_RD(unsigned char ADR,unsigned char &DATA)
{ // чтение EEPROM
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0xE0;
USB_BUFO[1]=ADR;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
if (USB_GET_FEATURE()) { RESULT=(USB_BUFI[0]==0xE0)&(USB_BUFI[1]==ADR); DATA=USB_BUFI[2]; }
if (!RESULT) printf("Error reading EEPROM\n");
return RESULT;
}bool USB_EE_WR(unsigned char ADR,unsigned char DATA)
{ // запись EEPROM, 17ms
USB_BUF_CLEAR();
bool RESULT=false;
USB_BUFO[0]=0x0E;
USB_BUFO[1]=ADR; USB_BUFO[2]=DATA;
int i=USB_REPEAT; // число попыток
while (!RESULT & ((i--)>0))
if (USB_SET_FEATURE())
{
USB_PAUSE(15); // на запись в EEPROM
if (USB_GET_FEATURE()) RESULT=(USB_BUFI[0]==0x0E)&(USB_BUFI[1]==ADR)&(USB_BUFI[2]==DATA);
} else RESULT=false;
if (!RESULT) printf("Error writing EEPROM\n");
return RESULT;
}bool OW_RESET()
{ // RESET, ~3ms
bool RESULT=false;
int i;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x48;
unsigned char N=ONEWIRE_REPEAT;while (!RESULT &((N--)>0))
if (USB_SET_FEATURE())
{
USB_PAUSE(1);
if (USB_GET_FEATURE()) {
RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x48)&(USB_BUFI[2]==0x00);
}
else RESULT=false;
}
if (!RESULT) printf("Error OW_RESET\n");
return RESULT;
}bool OW_READ_BIT(unsigned char &B)
{ // чтение бита, 3ms
bool RESULT=false;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x81; USB_BUFO[2]=0x01;
if (USB_SET_FEATURE())
{
USB_PAUSE(1);
if (USB_GET_FEATURE())
{ RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x81); B=USB_BUFI[2]&0x01; }
}
if (!RESULT) printf("Error OW_READ_BIT\n");
return RESULT;
}bool OW_READ_2BIT(unsigned char &B)
{ // чтение 2-x бит, 3ms
bool RESULT=false;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x82;
USB_BUFO[2]=0x01; USB_BUFO[3]=0x01;
if (USB_SET_FEATURE())
{
USB_PAUSE(1);
if (USB_GET_FEATURE())
{ RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x82); B=(USB_BUFI[2]&0x01)+((USB_BUFI[3]<<1)&0x02); }
}
if (!RESULT) printf("Error OW_READ_2BIT\n");
return RESULT;
}bool OW_READ_BYTE(unsigned char &B)
{ // чтение байта, 3ms
bool RESULT=false;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x88; USB_BUFO[2]=0xFF;
if (USB_SET_FEATURE())
{
USB_PAUSE(1);
if (USB_GET_FEATURE())
{ RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x88); B=USB_BUFI[2]; }
}
if (!RESULT) printf("Error OW_READ_BYTE\n");
return RESULT;
}bool OW_READ_4BYTE(unsigned long &B)
{ // чтение 4 байта, 4ms
bool RESULT=false;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x84; USB_BUFO[2]=0xFF;
USB_BUFO[3]=0xFF; USB_BUFO[4]=0xFF; USB_BUFO[5]=0xFF;
if (USB_SET_FEATURE())
{
USB_PAUSE(2);
if (USB_GET_FEATURE())
{ RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x84); B=USB_BUFI[2]+(USB_BUFI[3]<<8)+(USB_BUFI[4]<<16)+(USB_BUFI[5]<<24); }
}
if (!RESULT) printf("Error OW_READ_4BYTE\n");
return RESULT;
}bool OW_WRITE_BIT(unsigned char B)
{ // запись бита, 3ms
bool RESULT=false;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x81; USB_BUFO[2]=B&0x01;
if (USB_SET_FEATURE())
{
USB_PAUSE(1);
if (USB_GET_FEATURE())
RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x81)&((USB_BUFI[2]&0x01)==(B&0x01));
}
if (!RESULT) printf("Error OW_WRITE_BIT\n");
return RESULT;
}bool OW_WRITE_BYTE(unsigned char B)
{ // запись байта, 3ms
bool RESULT=false;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x88; USB_BUFO[2]=B;
if (USB_SET_FEATURE())
{
USB_PAUSE(1);
if (USB_GET_FEATURE())
RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x88)&(USB_BUFI[2]==B);
}
if (!RESULT) printf("Error OW_WRITE_BYTE\n");
return RESULT;
}bool OW_WRITE_4BYTE(unsigned long B)
{ // запись 4 байта, 4ms
bool RESULT=false;
unsigned char D0, D1, D2, D3;
D0=B&0xFF;
D1=(B>>8) &0xFF;
D2=(B>>16)&0xFF;
D3=(B>>24)&0xFF;
USB_BUF_CLEAR();
USB_BUFO[0]=0x18; USB_BUFO[1]=0x84; USB_BUFO[2]=B&0xFF;
USB_BUFO[3]=(B>>8)&0xFF;
USB_BUFO[4]=(B>>16)&0xFF;
USB_BUFO[5]=(B>>24)&0xFF;
if (USB_SET_FEATURE())
{
USB_PAUSE(2);
if (USB_GET_FEATURE())
RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x84)&(USB_BUFI[2]==D0&(USB_BUFI[3]==D1)&(USB_BUFI[4]==D2)&(USB_BUFI[5]==D3));
}
if (!RESULT) printf("Error OW_WRITE_4BYTE\n");
return RESULT;
}unsigned char CRC8(unsigned char CRC, unsigned char D)
{ // подчсёт CRC для DALLAS
unsigned char R=CRC;
for (int i=0; i<8; i++)
if ((R^(D>>i))&0x01==0x01) R=((R^0x18)>>1)|0x80;
else R=(R>>1)&0x7F;
return R;
}bool READ_ROM(unsigned long long &ROM64)
{ // чтение ROM, 14ms
bool RESULT=false;
unsigned long B;
unsigned char N=ONEWIRE_REPEAT;
unsigned long long T, CRC;
while (!RESULT&((N--)>0))
if (OW_RESET())
if (OW_WRITE_BYTE(0x33))
{ // чтение 64 бит
ROM64=0; CRC=0;
if (OW_READ_4BYTE(B))
{
T=B;
ROM64=ROM64+T;
if (OW_READ_4BYTE(B)) { T=B; ROM64=ROM64+(T<<32); RESULT=true; }
else RESULT=false;
}
else RESULT=false;
// проверка CRC
if (RESULT)
{
T=ROM64;
for (int i=0; i<8; i++) CRC=CRC8(CRC, (T>>(i*8))&0xFF);
RESULT=CRC==0;
}
}
if (!RESULT) printf("Error READ_ROM\n");
return RESULT;
}bool MATCH_ROM(unsigned long long ROM)
{ // выбор прибора по ROM, 14ms
bool RESULT=false;
unsigned long long T=ROM;
unsigned char N=ONEWIRE_REPEAT;
while (!RESULT&((N--)>0))
if (OW_RESET())
if (OW_WRITE_BYTE(0x55))
if (OW_WRITE_4BYTE(T&0xFFFFFFFF))
RESULT=OW_WRITE_4BYTE((T>>32)&0xFFFFFFFF);
if (!RESULT) printf("Error MATCH_ROM\n");
return RESULT;
}bool SKIP_ROM()
{ // пропуск ROM-команд, 6ms
bool RESULT=false;
unsigned char N=ONEWIRE_REPEAT;
while (!RESULT&((N--)>0))
if (OW_RESET()) RESULT=OW_WRITE_BYTE(0xCC);
if (!RESULT) printf("Error SKIP_ROM\n");
return RESULT;
}bool SEARCH_ROM(unsigned long long ROM_NEXT, int PL)
{ // поиск ROM, 1 dev - 410ms, 5 dev - 2.26s, 20 dev - 8.89s
bool RESULT=false;
unsigned char N=ONEWIRE_REPEAT;
unsigned char BIT;
bool CL[64]; for (int i=0; i<64; i++) CL[i]=false;
unsigned long long RL[64];
unsigned long long B1=1, CRC, ROM;
while (!RESULT&((N--)>0))
{
ROM=0;
if (OW_RESET()) RESULT=OW_WRITE_BYTE(0xF0);
if (RESULT)
for (int i=0; i<64; i++)
if (RESULT)
if (OW_READ_2BIT(BIT))
switch (BIT&0x03)
{
case 0 :
{ // коллизия есть
if (PL<i) {CL[i]=true; RL[i]=ROM;}
if (PL>=i) BIT=(ROM_NEXT>>i)&0x01; else BIT=0;
if(!OW_WRITE_BIT(BIT)) { RESULT=false; i=64; }
if (BIT==1) ROM=ROM+(B1<<i);
break;
}
case 1 : { if (!OW_WRITE_BIT(0x01)) { RESULT=false; i=64; } else ROM=ROM+(B1<<i); break;}
case 2 : { if (!OW_WRITE_BIT(0x00)) { RESULT=false; i=64; } break;}
case 3 : { RESULT=false; i=64; break;} // нет на линии
}
else { RESULT=false; i=64; }
if (ROM==0) RESULT=false;
if (RESULT) { CRC=0; for (int j=0; j<8; j++) CRC=CRC8(CRC, (ROM>>(j*8))&0xFF); RESULT=CRC==0; }
}
if (!RESULT) printf("Error SEARCH_ROM\n");
else ONEWIRE_ROM[ONEWIRE_COUNT++]=ROM;
// рекурентный вызов поиска
for (int i=0; i<64; i++)
if (CL[i]) SEARCH_ROM(RL[i]|(B1<<i), i);
return RESULT;
}bool SKIP_ROM_CONVERT()
{ // пропуск ROM-команд, старт измерения температуры, 9ms
bool RESULT=false;
unsigned char N=ONEWIRE_REPEAT;
while (!RESULT&((N--)>0))
if (OW_RESET())
if (OW_WRITE_BYTE(0xCC))
RESULT=OW_WRITE_BYTE(0x44);
if (!RESULT) printf("Error SKIP_ROM_CONVERT\n");
return RESULT;
}bool GET_TEMPERATURE(unsigned long long ROM, float &T)
{ // чтение температуры, 28ms
unsigned long long CRC;
unsigned long L1, L2;
unsigned char L3;
unsigned char FAMILY=ROM&0xFF;
bool RESULT=false;
unsigned char N=ONEWIRE_REPEAT;
while (!RESULT&((N--)>0))
if (MATCH_ROM(ROM))
if (OW_WRITE_BYTE(0xBE))
if (OW_READ_4BYTE(L1))
if (OW_READ_4BYTE(L2))
if (OW_READ_BYTE(L3))
{
CRC=0;
for (int i=0; i<4; i++) CRC=CRC8(CRC, (L1>>(i*8))&0xFF);
for (int i=0; i<4; i++) CRC=CRC8(CRC, (L2>>(i*8))&0xFF);
CRC=CRC8(CRC, L3);
RESULT=CRC==0;short K=L1&0xFFFF;
// DS18B20 +10.125=00A2h, -10.125=FF5Eh
// DS18S20 +25.0=0032h, -25.0=FFCEh
// K=0x0032;
T=1000; // для неопознанной FAMILY датчик отсутствует
if ((FAMILY==0x28)|(FAMILY==0x22)) T=K*0.0625; // DS18B20 | DS1822
if (FAMILY==0x10) T=K*0.5; // DS18S20 | DS1820
}
if (!RESULT) printf("Error GET_TEMPERATURE\n");
return RESULT;
}
int read_ports()
{
int ret=0;
unsigned char PS;
if(USB_GET_PORT(PS)) {
if((PS==8)|(PS==24)) printf("Port1 is on\n");
else printf("Port1 is off\n");
if(PS>=16) printf("Port2 is on\n");
else printf("Port2 is off\n");
return 1;
}
return 0;
}int set_port(int num, bool stat)
{
unsigned char PS, PS_OLD;
bool ret;if (USB_GET_PORT(PS))
{ // удалость прочитать
PS_OLD=PS;
} else { printf("Error USB_GET_PORT\n"); return 0; }
// включение / выключение
if ((num==1)&(stat==1)) { PS=PS|0x08; ret = USB_SET_PORT(PS); }
else if ((num==1)&(stat==0)) { PS=PS&0x10; ret = USB_SET_PORT(PS); }
else if ((num==2)&(stat==1)) { PS=PS|0x10; ret = USB_SET_PORT(PS); }
else if ((num==2)&(stat==0)) { PS=PS&0x08; ret = USB_SET_PORT(PS); }
if(!ret) return 0;
printf("Status port changed\n");
return 1;
}
int device_info() {
int ret=0;
unsigned int SV,ID;
unsigned char FAMILY;
ret = USB_GET_SOFTV(SV);
if(ret) printf("Firmware: %xh\n", SV);
ret = USB_GET_FAMILY(FAMILY);
if(ret) printf("USB series: %xh\n", FAMILY);
ret = USB_GET_ID(ID);
if(ret) printf("USB identifier: %xh\n", ID);
return 1;
}
int scan() {
int ret;
ret = SEARCH_ROM(0, 0);
for(int i=1;i<=ONEWIRE_COUNT;i++) {
printf("temp_id%d = %x",i, (ONEWIRE_ROM[i-1]>>32)&0xFFFFFFFF);
printf("%x\n",ONEWIRE_ROM[i-1]&0xFFFFFFFF);
}
return 1;
}int temp(unsigned long long ROM) {
int ret;
ONEWIRE_COUNT = 1;
ONEWIRE_ROM[0] = ROM;
SKIP_ROM_CONVERT();
ret = GET_TEMPERATURE(ONEWIRE_ROM[0], T);
if(ret) printf("%f\n",T);
}int ports_save() {
unsigned char PS;
if (USB_GET_PORT(PS)) {
if (USB_EE_WR(0x04, PS)) {printf("Status ports saved\n");return 1;}
}
printf("Error saving ports status\n");
return 0;
}int delay_get() {
unsigned char B;
USB_EE_RD(0x05, B);
printf("%d\n", B);
return 1;
}int delay_set(int B) {
if((B<5)|(B>255)) {
printf("Wrong num %d\n",B);
return 0;
}
if (USB_EE_WR(0x05, B)) {printf("Delay changed\n");return 1;}
return 0;
}
long long unsigned int HexStringToUInt(char* s)
{
long long unsigned int v = 0;
while (char c = *s++)
{
if (c < '0') return 0; //invalid character
if (c > '9') //shift alphabetic characters down
{
if (c >= 'a') c -= 'a' - 'A'; //upper-case 'a' or higher
if (c > 'Z') return 0; //invalid character
if (c > '9') c -= 'A'-1-'9'; //make consecutive with digits
if (c < '9' + 1) return 0; //invalid character
}
c -= '0'; //convert char to hex digit value
v = v << 4; //shift left by a hex digit
v += c; //add the current digit
}return v;
}int main( int argc, char **argv)
{
lvr_winusb = setup_libusb_access();char buf;
if(argc==1) {
printf("Temperature sensor BM1707 control v1.0\n");
if(lvr_winusb!=NULL) {
printf("Device has been plugged\n");
}
else printf("Device unplugged\n");
printf("\nUsage: bmcontrol [options]\n\n");
printf(" info Show device information\n");
printf(" scan Scaning temperature sensors\n");
printf(" temp <id> Show temperature sensor <id> \n");
printf(" ports Show ports status\n");
printf(" pset <port> <status> Set off/on port status.\n");
printf(" Correct value: port [1, 2] status [0, 1]. \n");
printf(" psave Save ports status in EEPROM\n");
printf(" delay Get delay time of device before power save\n");
printf(" delay <5-255> Set delay time of device before power save\n");
}
else if(lvr_winusb!=NULL){
if(strcmp(argv[1],"ports") == 0) buf = read_ports();
else if(strcmp(argv[1],"info") == 0) device_info();
else if(strcmp(argv[1],"scan") == 0) scan();
else if(strcmp(argv[1],"psave") == 0) ports_save();
else if((strcmp(argv[1],"temp") == 0)&&(argv[2])) {
long unsigned rom1=0, rom2=0;
long long unsigned rom=0;
rom = HexStringToUInt(argv[2]);
temp(rom);
}
else if((strcmp(argv[1],"pset") == 0)&(argc==4)) buf = set_port(atoi((const char*) argv[2]), (bool) atoi((const char*) argv[3]));
else if((strcmp(argv[1],"delay") == 0)&(argc==2)) delay_get();
else if((strcmp(argv[1],"delay") == 0)&(argc==3)) delay_set( atoi(argv[2]));
else printf("Wrong command %s.\n", argv[1]);
}
else {
printf("Device not plugged\n");
exit(-1);
}
if(lvr_winusb!=NULL) {
usb_release_interface(lvr_winusb, 0);
usb_close(lvr_winusb);
}
return 0;
}
и makefileCC = g++all: bmcontrol
%.o: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -I. -I/usr/include -lusb -o $@ $^
bmcontrol: main.o
$(CC) -I/usr/include -L/usr/lib -lusb -o $@ $^
clean:
rm -f *.o bmcontrolпри сборке make
вываливаются ошибки
g++ -c -I. -I/usr/include -lusb -o main.o main.c
main.c:32:1: error: ‘usb_dev_handle’ does not name a type
main.c:33:1: error: ‘usb_dev_handle’ does not name a type
main.c:59:2: error: ‘usb_dev_handle’ does not name a type
main.c:79:1: error: ‘usb_dev_handle’ does not name a type
main.c: In function ‘bool USB_GET_FEATURE()’:
main.c:99:38: error: ‘lvr_winusb’ was not declared in this scope
main.c:99:102: error: ‘usb_control_msg’ was not declared in this scope
main.c: In function ‘bool USB_SET_FEATURE()’:
main.c:115:38: error: ‘lvr_winusb’ was not declared in this scope
main.c:115:102: error: ‘usb_control_msg’ was not declared in this scope
main.c: In function ‘int main(int, char**)’:
main.c:637:5: error: ‘lvr_winusb’ was not declared in this scope
main.c:637:38: error: ‘setup_libusb_access’ was not declared in this scope
main.c:669:104: error: ‘atoi’ was not declared in this scope
main.c:671:87: error: ‘atoi’ was not declared in this scope
main.c:676:21: error: ‘exit’ was not declared in this scope
main.c:679:48: error: ‘usb_release_interface’ was not declared in this scope
main.c:680:33: error: ‘usb_close’ was not declared in this scope
make: *** [main.o] Error 1что я делаю не так?
1. Убедитесь, что пакет libusb-dev установлен
2. Вот эту строчку:
#include </usr/include/libusb-1.0/libusb.h>
заменяете на:
#include <usb.h>
3. Собирается всё одной строчкой (вместо вашего мейк-файла):
g++ -lusb main.c -o bmcontrol
ну либо можно переделать ваш Makefile:
APP = bmcontrol
CXXFLAGS = -Wall -O2 -s
LDFLAGS = $(shell pkg-config --libs libusb)
OBJS = main.odefault: $(APP)
%.o: %.c
$(CXX) $(CXXFLAGS) -c -o $@ $^
$(APP): $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $^clean:
rm -f *.o $(APP).PHONY: default $(APP) clean
4. Ну и напоследок просто совет: у вас там куча ошибок
4.1 Попробуйте собрать с опцией "-Wall" и пофиксите все предупреждения
4.2 Установите cppcheck и пофиксите все ошибки, которые выдает эта команда:
cppcheck --enable=all -I /usr/include/ main.c
Если вы имели ввиду, как для Debian/Raspbian сделать deb-пакет, то есть разные способы, простые (для себя) и сложные (если хотите добавить свой пакет в репозиторий Debian).Самый простой способ: использовать утилиту "checkinstall" вместо команды "make install".
1. Добавить install правило в ваш Makefile:
PREFIX ?= /usr/local
APP = bmcontrolinstall:
install -m 0755 $(APP) $(PREFIX)/bin2. Выполнить команду "make".
3. Запустить утилиту "sudo checkinstall" и ответить на вопросы. Или можно как то так:
checkinstall --pkgname=bmcontrol --install=no --default
sudo dpkg -i bmcontrol*.deb
>[оверквотинг удален]
> install:
> install -m 0755 $(APP) $(PREFIX)/bin
>
Все решилось сборкой и установкой библиотеки libusb-0.1-12
после этого файл bmcontrol собрался без ошибок
Все спасибо
> после этого файл bmcontrol собрался без ошибокА в курсе, чё будет с этим кодом, если gcc сказать -O2 и больше?
void USB_PAUSE(unsigned long long MS)
{ // MS - задержка в милисекундах блокирует всё
for (unsigned long long i=0; i<MS * USB_PAUSE_CONST; i++);
}
правильно, он превратиться в:
void USB_PAUSE(void)
{
return;
}если прям так уверены, что 50000 циклов сравнения и сложения прим. равны 1 мс,
то надо volatile писать.
void USB_PAUSE(unsigned long long MS)
{
for (unsigned long long volatile i=0; i < (MS * USB_PAUSE_CONST); i++);
}
> если прям так уверены, что 50000 циклов сравнения и сложения прим. равны
> 1 мс,
> то надо volatile писать.Ну а если совсем по уму, то так:
1. Если можно использовать неблокирующее ожидание (по сути планировщик будет выполнять другие процессы, пока ожидание не закончится, т.е. как если бы мы делали sched_yield()):
#include <time.h>void sleep_nonblocking(unsigned int msecs)
{
struct timespec req;req.tv_sec = msecs / 1000;
req.tv_nsec = (msecs - req.tv_sec * 1000) * 1000000;if (nanosleep(&req, NULL) == -1) {
perror("Error occurred while sleeping");
exit(EXIT_FAILURE);
}
}
2. Если нужно обязательно блокирующее ожидание (как у вас сейчас сделано):
#include <time.h>
#include <stdio.h>
#include <stdlib.h>#define CLOCKS_PER_MSEC (CLOCKS_PER_SEC / 1000)
void sleep_blocking(unsigned int msecs)
{
clock_t goal;goal = msecs * CLOCKS_PER_MSEC + clock();
while (goal > clock());
}
При этом для обоих случаев можно компилировать с "-O2" и не нужно использовать volatile.Подробнее почитать про эти вызовы можно в "man 2 nanosleep" и в "man 3 clock" (должен быть установлен пакет manpages-dev).
Да, и еще, на всякий пожарный: код с "nanosleep()" нельзя компилировать с опцией "-ansi". Подробности в /usr/include/features.h.
Что касается портируемости: вот например как сделали в VLC:
Linux:
http://git.videolan.org/?p=vlc.git;a=blob;f=src/posix/thread...Windows:
http://git.videolan.org/?p=vlc.git;a=blob;f=src/win32/thread...
> void sleep_nonblocking(unsigned int msecs)
> void sleep_blocking(unsigned int msecs)Вот только с названиями я погорячился: для этих функций уже есть хорошие названия:
sleep_nonblocking() -> msleep()
sleep_blocking() -> mdelay()
> Ну а если совсем по уму, то так:Плоха сделал, давай ищо! Нужна через asm("rdtsc"..), с коррекцией, нормализацией таймера,
реалтаймом, и barrier() не забудь, а то мало ли чо, мож кэш плохой.
>> Ну а если совсем по уму, то так:
> Плоха сделал, давай ищо! Нужна через asm("rdtsc"..), с коррекцией, нормализацией таймера,
> реалтаймом, и barrier() не забудь, а то мало ли чо, мож
> кэш плохой.однако :)
>> Ну а если совсем по уму, то так:
> Плоха сделал, давай ищо! Нужна через asm("rdtsc"..), с коррекцией, нормализацией таймера,
> реалтаймом, и barrier() не забудь, а то мало ли чо, мож
> кэш плохой.Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)
> Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)Сам тащусь :)
С наступающим Новым Годом!
>> Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)
> Сам тащусь :)
> С наступающим Новым Годом!и вас по тому же месту! :)
>>> Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)
>> Сам тащусь :)
>> С наступающим Новым Годом!
> и вас по тому же месту! :)Продолжаем...
Функция GET_TEMPERATURE выдает ошибку:
Вот код функции
bool GET_TEMPERATURE(unsigned long long ROM, float &T)
{
if ( DEBUG ) printf("[D] enter GET_TEMPERATURE\n");
unsigned long long CRC;
unsigned long L1, L2;
unsigned char L3;
unsigned char FAMILY=ROM&0xFF;
bool RESULT=false;
unsigned char N=3;
while (!RESULT&((N--)>0))
if (MATCH_ROM(ROM))
if (OW_WRITE_BYTE(0xBE))
if (OW_READ_4BYTE(L1))
if (OW_READ_4BYTE(L2))
if (OW_READ_BYTE(L3))
{
if ( DEBUG ) printf("[D] L1=%lx\tL2=%lx\tL3=%hhx\n", L1, L2, L3);
CRC=0;
for (int i=0; i<4; i++) CRC=CRC8(CRC, (L1>>(i*8))&0xFF);
if ( DEBUG ) printf("[D] CRC=%llx\n", CRC);
for (int i=0; i<4; i++) CRC=CRC8(CRC, (L2>>(i*8))&0xFF);
if ( DEBUG ) printf("[D] CRC=%llx\n", CRC);
CRC=CRC8(CRC, L3);
if ( DEBUG ) printf("[D] CRC=%llx\n", CRC);
RESULT=CRC==0;
short K=L1&0xFFFF;
// DS18B20 +10.125=00A2h, -10.125=FF5Eh
// DS18S20 +25.0=0032h, -25.0=FFCEh
// K=0x0032;
T=1000; // for unknow FAMILY - no sensor exists
if ((FAMILY==0x28)|(FAMILY==0x22)) T=K*0.0625; // DS18B20 | DS1822
if (FAMILY==0x10) T=K*0.5; // DS18S20 | DS1820
if ( DEBUG ) printf("[D] ~T=%f\n", T);
} else printf("[!] !OW_READ_BYTE(L3) \n");
else printf("[!] !OW_READ_4BYTE(L2) \n");
else printf("[!] !OW_READ_4BYTE(L1) \n");
else printf("[!] !OW_WRITE_BYTE(0xBE) \n");
else printf("[!] !MATCH_ROM(ROM) \n");
if (!RESULT) printf("[!] Error GET_TEMPERATURE\n");
return RESULT;
}
вот вывод DEBUG# /root/mp707/bmcontrol scan
temp_id1 = 8300000483000004
temp_id2 = 40000034000003
# /root/mp707/bmcontrol temp 40000034000003
[D] enter GET_TEMPERATURE
[D] L1=ffffffff L2=ffffffff L3=ff
[D] CRC=8d
[D] CRC=c9
[D] CRC=63
[D] ~T=1000.000000
[D] L1=ffffffff L2=ffffffff L3=ff
[D] CRC=8d
[D] CRC=c9
[D] CRC=63
[D] ~T=1000.000000
[D] L1=ffffffff L2=ffffffff L3=ff
[D] CRC=8d
[D] CRC=c9
[D] CRC=63
[D] ~T=1000.000000
[!] Error GET_TEMPERATURE
Что не так?
> Что не так?Переменная RESULT должна быть не нулевой при выходе из функции, а для этого CRC8(L3) должен быть нулем. У вас же CRC8(L3) равен 63. Очевидно, L3 некорректный (он равен ff). Да и L1, L2 тоже странные, ffffffff. И это response на команду 0xbe, для DS18B20 это "Read Scratchpad". Не похоже на корректные значения датчика. А id датчиков правильные? Либо вы неправильно программу используете, либо девайс ваш накрылся. Ну или прога кривая.
>> Что не так?
> Переменная RESULT должна быть не нулевой при выходе из функции, а для
> этого CRC8(L3) должен быть нулем. У вас же CRC8(L3) равен 63.
> Очевидно, L3 некорректный (он равен ff). Да и L1, L2 тоже
> странные, ffffffff. И это response на команду 0xbe, для DS18B20 это
> "Read Scratchpad". Не похоже на корректные значения датчика. А id датчиков
> правильные? Либо вы неправильно программу используете, либо девайс ваш накрылся. Ну
> или прога кривая.Девайс работает и Датчики исправные только что проверил в Win.
Насчет id датчиков
есть подозрения что они не правильно определяютсяв Win
это
83000004BFC35D28
0400000334EDDD28а BMcontrol в Raspbian
определяет их как
8300000483000004
40000034000003
>[оверквотинг удален]
> Насчет id датчиков
> есть подозрения что они не правильно определяются
> в Win
> это
> 83000004BFC35D28
> 0400000334EDDD28
> а BMcontrol в Raspbian
> определяет их как
> 8300000483000004
> 40000034000003Кажется, в Linux неправильно работает считывание. Заметьте, в Linux каждые 4 байта (32 бита) повторяются, например 0x83000004, а дальше опять тоже самое. Скорее всего, прога ваша глючная и не протестированная.
>[оверквотинг удален]
>> это
>> 83000004BFC35D28
>> 0400000334EDDD28
>> а BMcontrol в Raspbian
>> определяет их как
>> 8300000483000004
>> 40000034000003
> Кажется, в Linux неправильно работает считывание. Заметьте, в Linux каждые 4 байта
> (32 бита) повторяются, например 0x83000004, а дальше опять тоже самое. Скорее
> всего, прога ваша глючная и не протестированная.Знаете, у меня есть подозрение, что как раз функция задержки у вас не выполняет свою задачу. Попробуйте заменить у себя эту функцию:
void USB_PAUSE(unsigned long long MS)
{ // MS - задержка в милисекундах
// блокирует всё
for (unsigned long long i=0; i<MS*USB_PAUSE_CONST; i++);
}
на эту:
void USB_PAUSE(unsigned int msecs)
{
clock_t goal;goal = msecs * CLOCKS_PER_MSEC + clock();
while (goal > clock());
}
а в самый верх программы добавьте это:
#include <time.h>
#include <stdlib.h>#define CLOCKS_PER_MSEC (CLOCKS_PER_SEC / 1000)
Не удивлюсь, если после этого заработает. А автору программы надо руки пообрывать.
>[оверквотинг удален]
> Насчет id датчиков
> есть подозрения что они не правильно определяются
> в Win
> это
> 83000004BFC35D28
> 0400000334EDDD28
> а BMcontrol в Raspbian
> определяет их как
> 8300000483000004
> 40000034000003Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/ . Попробуйте оттуда собрать, может сходу заработает. У вас по идее старая версия (1.0) отсюда: http://devphp.org.ua/?menu=scripts&sub=&sshow=5
Еще думаю вам будет интересно почитать вот это (и комментарии ниже): https://plus.google.com/+SergeyShpikin/posts/PYWwMJB6Wv3
Вот еще парочка интересных ссылок по MP707:http://www.masterkit.ru/forum/viewtopic.php?t=1370&postdays=...
http://www.sinava.ru/MP707.php
http://habrahabr.ru/post/164399/
http://blog-i.ru/umniy-dom-versiya-2-0/temperaturniy-kontrol...
Ссылка на репозиторий плохо вставилась, вот правильная: https://code.google.com/p/bmcontrol/
> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/
>> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/
> А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/Нефеншуй! :-P
RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);
Нада
#include <linux/usb.h>
RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, USB_CTRL_SET_TIMEOUT);
>>> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/
>> А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/
> Нефеншуй! :-P
> RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);
> Нада
> #include <linux/usb.h>
> RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, USB_CTRL_SET_TIMEOUT);Во-первых для юзерспейса (в /usr/include) нет хедера linux/usb.h, это только для ядра. Во-вторых, под вендой (в MinGW) уж точно такого нет, а я пытался сделать чтобы всё стало кросс-платформенно.
Кстати, после каждого usb_control_msg() нужно 20 мс. таймаут ставить.
Если после записи сразу попытаешься считать.
Примерно из 100 раз одно значение будет неверное.
Можешь тестовый брутфорс на флешке устроить.libusb ваще корявое угэ.
> Кстати, после каждого usb_control_msg() нужно 20 мс. таймаут ставить.
> Если после записи сразу попытаешься считать.
> Примерно из 100 раз одно значение будет неверное.
> Можешь тестовый брутфорс на флешке устроить.
> libusb ваще корявое угэ.Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс? А где можно почитать об этом баге? И не знаете, был ли он исправлен в libusb-1.0 (по отношению к 0.1)?
Я просто никогда с libusb не работал, поэтому ничего не знаю про него, а по поводу моих фиксов -- они относятся к коду bmcontrol вообще, а не к работе с libusb.
> А где можно почитать об этом баге? был ли он исправлен в libusb-1.0 (по отношению к 0.1)?Я уж и не вспомню, года 3 не работал с libusb.
Погугли на тему: libusb timer error
Они ж там для задержек используют таймеры вместо *sleep()/*delay(), вот чёй-то там накосячили.
А, ещё косяк вспомнил: после освобождения драйвера прибора usb_detach_kernel_driver_np()
драйвер особо и не освобождался, в моём случае это был uvcvideo.ko
Второй раз подключится к нему нельзя было. Если драйвер в виде модуля,
то спасало rmmod/insmod, а если монолитом, только ребут.
> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
ret = usb_control_msg();
usleep(20);
if ( ret < 0 )
ля-ля-ля ...error;
>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
> ret = usb_control_msg();
> usleep(20);
> if ( ret < 0 )
> ля-ля-ля ...error;Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
>>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
>> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
>> ret = usb_control_msg();
>> usleep(20);
>> if ( ret < 0 )
>> ля-ля-ля ...error;
> Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...Собрал. Работает!
Ваша версия: сканирование проходит дольше чем сборка для OpenWRT,
а вот опрос датчиков быстрее раза в два.
>>>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
>>> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
>>> ret = usb_control_msg();
>>> usleep(20);
>>> if ( ret < 0 )
>>> ля-ля-ля ...error;
>> Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
> Собрал. Работает!
> Ваша версия: сканирование проходит дольше чем сборка для OpenWRT,
> а вот опрос датчиков быстрее раза в два.Сборка под OpenWRT -- вот эта https://github.com/bubbafix/openwrt-bm1707/blob/master/packa...? Я дорабатывал оригинальную версию, про другие переделки ничего не могу сказать. Надеюсь, автор получил моё письмо и затянет изменения к себе в mainline.
>[оверквотинг удален]
>>>> if ( ret < 0 )
>>>> ля-ля-ля ...error;
>>> Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
>> Собрал. Работает!
>> Ваша версия: сканирование проходит дольше чем сборка для OpenWRT,
>> а вот опрос датчиков быстрее раза в два.
> Сборка под OpenWRT -- вот эта https://github.com/bubbafix/openwrt-bm1707/blob/master/packa...
> ? Я дорабатывал оригинальную версию, про другие переделки ничего не
> могу сказать. Надеюсь, автор получил моё письмо и затянет изменения к
> себе в mainline.
diff -ru a/main.c b/main.c
--- a/main.c 1979-12-31 00:00:00.000000000 +0300
+++ b/main.c 2014-01-05 00:08:35.859593000 +0400
@@ -370,10 +370,10 @@
D2=(B>>16)&0xFF;
D3=(B>>24)&0xFF;
USB_BUF_CLEAR();
- USB_BUFO[0]=0x18; USB_BUFO[1]=0x84; USB_BUFO[2]=B&0xFF;
- USB_BUFO[3]=(B>>8)&0xFF;
- USB_BUFO[4]=(B>>16)&0xFF;
- USB_BUFO[5]=(B>>24)&0xFF;
+ USB_BUFO[0]=0x18; USB_BUFO[1]=0x84; USB_BUFO[2]=D0;
+ USB_BUFO[3]=D1;
+ USB_BUFO[4]=D2;
+ USB_BUFO[5]=D3;
if (USB_SET_FEATURE())
{
USB_PAUSE(2);
@@ -414,13 +414,11 @@
{ bool RESULT=false;
unsigned char N=ONEWIRE_REPEAT;
unsigned char BIT;
- bool CL[64];
+ bool CL[64]= {false}; // array of false :)
int i;
uint64_t RL[64];
uint64_t B1=1, CRC, ROM;
- for (i=0; i<64; i++) CL[i]=false;
-
while (!RESULT && N--)
{
ROM=0;
> @@ -414,13 +414,11 @@
> { bool RESULT=false;
> unsigned char N=ONEWIRE_REPEAT;
> unsigned char BIT;
> - bool CL[64];
> + bool CL[64]= {false}; // array of false :)
> - for (i=0; i<64; i++) CL[i]=false;
> -Ну, я понял бы, заменил бы memset-ом, но ведь инициализация переменной в стеке будет сделана компилятором тем же циклом. ... Или это такой хитрый способ исполнить именно memset "руками" компилера?
> Или это такой хитрый способ исполнить именно memset "руками" компилера?Ага.
mov $0x0,%eax ; чем заполняем, в EAX
mov $0x20,%edx ; длина - 32 или 0x20 (32 WORD или 64 BYTE)
mov %ebx,%edi ; указатель на начало в EDI
mov %edx,%ecx ; длину в ECX
rep stos %eax,%es:(%edi) ; повторять запись по адресу указанному в (ES:EDI) значением в EAX, пока ECX не будет равен 0
sub $0xffffff80,%esp ; новый указатель
На x86_64 оно за 10 повторов обнулит, даже если у тя тип будет unsigned char или short.
Поэтому типы меньше int на x64 практически бесполезны.Это обычный цикл
из-за операции сравнения (i < 64) получим цикл loop 64 раза.
jg out
mov 0xc(%esp),%eax
loop:
mov 0xc(%esp),%eax
inc %eax
mov %eax,0xc(%esp)
mov 0xc(%esp),%eax
cmp $0x3f,%eax
jle loop
out:
add $0x10,%esp
---
Так что, чтоб лишний раз не дёргать glibc. Конечно есть __builtin_memset,
но он всё равно тормознутее и не портабельно, а эта фича STD C99
>
> diff -ru a/main.c b/main.c
>https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
Авторство сохранено.
>...
diff -ur a/main.c b/main.c
--- a/main.c 1979-12-31 00:00:00.000000000 +0300
+++ b/main.c 2014-01-06 21:19:23.107679000 +0400
@@ -11,8 +11,11 @@
#include <string.h>
#include <stdint.h>
#include <time.h>
+#include <stdbool.h>
+#ifndef bool
typedef enum { false, true } bool;
+#endif
#define VERSION "1.1.1"
#define VENDOR_ID 0x16c0
>[оверквотинг удален]
> #include <string.h>
> #include <stdint.h>
> #include <time.h>
> +#include <stdbool.h>
> +#ifndef bool
> typedef enum { false, true } bool;
> +#endif
> #define VERSION "1.1.1"
> #define VENDOR_ID 0x16c0
>Сделал так: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
> Сделал так: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...Заодно для пущей портабельности вот такую штуку сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
>>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
>> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
>> ret = usb_control_msg();
>> usleep(20);
>> if ( ret < 0 )
>> ля-ля-ля ...error;
> Сделал:Ага, оно самое.
Там бы знаешь ещё что, - понять что за константы в функции usb_control_msg()
эта GET // from device
usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);эта SET // to device
usb_control_msg(lvr_winusb, 0x21, 0x09, 0x300, 0, (char *)USB_BUFO, 0x8, timeout);Я так думаю, что:
0xA1 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN) /* (0x01 << 5) | 0x01 | 0x80 */
0x21 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT) /* (0x01 << 5) | 0x01 | 0x00 */0x01 - это по-моему запрос .... скорее всего CLEAR_FEATURE
0x09 - тута видимо SET_CONFIGURATION0x8 - это sizeof(USB_BUFI) и sizeof(USB_BUFO) // размер буфера
0 - смещение он начала буфера.0x300 - это типа сколько байт будет передано. Видимо афтор оригинала тоже где-то скопипастил код. :)
> Там бы знаешь ещё что, - понять что за константы в функции usb_control_msg()Как говорится, good point. Только я по незнанию немного подвис на этом этапе. Но вроде разобрался. Ниже результаты.
> 0xA1 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN) /* (0x01 << 5) | 0x01 | 0x80 */
> 0x21 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT) /* (0x01 << 5) | 0x01 | 0x00 */Верно, только в include/usb.h нет USB_DIR_*, там USB_ENDPOINT_* взамен.
> 0x01 - это по-моему запрос .... скорее всего CLEAR_FEATURE
> 0x09 - тута видимо SET_CONFIGURATIONДумаю это скорее вот что:
/*
* HID class requests
*/
#define HID_REQ_GET_REPORT 0x01
#define HID_REQ_SET_REPORT 0x09украдено отсюда: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux....
> 0x300 - это типа сколько байт будет переданоМне кажется, это вот что: если взять вот эту спеку: http://www.usb.org/developers/devclass_docs/HID1_11.pdf ...есть на этой странице http://www.usb.org/developers/hidpage/ )
и посмотреть на главу "7.2.1 Get_Report Request", там в Remarks написано вот что:
The wValue field specifies the Report Type in the high byte and the Report
ID in the low byte. Set Report ID to 0 (zero) if Report IDs are not used.Report Type is specified as follows:
Value Report Type
01 Input
02 Output
03 Feature
04-FF ReservedТак что 0x0300 это просто Report Type = Feature (0x03 в верхем байте), при том что Report ID = 0, т.е. Report IDs не используются.
Короче вот мой полный коммит:
https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
> Думаю это скорее вот что:
>
> /*
> * HID class requests
> */
> #define HID_REQ_GET_REPORT 0x01
> #define HID_REQ_SET_REPORT 0x09
>А эта приблуда HID девайс? =-о
>> Думаю это скорее вот что:
>>
>> /*
>> * HID class requests
>> */
>> #define HID_REQ_GET_REPORT 0x01
>> #define HID_REQ_SET_REPORT 0x09
>>
> А эта приблуда HID девайс? =-оВсё указывает на это. А что?
Суть девайса: контроллер ATTiny, который с одной стороны умеет общаться с PC по USB, а с другой стороны выступает в качестве хоста сенсоров, т.е. коллектит данные сенсоров, которые висят на 1-wire шине (температурные датчики ds1820). Даём команды с компа через эту тулзовину на контроллер (по USB) и получаем выхлоп -- температуру датчиков, их ID и т.д. По идее логично такой девайс сделать HID.
>> А эта приблуда HID девайс? =-о
> Всё указывает на это. А что?Отсюда http://ru.wikipedia.org/wiki/USB_HID :
Другие устройства...
Этим стали массово пользоваться, и появилось огромное количество устройств, которые, по сути, интерфейсами взаимодействия с человеком не являются. Например, *термометр*, ..... Любое устройство может принадлежать к USB HID классу, если оно удовлетворяет логическим спецификациям HID Consumer Control.
Так что имеем USB HID термометр :)
Подобного добра уже было наделано много, в чём можно убедиться нагуглив по запросу "USB HID thermometer ATTiny45 DS18B20".
В прошивке они обычно юзают вот эту софтварную (bitbang) реализацию USB: http://www.obdev.at/products/vusb/index.html
Даже общие рекомендации есть: https://github.com/eldavido/cp-hidkeys/blob/master/Readme.txt
>>> Думаю это скорее вот что:
>>>
>>> /*
>>> * HID class requests
>>> */
>>> #define HID_REQ_GET_REPORT 0x01
>>> #define HID_REQ_SET_REPORT 0x09
>>>
>> А эта приблуда HID девайс? =-о
> Всё указывает на это. А что?Да это так, условности. HID, Audio, COM,...
USB делятся всего на 4 типа, по режиму передачи: Изохронные, Управляющие, Прерывания и Блобы (BULK).
По назначению - все девайсы ENDPOINTы (Хабы отдельная песня)
>> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/
> А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/Добрый день,
Пытаюсь собрать bmcontrol для роутера ASUS WL500gP v.1 с прошивкой WL500gp-1.9.2.7-rtn-r5066.trx на ядре 2.6.22. Компилирую на самом устройстве. Версия программы 1.1 компилируется без ошибок, но неверно определяется ID датчиков, как у DimNsk. Пробовал последнюю версию 1.1.1 от skb7, компилится с ошибками:[admin@WL-500gP bm]$ make
cc -Wall -pedantic -O2 -s -Iinclude -std=c99 -D_POSIX_C_SOURCE=199309L -c -o src/main.o src/main.c
In file included from include/os/usb.h:5,
from src/main.c:8:
/opt/include/usb.h:67: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:73: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:80: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:93: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:118: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:144: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:161: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:178: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:253: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:265: error: expected specifier-qualifier-list before Б─≤u_int32_tБ─≥
src/main.c: In function Б─≤find_lvr_winusbБ─≥:
src/main.c:88: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idVendorБ─≥
src/main.c:89: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idProductБ─≥
make: *** [src/main.o] Error 1На Ubuntu все работает, а на роутере нет. Подскажите, в чем может быть проблема?
Вычитывание ID датчиков неправильно работает из-за слишком маленькой задержки ожидания. Как временное решение можете использовать bmcontrol 1.1, но исправьте функцию задержки, как я описал в ответе #18 в этом треде.Лучше конечно попробовать починить мою версию для вашего девайса.
Чтобы пофиксить мою версию, я хотел бы узнать следующее:
1. Какая версия libusb используется? 0.1 или 1.0?
2. По хорошему такое должно делаться кросс-компиляцией, а не компилить на самом девайсе. Есть тулчейн для вашего девайса? Я хотел бы воспроизвести вашу ошибку у себя и посмотреть, в чем дело.
3. Ваша прошивка -- это не OpenWRT случайно?
Большое спасибо за отклик.Попробую собрать bmcontrol 1.1 с исправленной функцией задержки, напишу о результате.
Давайте попробуем починить вашу версию bmcontrol:
1. В прошивке роутера по умолчанию стоит libusb1.0, я дополнительно устанавливал libusb_0.1.12-2_mipsel.ipk отсюда http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/.2. Я изначально хотел собрать кросс-компиляцией на Ubuntu 12.10, но там было очень много ошибок во время компиляции, которые поправить мне не удалось. Поэтому стал пытаться уже на самом устройстве. Тулчейн есть тут - https://code.google.com/p/wl500g/downloads/list. Я пробовал на версии hndtools-mipsel-uclibc-4.6.4-K26-r5299.tar.bz2.
3. Неа, прошивка не OpenWRT. Это прощивка от Олега доработанная энтузиастами 1.9.2.7-rtn-r5066 - https://code.google.com/p/wl500g/
> 1. В прошивке роутера по умолчанию стоит libusb1.0, я дополнительно устанавливал libusb_0.1.12-2_mipsel.ipk
> отсюда http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/.т.е. вы собирали с 1.0? или с 0.1? потому что bmcontrol написана под libusb-0.1, естественно в 1.0 все изменилось и не будет собираться. Меня на эту мысль навело отсутствие полей idVendor и idProduct в структуре usb_device_descriptor (судя по ошибкам компиляции из вашего вывода сборки). Убедитесь в следующем:
1. при сборке должен использоваться хедер usb.h именно от версии 0.1 (строка номер 5 в файле include/os/usb.h в моем проекте).Если у вас этот хедер лежит не в стандартном месте (/usr/include), то нужно явно это указать компилятору при сборке. Сделать это можно в файле Makefile: во второй строке (CFLAGS) указать этот путь с помощью флага "-I" таким образом (для /opt/include):
CFLAGS = -Wall -pedantic -O2 -s -Iinclude -I/opt/includeТакже покажите вывод следующих команд:
$ pkg-config --cflags libusb
$ pkg-config --libs libusbПо хорошему вывод первой надо использовать в Makefile для задания CFLAGS в Makefile, а вывод второй -- для задания LDFLAGS в Makefile; CLFAGS и LDFLAGS попросту скармливаются потом компилятору и компоновщику соответственно, а поскольку "gcc" выступает в роли обоих -- то оба этих списка скармливаются gcc. Если у вас оно отработает корректно -- я поменяю у себя в проекте таким образом поведение мейк-файла.
2. при компоновке (linking) должна использоваться библиотека libusb именно версии 0.1
У меня в Makefile есть строка:
LDFLAGS = -lusbэто указывает компоновщику линковать проект с библиотекой libusb.so или libusb.a, но библиотека ищется по стандартным путям только (/usr/lib и т.д.). Если у вас libusb-0.1 лежит не по стандартному пути, нужно в LDFLAGS дописать путь к вашей либе таким образом (пример для случая если у вас либа лежит в /opt/lib):
LDFLAGS = -lusb -L/opt/libТ.е. у меня подозрение, что это не у меня криво сделано, а просто нестандартные пути у вас. Хотя правда возникает вопрос, почему версия 1.1 у вас нормально собирается... В общем, попробуйте сделать, что я написал пока, а насчет кросс-компиляции -- позже посмотрю и напишу.
В общем, я внес изменение в свой проект, чтобы использовался pkg-config при сборке, не знаю, может это поможет, проверьте. Обновить проект можно так:
$ git pull --rebaseВот само изменение:
https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
Но если у вас нет pkg-config или нет для него файла для libusb-0.1 (у меня он например поставляется с пакетом libusb-dev и находится тут: /usr/lib/x86_64-linux-gnu/pkgconfig/libusb.pc), то ничего вообще не соберется.
> Версия программы 1.1 компилируется без ошибокПосмотрел, какие различия между моим и его мейк-файлом. Попробуйте сделать следующие шаги. После каждого пробуйте собирать. Один из них наверняка поможет (скорее всего самый первый пункт). Напишите потом плиз о резултьтатах. Вот что стоит попробовать:
1. Добавить в самое начало моего Makefile строку:
CC = g++
2. В список CFLAGS (в моем Makefile) добавить такое:
-I/usr/include
3. В список LDFLAGS добавить тоже самое что в предыдущем пункте было добавлено в CFLAGS.4. В список LDFLAGS добавить:
-L/usr/lib
5. В список CFLAGS добавить:
$(EXTRA_CFLAGS)
> т.е. вы собирали с 1.0? или с 0.1?Собирал для версии libusb-0.1, но я был не уверен, что компилятор использует именно версию 0.1, т.к. установлено обе версии libusb.
> В общем, я внес изменение в свой проект, чтобы использовался pkg-config при сборке, не
> знаю, может это поможет, проверьте.Обновил проект. pkg-config на роутере есть, пути подставляются в Makrefile корректно. Но все равно ошибки, как в моем сообщении №46.
> 1. Добавить в самое начало моего Makefile строку: CC = g++Добавил строку CC, вот такие ошибки:
[admin@WL-500gP bm1.1.2]$ make
g++ -Wall -pedantic -O2 -s -Iinclude -I/opt/include -std=c99 -D_POSIX_C_SOURCE=199309L -c -o src/main.o src/main.c
cc1plus: warning: command line option "-std=c99" is valid for C/ObjC but not for C++
src/main.c: In function Б─≤uint64_t HexStringToUInt(char*)Б─≥:
src/main.c:641: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
make: *** [src/main.o] Error 1Удалил строку СС и еще удалил строку CFLAGS += -std=c99 -D_POSIX_C_SOURCE=199309L из Makefile. Сборка прошла без ошибок, bmcontrol работает и теперь ID датчика определяется верно!
[admin@WL-500gP bm1.1.2]$ make
cc -Wall -pedantic -O2 -s -Iinclude -I/opt/include -c -o src/main.o src/main.c
cc -o bmcontrol src/main.o -L/opt/lib -lusb
[admin@WL-500gP bm1.1.2]$ ./bmcontrol info
Firmware: 3h
USB series: 29h
USB identifier: a9bh
[admin@WL-500gP bm1.1.2]$ ./bmcontrol scan
temp_id1 = 8900000357526b28
[admin@WL-500gP bm1.1.2]$ ./bmcontrol temp 8900000357526b28
21.875000Спасибо огромное.
P.S. Осталось только проверить правдивость показаний датчика.
> P.S. Осталось только проверить правдивость показаний датчика.Результаты измерений похожи на правду.
Написал скрипт, который снимает показания каждые 5 минут и записывает их в файл. За несколько дней наблюдений выявилась странная особенность, иногда вместе с результатом измерения появляется сообщение - Error OW_WRITE_BYTE. Измерение температуры в этот момент происходит, как видно из лога:
16.7 11.03.2014_08:05
16.7 11.03.2014_08:10
Error OW_WRITE_BYTE 16.6 11.03.2014_08:15
16.6 11.03.2014_08:20
16.6 11.03.2014_08:25Смотрел в код, но так и не смог разобраться, почему появляется это сообщение.
>[оверквотинг удален]
> файл. За несколько дней наблюдений выявилась странная особенность, иногда вместе с
> результатом измерения появляется сообщение - Error OW_WRITE_BYTE. Измерение температуры
> в этот момент происходит, как видно из лога:
> 16.7 11.03.2014_08:05
> 16.7 11.03.2014_08:10
> Error OW_WRITE_BYTE 16.6 11.03.2014_08:15
> 16.6 11.03.2014_08:20
> 16.6 11.03.2014_08:25
> Смотрел в код, но так и не смог разобраться, почему появляется это
> сообщение.Пока что не разбирался, в чем проблема, но сделал такой коммит:
https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...Если вы обновите исходники, чтобы получить это изменение:
$ git pull --rebase
и пересоберете проект, то можно будет "выкинуть" сообщения об ошибках, чтобы они не мешали вашему скрипту:
$ ./bmcontrol 2>/dev/nullили если надо вести логи, то можно как-то так:
$ ./bmcontrol 2>log-err.txt | tee log-out.txt
> иногда вместе с результатом измерения появляется сообщение - Error OW_WRITE_BYTEОчень похоже на то, что говорил pavlinux здесь:
https://www.opennet.ru/openforum/vsluhforumID9/9804.html#25Попробуйте увеличить QUIRK_LIBUSB_SLEEP до 100. По-хорошему конечно надо переехать с libusb-0.1 на libusb-1.0, по идее там это починили.
> Смотрел в код, но так и не смог разобраться, почему появляется это
> сообщение.Это сообщение показывается, если вызов OW_WRITE_BYTE() завершился некорректно в одной из следующих функций:
- MATCH_ROM()
- SEARCH_ROM()
- SKIP_ROM_CONVERT()
- GET_TEMPERATURE()
Думаю, в вашем случае это была GET_TEMPERATURE().В каждой из этих функций в случае некорректного завершения OW_WRITE_BYTE делается несколько повторов (ONEWIRE_REPEAT=5), что видно из кода:
while (!RESULT && N--)
Если за 5 повторов так и не вышло нормально выполнить OW_WRITE_BYTE(), тогда будет выведено сообщение о том, в какой верхней функции произошла ошибка (список этих функций я написал выше). Но поскольку вы видите всего один вывод об ошибке, значит при повторном чтении программе удалось нормально прочитать значение датчика и вывести его. Иначе бы вы увидели 5 выводов "Error OW_WRITE_BYTE" и потом еще вывод об ошибке верхней функции.Глядя в код OW_WRITE_BYTE() можно увидеть, что всего 3 возможных причины ошибки:
1. ошибка в вызове USB_SET_FEATURE()
2. ошибка в вызове USB_GET_FEATURE()
3. некорректный USB буффер после чтения записанного значения (т.е. либо записалось что-то не то, либо прочиталось неправильно).В нашем случае это 3-я ошибка. Почему она возникает -- см. в самом верху этого сообщения.
> Очень похоже на то, что говорил pavlinux здесь:
> https://www.opennet.ru/openforum/vsluhforumID9/9804.html#25
> Попробуйте увеличить QUIRK_LIBUSB_SLEEP до 100. По-хорошему конечно надо переехать с libusb-0.1
> на libusb-1.0, по идее там это починили.Спасибо за развернутый ответ. Увеличил QUIRK_LIBUSB_SLEEP до 100, продолжаю наблюдение. Если не поможет, то поправлю скрипт, чтобы не выводил сообщения об ошибках по вашей инструкции.
> Спасибо за развернутый ответ. Увеличил QUIRK_LIBUSB_SLEEP до 100, продолжаю наблюдение.
> Если не поможет, то поправлю скрипт, чтобы не выводил сообщения об
> ошибках по вашей инструкции.Напишите плиз о результатах. Если поможет увеличение задержки на libusb_quirks -- я вмержу в свою ветку это изменение.
>> Спасибо за развернутый ответ. Увеличил QUIRK_LIBUSB_SLEEP до 100, продолжаю наблюдение.
>> Если не поможет, то поправлю скрипт, чтобы не выводил сообщения об
>> ошибках по вашей инструкции.
> Напишите плиз о результатах. Если поможет увеличение задержки на libusb_quirks -- я
> вмержу в свою ветку это изменение.Не помогло. Вчера утром внес изменения - увеличил QUIRK_LIBUSB_SLEEP до 100, ошибок не было. Вечером добавил к плате еще два датчика температуры DS18B20, скрипт теперь считывает показания с трех датчиков и записывает результаты в файл. Наблюдал весь вечер - ошибок не было. Утром глянул лог, а там снова куча ошибок. Первая появилась около часа ночи, потом они стали регулярными:
16.5 0.6 20.6 12.03.2014_06:01
16.5 0.5 Error OW_WRITE_BYTE 20.6 12.03.2014_06:05
16.4 Error OW_WRITE_BYTE 0.5 Error OW_WRITE_BYTE Error OW_WRITE_BYTE 20.6 12.03.2014_06:10
Error OW_WRITE_BYTE Error OW_WRITE_BYTE 16.4 0.4 20.6 12.03.2014_06:15
16.4 Error OW_WRITE_BYTE 0.3 20.6 12.03.2014_06:20
16.4 0.3 20.6 12.03.2014_06:25
16.3 0.2 20.5 12.03.2014_06:30
> Не помогло. Вчера утром внес изменения - увеличил QUIRK_LIBUSB_SLEEP до 100, ошибок
> не было. Вечером добавил к плате еще два датчика температуры DS18B20,
> скрипт теперь считывает показания с трех датчиков и записывает результаты в
> файл. Наблюдал весь вечер - ошибок не было. Утром глянул лог,
> а там снова куча ошибок. Первая появилась около часа ночи, потом
> они стали регулярными:Ну это не дело, конечно. Проблема может быть не только в libusb, а еще и в прошивке контроллера. Конечно, неплохо было бы разработать свой подобный девайс, написать там всё по уму, сделать его опен-сорсным. В этом девайсе, конечно, приходится только догадываться, что пошло не так.
Еще вариант (поскольку проблемы начались после подключения дополнительных датчиков) -- неправильное подключение внешних датчиков. Посмотрите по этой ссылке, как их подключать: http://www.sinava.ru/MP707.php
а именно ответ на этот вопрос:
- Подключил к устройству термодатчик на расстоянии 5 метров - работает нормально. Затем подключил его на расстоянии 40 метров - устройство его не видит! Но ведь заявлено расстояние до последнего термодатчика 100 метров по витой паре 5 категории. Но у меня растояние 40 метров! При этом хоть ВИТАЯ, хоть НЕ ВИТАЯ ПАРА, но устройство не видит термодатчик! Что можно сделать?
> Ну это не дело, конечно. Проблема может быть не только в libusb,
> а еще и в прошивке контроллера. Конечно, неплохо было бы разработать
> свой подобный девайс, написать там всё по уму, сделать его опен-сорсным.
> В этом девайсе, конечно, приходится только догадываться, что пошло не так.Верно, это было бы лучшим вариантом. К сожалению, разработчики контроллера не участвуют в дальнейшей его поддержки для *nix систем.
>[оверквотинг удален]
> http://www.sinava.ru/MP707.php
> а именно ответ на этот вопрос:
>
> - Подключил к устройству термодатчик на расстоянии 5 метров - работает нормально.
> Затем подключил его на расстоянии 40 метров - устройство его не
> видит! Но ведь заявлено расстояние до последнего термодатчика 100 метров по
> витой паре 5 категории. Но у меня растояние 40 метров! При
> этом хоть ВИТАЯ, хоть НЕ ВИТАЯ ПАРА, но устройство не видит
> термодатчик! Что можно сделать?
>Да, видел эту статью. На ее основе подключал датчики. Я не думаю, что проблема с подключением, т.к. все дополнительные датчики определяются без проблем и показывают действительные показания температуры. Попробую потом отключить доп.датчики и посмотрю на наличие ошибок.
> src/main.c: In function Б─≤find_lvr_winusbБ─≥:
> src/main.c:88: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idVendorБ─≥
> src/main.c:89: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idProductБ─≥
> Подскажите, в чем может быть проблема?Из браузера мышом копипастил? :)
>> src/main.c: In function Б─≤find_lvr_winusbБ─≥:
>> src/main.c:88: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idVendorБ─≥
>> src/main.c:89: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idProductБ─≥
>> Подскажите, в чем может быть проблема?
> Из браузера мышом копипастил? :)Копировал мышкой, но не из браузера, а из окна PuTTy.
Поскольку у вас есть девайс, не могли бы вы попробовать собрать и протестировать эту прогу на linux и windows? Я пофиксил несколько багов и сделал код кросс-платформенным, так что должно собираться и по идее работать на linux и windows. Написал автору на почту, может он себе в mainline затащит эти патчи.Вот репозиторий: https://code.google.com/r/joeskb7-bmcontrol/
Склонировать исходники можно с помощб Git, командой:
git clone https://code.google.com/r/joeskb7-bmcontrol/
Инструкции по сборке -- в файле README.Напишите результат как проверите.
>[оверквотинг удален]
> [D] CRC=c9
> [D] CRC=63
> [D] ~T=1000.000000
> [D] L1=ffffffff L2=ffffffff L3=ff
> [D] CRC=8d
> [D] CRC=c9
> [D] CRC=63
> [D] ~T=1000.000000
> [!] Error GET_TEMPERATURE
> Что не так?
if (OW_READ_4BYTE(L1))
if (OW_READ_4BYTE(L2))
if (OW_READ_BYTE(L3)) {
if (DEBUG)
printf("[D] L1=%lx\tL2=%lx\tL3=%hhx\n", L1, L2, L3);L1, L2, L3 - не инициализируются и передаются в эти функции, обратно - хрен, точнее bool.
Тогда уже так, чтобы было более понятно, что это просто loop delay:
void ldelay(volatile unsigned long loops)
{
while (loops--);
}
Скажите пожалуйста, как добиться чтобы bmcontrol заработал без sudo?/home/lukich/Downloads/bmcontrol temp a2000003351bd328
Could not set configuration 1 :
Device not plugged