Beaglebone black LCD4 and PWM - beagleboneblack

I have a BBB running Debian Jessie. I have a modified LCD4 cape that runs great. My LCD cape uses EHRPWM1A. I would like to use the PWM output of EHRPWM1B. It is going to attach to a piezo buzzer.
I know that I can use the PWM output when my LCD cape is not enabled. I have modified the BB-BONE-BACONE cape to create 2 PWM outputs. I know that it is possible to control both the backlight for the LCD as well as the PWM for the buzzer simultaneously.
With my LCD cape enabled, I can export the PWM channel for my buzzer, set my period and duty cycle, but I get no output. Anybody have any thoughts about why this is?
My guess is that I don't understand something about how the /sys/class/backlight interacts with the PWM, but I don't know for certain.

So I managed to get this working by compiling the PWM into the overlay.
For anyone interested in this in the future, I've posted the overlay I used below.
/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/plugin/;
#include <dt-bindings/board/am335x-bbw-bbb-base.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green";
/* identification */
part-number = "BB-BONE-LCD4-01";
version = "00A2";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P8.45", /* lcd: lcd_data0 */
"P8.46", /* lcd: lcd_data1 */
"P8.43", /* lcd: lcd_data2 */
"P8.44", /* lcd: lcd_data3 */
"P8.41", /* lcd: lcd_data4 */
"P8.42", /* lcd: lcd_data5 */
"P8.39", /* lcd: lcd_data6 */
"P8.40", /* lcd: lcd_data7 */
"P8.37", /* lcd: lcd_data8 */
"P8.38", /* lcd: lcd_data9 */
"P8.36", /* lcd: lcd_data10 */
"P8.34", /* lcd: lcd_data11 */
"P8.35", /* lcd: lcd_data12 */
"P8.33", /* lcd: lcd_data13 */
"P8.31", /* lcd: lcd_data14 */
"P8.32", /* lcd: lcd_data15 */
"P8.27", /* lcd: lcd_vsync */
"P8.29", /* lcd: lcd_hsync */
"P8.28", /* lcd: lcd_pclk */
"P8.30", /* lcd: lcd_ac_bias_en */
"P9.16", /* buzzer pin */
"ehrpwm1a",
"ehrpwm1b",
"lcdc",
"tscadc";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins {
pinctrl-single,pins = <
BONE_P9_14 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* gpmc_a2.ehrpwm1a */
BONE_P9_16 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* gpmc_a2.ehrpwm1a */
>;
};
bb_lcd_lcd_pins: pinmux_bb_lcd_lcd_pins {
pinctrl-single,pins = <
BONE_P9_27 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* mcasp0_fsr.gpio3_19 */
BONE_P8_45 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */
BONE_P8_46 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */
BONE_P8_43 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */
BONE_P8_44 (PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */
BONE_P8_41 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */
BONE_P8_42 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */
BONE_P8_39 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */
BONE_P8_40 (PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */
BONE_P8_37 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */
BONE_P8_38 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */
BONE_P8_36 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */
BONE_P8_34 (PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */
BONE_P8_35 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */
BONE_P8_33 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */
BONE_P8_31 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */
BONE_P8_32 (PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */
BONE_P8_27 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync.lcd_vsync */
BONE_P8_29 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync.lcd_hsync */
BONE_P8_28 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk.lcd_pclk */
BONE_P8_30 (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */
>;
};
};
};
fragment#1 {
target = <&epwmss1>;
__overlay__ {
status = "okay";
};
};
fragment#2 {
target = <&ehrpwm1>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&bb_lcd_pwm_backlight_pins>;
status = "okay";
};
};
fragment#3 {
target = <&lcdc>;
__overlay__ {
status = "okay";
};
};
fragment#4 {
target = <&tscadc>;
__overlay__ {
status = "okay";
tsc {
ti,wires = <4>;
ti,x-plate-resistance = <200>;
ti,coordinate-readouts = <5>;
ti,wire-config = <0x00 0x11 0x22 0x33>;
};
adc {
ti,adc-channels = <4 5 6 7>;
};
};
};
fragment#5 {
target-path="/";
__overlay__ {
/* avoid stupid warning */
#address-cells = <1>;
#size-cells = <1>;
backlight {
status = "okay";
compatible = "pwm-backlight";
pwms = <&ehrpwm1 0 250000 0>;
brightness-levels = <
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
100
>;
default-brightness-level = <100>;
};
panel {
status = "okay";
compatible = "ti,tilcdc,panel";
pinctrl-names = "default";
pinctrl-0 = <&bb_lcd_lcd_pins>;
panel-info {
ac-bias = <255>;
ac-bias-intrpt = <0>;
dma-burst-sz = <16>;
bpp = <16>;
fdd = <0x80>;
sync-edge = <0>;
sync-ctrl = <1>;
raster-order = <0>;
fifo-th = <0>;
};
display-timings {
native-mode = <&timing0>;
/* www.newhavendisplay.com/app_notes/OTA5180A.pdf */
timing0: 480x272 {
clock-frequency = <9200000>;
hactive = <480>;
vactive = <272>;
hfront-porch = <8>;
hback-porch = <47>;
hsync-len = <41>;
vback-porch = <2>;
vfront-porch = <3>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
};
};
For PWM control, use the following commands:
sudo su //or log in as root
echo 1 > /sys/class/pwm/pwmchip0/export //export PWM to userspace
cd /sys/class/pwm/pwmchip0/pwm1 //change directories to make things a bit easier
echo 250000 > period //NOTE: this number must match the frequency used for the LCD backlight
echo 125000 > duty_cycle //set our duty cycle of the PWM in nano seconds
echo 1 > enable //turn PWM on
echo 0 > enable //turn PWM off
Hope this helps other people.

Related

How to discover physical address corresponding to PCIe device memory?

I'm trying to access a PCIe device memory from a user space program. I open the file: /sys/bus/pci/devices/0000:3b:00.0/resource0 and then I call mmap that will return a virtual address.
When writing at this virtual address (VA) the MMU will translate it to a physical address (PA), the memory controller will convert the write to the PA into a TLP to request a write to the PCIe device. (AFAIU)
How can I get the physical address that is being used? I had a look to /proc//maps and I see that there is an address that coincides with the PCIe bar0 address (0xa0000000).
But this address seems too low, it overlaps with DDR memory.
I also tried this program to convert VA to PA but it doesn't seem to give sensible results for such mapping:
virt2phys$ cat v2p.c
#define _XOPEN_SOURCE 700
#include <fcntl.h> /* open */
#include <stdint.h> /* uint64_t */
#include <stdio.h> /* printf */
#include <stdlib.h> /* size_t */
#include <unistd.h> /* pread, sysconf */
typedef struct {
uint64_t pfn : 55;
unsigned int soft_dirty : 1;
unsigned int file_page : 1;
unsigned int swapped : 1;
unsigned int present : 1;
} PagemapEntry;
/* Parse the pagemap entry for the given virtual address.
*
* #param[out] entry the parsed entry
* #param[in] pagemap_fd file descriptor to an open /proc/pid/pagemap file
* #param[in] vaddr virtual address to get entry for
* #return 0 for success, 1 for failure
*/
int pagemap_get_entry(PagemapEntry *entry, int pagemap_fd, uintptr_t vaddr)
{
size_t nread;
ssize_t ret;
uint64_t data;
uintptr_t vpn;
vpn = vaddr / sysconf(_SC_PAGE_SIZE);
nread = 0;
while (nread < sizeof(data)) {
ret = pread(pagemap_fd, ((uint8_t*)&data) + nread, sizeof(data) - nread,
vpn * sizeof(data) + nread);
nread += ret;
if (ret <= 0) {
return 1;
}
}
entry->pfn = data & (((uint64_t)1 << 55) - 1);
entry->soft_dirty = (data >> 55) & 1;
entry->file_page = (data >> 61) & 1;
entry->swapped = (data >> 62) & 1;
entry->present = (data >> 63) & 1;
return 0;
}
/* Convert the given virtual address to physical using /proc/PID/pagemap.
*
* #param[out] paddr physical address
* #param[in] pid process to convert for
* #param[in] vaddr virtual address to get entry for
* #return 0 for success, 1 for failure
*/
int virt_to_phys_user(uintptr_t *paddr, pid_t pid, uintptr_t vaddr)
{
char pagemap_file[BUFSIZ];
int pagemap_fd;
snprintf(pagemap_file, sizeof(pagemap_file), "/proc/%ju/pagemap", (uintmax_t)pid);
pagemap_fd = open(pagemap_file, O_RDONLY);
if (pagemap_fd < 0) {
return 1;
}
PagemapEntry entry;
if (pagemap_get_entry(&entry, pagemap_fd, vaddr)) {
return 1;
}
close(pagemap_fd);
*paddr = (entry.pfn * sysconf(_SC_PAGE_SIZE)) + (vaddr % sysconf(_SC_PAGE_SIZE));
return 0;
}
int main(int argc, char **argv)
{
pid_t pid;
uintptr_t vaddr, paddr = 0;
if (argc < 3) {
printf("Usage: %s pid vaddr(in hex)\n", argv[0]);
return EXIT_FAILURE;
}
pid = strtoull(argv[1], NULL, 0);
vaddr = strtoull(argv[2], NULL, 16);
if (virt_to_phys_user(&paddr, pid, vaddr)) {
fprintf(stderr, "error: virt_to_phys_user\n");
return EXIT_FAILURE;
};
printf("0x%jx\n", (uintmax_t)paddr);
return EXIT_SUCCESS;
}

Format error setting up AudioQueue for recording, but only happens once in a while

So oddly, this error happens only once in a while, when we are setting up the audio queue (even though I'm doing everything the same way). Device iPhone 5, iOS8.3:
mediaserverd[37] <Error>: 15:14:24.594 ERROR: [0x2883000] >aq> 323: AudioConverterNew from AudioQueueNew returned 'fmt?'
io: 0 ch, 44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved
client: 0 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit signed integer
Here's the code that triggers it.
SetupAudioFormat(kAudioFormatLinearPCM);
// create the queue
XThrowIfError(AudioQueueNewInput(
&mRecordFormat,
MyInputBufferHandler,
this /* userData */,
NULL /* run loop */, NULL /* run loop mode */,
0 /* flags */, &mQueue), "AudioQueueNewInput failed");
where mRecordFormat is setup like:
void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
{
memset(&mRecordFormat, 0, sizeof(mRecordFormat));
UInt32 size = sizeof(mRecordFormat.mSampleRate);
mRecordFormat.mSampleRate=[AVAudioSession sharedInstance].sampleRate;
size = sizeof(mRecordFormat.mChannelsPerFrame);
mRecordFormat.mChannelsPerFrame=(UInt32)[AVAudioSession sharedInstance].inputNumberOfChannels;
mRecordFormat.mFormatID = inFormatID;
mRecordFormat.mBytesPerFrame =mRecordFormat.mChannelsPerFrame * sizeof (SInt16);
if (inFormatID == kAudioFormatLinearPCM)
{
// if we want pcm, default to signed 16-bit little-endian
mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
mRecordFormat.mBitsPerChannel = 16;
mRecordFormat.mBytesPerPacket = mRecordFormat.mBytesPerFrame = (mRecordFormat.mBitsPerChannel / 8) * mRecordFormat.mChannelsPerFrame;
mRecordFormat.mFramesPerPacket = 1;
} else if(inFormatID==kAudioFileAIFFType) {
mRecordFormat.mFramesPerPacket = 1;
mRecordFormat.mFormatFlags =
kLinearPCMFormatFlagIsBigEndian
| kLinearPCMFormatFlagIsSignedInteger
| kLinearPCMFormatFlagIsPacked;
}
}
My interpretation of the error is that the phone is recording as 32-bit little-endian float, deinterleaved and I'm trying to setup a queue with a format that is 16-bit signed integer. But why don't I get the error everytime? How to fix it?
AudioStreamBasicDescriptions are really annoying. Here is what I use. I have typedefed AudioStreamBasicDescription to ASBD
ASBD asbdWithInfo(Boolean isFloat,int numberOfChannels,Boolean interleavedIfStereo){
ASBD asbd = {0};
int sampleSize = isFloat ? sizeof(float) : sizeof(SInt16);
asbd.mChannelsPerFrame = (numberOfChannels == 1) ? 1 : 2;
asbd.mBitsPerChannel = 8 * sampleSize;
asbd.mFramesPerPacket = 1;
asbd.mSampleRate = 44100.0;
asbd.mBytesPerFrame = interleavedIfStereo ? sampleSize * asbd.mChannelsPerFrame : sampleSize;
asbd.mBytesPerPacket = asbd.mBytesPerFrame;
asbd.mReserved = 0;
asbd.mFormatID = kAudioFormatLinearPCM;
if (isFloat) {
asbd.mFormatFlags = kAudioFormatFlagIsFloat;
if (interleavedIfStereo) {
if (numberOfChannels == 1) {
asbd.mFormatFlags = asbd.mFormatFlags | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
}
}
else{
asbd.mFormatFlags = asbd.mFormatFlags | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked ;
}
}
else{
asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
if (!interleavedIfStereo) {
if (numberOfChannels > 1) {
asbd.mFormatFlags = asbd.mFormatFlags | kAudioFormatFlagIsNonInterleaved;
}
}
}
return asbd;
}

MobileDevice Framework AMDeviceCopyValue get ECID

(Hope this post don't get too messy)
Hello, I have a question about the AMDeviceCopyValue function in mobiledevice library, because I want to grab the ECID from a connected iDevice and print it, in the c console.
#include "MobileDevice.h"
void device_callback(struct am_device_notification_callback_info *info, void *arg) {
struct am_device *dev;
if (info->msg == ADNCI_MSG_CONNECTED) {
dev = info->dev;
CFRetain(dev);
AMDSetLogLevel(5);
AMDeviceConnect(dev);
assert(AMDeviceIsPaired(dev));
assert(!AMDeviceValidatePairing(dev));
assert(!AMDeviceStartSession(dev));
assert(AMDeviceIsPaired(dev));
assert(AMDeviceValidatePairing(dev) == 0);
CFStringRef Serial = AMDeviceCopyValue(dev, 0, CFSTR("SerialNumber"));
printf("Serial (%s)", CFStringGetCStringPtr(Serial, CFStringGetSystemEncoding()));
}
}
int main(int argc, char *argv[]) {
struct am_device_notification *notify;
AMDeviceNotificationSubscribe(&device_callback, 0, 0, NULL, &notify);
CFRunLoopRun();
}
This code will print out the serial number of the iDevice,but I want it to print out the ECID so I read at theiphonewiki that if I wanted to get the ECID I had to use the value "UniqueChipID" with the function (AMDeviceCopyValue) link
but that doesn't seem to work very well....
Cause if I edit the value from SerialNumber to UniqueChipID, and run the code it all crashes.... :(
so if you want to try to help me, first you have to create a header file(I called it MobileDevice.h) (you also have to add MobileDevice.framework (its a private apple framework found in /System/Library/PrivateFrameworks ) and add this code to the MobileDevice.h
/* ----------------------------------------------------------------------------
* MobileDevice.h - interface to MobileDevice.framework
* $LastChangedDate: 2007-07-09 18:59:29 -0700 (Mon, 09 Jul 2007) $
*
* Copied from http://iphonesvn.halifrag.com/svn/iPhone/
* With modifications from Allen Porter and Scott Turner
*
* ------------------------------------------------------------------------- */
#ifndef MOBILEDEVICE_H
#define MOBILEDEVICE_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(WIN32)
#include <CoreFoundation.h>
typedef unsigned int mach_error_t;
#elif defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
#include <mach/error.h>
#endif
/* Error codes */
#define MDERR_APPLE_MOBILE (err_system(0x3a))
#define MDERR_IPHONE (err_sub(0))
/* Apple Mobile (AM*) errors */
#define MDERR_OK ERR_SUCCESS
#define MDERR_SYSCALL (ERR_MOBILE_DEVICE | 0x01)
#define MDERR_OUT_OF_MEMORY (ERR_MOBILE_DEVICE | 0x03)
#define MDERR_QUERY_FAILED (ERR_MOBILE_DEVICE | 0x04)
#define MDERR_INVALID_ARGUMENT (ERR_MOBILE_DEVICE | 0x0b)
#define MDERR_DICT_NOT_LOADED (ERR_MOBILE_DEVICE | 0x25)
/* Apple File Connection (AFC*) errors */
#define MDERR_AFC_OUT_OF_MEMORY 0x03
/* USBMux errors */
#define MDERR_USBMUX_ARG_NULL 0x16
#define MDERR_USBMUX_FAILED 0xffffffff
/* Messages passed to device notification callbacks: passed as part of
* am_device_notification_callback_info. */
#define ADNCI_MSG_CONNECTED 1
#define ADNCI_MSG_DISCONNECTED 2
#define ADNCI_MSG_UNKNOWN 3
#define AMD_IPHONE_PRODUCT_ID 0x1290
#define AMD_IPHONE_SERIAL "3391002d9c804d105e2c8c7d94fc35b6f3d214a3"
/* Services, found in /System/Library/Lockdown/Services.plist */
#define AMSVC_AFC CFSTR("com.apple.afc")
#define AMSVC_BACKUP CFSTR("com.apple.mobilebackup")
#define AMSVC_CRASH_REPORT_COPY CFSTR("com.apple.crashreportcopy")
#define AMSVC_DEBUG_IMAGE_MOUNT CFSTR("com.apple.mobile.debug_image_mount")
#define AMSVC_NOTIFICATION_PROXY CFSTR("com.apple.mobile.notification_proxy")
#define AMSVC_PURPLE_TEST CFSTR("com.apple.purpletestr")
#define AMSVC_SOFTWARE_UPDATE CFSTR("com.apple.mobile.software_update")
#define AMSVC_SYNC CFSTR("com.apple.mobilesync")
#define AMSVC_SCREENSHOT CFSTR("com.apple.screenshotr")
#define AMSVC_SYSLOG_RELAY CFSTR("com.apple.syslog_relay")
#define AMSVC_SYSTEM_PROFILER CFSTR("com.apple.mobile.system_profiler")
typedef unsigned int afc_error_t;
typedef unsigned int usbmux_error_t;
typedef unsigned int service_conn_t;
struct am_recovery_device;
typedef struct am_device_notification_callback_info {
struct am_device *dev; /* 0 device */
unsigned int msg; /* 4 one of ADNCI_MSG_* */
} __attribute__ ((packed)) am_device_notification_callback_info;
/* The type of the device restore notification callback functions.
* TODO: change to correct type. */
typedef void (*am_restore_device_notification_callback)(struct
am_recovery_device *);
/* This is a CoreFoundation object of class AMRecoveryModeDevice. */
typedef struct am_recovery_device {
unsigned char unknown0[8]; /* 0 */
am_restore_device_notification_callback callback; /* 8 */
void *user_info; /* 12 */
unsigned char unknown1[12]; /* 16 */
unsigned int readwrite_pipe; /* 28 */
unsigned char read_pipe; /* 32 */
unsigned char write_ctrl_pipe; /* 33 */
unsigned char read_unknown_pipe; /* 34 */
unsigned char write_file_pipe; /* 35 */
unsigned char write_input_pipe; /* 36 */
} __attribute__ ((packed)) am_recovery_device;
/* A CoreFoundation object of class AMRestoreModeDevice. */
typedef struct am_restore_device {
unsigned char unknown[32];
int port;
} __attribute__ ((packed)) am_restore_device;
/* The type of the device notification callback function. */
typedef void(*am_device_notification_callback)(struct
am_device_notification_callback_info *, void* arg);
/* The type of the _AMDDeviceAttached function.
* TODO: change to correct type. */
typedef void *amd_device_attached_callback;
typedef struct am_device {
unsigned char unknown0[16]; /* 0 - zero */
unsigned int device_id; /* 16 */
unsigned int product_id; /* 20 - set to AMD_IPHONE_PRODUCT_ID */
char *serial; /* 24 - set to AMD_IPHONE_SERIAL */
unsigned int unknown1; /* 28 */
unsigned char unknown2[4]; /* 32 */
unsigned int lockdown_conn; /* 36 */
unsigned char unknown3[8]; /* 40 */
} __attribute__ ((packed)) am_device;
typedef struct am_device_notification {
unsigned int unknown0; /* 0 */
unsigned int unknown1; /* 4 */
unsigned int unknown2; /* 8 */
am_device_notification_callback callback; /* 12 */
unsigned int unknown3; /* 16 */
} __attribute__ ((packed)) am_device_notification;
typedef struct afc_connection {
unsigned int handle; /* 0 */
unsigned int unknown0; /* 4 */
unsigned char unknown1; /* 8 */
unsigned char padding[3]; /* 9 */
unsigned int unknown2; /* 12 */
unsigned int unknown3; /* 16 */
unsigned int unknown4; /* 20 */
unsigned int fs_block_size; /* 24 */
unsigned int sock_block_size; /* 28: always 0x3c */
unsigned int io_timeout; /* 32: from AFCConnectionOpen, usu. 0 */
void *afc_lock; /* 36 */
unsigned int context; /* 40 */
} __attribute__ ((packed)) afc_connection;
typedef struct afc_directory {
unsigned char unknown[0]; /* size unknown */
} __attribute__ ((packed)) afc_directory;
typedef struct afc_dictionary {
unsigned char unknown[0]; /* size unknown */
} __attribute__ ((packed)) afc_dictionary;
typedef unsigned long long afc_file_ref;
typedef struct usbmux_listener_1 { /* offset value in iTunes */
unsigned int unknown0; /* 0 1 */
unsigned char *unknown1; /* 4 ptr, maybe device? */
amd_device_attached_callback callback; /* 8 _AMDDeviceAttached */
unsigned int unknown3; /* 12 */
unsigned int unknown4; /* 16 */
unsigned int unknown5; /* 20 */
} __attribute__ ((packed)) usbmux_listener_1;
typedef struct usbmux_listener_2 {
unsigned char unknown0[4144];
} __attribute__ ((packed)) usbmux_listener_2;
typedef struct am_bootloader_control_packet {
unsigned char opcode; /* 0 */
unsigned char length; /* 1 */
unsigned char magic[2]; /* 2: 0x34, 0x12 */
unsigned char payload[0]; /* 4 */
} __attribute__ ((packed)) am_bootloader_control_packet;
/* ----------------------------------------------------------------------------
* Public routines
* ------------------------------------------------------------------------- */
void AMDSetLogLevel(int level);
/* Registers a notification with the current run loop. The callback gets
* copied into the notification struct, as well as being registered with the
* current run loop. dn_unknown3 gets copied into unknown3 in the same.
* (Maybe dn_unknown3 is a user info parameter that gets passed as an arg to
* the callback?) unused0 and unused1 are both 0 when iTunes calls this.
* In iTunes the callback is located from $3db78e-$3dbbaf.
*
* Returns:
* MDERR_OK if successful
* MDERR_SYSCALL if CFRunLoopAddSource() failed
* MDERR_OUT_OF_MEMORY if we ran out of memory
*/
mach_error_t AMDeviceNotificationSubscribe(am_device_notification_callback
callback, unsigned int unused0, unsigned int unused1, void* //unsigned int
dn_unknown3, struct am_device_notification **notification);
/* Connects to the iPhone. Pass in the am_device structure that the
* notification callback will give to you.
*
* Returns:
* MDERR_OK if successfully connected
* MDERR_SYSCALL if setsockopt() failed
* MDERR_QUERY_FAILED if the daemon query failed
* MDERR_INVALID_ARGUMENT if USBMuxConnectByPort returned 0xffffffff
*/
mach_error_t AMDeviceConnect(struct am_device *device);
/* Calls PairingRecordPath() on the given device, than tests whether the path
* which that function returns exists. During the initial connect, the path
* returned by that function is '/', and so this returns 1.
*
* Returns:
* 0 if the path did not exist
* 1 if it did
*/
int AMDeviceIsPaired(struct am_device *device);
/* iTunes calls this function immediately after testing whether the device is
* paired. It creates a pairing file and establishes a Lockdown connection.
*
* Returns:
* MDERR_OK if successful
* MDERR_INVALID_ARGUMENT if the supplied device is null
* MDERR_DICT_NOT_LOADED if the load_dict() call failed
*/
mach_error_t AMDeviceValidatePairing(struct am_device *device);
/* Creates a Lockdown session and adjusts the device structure appropriately
* to indicate that the session has been started. iTunes calls this function
* after validating pairing.
*
* Returns:
* MDERR_OK if successful
* MDERR_INVALID_ARGUMENT if the Lockdown conn has not been established
* MDERR_DICT_NOT_LOADED if the load_dict() call failed
*/
mach_error_t AMDeviceStartSession(struct am_device *device);
/* Starts a service and returns a handle that can be used in order to further
* access the service. You should stop the session and disconnect before using
* the service. iTunes calls this function after starting a session. It starts
* the service and the SSL connection. unknown may safely be
* NULL (it is when iTunes calls this), but if it is not, then it will be
* filled upon function exit. service_name should be one of the AMSVC_*
* constants. If the service is AFC (AMSVC_AFC), then the handle is the handle
* that will be used for further AFC* calls.
*
* Returns:
* MDERR_OK if successful
* MDERR_SYSCALL if the setsockopt() call failed
* MDERR_INVALID_ARGUMENT if the Lockdown conn has not been established
*/
mach_error_t AMDeviceStartService(struct am_device *device, CFStringRef
service_name, service_conn_t *handle, unsigned int *
unknown);
mach_error_t AMDeviceStartHouseArrestService(struct am_device *device, CFStringRef identifier, void *unknown, service_conn_t *handle, unsigned int *what);
/* Stops a session. You should do this before accessing services.
*
* Returns:
* MDERR_OK if successful
* MDERR_INVALID_ARGUMENT if the Lockdown conn has not been established
*/
mach_error_t AMDeviceStopSession(struct am_device *device);
/* Opens an Apple File Connection. You must start the appropriate service
* first with AMDeviceStartService(). In iTunes, io_timeout is 0.
*
* Returns:
* MDERR_OK if successful
* MDERR_AFC_OUT_OF_MEMORY if malloc() failed
*/
afc_error_t AFCConnectionOpen(service_conn_t handle, unsigned int io_timeout,
struct afc_connection **conn);
/* Pass in a pointer to an afc_device_info structure. It will be filled. */
afc_error_t AFCDeviceInfoOpen(afc_connection *conn, struct
afc_dictionary **info);
/* Turns debug mode on if the environment variable AFCDEBUG is set to a numeric
* value, or if the file '/AFCDEBUG' is present and contains a value. */
void AFCPlatformInit();
/* Opens a directory on the iPhone. Pass in a pointer in dir to be filled in.
* Note that this normally only accesses the iTunes sandbox/partition as the
* root, which is /var/root/Media. Pathnames are specified with '/' delimiters
* as in Unix style.
*
* Returns:
* MDERR_OK if successful
*/
afc_error_t AFCDirectoryOpen(afc_connection *conn, const char *path,
struct afc_directory **dir);
/* Acquires the next entry in a directory previously opened with
* AFCDirectoryOpen(). When dirent is filled with a NULL value, then the end
* of the directory has been reached. '.' and '..' will be returned as the
* first two entries in each directory except the root; you may want to skip
* over them.
*
* Returns:
* MDERR_OK if successful, even if no entries remain
*/
afc_error_t AFCDirectoryRead(afc_connection *conn/*unsigned int unused*/, struct afc_directory *dir,
char **dirent);
afc_error_t AFCDirectoryClose(afc_connection *conn, struct afc_directory *dir);
afc_error_t AFCDirectoryCreate(afc_connection *conn, const char *dirname);
afc_error_t AFCRemovePath(afc_connection *conn, const char *dirname);
afc_error_t AFCRenamePath(afc_connection *conn, const char *from, const char *to);
afc_error_t AFCLinkPath(afc_connection *conn, long long int linktype, const char *target, const char *linkname);
/* Returns the context field of the given AFC connection. */
unsigned int AFCConnectionGetContext(afc_connection *conn);
/* Returns the fs_block_size field of the given AFC connection. */
unsigned int AFCConnectionGetFSBlockSize(afc_connection *conn);
/* Returns the io_timeout field of the given AFC connection. In iTunes this is
* 0. */
unsigned int AFCConnectionGetIOTimeout(afc_connection *conn);
/* Returns the sock_block_size field of the given AFC connection. */
unsigned int AFCConnectionGetSocketBlockSize(afc_connection *conn);
/* Closes the given AFC connection. */
afc_error_t AFCConnectionClose(afc_connection *conn);
/* Registers for device notifications related to the restore process. unknown0
* is zero when iTunes calls this. In iTunes,
* the callbacks are located at:
* 1: $3ac68e-$3ac6b1, calls $3ac542(unknown1, arg, 0)
* 2: $3ac66a-$3ac68d, calls $3ac542(unknown1, 0, arg)
* 3: $3ac762-$3ac785, calls $3ac6b2(unknown1, arg, 0)
* 4: $3ac73e-$3ac761, calls $3ac6b2(unknown1, 0, arg)
*/
unsigned int AMRestoreRegisterForDeviceNotifications(
am_restore_device_notification_callback dfu_connect_callback,
am_restore_device_notification_callback recovery_connect_callback,
am_restore_device_notification_callback dfu_disconnect_callback,
am_restore_device_notification_callback recovery_disconnect_callback,
unsigned int unknown0,
void *user_info);
/* Causes the restore functions to spit out (unhelpful) progress messages to
* the file specified by the given path. iTunes always calls this right before
* restoring with a path of
* "$HOME/Library/Logs/iPhone Updater Logs/iPhoneUpdater X.log", where X is an
* unused number.
*/
unsigned int AMRestoreEnableFileLogging(char *path);
/* Initializes a new option dictionary to default values. Pass the constant
* kCFAllocatorDefault as the allocator. The option dictionary looks as
* follows:
* {
* NORImageType => 'production',
* AutoBootDelay => 0,
* KernelCacheType => 'Release',
* UpdateBaseband => true,
* DFUFileType => 'RELEASE',
* SystemImageType => 'User',
* CreateFilesystemPartitions => true,
* FlashNOR => true,
* RestoreBootArgs => 'rd=md0 nand-enable-reformat=1 -progress'
* BootImageType => 'User'
* }
*
* Returns:
* the option dictionary if successful
* NULL if out of memory
*/
CFMutableDictionaryRef AMRestoreCreateDefaultOptions(CFAllocatorRef allocator);
/* ----------------------------------------------------------------------------
* Less-documented public routines
* ------------------------------------------------------------------------- */
/* mode 2 = read, mode 3 = write */
afc_error_t AFCFileRefOpen(afc_connection *conn, const char *path,
unsigned long long mode, afc_file_ref *ref);
afc_error_t AFCFileRefSeek(afc_connection *conn, afc_file_ref ref,
unsigned long long offset1, unsigned long long offset2);
afc_error_t AFCFileRefRead(afc_connection *conn, afc_file_ref ref,
void *buf, unsigned int *len);
afc_error_t AFCFileRefSetFileSize(afc_connection *conn, afc_file_ref ref,
unsigned long long offset);
afc_error_t AFCFileRefWrite(afc_connection *conn, afc_file_ref ref,
const void *buf, unsigned int len);
afc_error_t AFCFileRefClose(afc_connection *conn, afc_file_ref ref);
afc_error_t AFCFileInfoOpen(afc_connection *conn, const char *path, struct
afc_dictionary **info);
afc_error_t AFCKeyValueRead(struct afc_dictionary *dict, char **key, char **
val);
afc_error_t AFCKeyValueClose(struct afc_dictionary *dict);
unsigned int AMRestorePerformRecoveryModeRestore(struct am_recovery_device *
rdev, CFDictionaryRef opts, void *callback, void *user_info);
unsigned int AMRestorePerformRestoreModeRestore(struct am_restore_device *
rdev, CFDictionaryRef opts, void *callback, void *user_info);
struct am_restore_device *AMRestoreModeDeviceCreate(unsigned int unknown0,
unsigned int connection_id, unsigned int unknown1);
unsigned int AMRestoreCreatePathsForBundle(CFStringRef restore_bundle_path,
CFStringRef kernel_cache_type, CFStringRef boot_image_type, unsigned int
unknown0, CFStringRef *firmware_dir_path, CFStringRef *
kernelcache_restore_path, unsigned int unknown1, CFStringRef *
ramdisk_path);
unsigned int AMDeviceGetConnectionID(struct am_device *device);
mach_error_t AMDeviceEnterRecovery(struct am_device *device);
mach_error_t AMDeviceDisconnect(struct am_device *device);
mach_error_t AMDeviceRetain(struct am_device *device);
mach_error_t AMDeviceRelease(struct am_device *device);
CFStringRef AMDeviceCopyValue(struct am_device *device, unsigned int, CFStringRef cfstring);
CFStringRef AMDeviceCopyDeviceIdentifier(struct am_device *device);
typedef void (*notify_callback)(CFStringRef notification, void *data);
mach_error_t AMDPostNotification(service_conn_t socket, CFStringRef notification, CFStringRef userinfo);
mach_error_t AMDObserveNotification(void *socket, CFStringRef notification);
mach_error_t AMDListenForNotifications(void *socket, notify_callback cb, void *data);
mach_error_t AMDShutdownNotificationProxy(void *socket);
/*edits by geohot*/
mach_error_t AMDeviceDeactivate(struct am_device *device);
mach_error_t AMDeviceActivate(struct am_device *device, CFMutableDictionaryRef);
/*end*/
void *AMDeviceSerialize(struct am_device *device);
void AMDAddLogFileDescriptor(int fd);
//kern_return_t AMDeviceSendMessage(service_conn_t socket, void *unused, CFPropertyListRef plist);
//kern_return_t AMDeviceReceiveMessage(service_conn_t socket, CFDictionaryRef options, CFPropertyListRef * result);
/* ----------------------------------------------------------------------------
* Semi-private routines
* ------------------------------------------------------------------------- */
/* Pass in a usbmux_listener_1 structure and a usbmux_listener_2 structure
* pointer, which will be filled with the resulting usbmux_listener_2.
*
* Returns:
* MDERR_OK if completed successfully
* MDERR_USBMUX_ARG_NULL if one of the arguments was NULL
* MDERR_USBMUX_FAILED if the listener was not created successfully
*/
usbmux_error_t USBMuxListenerCreate(struct usbmux_listener_1 *esi_fp8, struct
usbmux_listener_2 **eax_fp12);
/* ----------------------------------------------------------------------------
* Less-documented semi-private routines
* ------------------------------------------------------------------------- */
usbmux_error_t USBMuxListenerHandleData(void *);
/* ----------------------------------------------------------------------------
* Private routines - here be dragons
* ------------------------------------------------------------------------- */
/* AMRestorePerformRestoreModeRestore() calls this function with a dictionary
* in order to perform certain special restore operations
* (RESTORED_OPERATION_*). It is thought that this function might enable
* significant access to the phone. */
typedef unsigned int (*t_performOperation)(struct am_restore_device *rdev,
CFDictionaryRef op); // __attribute__ ((regparm(2)));
#ifdef __cplusplus
}
#endif
#endif
Would loved any help I can get!!!
And I hope this post isĀ“nt to messy?
The value associated with UniqueChipID is a CFNumber not a CFString.
4 : <CFString 0x7fa18bf62f90 [0x7fff7279ecf0]>{contents = "UniqueChipID"} = <CFNumber 0x18a19201535c55c5 [0x7fff7279ecf0]>{value = +0000000000000000, type = kCFNumberSInt64Type}
Incidentally, CFShow is your friend.
Example:
CFNumberRef ecid = AMDeviceCopyValue(dev, 0, CFSTR("UniqueChipID"));

obtaining scsi(including SAS and FC) hardisk model and serial number

I have recently been playing around with some hard drive stuff. Now what I want to do is print out the model and serial number of harddisk. Sata drives are very easy with ioctl. scsi on the other hand I have to send an inquiry command. I found a very helpful site which explains everything and even has a example program: http://tldp.org/HOWTO/archived/SCSI-Programming-HOWTO/SCSI-Programming-HOWTO-24.html
but I only get nothing or gibberish as a result if I print it out. I even had to fix the program as stdlib wasn't included and the function Inquiry returned a local variable. But I have no idea how to fix it...
#define DEVICE "/dev/sdb"
/* Example program to demonstrate the generic SCSI interface */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/sg.h>
#define SCSI_OFF sizeof(struct sg_header)
static unsigned char cmd[SCSI_OFF + 18]; /* SCSI command buffer */
int fd; /* SCSI device/file descriptor */
/* process a complete scsi cmd. Use the generic scsi interface. */
static int handle_scsi_cmd(unsigned cmd_len, /* command length */
unsigned in_size, /* input data size */
unsigned char *i_buff, /* input buffer */
unsigned out_size, /* output data size */
unsigned char *o_buff /* output buffer */
)
{
int status = 0;
struct sg_header *sg_hd;
/* safety checks */
if (!cmd_len) return -1; /* need a cmd_len != 0 */
if (!i_buff) return -1; /* need an input buffer != NULL */
#ifdef SG_BIG_BUFF
if (SCSI_OFF + cmd_len + in_size > SG_BIG_BUFF) return -1;
if (SCSI_OFF + out_size > SG_BIG_BUFF) return -1;
#else
if (SCSI_OFF + cmd_len + in_size > 4096) return -1;
if (SCSI_OFF + out_size > 4096) return -1;
#endif
if (!o_buff) out_size = 0;
/* generic scsi device header construction */
sg_hd = (struct sg_header *) i_buff;
sg_hd->reply_len = SCSI_OFF + out_size;
sg_hd->twelve_byte = cmd_len == 12;
sg_hd->result = 0;
#if 0
sg_hd->pack_len = SCSI_OFF + cmd_len + in_size; /* not necessary */
sg_hd->pack_id; /* not used */
sg_hd->other_flags; /* not used */
#endif
/* send command */
status = write( fd, i_buff, SCSI_OFF + cmd_len + in_size );
if ( status < 0 || status != SCSI_OFF + cmd_len + in_size ||
sg_hd->result ) {
/* some error happened */
fprintf( stderr, "write(generic) result = 0x%x cmd = 0x%x\n",
sg_hd->result, i_buff[SCSI_OFF] );
perror("");
return status;
}
if (!o_buff) o_buff = i_buff; /* buffer pointer check */
/* retrieve result */
status = read( fd, o_buff, SCSI_OFF + out_size);
if ( status < 0 || status != SCSI_OFF + out_size || sg_hd->result ) {
/* some error happened */
fprintf( stderr, "read(generic) result = 0x%x cmd = 0x%x\n",
sg_hd->result, o_buff[SCSI_OFF] );
fprintf( stderr, "read(generic) sense "
"%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
sg_hd->sense_buffer[0], sg_hd->sense_buffer[1],
sg_hd->sense_buffer[2], sg_hd->sense_buffer[3],
sg_hd->sense_buffer[4], sg_hd->sense_buffer[5],
sg_hd->sense_buffer[6], sg_hd->sense_buffer[7],
sg_hd->sense_buffer[8], sg_hd->sense_buffer[9],
sg_hd->sense_buffer[10], sg_hd->sense_buffer[11],
sg_hd->sense_buffer[12], sg_hd->sense_buffer[13],
sg_hd->sense_buffer[14], sg_hd->sense_buffer[15]);
if (status < 0)
perror("");
}
/* Look if we got what we expected to get */
if (status == SCSI_OFF + out_size) status = 0; /* got them all */
return status; /* 0 means no error */
}
#define INQUIRY_CMD 0x12
#define INQUIRY_CMDLEN 6
#define INQUIRY_REPLY_LEN 96
#define INQUIRY_VENDOR 8 /* Offset in reply data to vendor name */
/* request vendor brand and model */
static unsigned char *Inquiry ( void )
{
unsigned char Inqbuffer[ SCSI_OFF + INQUIRY_REPLY_LEN ];
unsigned char cmdblk [ INQUIRY_CMDLEN ] =
{ INQUIRY_CMD, /* command */
0, /* lun/reserved */
0, /* page code */
0, /* reserved */
INQUIRY_REPLY_LEN, /* allocation length */
0 };/* reserved/flag/link */
memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );
/*
* +------------------+
* | struct sg_header | <- cmd
* +------------------+
* | copy of cmdblk | <- cmd + SCSI_OFF
* +------------------+
*/
if (handle_scsi_cmd(sizeof(cmdblk), 0, cmd,
sizeof(Inqbuffer) - SCSI_OFF, Inqbuffer )) {
fprintf( stderr, "Inquiry failed\n" );
exit(2);
}
return (Inqbuffer + SCSI_OFF);
}
void main( void )
{
fd = open(DEVICE, O_RDWR);
if (fd < 0) {
fprintf( stderr, "Need read/write permissions for "DEVICE".\n" );
exit(1);
}
/* print some fields of the Inquiry result */
printf( "||%s||", Inquiry() + INQUIRY_VENDOR );
}

how to read status registers of a printer in qnx

i am using an x86 processor.
the interface used to connect to the printer is a usb parallel port ieee1284.
i can send data to the printer no problem.
i have tested it with the following command.
cat file.txt > /dev/usbpar0
i have read on several forums that there is no base address for a usb parallel port.
what would be the easiest way of reading the status of the printer.
I need to know if it is out of paper or there is a paper jam. that is why i need to read the status registers.
I have included the source code i have tried to copy from [here][1]
#include <iostream>
#include <iomanip>
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include "stdlib.h"
#include "unistd.h"
#include "sys/io.h"
#include <hw/inout.h>
#include <stdint.h>
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h> /* open() */
#include <sys/types.h> /* open() */
#include <sys/stat.h> /* open() */
#include <sys/ioctl.h>
#include "parport.h"
#include "ppdev.h"
#define DEVICE "/dev/usbpar0"
int write_data(int fd, unsigned char data);
int status_pins(int fd);
using namespace std;
int main(int argc, char **argv)
{
struct ppdev_frob_struct frob;
int fd;
int mode;
if((fd=open(DEVICE, O_RDWR)) < 0) {
fprintf(stderr, "can not open %s\n", DEVICE);
return 10;
}
ThreadCtl(_NTO_TCTL_IO, 0);
status_pins(fd);
close(fd);
return 0;
}
/* trivial example how to write data */
int write_data(int fd, unsigned char data)
{
return(ioctl(fd, PPWDATA, &data));
}
/* example how to read 8 bit from the data lines */
int read_data(int fd)
{
int mode, res;
unsigned char data;
mode = IEEE1284_MODE_ECP;
res=ioctl(fd, PPSETMODE, &mode); /* ready to read ? */
mode=255;
res=ioctl(fd, PPDATADIR, &mode); /* switch output driver off */
printf("ready to read data !\n");
fflush(stdout);
sleep(10);
res=ioctl(fd, PPRDATA, &data); /* now fetch the data! */
printf("data=%02x\n", data);
fflush(stdout);
sleep(10);
data=0;
res=ioctl(fd, PPDATADIR, data);
return 0;
}
/* example how to read the status lines. */
int status_pins(int fd)
{
int val;
ioctl(fd, PPRSTATUS, &val);
val^=PARPORT_STATUS_BUSY; /* /BUSY needs to get inverted */
printf("BUSY = %s\n",
((val & PARPORT_STATUS_BUSY)==PARPORT_STATUS_BUSY)?"HI":"LO");
printf("ERROR = %s\n",
((val & PARPORT_STATUS_ERROR)==PARPORT_STATUS_ERROR)?"HI":"LO");
printf("SELECT = %s\n",
((val & PARPORT_STATUS_SELECT)==PARPORT_STATUS_SELECT)?"HI":"LO");
printf("PAPEROUT = %s\n",
((val & PARPORT_STATUS_PAPEROUT)==PARPORT_STATUS_PAPEROUT)?"HI":"LO");
printf("ACK = %s\n",
((val & PARPORT_STATUS_ACK)==PARPORT_STATUS_ACK)?"HI":"LO");
return 0;
}
/* example how to use frob ... toggle STROBE on and off without messing
around the other lines */
int strobe_blink(int fd)
{
struct ppdev_frob_struct frob;
frob.mask = PARPORT_CONTROL_STROBE; /* change only this pin ! */
while(1) {
frob.val = PARPORT_CONTROL_STROBE; /* set STROBE ... */
ioctl(fd, PPFCONTROL, &frob);
usleep(500);
frob.val = 0; /* and clear again */
ioctl(fd, PPFCONTROL, &frob);
usleep(500);
}
}
"parport.h"
/* $Id: parport.h,v 1.1 1998/05/17 10:57:52 andrea Exp andrea $ */
/*
* Any part of this program may be used in documents licensed under
* the GNU Free Documentation License, Version 1.1 or any later version
* published by the Free Software Foundation.
*/
#ifndef _PARPORT_H_
#define _PARPORT_H_
/* Start off with user-visible constants */
/* Maximum of 16 ports per machine */
#define PARPORT_MAX 16
/* Magic numbers */
#define PARPORT_IRQ_NONE -1
#define PARPORT_DMA_NONE -1
#define PARPORT_IRQ_AUTO -2
#define PARPORT_DMA_AUTO -2
#define PARPORT_DMA_NOFIFO -3
#define PARPORT_DISABLE -2
#define PARPORT_IRQ_PROBEONLY -3
#define PARPORT_IOHI_AUTO -1
#define PARPORT_CONTROL_STROBE 0x1
#define PARPORT_CONTROL_AUTOFD 0x2
#define PARPORT_CONTROL_INIT 0x4
#define PARPORT_CONTROL_SELECT 0x8
#define PARPORT_STATUS_ERROR 0x8
#define PARPORT_STATUS_SELECT 0x10
#define PARPORT_STATUS_PAPEROUT 0x20
#define PARPORT_STATUS_ACK 0x40
#define PARPORT_STATUS_BUSY 0x80
/* Type classes for Plug-and-Play probe. */
typedef enum {
PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */
PARPORT_CLASS_PRINTER,
PARPORT_CLASS_MODEM,
PARPORT_CLASS_NET,
PARPORT_CLASS_HDC, /* Hard disk controller */
PARPORT_CLASS_PCMCIA,
PARPORT_CLASS_MEDIA, /* Multimedia device */
PARPORT_CLASS_FDC, /* Floppy disk controller */
PARPORT_CLASS_PORTS,
PARPORT_CLASS_SCANNER,
PARPORT_CLASS_DIGCAM,
PARPORT_CLASS_OTHER, /* Anything else */
PARPORT_CLASS_UNSPEC, /* No CLS field in ID */
PARPORT_CLASS_SCSIADAPTER
} parport_device_class;
/* The "modes" entry in parport is a bit field representing the
capabilities of the hardware. */
#define PARPORT_MODE_PCSPP (1<<0) /* IBM PC registers available. */
#define PARPORT_MODE_TRISTATE (1<<1) /* Can tristate. */
#define PARPORT_MODE_EPP (1<<2) /* Hardware EPP. */
#define PARPORT_MODE_ECP (1<<3) /* Hardware ECP. */
#define PARPORT_MODE_COMPAT (1<<4) /* Hardware 'printer protocol'. */
#define PARPORT_MODE_DMA (1<<5) /* Hardware can DMA. */
#define PARPORT_MODE_SAFEININT (1<<6) /* SPP registers accessible in IRQ. */
/* IEEE1284 modes:
Nibble mode, byte mode, ECP, ECPRLE and EPP are their own
'extensibility request' values. Others are special.
'Real' ECP modes must have the IEEE1284_MODE_ECP bit set. */
#define IEEE1284_MODE_NIBBLE 0
#define IEEE1284_MODE_BYTE (1<<0)
#define IEEE1284_MODE_COMPAT (1<<8)
#define IEEE1284_MODE_BECP (1<<9) /* Bounded ECP mode */
#define IEEE1284_MODE_ECP (1<<4)
#define IEEE1284_MODE_ECPRLE (IEEE1284_MODE_ECP | (1<<5))
#define IEEE1284_MODE_ECPSWE (1<<10) /* Software-emulated */
#define IEEE1284_MODE_EPP (1<<6)
#define IEEE1284_MODE_EPPSL (1<<11) /* EPP 1.7 */
#define IEEE1284_MODE_EPPSWE (1<<12) /* Software-emulated */
#define IEEE1284_DEVICEID (1<<2) /* This is a flag */
#define IEEE1284_EXT_LINK (1<<14) /* This flag causes the
* extensibility link to
* be requested, using
* bits 0-6. */
/* For the benefit of parport_read/write, you can use these with
* parport_negotiate to use address operations. They have no effect
* other than to make parport_read/write use address transfers. */
#define IEEE1284_ADDR (1<<13) /* This is a flag */
#define IEEE1284_DATA 0 /* So is this */
/* Flags for block transfer operations. */
#define PARPORT_EPP_FAST (1<<0) /* Unreliable counts. */
#define PARPORT_W91284PIC (1<<1) /* have a Warp9 w91284pic in the device */
/* The rest is for the kernel only */
#endif /* _PARPORT_H_ */
"ppdev.h"
/*
* linux/include/linux/ppdev.h
*
* User-space parallel port device driver (header file).
*
* Copyright (C) 1998-9 Tim Waugh <tim#cyberelk.demon.co.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Added PPGETTIME/PPSETTIME, Fred Barnes, 1999
* Added PPGETMODES/PPGETMODE/PPGETPHASE, Fred Barnes <frmb2#ukc.ac.uk>, 03/01/2001
*/
#define PP_IOCTL 'p'
/* Set mode for read/write (e.g. IEEE1284_MODE_EPP) */
#define PPSETMODE _IOW(PP_IOCTL, 0x80, int)
/* Read status */
#define PPRSTATUS _IOR(PP_IOCTL, 0x81, unsigned char)
#define PPWSTATUS OBSOLETE__IOW(PP_IOCTL, 0x82, unsigned char)
/* Read/write control */
#define PPRCONTROL _IOR(PP_IOCTL, 0x83, unsigned char)
#define PPWCONTROL _IOW(PP_IOCTL, 0x84, unsigned char)
struct ppdev_frob_struct {
unsigned char mask;
unsigned char val;
};
#define PPFCONTROL _IOW(PP_IOCTL, 0x8e, struct ppdev_frob_struct)
/* Read/write data */
#define PPRDATA _IOR(PP_IOCTL, 0x85, unsigned char)
#define PPWDATA _IOW(PP_IOCTL, 0x86, unsigned char)
/* Read/write econtrol (not used) */
#define PPRECONTROL OBSOLETE__IOR(PP_IOCTL, 0x87, unsigned char)
#define PPWECONTROL OBSOLETE__IOW(PP_IOCTL, 0x88, unsigned char)
/* Read/write FIFO (not used) */
#define PPRFIFO OBSOLETE__IOR(PP_IOCTL, 0x89, unsigned char)
#define PPWFIFO OBSOLETE__IOW(PP_IOCTL, 0x8a, unsigned char)
/* Claim the port to start using it */
#define PPCLAIM _IO(PP_IOCTL, 0x8b)
/* Release the port when you aren't using it */
#define PPRELEASE _IO(PP_IOCTL, 0x8c)
/* Yield the port (release it if another driver is waiting,
* then reclaim) */
#define PPYIELD _IO(PP_IOCTL, 0x8d)
/* Register device exclusively (must be before PPCLAIM). */
#define PPEXCL _IO(PP_IOCTL, 0x8f)
/* Data line direction: non-zero for input mode. */
#define PPDATADIR _IOW(PP_IOCTL, 0x90, int)
/* Negotiate a particular IEEE 1284 mode. */
#define PPNEGOT _IOW(PP_IOCTL, 0x91, int)
/* Set control lines when an interrupt occurs. */
#define PPWCTLONIRQ _IOW(PP_IOCTL, 0x92, unsigned char)
/* Clear (and return) interrupt count. */
#define PPCLRIRQ _IOR(PP_IOCTL, 0x93, int)
/* Set the IEEE 1284 phase that we're in (e.g. IEEE1284_PH_FWD_IDLE) */
#define PPSETPHASE _IOW(PP_IOCTL, 0x94, int)
/* Set and get port timeout (struct timeval's) */
#define PPGETTIME _IOR(PP_IOCTL, 0x95, struct timeval)
#define PPSETTIME _IOW(PP_IOCTL, 0x96, struct timeval)
/* Get available modes (what the hardware can do) */
#define PPGETMODES _IOR(PP_IOCTL, 0x97, unsigned int)
/* Get the current mode and phaze */
#define PPGETMODE _IOR(PP_IOCTL, 0x98, int)
#define PPGETPHASE _IOR(PP_IOCTL, 0x99, int)
/* get/set flags */
#define PPGETFLAGS _IOR(PP_IOCTL, 0x9a, int)
#define PPSETFLAGS _IOW(PP_IOCTL, 0x9b, int)
/* flags visible to the world */
#define PP_FASTWRITE (1<<2)
#define PP_FASTREAD (1<<3)
#define PP_W91284PIC (1<<4)
/* only masks user-visible flags */
#define PP_FLAGMASK (PP_FASTWRITE | PP_FASTREAD | PP_W91284PIC)
I managed to find a solution to my problem by using the devctl command. i could read the status of the printer.
#include <iostream>
#include <iomanip>
#include <devctl.h>
#include <sys/dcmd_chr.h>
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include "stdlib.h"
#include "unistd.h"
#include "sys/io.h"
#include <hw/inout.h>
#include <stdint.h>
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h> /* open() */
#include <sys/types.h> /* open() */
#include <sys/stat.h> /* open() */
#include <sys/ioctl.h>
#include "parport.h"
#include "ppdev.h"
#define DEVICE "/dev/usbpar0"
int status_pins(int fd);
using namespace std;
int main(int argc, char **argv)
{
int fd;
if((fd=open(DEVICE, O_RDWR)) < 0) {
fprintf(stderr, "can not open %s\n", DEVICE);
return 10;
}
// ThreadCtl(_NTO_TCTL_IO, 0);
int data = 0, error;
if (error = devctl (fd, DCMD_CHR_LINESTATUS, &data,
sizeof(data), NULL))
{
fprintf(stderr, "Error setting RTS: %s\n",
strerror ( error ));
exit(EXIT_FAILURE);
}
if (data & _LINESTATUS_PAR_NOERROR)
{
printf("No Error Detected!\n");
}
else
{
printf("Error Detected\n");
}
if (data & _LINESTATUS_PAR_PAPEROUT)
{
printf("Paper Empty\n");
}
else
{
printf("Paper OK!\n");
}
close(fd);
return 0;
}

Resources