Hi everyone,
I'm a bit desperate, as I can not seem to get this to work. I'm writing an application that communicates with an PIC 18F over USB. I've got the program running so far that I can send commands. Only receiving data isn't working. I've made an object, USBController, that takes care of all the USB stuff. Here is a part of it's code (full code included at bottom), I think something goes wrong here:
I get an "exc_bad_access" error when I send the command 0x81 to the PIC, which on that command returns the status of its input ports. I wasn't able to find any objects with Zombies. This was my stack content:
Does somebody know what's wrong? Is there some setting I have to set to enable Callbacks? I think I followed the HID guide pretty closely, and I have the setup working when I run it with hidapi...
Thanks in advance,
Emiel
This is the complete code:
I'm a bit desperate, as I can not seem to get this to work. I'm writing an application that communicates with an PIC 18F over USB. I've got the program running so far that I can send commands. Only receiving data isn't working. I've made an object, USBController, that takes care of all the USB stuff. Here is a part of it's code (full code included at bottom), I think something goes wrong here:
Code:
//
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#import "USBController.h"
//The callback function
static void Handle_IOHIDDeviceIOHIDReportCallback(void *context, IOReturn result, void *sender,
IOHIDReportType report_type, uint32_t report_id,
uint8_t *report, CFIndex report_length)
{
printf("hello");
}
@implementation USBController
- (void)ConnectToDevice{
//...
IOHIDDeviceScheduleWithRunLoop(tIOHIDDeviceRefs[0], CFRunLoopGetCurrent(), runloopmode);//kCFRunLoopDefaultMode);
CFIndex reportSize = 128; // note: this should be greater than or equal to the size of the report
uint8_t report = malloc(reportSize);
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize, Handle_IOHIDDeviceIOHIDReportCallback, (void*)self);
//...
}
@end
I get an "exc_bad_access" error when I send the command 0x81 to the PIC, which on that command returns the status of its input ports. I wasn't able to find any objects with Zombies. This was my stack content:
Code:
#0 0x7fffffe007c5 in __memcpy
#1 0x102709d6e in IOHIDDeviceClass::_hidReportHandlerCallback
#2 0x7fff8839468e in __CFMachPortPerform
#3 0x7fff8836c6e1 in __CFRunLoopRun
#4 0x7fff8836adbf in CFRunLoopRunSpecific
#5 0x7fff8885193a in RunCurrentEventLoopInMode
#6 0x7fff8885173f in ReceiveNextEventCommon
#7 0x7fff888515f8 in BlockUntilNextEventMatchingListInMode
#8 0x7fff861bfe64 in _DPSNextEvent
#9 0x7fff861bf7a9 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
#10 0x7fff8618548b in -[NSApplication run]
#11 0x7fff8617e1a8 in NSApplicationMain
#12 0x100000c55 in main at main.m:13
Does somebody know what's wrong? Is there some setting I have to set to enable Callbacks? I think I followed the HID guide pretty closely, and I have the setup working when I run it with hidapi...
Thanks in advance,
Emiel
This is the complete code:
Code:
//
// USBController.m
// usbtest
//
// Created by Emiel van de Ven on 27-07-11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#import "USBController.h"
//The callback function
static void Handle_IOHIDDeviceIOHIDReportCallback(void *context, IOReturn result, void *sender,
IOHIDReportType report_type, uint32_t report_id,
uint8_t *report, CFIndex report_length)
{
printf("hello");
}
@implementation USBController
- (CFMutableDictionaryRef)CreateMatchingDictionary:(UInt32)VID ProductionID:(UInt32)PID {
CFMutableDictionaryRef matchingDictionary = NULL;
// Set up a matching dictionary to search I/O Registry by class name for all HID class devices.
matchingDictionary = IOServiceMatching (kIOHIDDeviceKey);
if (matchingDictionary != NULL)
{
CFNumberRef cfValue;
cfValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type, &VID );
CFDictionaryAddValue( matchingDictionary, CFSTR("VendorID"),
cfValue);
cfValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type, &PID );
CFDictionaryAddValue( matchingDictionary, CFSTR("ProductID"),
cfValue);
}
else
printf ("Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
//printf ("Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
return matchingDictionary;
}
- (void)ConnectToDevice{
tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
// Create a device matching dictionary
CFDictionaryRef matchingCFDictRef = [self CreateMatchingDictionary:0x04D8 ProductionID:0x0042];
// set the HID device matching dictionary
IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );
// Now open the IO HID Manager reference
IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone );
// and copy out its devices
CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef );
// how many devices in the set?
CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef );
deviceIndex = 0;
// allocate a block of memory to extact the device ref's from the set into
tIOHIDDeviceRefs = calloc(deviceCount, sizeof( IOHIDDeviceRef ) );
// now extract the device ref's from the set
CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs );
// open the device
IOReturn ret = IOHIDDeviceOpen(tIOHIDDeviceRefs[0], kIOHIDOptionsTypeNone);
if (ret == kIOReturnSuccess) {
//schedule with runloop
IOHIDDeviceScheduleWithRunLoop(tIOHIDDeviceRefs[0], CFRunLoopGetCurrent(), runloopmode);//kCFRunLoopDefaultMode);
CFIndex reportSize = 128; // note: this should be greater than or equal to the size of the report
uint8_t report = malloc(reportSize);
IOHIDDeviceRegisterInputReportCallback(tIOHIDDeviceRefs[0], report, reportSize, Handle_IOHIDDeviceIOHIDReportCallback, (void*)self);
char data[256];
size_t length_to_send;
data[0] = 0x81; //ask for data
length_to_send = 1;
//send to device
IOHIDDeviceSetReport(tIOHIDDeviceRefs[0],
kIOHIDReportTypeOutput,
data[0], /* Report ID*/
(const unsigned char*)data, length_to_send);
}
}
@end