Demo code for basic 3D graphics on the MBED application shield's LCD (K64F). Left pot changes Z depth, joystick rotates one of the cubes.

Dependencies:   C12832 FXOS8700CQ gfx3d mbed

main.cpp

Committer:
co657_frmb
Date:
2015-11-01
Revision:
0:fe1c42b7b490
Child:
1:3810f9d9c775

File content as of revision 0:fe1c42b7b490:

/*
 *  co657_lcdplay (main.cpp): playing with the MBED shield's LCD
 *  Copyright (C) 2015 Fred Barnes, University of Kent <frmb@kent.ac.uk>
 */

#include "mbed.h"
#include "C12832.h"
#include "FXOS8700CQ.h"

#include "gfx3d.h"

#define BENCHMARK

/* some global objects */
Serial host (USBTX, USBRX);

C12832 shld_lcd (D11, D13, D12, D7, D10);                   /* LCD on the shield (128x32) */

FXOS8700CQ fxos (PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1);     /* On-board accelerometer: SDA, SCL, (addr << 1) */

InterruptIn fxos_int1 (PTC6);                               /* unused, common with SW2 on FRDM-K64F */
InterruptIn fxos_int2 (PTC13);                              /* should just be the Data-Ready interrupt */
InterruptIn sw3_int (PTA4);                                 /* switch SW3 */

SRAWDATA fxos_acc;                                          /* collected accelerometer data */
SRAWDATA fxos_mag;                                          /* collected magnetometer data */

Ticker frametimer;                                          /* timer that will be used to update frames and whatnot */

#ifdef BENCHMARK
Timer perftimer;
#endif

#define PFLAG_TIMER         (0x01)                          /* next frame please */
#define PFLAG_FXOS          (0x02)                          /* accel/magno data ready */

static volatile uint8_t pflags = 0x00;                      /* program flags */



/*
 *  unused (?) -- also SW2 on the board
 */
void trigger_fxos_int1 (void)
{
    return;
}


/*
 *  read-ready interrupt for FXOS8700CQ
 */
void trigger_fxos_int2 (void)
{
    pflags |= PFLAG_FXOS;
    return;
}


/*
 *  interrupt handler for SW3 on the board
 */
void trigger_sw3_int (void)
{
    return;
}


/*
 *  interrupt handler for the frametimer Ticker object
 */
void trigger_frametimer (void)
{
    pflags |= PFLAG_TIMER;
    return;
}


/*
 *  dumps the global accelerometer/magnetomer reading to the serial-port "host"
 */
void print_reading (void)
{
    host.printf ("A X:%5d Y:%5d Z:%5d   M X:%5d Y:%5d Z:%5d\r\n",
            fxos_acc.x, fxos_acc.y, fxos_acc.z,
            fxos_mag.x, fxos_mag.y, fxos_mag.z);
}



/*
 *  start here
 */
int main (void)
{
    angle_t a;
    
    /* initialise */
    host.baud (38400);
    
    shld_lcd.set_auto_up (0);           /* we'll do it ourselves */
    shld_lcd.cls ();
    shld_lcd.copy_to_lcd ();
    
    fxos_int2.fall (trigger_fxos_int2);    /* level triggered interrupt */
    fxos.enable();                          /* enable device */

    /* Interrupt for SW3 button-down state */
    sw3_int.mode (PullUp);                  /* Since the FRDM-K64F doesn't have its SW2/SW3 pull-ups populated */
    sw3_int.fall (trigger_sw3_int);

    /* setup frame timer */
    frametimer.attach_us (trigger_frametimer, 40000);

    /* Example data printing */
    fxos.get_data (&fxos_acc, &fxos_mag);
    print_reading ();

    a = 0;
    for (;;) {
        uint8_t cflags = 0x00;
        
        if (pflags & PFLAG_TIMER) {
            g3d_p3_t pts1[8];                   /* points for rotates/translated cubes */
            g3d_2p3_t pts2[8];                  /* points for projected cube */
            int i;
            
            /* push last frame first */
            shld_lcd.copy_to_lcd ();
            shld_lcd.cls ();
            
            for (i=0; i<4; i++) {
                g3d_p3_t trans = {3.0f * gfx3d_sin (a + (i * 64)), 0.0f, 3.0f * gfx3d_cos (a + (i * 64))};
            
                /* rotate, translate and render! */
                if (i == 0) {
                    gfx3d_translate (g3d_cubepnts, pts1, 8, trans);
                } else {
                    gfx3d_rotate_demo (g3d_cubepnts, pts1, 8, (a * i) & 0xff);
                    gfx3d_translate (pts1, pts1, 8, trans);
                }

                gfx3d_project (pts1, pts2, 8);
        
                gfx3d_wirecube (pts2, shld_lcd);
            }
            
            a++;
            
            cflags |= PFLAG_TIMER;
        }
        if (pflags & PFLAG_FXOS) {
            fxos.get_data (&fxos_acc, &fxos_mag);
            cflags |= PFLAG_FXOS;
        }
        
        __disable_irq ();
        pflags &= ~cflags;
        if (!pflags) {
            sleep ();
        }
        __enable_irq ();
    }
    
}