14. Griffin Hardware

The griffin knob is a secondary core peripharal used in Monolith that is used alongside the Monome. It is controlled using the hidapi wrapper.

14.1. hidapi system include

The hidapi uses a system include hidapi/hidapi.h

<<system_includes>>=
#ifndef MONOLITH_SIMPLE
#include "hidapi/hidapi.h"
#endif

14.2. Griffin Hardware Data

Griffin is stored in an hidapi handle of type hid_devicecalled griffin_handle.

<<struct_contents>>=
#ifndef MONOLITH_SIMPLE
hid_device *griffin_handle;
#endif
<<init>>=
#ifndef MONOLITH_SIMPLE
m->griffin_handle = NULL;
#endif

It is closed with hid_close.

<<close_griffin_handle>>=
#ifndef MONOLITH_SIMPLE
if(m->griffin_handle != NULL) hid_close(m->griffin_handle);
#endif

14.3. Griffin Setup and Cleanup

The Griffin knob is started and initialized with the function monolith_griffin_setup.

<<function_declarations>>=
void monolith_griffin_setup(monolith_d *m);

The nice thing about the hidapi wrapper is that is loads devices using Vendor and Product ID numbers, which are cross-platform. No os-dependent code needed with this layer, which is nice.

We want pulling to be non-blocking, so this must be explicitely set using hid_set_nonblocking.

<<functions>>=
void monolith_griffin_setup(monolith_d *m)
{
#ifndef MONOLITH_SIMPLE
    monolith_griffin_d *g;
    g = &m->vgriffin;
    if(m->griffin_handle != NULL) return;
    m->griffin_handle = hid_open(0x077d, 0x0410, NULL);
    if(m->griffin_handle == NULL) {
        fprintf(stderr, "Could not open Griffin knob\n");
        return;
    }

    hid_set_nonblocking(m->griffin_handle, 1);

<<set_griffin_callbacks>>
#endif
}

Griffin setup is implemented as a function called monolith:griffin-setup.

<<primitive_entries>>=
{"monolith:griffin-setup", pp_griffin_setup, 0, 0, {CHR,___,___}},
<<scheme_functions>>=
static cell pp_griffin_setup(cell x) {
    monolith_griffin_setup(monolith_data_get());
    return UNSPECIFIC;
}

At the end of the program, the griffin is closed with the function monolith_griffin_cleanup.

<<function_declarations>>=
void monolith_griffin_cleanup(monolith_d *m);
<<functions>>=
void monolith_griffin_cleanup(monolith_d *m)
{
<<close_griffin_handle>>
}

This gets called at cleanup.

<<cleanup>>=
monolith_griffin_cleanup(m);

14.4. Polling the Griffin

Griffin events are pulled with the function monolith_griffin_poll.

This is code directly lifted from monomer.

<<function_declarations>>=
void monolith_griffin_poll(monolith_d *m);
<<functions>>=
void monolith_griffin_poll(monolith_d *m)
{
#ifndef MONOLITH_SIMPLE
    static unsigned char buf[16];
    int res;
    if(m->griffin_handle == NULL) return;
    res = hid_read(m->griffin_handle, buf, 16);
    if(res > 0) {
        if(buf[1] == 0) {
            monolith_griffin_push(&m->vgriffin, buf[0]);
        } else if(buf[1] > 0) {
            monolith_griffin_turn(&m->vgriffin,
                                  (signed char)buf[1]);
        }
    }
#endif
}

The poll function is called inside of the main poll callback.

<<poll_the_griffin>>=
#ifndef MONOLITH_SIMPLE
monolith_griffin_poll(m);
#endif

14.5. Set Griffin Callbacks

14.5.1. Set Default Turn Callback

<<static_function_declarations>>=
#ifndef MONOLITH_SIMPLE
static void griffin_turn(monolith_griffin_d *g, int state);
#endif
<<functions>>=
#ifndef MONOLITH_SIMPLE
static void griffin_turn(monolith_griffin_d *g, int state)
{
    if(g->md->curpage != NULL) {
        monolith_page_turn(g->md->curpage, state);
    }
}
#endif
<<set_griffin_callbacks>>=
monolith_griffin_turn_set(g, griffin_turn);

14.5.2. Set Default Push Callback

<<static_function_declarations>>=
#ifndef MONOLITH_SIMPLE
static void griffin_push(monolith_griffin_d *g, int state);
#endif
<<functions>>=
#ifndef MONOLITH_SIMPLE
static void griffin_push(monolith_griffin_d *g, int state)
{
    if(g->md->curpage != NULL) {
        monolith_page_push(g->md->curpage, state);
    }
}
#endif
<<set_griffin_callbacks>>=
monolith_griffin_push_set(g, griffin_push);



prev | home | next