Snow, Food and Macro Magic

I’m not dead! Well, dead in the physical, life-challenged kind of way – but I am dead tired. Getting up at 6 every weekday morning when it’s cold and pitch-black outside really starts to take its toll on you after a while, so I like using my Saturday mornings (and, usually, afternoons) to catch up on some missed sleep. While delicious and somewhat invigorating during the day, truckloads of coffee simply aren’t an adequate substitute I’ve found. Apologies to the Atmel marketing team, whose company-wide presentation I fell asleep in last week (I couldn’t understand what was being said anyway, and with everyone there I just sort of dozed off in the back).

So, time for a slightly belated update on my week – never a dull moment! I’m actually kind of sad that my time here is already half over; six weeks of my life have seemingly flown by. Last weekend my roommates and I decided that enough was enough, and we were going to go out into the snow and act like six year olds, and we were going to have fun dammit. I found out something new: it turns out you need a certain air temperature to make good snowballs and snowmen, or the snow won’t stay compacted together. Simon (my Norwegian housemate) pulled out what has got to be the world’s tiniest plastic sled thing-a-majig, which we had great fun sliding down the hill on. I remembered to take a few pictures and even a short video this time, so take a look if you haven’t seen it yet.

I’ve decided to insist on carbon-dating for my food now, since it seems that every Western Europe cullinary dish starts with the directions “Take a fish”, shortly followed by the phrase “and bury it”. I’m not sure what horrible period of starvation in the continent’s history sparked such a odd collection of partially manky dishes like this one or this one or (infamously) this one – but I prefer my food in the realms of edibility regardless of how adventurous I am when it comes to eating.

Actually, related to this, I found out today that the slightly oddly tasting salmon I’ve been eating at lunch time for the past few weeks (when the ordinary Smoked Salmon was not available) is not just a bit differently seasoned than normal, but also decidedly a bit more dead: it’s another Norwegian dish called “Gravlax”. I didn’t get a picture of my face upon learning this, so I’ll leave that up to the imagination of you all to imagine the horror.

But last night was a special night indeed. In town was none other than Massimo – yes, THAT Massimo – and a few of his coworkers from Arduino. Finally meeting some of the people behind the Arduino project – nay movement, arguably the biggest impact in the embedded hobbyist world in recent years, was a wonderful experience. They all turned out to be very engaging people; I heard many good stories over my steak while eating dinner with them at Jonathon Mat, a local restaurant in a part of the city I haven’t explored yet. I ate Reindeer too – it was recommended to me, and while in Norway I thought I’d try something new but a little safer than the local fish dishes. It’s actually a damn good meat and I wish I could eat it back home, as it has a unique flavour and a beautiful tenderness. I also ate a Salmon and Capaccio starter dish however, proving once again that I really, really don’t learn some life lessons.

Tomorrow night I’ll probably gain yet another good set of stories to share, as it’s the annual Atmel New Years Celebration party – yes, a tad late in the year, but that’s how things work in the corporate world – held at a local hall of some type in the “hippie alternative” part of town, according to some of my co-workers. I’ll bring my camera.


And back to the boring electronics stuff. This week I finally got around to updating the LUFA HID demos with some sexy new HID report descriptor macros, turning horrific tables like this:

USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{
        0x05, 0x01,          /* Usage Page (Generic Desktop)                       */
        0x09, 0x04,          /* Usage (Joystick)                                   */
        0xa1, 0x01,          /* Collection (Application)                           */
        0x09, 0x01,          /*   Usage (Pointer)                                  */
        0xa1, 0x00,          /*   Collection (Physical)                            */
        0x05, 0x01,          /*     Usage Page (Generic Desktop)                   */
        0x09, 0x30,          /*     Usage (X)                                      */
        0x09, 0x31,          /*     Usage (Y)                                      */
        0x15, 0x9c,          /*     Logical Minimum (-100)                         */
        0x25, 0x64,          /*     Logical Maximum (100)                          */
        0x75, 0x08,          /*     Report Size (8)                                */
        0x95, 0x02,          /*     Report Count (2)                               */
        0x81, 0x82,          /*     Input (Data, Variable, Absolute, Volatile)     */
        0xc0,                /*   End Collection                                   */
        0x05, 0x09,          /*   Usage Page (Button)                              */
        0x09, 0x02,          /*   Usage (Button 2)                                 */
        0x09, 0x01,          /*   Usage (Button 1)                                 */
        0x15, 0x00,          /*   Logical Minimum (0)                              */
        0x25, 0x01,          /*   Logical Maximum (1)                              */
        0x75, 0x01,          /*   Report Size (1)                                  */
        0x95, 0x02,          /*   Report Count (2)                                 */
        0x81, 0x02,          /*   Input (Data, Variable, Absolute)                 */
        0x75, 0x06,          /*   Report Size (6)                                  */
        0x95, 0x01,          /*   Report Count (1)                                 */
        0x81, 0x01,          /*   Input (Constant)                                 */
        0xc0                 /* End Collection                                     */
};

Into slightly less horrific lists of macros like this:

USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] =
{
        HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
        HID_RI_USAGE(8, 0x04), /* Joystick */
        HID_RI_COLLECTION(8, 0x01), /* Application */
            HID_RI_USAGE(8, 0x01), /* Pointer */
            HID_RI_COLLECTION(8, 0x00), /* Physical */
                HID_RI_USAGE(8, 0x30), /* Usage X */
                HID_RI_USAGE(8, 0x31), /* Usage Y */
                HID_RI_LOGICAL_MINIMUM(8, -100),
                HID_RI_LOGICAL_MAXIMUM(8, 100),
                HID_RI_REPORT_SIZE(8, 0x08),
                HID_RI_REPORT_COUNT(8, 0x02),
                HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
            HID_RI_END_COLLECTION(0),
            HID_RI_USAGE_PAGE(8, 0x09), /* Button */
            HID_RI_USAGE(8, 0x02), /* Button 1 */
            HID_RI_USAGE(8, 0x01), /* Button 2 */
            HID_RI_LOGICAL_MINIMUM(8, 0x00),
            HID_RI_LOGICAL_MAXIMUM(8, 0x01),
            HID_RI_REPORT_SIZE(8, 0x01),
            HID_RI_REPORT_COUNT(8, 0x02),
            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
            HID_RI_REPORT_SIZE(8, 0x06),
            HID_RI_REPORT_COUNT(8, 0x01),
            HID_RI_INPUT(8, HID_IOF_CONSTANT),
        HID_RI_END_COLLECTION(0),
};

Which are still reasonably obtuse to those who haven’t read the HID specification, but which will make the creation and editing of new descriptors much easier without the aid of the fairly awfully written HID Descriptor tool from the USB-IF. My implementation abuses the heck out of the C preprocessor to achieve this level of awesome – the first macro parameter gives the data size, which is the number of bytes the second data parameter is decomposed into for the finaly array contents – but I think the macro magic is worth the improved readability.

I’ve got a few more ideas for asynchronous endpoints and pipes I want to prototype in the next week or so, so stay tuned for news in that area.

I’m off to bed.

 

Comments: 6

Leave a reply »

 
 
 

I’ve really enjoyed this post and glad you’re having fun.

By the way, the new HID descriptors read like poetry!

 

Hi Dean,
I once worked for a danish company and lerned to know (engl. wikipedia):
“Gammel Dansk” is a Danish alcoholic beverage …
The name “Gammel Dansk” translates directly from Danish as “Old Danish”.

But “Gammel” in German means something like “rotten”. So its not far from “old” to rotten”.

 

Hi Dean,

If you think the various fish dishes you listed above are bad, you problably do not want to try this one http://en.wikipedia.org/wiki/Hakarl
(you would have to trave to Iceland anyway)

But since you clearly did like the gravlaks until you found out what it was, you should take the opportunity to try the rakfisk while you are in Norway. Very good and tasty if prepared right, only tasty if not. (Let the locals try first. 😉

Bård

 

Great work! Is the HID report descriptor macro available as a separate header file? I use V-USB a lot and the same macros would be very useful outside of LUFA.

 

Frank,

You can pull the header file here:

http://code.google.com/p/lufa-lib/source/browse/trunk/LUFA/Drivers/USB/Class/Common/HIDReportData.h

Which contains the macros. You are free to use them as you see fit, in accordance with the MIT license at the top of the header file. The brand-spanking-new standard Joystick/Mouse/Keyboard templates here:

http://code.google.com/p/lufa-lib/source/browse/trunk/LUFA/Drivers/USB/Class/Common/HID.h

Will be moved to that file also tonight, but for now you can just manually copy them in.

– Dean

 

Leave a Reply

 
(will not be published)
 
 
Comment
 
 

 

Vital Stats

  • 35 Years Old
  • Australian
  • Lover of embedded systems
  • Firmware engineer
  • Self-Proclaimed Geek

Latest Blog Posts

RSS