/****************************************************************************
*
*  Program for Twister, a Line Maze robot.
*
****************************************************************************/

#include <stdio.h>
#include <68332/isr.h>
#include <68332/qsm.h>
#include <68332/sim.h>
#include <68332/mrm/led.h>
#include <68332/mrm/lcd.h>
#include <../libsim/68332/sim_regs.h>
#include "func.h"

#define BAUD_RATE 0     // 0 means use the current baud rate

#define TICK_HZ_SHIFT   10
#define TICK_HZ         ( 1 << TICK_HZ_SHIFT )

int gTickFlag = 0;
int gTickOverrun = 0;
volatile int gTickCounter  = 0;

void ReadAD( void );
void TickHandler( void );

typedef unsigned int    sample_t;

volatile sample_t gAD[ 8 ];

int main( void )
{
    int  nextTick;
    int  ledState = 0;
    SIM_T *sim = (SIM_T *)SIM_BASE;
    
    set_processor_speed( CLOCK25MHZ );
    
    /*
     * since sciinit is required for all programs that do i/o
     * perhaps it should be in mrm_crt0.S also?  It would still
     * be available if the user wanted to change baud rate.
     */
    
    sciinit( BAUD_RATE );
    
    led_init();
    lcd_init( 2, 24, 0, FALSE );
    
    /*
     * Initialize the periodic timer. A value of 8 should cause a 1024 Hz
     * interrupt.
     *
     * With PTP == 0, you get interrupted 8192/PITM times per second.
     * With PTP == 1, you get interrupted   16/PITM times per second.
     */
    
    gTickCounter = 0;
    install_isr( 64, TickHandler );
    sim->PITR.BITS.PTP   = 0;
    sim->PITR.BITS.PITM  = 8192 / TICK_HZ;
    sim->PICR.BITS.PIRQL = 6;
    sim->PICR.BITS.PIV   = 64;

    MyClass myObj;
    myObj.MyFunc();

    while ( 1 )
    {
        // Wait for a 1/2 second rollover


        nextTick = gTickCounter >> (TICK_HZ_SHIFT - 1);
        while ( nextTick == ( gTickCounter >> (TICK_HZ_SHIFT - 1)))
        {
            ;
        }
        
        if ( ledState )
        {
            int min = nextTick / 120;
            int sec = ( nextTick / 2 ) % 60;
            
            iprintf( "\r%02d:%02d 0x%02x (%3d), 0x%02x (%3d)", min, sec, gAD[0], gAD[0], gAD[1], gAD[1] );
            
            lcd_printf( "\f%02d:%02d 0x%02x (%3d)\n      0x%02x (%3d)", min, sec, gAD[0], gAD[0], gAD[1], gAD[1] );
            
            fflush( stdout );
            
            led_on( GreenLED );
            led_off( RedLED );
        }
        else
        {
            led_off( GreenLED );
            led_on( RedLED );
        }
        ledState = !ledState;
   }

   exit( 0 );
}

/****************************************************************************
*
*  Reads A/D channels
*
****************************************************************************/

void ReadAD( void )
{
   gAD[ 0 ] = *(unsigned char *)0xf00000; // Latch address 0
   gAD[ 0 ] = *(unsigned char *)0xf00001; // Start conversion 0, latch 1
   gAD[ 0 ] = *(unsigned char *)0xf00002; // Read 0, start conversion 1, latch 2
   gAD[ 1 ] = *(unsigned char *)0xf00003; // Read 1, start conversion 2, latch 3
   gAD[ 2 ] = *(unsigned char *)0xf00004; // Read 2, start conversion 3, latch 4
   gAD[ 3 ] = *(unsigned char *)0xf00005; // Read 3, start conversion 4, latch 5
   gAD[ 4 ] = *(unsigned char *)0xf00006; // Read 4, start conversion 5, latch 6
   gAD[ 5 ] = *(unsigned char *)0xf00007; // Read 5, start conversion 6, latch 7
   gAD[ 6 ] = *(unsigned char *)0xf00000; // Read 6, start conversion 7
   gAD[ 7 ] = *(unsigned char *)0xf00000; // Read 7

} /* ReadAD */

/****************************************************************************
*
*  Called for each tick of the Periodic Interval Timer.
*
****************************************************************************/

void TickHandler( void )
{

   if( gTickFlag )
   {
      gTickOverrun++;
      return;
   }
   gTickFlag = 1;

   gTickCounter++;

   ReadAD();
   
   gTickFlag = 0;
}

