From: Mike F. <va...@ge...> - 2007-10-20 16:24:44
Attachments:
lirc_bfin_timer.c
signature.asc
|
first a little background ... the Blackfin processor has a few dedicated multifunction timer pins which can trivially measure incoming waveforms down to the granularity of ~10 nanoseconds and up to ~30 seconds. these can be hooked up directly to 3.3V IR sensors so that the IR waveform can be recorded. i can do the Blackfin part no problem, it's the lirc side where i get fuzzy ;). i imagine it's due to my unfamiliarity with remotes in general and the underlying bits. i have the part done where an irq fires after the hardware captures the time for a single pulse and its associated duration, so i'm trying to pass that back up by using the lirc_dev layer. the .features member of lirc_plugin seems to be undocumented. am i supposed to be setting this field ? lirc_dev will set this automatically based on code_length ... but i'm unsure of what to put in for code_length and correspondingly, how to pass my two timing values back up via the lirc buffer functions in the add_to_buf function. ive been looking at lirc_{gpio,i2c,serial,parallel}, but unable to exactly correlate what little i need to do. the lirc documents touch on LIRC_MODEs MODE2, CODE, and LIRCCODE, but not RAW or PULSE. it also doesnt cover how a lirc_dev module would know which format to pass back up. i think the rest of what i have is correct ... i set sample_rate to 0 as i dont need polling; i'll wake the upper layers myself via the .get_queue workqueue which fires after each sample. any insight would be greatly appreciated :) -mike |
From: <li...@ba...> - 2007-10-21 09:38:47
|
Hi! Mike Frysinger "va...@ge..." wrote: [...] > the .features member of lirc_plugin seems to be undocumented. am i supposed > to be setting this field ? You can use lirc_streamzap or lirc_serial as reference. You should use LIRC_CAN_REC_MODE2 in the features field. code_length should be set to sizeof(lirc_t) * 8. Please also implement the LIRC_GET_REC_RESOLUTION ioctl. > lirc_dev will set this automatically based on > code_length ... but i'm unsure of what to put in for code_length and > correspondingly, how to pass my two timing values back up via the lirc > buffer functions in the add_to_buf function. In your code, change the line "lirc_buffer_write_1(buf, code);" to "lirc_buffer_write_n(buf, code, 2);". But this probably will not work anyway. What will happen with the last pulse in a stream? lirc expects to see the last pulse and after that the gap to the next pulse, which in this case can be a really long time. > i think the rest of what i have is correct ... i set sample_rate to 0 as i > dont need polling; i'll wake the upper layers myself via the .get_queue > workqueue which fires after each sample. You have to write the data from your interrupt handler as well. I can't see a call to gptimer_add_to_buf anywhere. Christoph |
From: Mike F. <va...@ge...> - 2007-10-21 17:10:06
|
On Sunday 21 October 2007, Christoph Bartelmus wrote: > Mike Frysinger "va...@ge..." wrote: > > the .features member of lirc_plugin seems to be undocumented. am i > > supposed to be setting this field ? > > You can use lirc_streamzap or lirc_serial as reference. i tried referring lirc_serial but it did a lot more than i needed to (since= it=20 fills out all of the fops while i want to let lirc_dev do it). i'll check= =20 out lirc_streamzap though, thanks! > You should use LIRC_CAN_REC_MODE2 in the features field. > code_length should be set to sizeof(lirc_t) * 8. > Please also implement the LIRC_GET_REC_RESOLUTION ioctl. will do > > lirc_dev will set this automatically based on > > code_length ... but i'm unsure of what to put in for code_length and > > correspondingly, how to pass my two timing values back up via the lirc > > buffer functions in the add_to_buf function. > > In your code, change the line "lirc_buffer_write_1(buf, code);" to > "lirc_buffer_write_n(buf, code, 2);". > But this probably will not work anyway. so my buf should be of type (lirc_t*) rather than (unsigned char*) ? the=20 prototypes confuse me as they indicate i should be passing up bytes of data= =20 rather than lirc_t stuff ... perhaps the prototypes should actually be=20 (void*) ? > What will happen with the last pulse in a stream? lirc expects to see > the last pulse and after that the gap to the next pulse, which in this > case can be a really long time. when i looked at the signal coming out of the IR sensor, the signal was idl= ing=20 high, so there was a rising edge after the last pulse in the stream ... sin= ce=20 my timer is triggering on rising edges, this seemed to be ok. is there a=20 standard for whether the signal will idle high or idle low ? seems like in= =20 theory, you cannot measure the last part if the signal is idling low ... > > i think the rest of what i have is correct ... i set sample_rate to 0 as > > i dont need polling; i'll wake the upper layers myself via the .get_que= ue > > workqueue which fires after each sample. > > You have to write the data from your interrupt handler as well. I can't > see a call to gptimer_add_to_buf anywhere. it was my understanding that the workqueue provides a call back interface. = i=20 tell lirc_dev to sleep on the queue passed back the .get_queue member of th= e=20 lirc_plugin and my interrupt handler wakes up the queue when more data come= s=20 in. then lirc_dev would call into my driver via the .add_to_buf member. a= =20 quick scan of lirc_dev seems to indicate this as well ... =2Dmike |
From: <li...@ba...> - 2007-10-21 17:44:45
|
Hi! Mike Frysinger "va...@ge..." wrote: [...] >> In your code, change the line "lirc_buffer_write_1(buf, code);" to >> "lirc_buffer_write_n(buf, code, 2);". >> But this probably will not work anyway. > so my buf should be of type (lirc_t*) rather than (unsigned char*) ? the > prototypes confuse me as they indicate i should be passing up bytes of data > rather than lirc_t stuff ... perhaps the prototypes should actually be > (void*) ? Yes, void* would probably make more sense. It depends on the mode, what data type is actually used. You should use lirc_t. >> What will happen with the last pulse in a stream? lirc expects to see >> the last pulse and after that the gap to the next pulse, which in this >> case can be a really long time. > when i looked at the signal coming out of the IR sensor, the signal was > idling high, so there was a rising edge after the last pulse in the stream > ... since my timer is triggering on rising edges, this seemed to be ok. is > there a standard for whether the signal will idle high or idle low ? All receivers I know are active low. > seems like in theory, you cannot measure the last part if the signal > is idling low ... How about the first pulse then. What will be the period length in this case? [...] >> You have to write the data from your interrupt handler as well. I can't >> see a call to gptimer_add_to_buf anywhere. > it was my understanding that the workqueue provides a call back interface. > i tell lirc_dev to sleep on the queue passed back the .get_queue member of > the lirc_plugin and my interrupt handler wakes up the queue when more data > comes in. then lirc_dev would call into my driver via the .add_to_buf > member. a quick scan of lirc_dev seems to indicate this as well ... This is only done when you use polling. It wouldn't work otherwise because there is no way to guarantee that lirc_dev picks up your data before the next interrupt comes in. Christoph |
From: Mike F. <va...@ge...> - 2007-10-23 01:40:11
|
On Sunday 21 October 2007, Christoph Bartelmus wrote: > Mike Frysinger "va...@ge..." wrote: > >> In your code, change the line "lirc_buffer_write_1(buf, code);" to > >> "lirc_buffer_write_n(buf, code, 2);". > >> But this probably will not work anyway. > > > > so my buf should be of type (lirc_t*) rather than (unsigned char*) ? t= he > > prototypes confuse me as they indicate i should be passing up bytes of > > data rather than lirc_t stuff ... perhaps the prototypes should actually > > be (void*) ? > > Yes, void* would probably make more sense. It depends on the mode, what > data type is actually used. You should use lirc_t. i'll send a patch then against cvs head once i get my driver finished up :) could you explain a little why .code_length has to be sizeof(lirc_t)*8 ? t= he=20 references to .code_length being in terms of bits confuses me ... or is tha= t=20 not relevant when operating in MODE2 ? > >> What will happen with the last pulse in a stream? lirc expects to see > >> the last pulse and after that the gap to the next pulse, which in this > >> case can be a really long time. > > > > when i looked at the signal coming out of the IR sensor, the signal was > > idling high, so there was a rising edge after the last pulse in the > > stream ... since my timer is triggering on rising edges, this seemed to > > be ok. is there a standard for whether the signal will idle high or id= le > > low ? > > All receivers I know are active low. > > > seems like in theory, you cannot measure the last part if the signal > > is idling low ... > > How about the first pulse then. What will be the period length in this > case? the behavior i saw was that it would be active high and then go low for a=20 fixed time before starting to transmit real data. since that first pulse=20 would be crazy long compared to normal data, i added "clamp" variables to=20 throw out samples that had a pulse larger than 5000usecs. > >> You have to write the data from your interrupt handler as well. I can't > >> see a call to gptimer_add_to_buf anywhere. > > > > it was my understanding that the workqueue provides a call back > > interface. i tell lirc_dev to sleep on the queue passed back the > > .get_queue member of the lirc_plugin and my interrupt handler wakes up > > the queue when more data comes in. then lirc_dev would call into my > > driver via the .add_to_buf member. a quick scan of lirc_dev seems to > > indicate this as well ... > > This is only done when you use polling. > It wouldn't work otherwise because there is no way to guarantee that > lirc_dev picks up your data before the next interrupt comes in. do you mean that while my analysis is correct for the behavior of the drive= r,=20 it would only work in practice when using polling due to the overhead ? if= i=20 had a buffer for my irq handler to spit into, it wouldnt be a problem ... b= ut=20 the behavior i'm seeing matches the comments in the lirc_dev header. the=20 lirc_dev is sleeping on my queue, waiting for my interrupt handler to wake = it=20 up, and then calling the add_to_buf function to get the values. but you're= =20 right that this is much too slow to prevent missing samples. i have the=20 driver working now where mode2 is spitting out pulse/space values that my i= rq=20 handler is capturing. but since the mechanism is too slow overall, i'll=20 convert it to manage .rbuf myself. thanks for your help! =2Dmike |
From: <li...@ba...> - 2007-10-27 15:24:27
|
Hi! Mike Frysinger "va...@ge..." wrote: [...] >> Yes, void* would probably make more sense. It depends on the mode, what >> data type is actually used. You should use lirc_t. > i'll send a patch then against cvs head once i get my driver finished up :) > > could you explain a little why .code_length has to be sizeof(lirc_t)*8 ? > the references to .code_length being in terms of bits confuses me ... or is > that not relevant when operating in MODE2 ? code_length is given in bits, so that's why sizeof(lirc_t)*CHAR_BIT has to be used. [...] > the behavior i saw was that it would be active high and then go low for a > fixed time before starting to transmit real data. since that first pulse > would be crazy long compared to normal data, i added "clamp" variables to > throw out samples that had a pulse larger than 5000usecs. You shouldn't do that. You should accept pulses up to 10 ms (I never saw anything longer than 9000 us) and gaps of any length. [...] >> This is only done when you use polling. >> It wouldn't work otherwise because there is no way to guarantee that >> lirc_dev picks up your data before the next interrupt comes in. > do you mean that while my analysis is correct for the behavior of the > driver, it would only work in practice when using polling due to the > overhead ? if i had a buffer for my irq handler to spit into, it wouldnt be > a problem ... but the behavior i'm seeing matches the comments in the > lirc_dev header. the lirc_dev is sleeping on my queue, waiting for my > interrupt handler to wake it up, and then calling the add_to_buf function to > get the values. but you're right that this is much too slow to prevent > missing samples. i have the driver working now where mode2 is spitting out > pulse/space values that my irq handler is capturing. but since the > mechanism is too slow overall, i'll convert it to manage .rbuf myself. Don't use add_to_buf or get_queue. They should only be used for drivers that need polling. Just add the data in your interrupt handler to the buffer and wake up anybody waiting on the buf.wait_poll queue. Christoph |
From: Mike F. <va...@ge...> - 2007-11-16 06:37:24
|
On Saturday 27 October 2007, Christoph Bartelmus wrote: > Mike Frysinger "va...@ge..." wrote: > > the behavior i saw was that it would be active high and then go low for= a > > fixed time before starting to transmit real data. since that first pul= se > > would be crazy long compared to normal data, i added "clamp" variables = to > > throw out samples that had a pulse larger than 5000usecs. scratch that ... i got clarification on the hardware and it's all data or a= ll=20 idle, nothing else :) > You shouldn't do that. You should accept pulses up to 10 ms (I never saw > anything longer than 9000 us) and gaps of any length. how would you suggest handling the trailing data ? for example, i'm dealin= g=20 with a remote at the moment that sends RC-6 data ... if the receiver is=20 active high and the last few bits are logically high as well, how do i know= =20 how long of a sample to send up to lirc ? or is it built into the RC-6=20 protocol such that this scenario cannot happen ? i cant tell if the timer= =20 used in lirc_streamzap is used for this or if it's just to queue up data an= d=20 blast it up to lirc_dev in one go. here's the mode2 output (for pressing "play/pause"): pulse 2715 space 829 pulse 498 space 830 pulse 498 space 387 pulse 498 space 387 pulse 1384 space 829 pulse 498 space 387 pulse 498 space 830 pulse 941 space 830 pulse 498 space 387 pulse 941 space 829 pulse 498 space 387 pulse 498 space 387 pulse 941 space 830 pulse 941 space 387 pulse 498 space 830 pulse 498 space 387 does this look correct ? i tried taking the generic RC-6.conf file and=20 feeding it to irrecord, but it barfs on me: root:~> irrecord /etc/lircd.conf irrecord: "begin" "remote" irrecord: parsing remote irrecord: creating first remote irrecord: "name" "RC-6" irrecord: parsing RC-6 remote irrecord: "bits" "8" irrecord: "flags" "RC6|CONST_LENGTH" irrecord: flag RC6 recognized irrecord: flag CONST_LENGTH recognized irrecord: flags value: 8196 irrecord: "eps" "30" irrecord: "aeps" "100" irrecord: "header" "2667" irrecord: "one" "444" irrecord: "zero" "444" irrecord: "pre_data_bits" "13" irrecord: "pre_data" "0xEFB" irrecord: "gap" "108000" irrecord: "toggle_bit" "5" irrecord: "begin" "codes" irrecord: begin codes irrecord: "end" "codes" irrecord: end codes irrecord: "end" "remote" irrecord: end remote irrecord - application for recording IR-codes for usage with lirc Copyright (C) 1998,1999 Christoph Bartelmus(li...@ba...) irrecord: driver supports receiving irrecord: resolution of receiver: 0 This program will record the signals from your remote control and create a config file for lircd. A proper config file for lircd is maybe the most vital part of this package, so you should invest some time to create a working config file. Although I put a good deal of effort in this program it is often not possible to automatically recognize all features of a remote control. Often short-comings of the receiver hardware make it nearly impossible. If you have problems to create a config file READ THE DOCUMENTATION of this package, especially section "Adding new remote controls" for how to get help. If there already is a remote control of the same brand available at http://www.lirc.org/remotes/ you might also want to try using such a remote as a template. The config files already contain all parameters of the protocol used by remotes of a certain brand and knowing these parameters makes the job of this program much easier. There are also template files for the most common protocols available in the remotes/generic/ directory of the source distribution of this package. You can use a template files by providing the path of the file as command line parameter. Please send the finished config files to <li...@ba...> so that I can make them available to others. Don't forget to put all information that you can get about the remote control in the header of the file. Press RETURN to continue. 21 444 444 444 444 0 8196 30 100 108000 Checking for toggle bit mask. Please press an arbitrary button repeatedly as fast as possible. Make sure you keep pressing the SAME button and that you DON'T HOLD the button down!. If you can't see any dots appear, then wait a bit between button presses. Press RETURN to continue. irrecord: c2658 irrecord: pending pulse: 0 irrecord: pending space: 0 irrecord: trying "/etc/lircd.conf.conf" remote irrecord: pending pulse: 0 irrecord: pending space: 0 irrecord: <p2658 irrecord: space expected irrecord: failed on sync irrecord: failed "/etc/lircd.conf.conf" remote irrecord: decoding failed for all remotes irrecord: pending pulse: 0 irrecord: pending space: 0 irrecord: <p2658 irrecord: space expected irrecord: failed on sync irrecord: c921 irrecord: pending pulse: 0 irrecord: pending space: 0 irrecord: trying "/etc/lircd.conf.conf" remote irrecord: pending pulse: 0 irrecord: pending space: 0 irrecord: <s921 irrecord: sync irrecord: expecting pulse: 2667 irrecord: +p423 irrecord: unget: 1 irrecord: failed on header irrecord: failed "/etc/lircd.conf.conf" remote irrecord: decoding failed for all remotes =2Dmike |
From: <li...@ba...> - 2007-11-17 16:48:44
|
Hi! Mike Frysinger "va...@ge..." wrote: [...] > how would you suggest handling the trailing data ? for example, i'm dealing > with a remote at the moment that sends RC-6 data ... if the receiver is > active high and the last few bits are logically high as well, how do i know > how long of a sample to send up to lirc ? or is it built into the RC-6 > protocol such that this scenario cannot happen ? i cant tell if the timer > used in lirc_streamzap is used for this or if it's just to queue up data and > blast it up to lirc_dev in one go. The timer in lirc_streamzap is used to change the timing in which the data is passed to lircd. This is due to a limitation of the USB receiver and should not be relevant for you. > here's the mode2 output (for pressing "play/pause"): > pulse 2715 > space 829 > pulse 498 [...] > space 830 > pulse 498 > space 387 > > does this look correct ? No. The first data should be a (long) space. The last will be a pulse. Usually any pulse will be so short that it should be sent by the driver almost immediately. The next space can take a long time because it will give the time until the next IR activity is detected since the last pulse. Christoph |
From: Andreas D. <an...@gm...> - 2007-11-18 11:02:40
|
In my case the drivers autodetection of active high/low was wrong, and I found a similar behaviour: pulse-space inverted. (the result of the autodetection is showed in the dmesg output) I set now the active low/high by hand (insmod option) and it works. Andreas Am Samstag, 17. November 2007 17:48 schrieb Christoph Bartelmus: > Hi! > > Mike Frysinger "va...@ge..." wrote: > [...] > > > how would you suggest handling the trailing data ? for example, i'm > > dealing with a remote at the moment that sends RC-6 data ... if the > > receiver is active high and the last few bits are logically high as well, > > how do i know how long of a sample to send up to lirc ? or is it built > > into the RC-6 protocol such that this scenario cannot happen ? i cant > > tell if the timer used in lirc_streamzap is used for this or if it's just > > to queue up data and blast it up to lirc_dev in one go. > > The timer in lirc_streamzap is used to change the timing in which the > data is passed to lircd. This is due to a limitation of the USB receiver > and should not be relevant for you. > > > here's the mode2 output (for pressing "play/pause"): > > pulse 2715 > > space 829 > > pulse 498 > > [...] > > > space 830 > > pulse 498 > > space 387 > > > > does this look correct ? > > No. The first data should be a (long) space. > The last will be a pulse. Usually any pulse will be so short that it > should be sent by the driver almost immediately. The next space can take > a long time because it will give the time until the next IR activity is > detected since the last pulse. > > Christoph > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2005. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ |
From: Mike F. <va...@ge...> - 2007-11-20 16:53:18
|
On Saturday 17 November 2007, Christoph Bartelmus wrote: > Mike Frysinger "va...@ge..." wrote: > > here's the mode2 output (for pressing "play/pause"): > > pulse 2715 > > space 829 > > pulse 498 > > [...] > > > space 830 > > pulse 498 > > space 387 > > > > does this look correct ? > > No. The first data should be a (long) space. > The last will be a pulse. Usually any pulse will be so short that it > should be sent by the driver almost immediately. The next space can take > a long time because it will give the time until the next IR activity is > detected since the last pulse. blah, this is because the hardware provided to use outputs RC6 in "cooked"= =20 mode rather than "raw" ... which is to say, it sends bits ~444 usecs in=20 length and if the signal is high during that span, it's a 1, otherwise it's= a=20 0 (instead of pulse/space combo's which represent a 1 or a 0). so the 2715= =20 pulse above represents the six first leading 0's in the RC6 header. is the= re=20 a mode for lirc here ? it seems LIRC_MODE_CODE is the closest, but i'll ha= ve=20 to the translation from length to # of bits in the driver ... :( =2Dmike |
From: <li...@ba...> - 2007-11-22 06:44:08
|
Hi! Mike Frysinger "va...@ge..." wrote: >>> here's the mode2 output (for pressing "play/pause"): >>> pulse 2715 >>> space 829 >>> pulse 498 [...] >> No. The first data should be a (long) space. [...] > blah, this is because the hardware provided to use outputs RC6 in "cooked" > mode rather than "raw" ... which is to say, it sends bits ~444 usecs in > length and if the signal is high during that span, it's a 1, otherwise it's > a 0 (instead of pulse/space combo's which represent a 1 or a 0). so the > 2715 pulse above represents the six first leading 0's in the RC6 header. is > there a mode for lirc here ? it seems LIRC_MODE_CODE is the closest, but > i'll have to the translation from length to # of bits in the driver ... :( To be honest, I have no idea what you are talking about. Why don't you just fix the driver to generate the correct pulse/space sequence like described before? Christoph |
From: Mike F. <va...@ge...> - 2007-11-28 07:47:34
|
On Tuesday 20 November 2007, Christoph Bartelmus wrote: > > blah, this is because the hardware provided to use outputs RC6 in > > "cooked" mode rather than "raw" ... which is to say, it sends bits ~444 > > usecs in length and if the signal is high during that span, it's a 1, > > otherwise it's a 0 (instead of pulse/space combo's which represent a 1 = or > > a 0). so the 2715 pulse above represents the six first leading 0's in > > the RC6 header. is there a mode for lirc here ? it seems LIRC_MODE_CO= DE > > is the closest, but i'll have to the translation from length to # of bi= ts > > in the driver ... :( > > To be honest, I have no idea what you are talking about. > Why don't you just fix the driver to generate the correct pulse/space > sequence like described before? the driver reflects what the hardware is transmitting, so there really is=20 nothing to fix in the driver as it matches reality: the incoming signal what i mean is, normally the input signal coming from IR receivers will go= =20 high/low to indicate the pulse/space for a single bit. the RC6 spec says=20 that the relationship between the pulse/space and its timing duration will= =20 translate to a 0 or 1, right ? well the hardware i have hear does not=20 transmit a pulse/space pairs to indicate 0 or 1, the signal coming from the= =20 hardware is logically high/low according to the value. so if the signal is high, it is a 1 ... if it is low, it is a 0. the=20 pulse/space i sent early was misinterpreting these as pulse/spaces instead = of=20 logical signals. consider the first two bytes in the RC6 header 0xFC (or in binary, 11111100= ). =20 the signal i get would be logically high for 6 bit times and then logically= =20 low for 2 bit times. sorry if my e-mails are confusing, i'm still new to the IR world :/ =2Dmike |
From: Mike F. <va...@ge...> - 2007-12-03 06:04:57
|
On Tuesday 20 November 2007, Christoph Bartelmus wrote: > To be honest, I have no idea what you are talking about. > Why don't you just fix the driver to generate the correct pulse/space > sequence like described before? sorry for the confusion again ... my previous google searches on the topic = of=20 the RC5/RC6 protocol indicated that the signals were all manchester encoded= =2E =20 after collecting a bunch of different remotes and setting up lirc_sir on my= =20 laptop and running comparisons, i used that data to analyze what was going= =20 on. i dont think it states it anywhere, but the long "space" that is=20 expected before every valid signal was being thrown away because it isnt re= al=20 data and it didnt make sense to me to give data to userspace that isnt vali= d. =20 but lirc apparently expects this and uses it. i have my driver working now and once i convert it to be a platform device= =20 driver, i'll send it out aiming for inclusion in lirc. =2Dmike |