Adding new firmware functions - page 2 - General Discussion and Assistance - CHDK Forum

Adding new firmware functions

  • 19 Replies
  • 14080 Views
*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Adding new firmware functions
« Reply #10 on: 23 / March / 2014, 19:42:41 »
Advertisements
I can suggest two approaches:
- put all the callback code in wrappers.c so it is always compiled as ARM
- put an ARM wrapper for the callback code in wrappers.c with the main thumb code in the usb_remote file

If the callback function is simple then it can probably live in wrappers.c, otherwise the second option is probably better.
So here's a patch file that I've been playing with.  It adds an enable_highspeed_usb() function to Lua that switches the USB remote pulse counting & width measurement to work from an HP timer.   If you don't make the function call from a script,  all the USB remote code works as before.  At some point we might want to limit how short a timer interval the user can try but for now it "caveat emptor".


I don't have a VxWorks camera to test it with but it works a charm on my DryOS cameras.

There is a little test script (pwm_test.lua) in the CHDK/SCRIPTS directory.     I've experimented with rate as fast as 100 uSec but that tends to be so fast it catches switch bounce :)

Will it work this way under VxWorks ?

No, it won't work correctly on VxWorks.

Adding ARM wrappers should fix it.

Code: [Select]
extern int usb_HPtimer_bad(int, int);
extern int usb_HPtimer_good(int, int);

int usb_HPtimer_handle=0;
int usb_HPtimer_error_count=0;

static int ARM_usb_HPtimer_good(int time, int interval) { return usb_HPtimer_good(time, interval); }
static int ARM_usb_HPtimer_bad(int time, int interval)) { return usb_HPtimer_bad(time, interval); }

int start_usb_HPtimer(int interval) // return 0 if timer already running or error,  1 if successful
{
    if ( usb_HPtimer_handle == 0 )
    {
        usb_HPtimer_handle = _SetHPTimerAfterNow(interval,ARM_usb_HPtimer_good,ARM_usb_HPtimer_bad,interval);
        if (!(usb_HPtimer_handle & 0x01)) return 1 ;
        usb_HPtimer_handle = 0 ;
    }
    return 0;
}

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: Adding new firmware functions
« Reply #11 on: 23 / March / 2014, 19:54:34 »
Thanks - updated patch attached.  Works fine on my A1200.

I'll do some testing with my arduino USB remote pulse generator rig to make sure the rest of the USB functions all work.  Probably want to add a way to get the timer error count out ( from the "bad" callback) so a script can tell if it's likely to be getting timing errors.
Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Adding new firmware functions
« Reply #12 on: 24 / March / 2014, 03:30:25 »
At some point soon,  it would be nice to get those two function added to stubs_entry.S (they are already in the funcs_by_name.csv & funcs_by_address.csv)

Added to trunk in revision 3397.

Phil.
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

*

Offline srsa_4c

  • ******
  • 4451
Re: Adding new firmware functions
« Reply #13 on: 24 / March / 2014, 14:24:03 »
updated patch attached
I don't know... I don't have a good feeling about the length of the timer callback(s). get_usb_bit() is usually calling a physw-related function to read in the keyboard state (_kbd_read_keys_r2), and I don't know what's inside that function.
The firmware's timer routines are usually short, and rarely call functions other than the ones re-arming the timer, setting an eventflag, freeing a semaphore...
I don't know what context the timer is running in, but doing "serious" work in a routine that gets called over 1000 times/sec may badly influence other parts of the system (frame sync for example and who knows what else).
Additionally, if a port happens to get the USB status from another (sub)CPU involving serial IO and yielding... that may turn out even worse (at least the s80 and the s3is are like that).

So, I would recommend getting the USB bit directly if possible, and perhaps only enabling the high speed routine on those cameras.

Re: Adding new firmware functions
« Reply #14 on: 24 / March / 2014, 18:38:06 »
So, I would recommend getting the USB bit directly if possible, and perhaps only enabling the high speed routine on those cameras.
Being able to read the USB port state from the mmio's directly would seem to be a good thing to do. Assuming the 5V status does not actually come from a USB controller chip register or something.

However,  I'm not a fan of limiting access to high speed pulse measurement - provided that we ensure that the USB HPtimer is only available via a script function.  Then it becomes a "try it and see" thing. Some scripts will work better than others - depending in part on the ability of the script writer to tailor the script.  (Things like the timer only running while not actually shooting for example.)   Sure, it will be experimental and some scripts won't work well on some cameras.   It might even be possible that using the function will mess up the timing so much that the camera shuts down at times?  It's going to take us a while to understand where the limits are - and there will certainly be limits on what we can do.

We could also place restrictions on the minimum interval time  (1 msec ?),   or have the action stack disable the timer during shooting operations,  or only allow the function to work with Lua scripts,  or have the timer disable itself after 1 second.   But I think that's stuff better left to the script writer.

And for all other CHDK operation,  things will work just like the do today.


Update : having said the above,  I think a  #define ENABLE_USB_HP_TIMER  1  in camera.h that causes the start_usb_HPtimer() to fail when it's #undef'd in specific camera platform_camera.h files is probably a good idea.

« Last Edit: 24 / March / 2014, 19:36:50 by waterwingz »
Ported :   A1200    SD940   G10    Powershot N    G16

Re: Adding new firmware functions
« Reply #15 on: 25 / March / 2014, 07:03:00 »
Hi,

great progress on that issue thanks a lot so far!

@waterwingz:

Code: [Select]
+result=enable_highspeed_usb(s)
+print("enable highspeed status=",result)
+result=enable_highspeed_usb(s)
+print("enable highspeed status=",result)
+repeat
+    x=get_usb_power(0)
+    if ( x > 0 ) then
+        print("width="..x)         
+    end
+    wait_click(100)
+until is_pressed("menu")
+result=enable_highspeed_usb(0)
+print("disable highspeed status=",result)
+result=enable_highspeed_usb(0)
+print("disable highspeed status=",result)
In your lua script you call two times:

Code: [Select]
+result=enable_highspeed_usb(s)
+print("enable highspeed status=",result)
and also two times:

Code: [Select]
+result=enable_highspeed_usb(0)
+print("disable highspeed status=",result)
Could you please tell me why you call two times each? Thanks a lot!

I come back to my project where I want to have a microcontroller to generate some pulses and CHDK should detect this pulses and trigger different actions depending on pulse pattern.
This actions I also need in rec mode e.g. for shooting an image, zoom etc..
So I personally need it in both modes. For my purpose I need this function run all the time since an extern pulse from the microcontroller can happen now, in 1 seconde or even in 3 minutes or whatever. If possible the implementation should take care that the camera functions in rec and play mode are not disturbed.

Quote
I would recommend getting the USB bit directly if possible

What would be the benefit compared to the HP_timer solution?


2 x IXUS 860IS 100c
2 x Powershot S110 103a

Re: Adding new firmware functions
« Reply #16 on: 25 / March / 2014, 07:50:59 »
Could you please tell me why you call two times each? Thanks a lot!
It's a test script.  I was making sure nothing fails if a script calls the start or stop functions more than one time.  I delete stuff like that if / when we get to an official release.

Quote
What would be the benefit compared to the HP_timer solution?
They are two different things.  srsa_4c is talking about possible issues with getting the usb port 5V status from an HP_timer function.


I come back to my project where I want to have a microcontroller to generate some pulses and CHDK should detect this pulses and trigger different actions depending on pulse pattern.
This actions I also need in rec mode e.g. for shooting an image, zoom etc..
So I personally need it in both modes. For my purpose I need this function run all the time since an extern pulse from the microcontroller can happen now, in 1 seconde or even in 3 minutes or whatever. If possible the implementation should take care that the camera functions in rec and play mode are not disturbed.
It's quite possible that you will not be able to do exactly what you want. There is only so much a little ARM processor can do and it mostly has its hands full running the camera.

Having said that,  there are a couple of things you can try.   

As srsa_4c suggested,  have the communication code idle in normal task mode watching the USB bit  (HP_timer disabled).   When your microcontroller wants to communicate, send a 30 mSec pulse first.  The communication code can detect that and switch to high speed mode only for as long as it takes to receive the data packet.  It then switches back to normal task mode.

You also want to pack data as tightly as possible in your communication packet so that you can make it as short as possible and thus use the slowest HP_timer rate possible.  Careful design of your communications strategy can mitigate a lot of potential problems.   Several short packets are probably better than one long packet for example.

You might also want to consider sending all your data packets two or three times.

Given all that,  you will need to do some experimenting and see what works for your camera and application.
« Last Edit: 25 / March / 2014, 09:56:37 by waterwingz »
Ported :   A1200    SD940   G10    Powershot N    G16

Re: Adding new firmware functions
« Reply #17 on: 25 / March / 2014, 11:11:37 »
Hi waterwingz,

thanks for your suggestions.

Quote
...When your microcontroller wants to communicate, send a 30 mSec pulse first.  The communication code can detect that and switch to high speed mode only for as long as it takes to receive the data packet.  It then switches back to normal task mode.

I already thought same idea so may I will give it a try.
Since we have to be carefull and should reduce the time using HP-Timer I still think about the solution which is based on the middle battery contact.

E.g.
100 Ohm = zoom in
200 Ohm = zoom out
300 Ohm = shutter half press
400 Ohm = shutter full press
...

With this I can trigger an action by only one pulse or maybe two if one is not enough to trigger all actions.
Which means I can drastically reduce the number of pulses.
Can HP-Timer be combined with middle battery contact detection?
The battery middle contact solution would reduce the time the HP-Timer is used. Do you think this is the better aproach?


Thanks for any suggestions.



2 x IXUS 860IS 100c
2 x Powershot S110 103a

*

Offline srsa_4c

  • ******
  • 4451
Re: Adding new firmware functions
« Reply #18 on: 25 / March / 2014, 13:22:37 »
Since we have to be carefull and should reduce the time using HP-Timer I still think about the solution which is based on the middle battery contact.

E.g.
100 Ohm = zoom in
200 Ohm = zoom out
300 Ohm = shutter half press
400 Ohm = shutter full press
...

With this I can trigger an action by only one pulse or maybe two if one is not enough to trigger all actions.
Which means I can drastically reduce the number of pulses.
Can HP-Timer be combined with middle battery contact detection?
The battery middle contact solution would reduce the time the HP-Timer is used. Do you think this is the better aproach?
You can probably use that. However, you'll need to sample that voltage at least twice to deal with rising and falling edges of your signal.

A friendly reminder: if you feel your subject is off-topic, please post in an appropriate thread ;)
« Last Edit: 25 / March / 2014, 13:24:32 by srsa_4c »

*

Offline srsa_4c

  • ******
  • 4451
"flash property" API, custom white balance accessible
« Reply #19 on: 22 / January / 2015, 19:38:31 »
While searching for something else, I found a method that seems to allow manipulating the "custom white balance" data.
The current procedure is not the most user friendly: the data can be read and written back, but writing the data doesn't affect the current session, it will only become active after switching the camera off and on again.

I found an API (yet another one) that allows storing and retrieving of various sized (pre-defined) data in flash. I have not been able to found a name for the functions, the only thing known is that they are located in "property.c" of the Canon source.
I decided calling them get_flash_property and set_flash_property.
Using set_flash_property does not immediately write to flash, it just changes the runtime copy of the data which will be stored in flash ROM during regular shutdown.

get_flash_property(int ID, char *buffer, int size)
set_flash_property(int ID, char *buffer, int size)


The number of these "properties" is camera (generation) dependent, but much lower than the number of the well known property cases or params.
This API seems to exist on all cameras, even the S1IS. "ID" is char* on ixus30 and ixus40.

The custom white balance property's name is "WB_ONEPUSHINFO" on ixus30/40. For the a3200, the ID is 2, size is 0x40.
Setting the property has no effect on the session's white balance data, it's apparently stored elsewhere.

This may not be the ultimate way to set custom white balance but it gives a new starting point for further research.

A patch is attached in case anybody is curious about the function addresses. Current method only locates them on DryOS, starting with the late r31 generation.

I probably don't have to mention that messing up these properties is an easy way to brick a camera.

 

Related Topics


SimplePortal © 2008-2014, SimplePortal