Example #1
0
//Simple delay function, no operation
void DelayMs(unsigned int msec)
{
    unsigned int tWait, tStart;
    tWait=(SYS_FREQ/2000)*msec;
    tStart=ReadCoreTimer();
    while((ReadCoreTimer()-tStart)<tWait);		// wait for the time to pass
}
Example #2
0
void waitFor(int time) {
    //time in microseconds
    //40 ticks is a microsecond, I think?
    //NU32_WriteUART1("Waiting\n");
    int finishtime = ReadCoreTimer() + time * 25;
    while (ReadCoreTimer() < finishtime);
}
Example #3
0
int ping_ultrasonic(int echo, int trig, int max_distance) //max_distance in cm
{//ping HC-SR04 ultrasonic range finder, 10us trigger pulse, sends eight 40kHz pulses
    //int start_time;
    int max_time; //max_time in system cycles
    int flight_time;
    //char message[100];
    //sprintf(message, "bump");

    //NU32_WriteUART1(message);
    max_time = max_distance * 2320; //Distance(cm) = Time(us)/58, 40 core cycles per us, 58*40=2320
    //start_time = ReadCoreTimer();
    WriteCoreTimer(0);
    set_pin(trig, HIGH);
    while(ReadCoreTimer() < 1600){ //400 cycles at 40MHz, 10us trigger pulse
    }
    set_pin(trig, LOW);
    //NU32_WriteUART1(message);
    while(!get_pin(echo)){
    }
    //NU32_WriteUART1(message);
    //start_time = ReadCoreTimer();
    WriteCoreTimer(0);
    while(get_pin(echo) && (ReadCoreTimer() < max_time)){
    }
    //flight_time = ReadCoreTimer() - start_time;
    flight_time = ReadCoreTimer();
    //sprintf(message, "%d\n", flight_time);
    //NU32_WriteUART1(message);
    return flight_time / 2320;
}
Example #4
0
void ShortDelay(                       // Short Delay 
  uint32 DelayCount)                   // Delay Time (CoreTimer Ticks) 
{ 
  uint32 StartTime;                    // Start Time 
  StartTime = ReadCoreTimer();         // Get CoreTimer value for StartTime 
  while ( (uint32)(ReadCoreTimer() - StartTime) < DelayCount ) {}; 
} 
Example #5
0
void
nrf_send_frames (struct frame *frame, int frames)
{
  int i;
  t[0] = ReadCoreTimer ();
  for (i = 0; i < frames - 1; i++)
    {
      t[i + 1] = ReadCoreTimer ();
      nrf_send_frame ((uint8_t *) (frame + i), 0);
      if (i % 4 == 3)
	{
	  delay_ms (5);
	}
    }
  nrf_send_frame ((uint8_t *) (frame + frames - 1), 1);
  t[i + 2] = ReadCoreTimer ();

  for (i = 0; i < frames; ++i)
    {
      printf ("%08d ns %08d ns\n\r", (t[i + 1] - t[0]) * 50,
	      (t[i + 1] - t[i]) * 50);
    }


}
void DelayMs(unsigned int msec)
{
    unsigned int tWait, tStart;
    tWait= (40000*msec);
    tStart=ReadCoreTimer();
    while((ReadCoreTimer()-tStart)<tWait);
}
Example #7
0
/******************************************************************************
*	delay_ms()
*
*	This functions provides a software millisecond delay
******************************************************************************/
void delay_ms(uint32_t msec)
{
	uint32_t tWait, tStart;
		
    tWait = (CPU_HZ/2000)*msec;
    tStart = ReadCoreTimer();
    while((ReadCoreTimer() - tStart) < tWait);
}
Example #8
0
void u8g_10MicroDelay(void)
{
    uint32_t d;
    uint32_t s;
    d = TICKS_PER_MILLISECOND/100;
    s = ReadCoreTimer();
    while ( (uint32_t)(ReadCoreTimer() - s) < d )
        ;
}
Example #9
0
/**
 * Block the processor for the desired number of milliseconds.
 * @note Assumes processor frequency of 80Mhz.
 * @param msec The number of milliseconds to block for.
 */
void _DelayMs(uint32_t msec)
 {
     uint32_t tWait, tStart;

	 // Calculate the amount of wait time in terms of core processor frequency.
     tWait = (80000000L / 2000) * msec;
     tStart = ReadCoreTimer();
     while ((ReadCoreTimer() - tStart) < tWait); // wait for the time to pass
 }
Example #10
0
void u8g_Delay(uint16_t val)
{
    uint32_t d;
    uint32_t s;
    d = val;
    d *= TICKS_PER_MILLISECOND;
    s = ReadCoreTimer();
    while ( (uint32_t)(ReadCoreTimer() - s) < d )
        ;
}
Example #11
0
void
delay_ms(uint32_t ms)
{
	uint32_t startTime, waitTime;

	startTime = ReadCoreTimer();
	waitTime = (FCY / 2000) * ms;

	while ((ReadCoreTimer() - startTime) < waitTime)
		;
}
Example #12
0
/************************************************************************************************** 
  Function: 
    void DelayS(const UINT s)
  
  Author(s): 
    mkobit
  
  Summary: 
    Delays for s seconds
  
  Description: 
    Blocking routine, sets core timer to 0, and calculates how many core timer ticks it needs to wait to delay for s seconds and delays
  
  Preconditions: 
    DelayInit called previously, core timer configured
  
  Parameters: 
    const UINT s - seconds to delay: should not be an excessively high number
  
  Returns: 
    void
  
  Example: 
    DelayS(2)
  
  Conditions at Exit: 
    Core timer overwritten to 0 before delay, could be any number after
  
**************************************************************************************************/
void DelayS(const UINT s) {
  UINT start;
  UINT ticks_to_wait;
  UINT core_time;

  ticks_to_wait = s * _core_hz;
  //WriteCoreTimer(0);  // clear timer
  start = ReadCoreTimer();
  do {
    core_time = ReadCoreTimer();
  } while((core_time - start) < ticks_to_wait);
}
Example #13
0
/************************************************************************************************** 
  Function: 
    void DelayMs(const UINT ms)
  
  Author(s): 
    mkobit
  
  Summary: 
    Delays for ms seconds
  
  Description: 
    Blocking routine, calculates how many core timer ticks required to delay for ms milliseconds and delays
  
  Preconditions: 
    DelayInit called previously, core timer configured
  
  Parameters: 
    const UINT ms - milliseconds to delay
  
  Returns: 
    void
  
  Example: 
    <code>
    DelayMs(250)
    </code>
  
  Conditions at Exit: 
    None
  
**************************************************************************************************/
void DelayMs(const UINT ms) {
  UINT start;
  UINT ticks_to_wait;
  UINT core_time;

  ticks_to_wait = ms * _core_ticks_in_ms;
  //WriteCoreTimer(0);  // clear timer
  start = ReadCoreTimer();
  do {
    core_time = ReadCoreTimer();
  } while((core_time - start) < ticks_to_wait);
  //while ((UINT) (ReadCoreTimer() - start) < ticks_to_wait) {};
}
Example #14
0
int ping_ultrasonic_median(int echo, int trig, int max_distance, int iterations)
{
    int flight_time[iterations];
    int i;
    int start_time;
    for(i = 0; i < iterations; i++){
        flight_time[i] = ping_ultrasonic(echo, trig, max_distance);
        start_time = ReadCoreTimer();
        while(ReadCoreTimer() - start_time < 4000000){//i think this is 50 ms
        }
    }
    return find_median(flight_time, iterations);
}
Example #15
0
void Delayus(UINT32 us)
{
    UINT32 stop = ReadCoreTimer() + us * (UINT32)(FCP0 / 1000000UL);

    #if 0 && defined(DEBUG)
        SerialPrint("start = ");
        SerialPrintNumber(ReadCoreTimer(), 10);
        SerialPrint("\r\n");
        SerialPrint("stop = ");
        SerialPrintNumber(stop, 10);
        SerialPrint("\r\n");
    #endif

    // valid only when using a signed type
    while ((INT32) (ReadCoreTimer() - stop) < 0);
}
Example #16
0
//************************************************************************
// Read the CoreTimer register, which counts up at a rate of 40MHz
// (CPU clock/2). Each microsecond will be 40 of these counts.
// We keep track of the total number of microseconds since the PIC
// was powered on, as an int. Which means that this value will
// overflow every 71.58 minutes. We have to keep track of the CoreTimer
// overflows. The first value of CoreTimer after an overflow is recorded,
// and all micros() calls after that (until the next overflow) are 
// referenced from that value. This insures accuracy and that micros()
// lines up perfectly with millis().
//************************************************************************
unsigned long micros()
{
unsigned int cur_timer_val	=	0;
unsigned int micros_delta	=	0;

	// Use this as a flag to tell the ISR not to touch anything
	gMicros_calculating	=	1;
	cur_timer_val	=	ReadCoreTimer();

	// Check for overflow
	if (cur_timer_val >= gCore_timer_last_val)
	{
		// Note - gCore_timer_micros is not added to here (just a =, not a +=)
		// so we don't accumulate any errors.
		micros_delta	=	(cur_timer_val - gCore_timer_first_val) / CORETIMER_TICKS_PER_MICROSECOND;
		gCore_timer_micros	=	gMicros_overflows + micros_delta;
	}
	else
	{
		// We have an overflow
		gCore_timer_micros		+=	((0xFFFFFFFF - gCore_timer_last_val) + cur_timer_val) / CORETIMER_TICKS_PER_MICROSECOND;
		// Store off the current counter value for use in all future micros() calls
		gCore_timer_first_val	=	cur_timer_val;
		// And store off current micros count for future micros() calls
		gMicros_overflows		=	gCore_timer_micros;
	}
	// Always record the current counter value and remember it for next time
	gCore_timer_last_val	=	cur_timer_val;
	gMicros_calculating		=	0;

	return(gCore_timer_micros);
}
Example #17
0
//////////////////////////////////////////////////////////////////////////////////
/// name: msDelay
/// params: unsigned int
/// return: void
/// desc: provides a pause/sleep for duration specified by input param
///       code provided by Eric Johnston
void msDelay(unsigned int delay_pd)
{
    unsigned int tWait;
    unsigned int tStart;
    
    // read current core timer
    tStart = ReadCoreTimer(); 
    
    // set time to be current time plus specified offset
    tWait = tStart + (CORE_TICKS_per_MS * delay_pd);  
    
    // wait for the time to pass
    while ( ReadCoreTimer() < tWait )
	{}
    
}
Example #18
0
//************************************************************************
void __ISR(_CORE_TIMER_VECTOR, ipl2) CoreTimerHandler(void)
{
unsigned int cur_timer_val;
	

	cur_timer_val	=	ReadCoreTimer();
	// clear the interrupt flag
	mCTClearIntFlag();

	// update the period
	UpdateCoreTimer(CORE_TICK_RATE);

	// .. things to do
	
	// Check for CoreTimer overflows, record for micros() function
	// If micros() is not called more often than every 107 seconds (the
	// period of overflow for CoreTimer) then overflows to CoreTimer
	// will be lost. So we put code here to check for this condition
	// and record it so that the next call to micros() will be accurate.
	if (!gMicros_calculating)
	{
		if (cur_timer_val < gCore_timer_last_val)
		{
			// We have an overflow
			gCore_timer_micros		+=	((0xFFFFFFFF - gCore_timer_last_val) + cur_timer_val) / CORETIMER_TICKS_PER_MICROSECOND;
			gCore_timer_first_val	=	cur_timer_val;
			gMicros_overflows	=	gCore_timer_micros;
		}
		gCore_timer_last_val	=	cur_timer_val;
	}
	
	// Count this millisecond
	gTimer0_millis++;
}
Example #19
0
/*********************************************************************
 * Function:        int main(void)
 *
 * PreCondition:    None
 *
 * Input:			None
 *
 * Output:          0 if some SPI transfer failed,
 * 					1 if the SPI transfers suceeded
 *
 * Side Effects:    None
 *
 * Overview:		Examples for the usage of the SPI Peripheral Lib
 *
 * Note:            None.
 ********************************************************************/
int	main(void)
{
     
      #if defined (__32MX220F032D__) || defined (__32MX250F128D__)
	SDI1Rbits.SDI1R = 1; //SET SDI1 to RPB5
      RPB1Rbits.RPB1R = 3; //SET RPB1R to SDO1
	#endif

	SpiChannel spiChn=SPI_CHANNEL1;	// the SPI channel to use

	// Configure the device for maximum performance but do not change the PBDIV
	// Given the options, this function will change the flash wait states, RAM
	// wait state and enable prefetch cache but will not change the PBDIV.
	// The PBDIV value is already set via the pragma FPBDIV option above..
	SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);


	srand(ReadCoreTimer());		// seed the pseudo random generator

	if(!SpiDoLoopbackExample(spiChn, 1024))
	{
		return 0;	// our example failed
	}

	return 1;

}
Example #20
0
//#=============================================================================
//# Delays
//#=============================================================================
//#-----------------------------------------------------------------------------
void Delayus(unsigned int t) {
    unsigned int CalT;
    WriteCoreTimer(0);
    CalT = t * 20;

    while ( (unsigned int)(ReadCoreTimer()) < CalT ) {};
} //Delayus
Example #21
0
/*********************************************************************
 * Function:        int main(void)
 *
 * PreCondition:    None
 *
 * Input:			None
 *
 * Output:          0 if some SPI transfer failed,
 * 					1 if the SPI transfers suceeded
 *
 * Side Effects:    None
 *
 * Overview:		Examples for the usage of the SPI Peripheral Lib
 *
 * Note:            None.
 ********************************************************************/
int	main(void)
{

      #if defined (__32MX220F032D__) || defined (__32MX250F128D__)
	SDI1Rbits.SDI1R = 1; //SET SDI1 to RPB5
      RPB1Rbits.RPB1R = 3; //SET RPB1R to SDO1

      RPA4bits.RPA4R = 0b0100; //SET RPA4 to SDO2
      SDI2Rbits.SDI2R = 1;     //SET SDI2 to RPB6
	#endif



	// Configure the device for maximum performance but do not change the PBDIV
	// Given the options, this function will change the flash wait states, RAM
	// wait state and enable prefetch cache but will not change the PBDIV.
	// The PBDIV value is already set via the pragma FPBDIV option above..
	SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);


	srand(ReadCoreTimer());		// seed the pseudo random generator

	if(!SpiDoMasterSlaveExample(100))
	{
		return 0;	// our example failed
	}


	return 1;

}
Example #22
0
int main(void)
{
    // BootloaderEntry();

    Initialize();

    sprintf(text,"\r\n\r\nHypnocube Boot Loader testing ver %s.\r\n",BootloaderVersion());
    PrintSerialMain(text);

    sprintf(text,"Boot loader result %d.\r\n",(int)bootResult);
    PrintSerialMain(text);
    
    WriteCoreTimer(0);
    while (1)
    {
        if (ReadCoreTimer()>1000*TICKS_PER_MILLISECOND)
        {
            PrintSerialMain(".");
            WriteCoreTimer(0);
            PORTAbits.RA1^=1; // blink our LED
        }
        uint8_t byte;
        
        if (UARTReadByte(&byte) && byte != 0xFC)
        {
            sprintf(text,"Main code saw command %d = %c.\r\n",(int)byte,byte);
            PrintSerialMain(text);
            BootloaderEntry(); // call again to simplify testing
        }
    }

    return 0;
}
Example #23
0
/********************************************************************
* Function: 	delay_us()
*
* Precondition: 
*
* Input: 		Micro second
*
* Output:		None.
*
* Side Effects:	Uses Core timer. This may affect other functions using core timers.
				For example, core timer interrupt may not work, or may loose precision.				
*
* Overview:     Provides Delay in microsecond.
*
*			
* Note:		 	None.
********************************************************************/
void delay_us(UINT us)
{
   
    UINT targetCount;  
    UINT bakupCount; 
    UINT8 loop = 0;
    // Assert "us" not zero. This must be caught during debug phase.
    //ASSERT(us!=0);
    // backup current count of the core timer.
    bakupCount = ReadCoreTimer();
    // Core timer increments every 2 sys clock cycles.
    // Calculate the counts required to complete "us". 
    targetCount = countPerMicroSec * us;      
    // Restart core timer.
    WriteCoreTimer(0);    
    // Wait till core timer completes the count.    
    while(ReadCoreTimer() < targetCount);
    
    // Restore count back.
    WriteCoreTimer(bakupCount + targetCount);       	
   
}  
Example #24
0
int read_ultrasonic(void)
{
    


  int flight_time[5];
  int av_flight = 0;
  int i;
  int start_time;

  // read the sensor 5 times and average the result
  for (i = 0; i < 5; i++) {
    start_time = ReadCoreTimer();

    // pulse the trigger for 20us to send the ultrasonic signals
    LATEbits.LATE9 = 1;
    while (ReadCoreTimer() - start_time < 1600) {
    }
    LATEbits.LATE9 = 0;

    // wait for echo to go high
    while (!PORTEbits.RE8) {
    }
    start_time = ReadCoreTimer();

    // wait until the ECHO pin goes low, or 12ms has passed
    while (PORTEbits.RE8 && (ReadCoreTimer() - start_time < 480000)) {
    }
    flight_time[i] = ReadCoreTimer() - start_time;
  }

  for (i = 0; i < 5; i++) {
    av_flight = av_flight + flight_time[i];
  }

  av_flight = av_flight / 5;

  return av_flight;
}
Example #25
0
void delay_us(unsigned count){
    unsigned startTime=ReadCoreTimer();
    unsigned endTime= startTime + (count* SYS_FREQ/1E6);
    if(endTime>UINT_MAX-100)// margin for safety. we don't want to wait a whole round
        endTime=0;
    debug_str("delay from ");
    debug_int_hex_16bit(startTime>>16);
    debug_int_hex_16bit(startTime>>00);
    debug_str("\r\nuntil      ");
    debug_int_hex_16bit(endTime>>16);
    debug_int_hex_16bit(endTime>>00);
    debug_nl();
    unsigned time;
    while((time=ReadCoreTimer())<endTime || (time>startTime && endTime<startTime) )//the second check is because the coreTimer regularly overflows
    {
        int c;
         for(c=0; c<10; c++)
            Nop();
    }
    debug_str(" done \r\n");

}
Example #26
0
    double current_time(int reset)
    {
        unsigned int ns;

        if (reset) {
            WriteCoreTimer(0);
        }

        /* get timer in ns */
        ns = ReadCoreTimer();

        /* return seconds as a double */
        return ( ns / CLOCK * 2.0);
    }
Example #27
0
unsigned int adc_grab(int sample_pin) {
  unsigned int elapsed=0,finishtime=0;
  unsigned int sample;
  
  AD1CON3bits.ADCS = 2;
  AD1CON1bits.ADON = 1;
  
  //ANALOG INPUTS ON AN0(RA0),AN1{RA1),AN4(RB2),AN5(RB3
  WriteCoreTimer(0);
  if (sample_pin<=1){
    // sample_pin is 1 or 2
    AD1CHSbits.CH0SA = sample_pin-1;
  }
  else{
    //sample_pin is 3 or 4
    AD1CHSbits.CH0SA = sample_pin+1;
  }

  AD1CON1bits.SAMP = 1; //start sampling
  elapsed = ReadCoreTimer();
  finishtime = elapsed + SAMPLE_TIME;
  while(ReadCoreTimer() < finishtime){//sample for more than 200ns
      ;
  }
  AD1CON1bits.SAMP = 0; //stop sampling and start converting
  while (!AD1CON1bits.DONE){
      ;
  }
  sample=ADC1BUF0;//read the buffer with the result
  char msg[100]={};
  sprintf(msg,"AN0: %4u (%5.3f volts)",sample,sample*(3.3/1024));
  //to check ADC values, set a breakpoint at the line below, view the variables tab
  //and look at the value for message. it says what the adc is reading in volts
  return(sample);
  //elapsed=ReadCoreTimer();
}
Example #28
0
    double current_time(int reset)
    {
        /* NOTE: core timer tick rate = 40 Mhz, 1 tick = 25 ns */

        unsigned int ns;

        /* should we reset our timer back to zero? Helps prevent timer
           rollover */

        if (reset) {
            WriteCoreTimer(0);
        }

        /* get timer in ns */
        ns = ReadCoreTimer() * 25;

        /* return seconds as a double */
        return ( ns / 1000000000.0 );
    }
// ************************************************************
int main( void)
{
//    double t;
    short v, i, j;
    char start;
    char roll;
    char s[32], kj;

    // init offsets
    x0 = 125;
    y0 = 100;
    z0 = 200;
    
    // hardware and video initialization 
    MMBInit();
    initVideo();
    initMatrix( mw, AOFFS, BOFFS, GOFFS, x0, y0, z0);
        
    // 3. main loop
    while( 1)
    {
        roll = 1;
        start = 0;
        gClearScreen();          
    
        // splash screen
        setColor( 2);  // red
        AT(8, 1); putsV( "Rubik's Cube Demo");
        AT(8, 3); putsV( "   LDJ v1.0");
        AT(8, 5); putsV( " for PIC32MX4 MMB");
        copyV();                        // update visible screen
        while( !MMBReadKey());
        srand( ReadCoreTimer());
             
        // clear all objects
        objc = MAXOBJ;
        pyc = MAXPOLY;
        pc = MAXP;
        
        // init all objects angles
        for( i=0; i<MAXOBJ; i++)
            a[i] = b[i] = g[i] = 0;
     
        // create the rubik cube
        newCube();
        
        // init cursor and define grid
        qx = 1; qy = 1;
        initGrid();        
        
        while ( roll)
        {
            // paint cube in current position (with cursor)
            gClearScreen();                 // clear the hidden screen
            for( i=objc; i<MAXOBJ; i++)
            {
                initMatrix( mo, 0, 0, 0, 0, 0, 0);
                drawObject( mo, i);
            }
            drawCursor( qx, qy);
            copyV();
            
            // read the joystick and rotate center rows 
            kj = MMBGetKey();
            
            if ( kj & 0x80)         // long pressure 
            {
                switch( kj & 0x7F){
                  case JOY_RIGHT:   // rotate whole cube
                        rotateCube( 0, +1, 0);
                    break;
                  case JOY_LEFT:    // rotate whole cube
                        rotateCube( 0, -1, 0);
                    break;
                  case JOY_UP:      // rotate whole cube
                        rotateCube( -1, 0, 0);
                    break;
                  case JOY_DOWN:    // rotate whole cube
                        rotateCube( +1, 0, 0);
                    break;
                  case JOY_SELECT:  // rotate face counter clockwise
                        rotateRow( 0, 0, 1, 2, +1);
                    break;
                }
            }
            else                    // short pressure
            {                       
                switch( kj){
                  case JOY_RIGHT:   // rotate only the current row 
                    if (qx == 2)
                        rotateRow( 0, 1, 0, qy, +1);
                    else qx++;
                    break;
                  case JOY_LEFT:    // rotate only the current row 
                    if (qx == 0)
                        rotateRow( 0, 1, 0, qy, -1);
                    else qx--;
                    break;
                  case JOY_UP:      // rotate only the current row 
                    if (qy == 2)
                        rotateRow( 1, 0, 0, qx, -1);
                    else qy++;
                    break;
                  case JOY_DOWN:    // rotate only the current row 
                    if (qy == 0)
                        rotateRow( 1, 0, 0, qx, +1);
                    else qy--;
                    break;
                  case JOY_SELECT:  // rotate face clockwise
                        rotateRow( 0, 0, 1, 2, -1);
                    break;
                } // switch
            } // short pressure     
        } //roll        
    } // main loop
} // main
int main() {
    CFGCONbits.JTAGEN = 0; // turn off JTAG, get back those pins for IO use
    // set PIC32to max computing power
    DEBUGLED = 0;
    // enable multi-vector interrupts
    INTEnableSystemMultiVectoredInt();
    INTEnableInterrupts();
    PIC32MX250_setup_pins();
    SYSTEMConfigPerformance(SYS_FREQ);

    setTimer2(OUTPUT_FREQ); //
    setupTimer3(BUFFER_FREQ);
    initPWM(); //Initializing PWM on OC3.

    // Initialize texture buffer and index to zero

    int i;
    tBuff.Index = 0; //init to zero
    tBuff.On = 0; //turn off
    tBuff.Length0 = 0; //start with zero length
    tBuff.Length1 = 0; //start with zero length
    tBuff.Front = 0;
    for (i = 0; i < MAX_BUFFER_LENGTH; i++) {
        tBuff.Buff0[i] = 0; //init entire buffer to zero
        tBuff.Buff1[i] = 0; //init entire buffer to zero
    }


    // Initialize the USB host
    ConnectionInit();
    DEBUGLED = 1;

    //Main USB State Machine
    while (1) {
        // Keep the USB connection running;
        // Handle incoming data and manage outgoing data.
        ConnectionTasks();
        // Main state machine
        switch (state) {
            case STATE_INIT:

                state = STATE_WAITING;
                h = INVALID_CHANNEL_HANDLE;
                break;

            case STATE_WAITING:
                DEBUGLED = 0;
                if (ADBAttached()) {
                    state = STATE_CONNECTING;
                }
                break;

            case STATE_CONNECTING:

                if (ADBConnected()) {
                    // Open a channel to the Android device
                    // See "adb.h" in libadb for more details
                    // (I don't think the name tcp:4545 matters)
                    h = ADBOpen("tcp:4545", &ADBCallback);

                    if (h != INVALID_CHANNEL_HANDLE) {
                        state = STATE_CONNECTED;
                        WriteCoreTimer(0);
                        // Send plaintext and let the recipient do formatting
                        ADBWrite(h & 0xFF, "Hello from TPAD!", 17);
                    }
                }
                break;

            case STATE_CONNECTED:
                DEBUGLED = 1;

                if (!ADBAttached()) {
                    state = STATE_INIT;
                }
                if (ADBChannelReady(h)) {

                    // Execute tasks that rely on the Android-PIC32 connection
                    // Here we will just wait for messages to come in and be handled below
                }
                // Timeout timer. If the coretimer is not reset by a keepalive command from the Android, the PIC will reset the USB communications
                if (ReadCoreTimer() > 200000000) {
                    state = STATE_INIT;
                }

                break;
        } // end state machine
    } // end while loop

    return 0;
}