[MAGEEC] Comms. protocol between data gatherer and host PC

James Pallister James.Pallister at bristol.ac.uk
Thu Feb 6 19:25:49 GMT 2014


Hi Alex,

> Am I right in thinking that the device is a HID class device, or is it
> more custom than this? (thinking about Windows driver support here)
Unfortunately I didn't think about Windows at all when I designed the
firmware. The device just exposes a vendor specific class. It also has a
bulk in and out endpoint, and an interrupt in endpoint, all of which are
currently unused in the latest firmware (they were previously used, and
I've forgotten to remove them from the descriptor).

In the first version of the firmware I streamed back every sample taken
by the ADC to the PC, using a standard serial class, however I ended up
having problems with this (I can't remember exactly what). The newest
version of the firmware dropped the tracing ability in favour of
accumulating onboard and sending back the final energy figures, which
turned out to be much more robust.

I don't think there is any reason the serial link couldn't be added back
in. There is an example using libopencm3 here:
   
https://github.com/libopencm3/libopencm3-examples/blob/master/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c

James


On 06/02/14 14:59, Alex J Lennon wrote:
> Hi James,
>
> That's really useful thanks. I have some background in USB development
> so can see where you are coming from with this.
>
> Am I right in thinking that the device is a HID class device, or is it
> more custom than this? (thinking about Windows driver support here)
>
> I had assumed that it would be enumerating as a standard serial class
> device and you would have a protocol running over the
> virtualised serial link, this being easier in terms of driver support
> on host OS platforms.
>
> Was there a reason for not going down the USB serial route? I am
> wondering how difficult that would be for me to put in place?
>
> Thanks!
>
> Alex
>
> On 06/02/2014 12:46, James Pallister wrote:
>> Hi Alex,
>>
>> I haven't gotten round to writing up the protocol yet, but it is
>> reasonably simple. Here is a fairly long and detailed email, which
>> will probably be copied to the wiki at some point.
>>
>>
>> The device appears as a custom USB device, and all of the commands
>> are sent as control transfers. There is almost a one-to-one mapping
>> between the methods in the pyenergy.EnergyMonitor class and the
>> control transfers performed to the device. The only slight
>> complication is there are 3 ADCs and 4 measurement points, the
>> mapping of which ADC measures which measurement point is done in the
>> enableMeasurementPoint method (with request number 7).
>>
>> For the exact details, see:
>> https://github.com/jpallister/stm32f4-energy-monitor/blob/pyusb/src/python/pyenergy.py
>>
>> The actual control transfers themselves use the bRequest parameter of
>> the control transfer to differentiate between types of action. The
>> wValue and wIndex parameters both specify data for that particular
>> request. There are many possible requests:
>>
>> Request
>> 	bRequest 	wValue 	wIndex 	Description
>> Toggle LEDS
>> 	0
>> 	N/A
>> 	N/A
>> 	Toggle one of the LEDs on the board
>> Start Measurement
>> 	1
>> 	Measurement point
>> 	N/A
>> 	Start measuring the measurement point specified by wValue
>> Stop Measurement
>> 	2
>> 	Measurement point
>> 	N/A
>> 	Stop measurement the measurement point specified by wValue
>> Set Serial
>> 	3
>> 	Low chars
>> 	High chars
>> 	Set the 4 character serial of the device.
>>
>> Bottom 8 bits of wValue is ASCII, character 0. Top 8 bits is
>> character 1.
>> Bottom 8 bits of wIndex is character 2 and top is character 3
>> Set Trigger
>> 	4
>> 	Measurement point and pin
>> 	Port
>> 	Set a trigger on a pin, so that measurement is automatically
>> triggered on a rising edge, and stopped on a falling edge.
>>
>> Bottom 8 bits is the pin number (wValue).
>> Top 8 bits is the measurement point number.
>> wIndex is the ASCII representation of the port (A, B, C...)
>> Currently I have only tested this with PA0.
>> Get Energy
>> 	6
>> 	Measurement point
>> 	N/A
>> 	Get the accumulated energy figures.
>>
>> Returns a 48 byte structure.
>>
>> typedef struct {
>>     uint64_t energy_accum;
>>     uint64_t elapsed_time;
>>     unsigned peak_power;
>>     unsigned peak_voltage;
>>     unsigned peak_current;
>>     unsigned n_samples;
>>     uint64_t avg_current;
>>     uint64_t avg_voltage;
>> } accumulated_data;
>>
>> Have a look at the convertData method in pyenergy.py for how to
>> convert these figures to real units.
>>
>> Map ADC to measurement point
>> 	7
>> 	Measurement point
>> 	ADC
>> 	Map an ADC to a measurement point.
>>
>> ADC = number 0-2.
>> Probably best not to do this while the measurement is running
>> Is running
>> 	8
>> 	Measurement point
>> 	N/A
>> 	Checks whether the measurement point is running or not. Useful for
>> when triggers are being used.
>>
>> Returns 4 bytes, integer.
>> 1 = Running
>> 0 = Not running
>> Get number of runs
>> 	9
>> 	Measurement point
>> 	N/A
>> 	Reports back the number of completed runs performed. This is mainly
>> a sanity check, so that the host will know if it has 'missed' a
>> measurement.
>>
>> Returns 4 bytes, integer = number of runs.
>> Clear number of runs
>> 	10
>> 	Measurement point
>> 	N/A
>> 	Resets the number of runs counter to 0.
>> Get instantaneous
>> 	11
>> 	Measurement point
>> 	N/A
>> 	This returns the most recent raw ADC values for voltage and current.
>> This is useful for graphs.
>>
>> 24 byte result structure.
>>
>> typedef struct {
>>     unsigned voltage;
>>     unsigned current;
>>     unsigned average_voltage;
>>     unsigned average_current;
>>     uint64_t current_time;
>> } instant_data;
>>
>> The current and voltage are both fairly noisey, so they are averaged
>> over the last 32 samples. This provides much smoother results.
>>
>> Have a look at the convertData method in pyenergy.py for how to
>> convert these figures to real units.
>>
>>
>> I'm not sure how this would be implemented in .NET, however if there
>> are bindings for libusb, then it boils down to some fairly easy
>> control transfers. The USB device appears as ID 0xf539:0xf539.
>>
>> For example in python:
>> # Return whether the measurement point is currently taking
>> # measurements or not
>> def isRunning(self, m_point=1):
>>     b = self< span class="o" style="box-sizing: border-box;
>> font-weight: bold;">.dev.ctrl_transfer(0xc1, 8, int(m_point), 0, 4)
>>     running = unpack("=L", b)
>>     return bool(running[0])
>>
>> Here the code is performing a control transfer on endpoint 0xC1
>> (indicating there is data to receive, endpoint 0x41 is used when no
>> data needs to be returned). Request type 8, for "is running", then
>> the measurement point as wValue. The final parameter indicates 4
>> bytes to be returned. This is converted to a boolean. I suspect it
>> would be similar in .NET.
>>
>> The board should be fairly forgiving about the sequencing of requests
>> sent to it, with the exception that Bad Things will happen if
>> different ADCs are mapped to the same measurement point in request 7.
>>
>> If anything is unclear, or I've missed out some vital bit of
>> information, just shout.
>>
>> Cheers,
>> James
>>
>> On 06/02/14 09:14, Alex J Lennon wrote:
>>> Hi all,
>>>
>>> Could anybody point me to a breakdown of the comms. protocol between
>>> the data gatherer and the host PC, if there is such a thing?
>>>
>>> I'm interested in putting together a simple .NET application, perhaps
>>> involving
>>> ZedGraph, having one foot on the dark-side as it were.
>>>
>>> Many thanks!
>>>
>>> Alex Lennon
>>>
>>>
>>> _______________________________________________
>>> mageec mailing list
>>> mageec at mageec.org
>>> http://mageec.org/cgi-bin/mailman/listinfo/mageec
>>
>
> -- 
>
> Dynamic Devices Ltd <http://www.dynamicdevices.co.uk/>
>
> Alex J Lennon / Director
> 1 Queensway, Liverpool L22 4RA
>
> mobile: +44 (0)7956 668178
>
> Linkedin <http://www.linkedin.com/in/alexjlennon> Skype
> <skype:alexjlennon?add>
>
> This e-mail message may contain confidential or legally privileged
> information and is intended only for the use of the intended
> recipient(s). Any unauthorized disclosure, dissemination,
> distribution, copying or the taking of any action in reliance on the
> information herein is prohibited. E-mails are not secure and cannot be
> guaranteed to be error free as they can be intercepted, amended, or
> contain viruses. Anyone who communicates with us by e-mail is deemed
> to have accepted these risks. Company Name is not responsible for
> errors or omissions in this message and denies any responsibility for
> any damage arising from the use of e-mail. Any opinion and other
> statement contained in this message and any attachment are solely
> those of the author and do not necessarily represent those of the company.
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mageec.org/pipermail/mageec/attachments/20140206/cef51600/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 3997 bytes
Desc: not available
URL: <http://mageec.org/pipermail/mageec/attachments/20140206/cef51600/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 631 bytes
Desc: not available
URL: <http://mageec.org/pipermail/mageec/attachments/20140206/cef51600/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 800 bytes
Desc: not available
URL: <http://mageec.org/pipermail/mageec/attachments/20140206/cef51600/attachment-0002.png>


More information about the mageec mailing list