Example #1
0
File: if_ie.c Project: MarginC/kame
/*
 * Process a command-complete interrupt.  These are only generated by
 * the transmission of frames.	This routine is deceptively simple, since
 * most of the real work is done by iestart().
 */
static int
ietint(struct ie_softc *sc)
{
	int	status;
	int	i;

	sc->arpcom.ac_if.if_timer = 0;
	sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;

	for (i = 0; i < sc->xmit_count; i++) {
		status = sc->xmit_cmds[i]->ie_xmit_status;

		if (status & IE_XS_LATECOLL) {
			printf("ie%d: late collision\n", sc->unit);
			sc->arpcom.ac_if.if_collisions++;
			sc->arpcom.ac_if.if_oerrors++;
		} else if (status & IE_XS_NOCARRIER) {
			printf("ie%d: no carrier\n", sc->unit);
			sc->arpcom.ac_if.if_oerrors++;
		} else if (status & IE_XS_LOSTCTS) {
			printf("ie%d: lost CTS\n", sc->unit);
			sc->arpcom.ac_if.if_oerrors++;
		} else if (status & IE_XS_UNDERRUN) {
			printf("ie%d: DMA underrun\n", sc->unit);
			sc->arpcom.ac_if.if_oerrors++;
		} else if (status & IE_XS_EXCMAX) {
			printf("ie%d: too many collisions\n", sc->unit);
			sc->arpcom.ac_if.if_collisions += 16;
			sc->arpcom.ac_if.if_oerrors++;
		} else {
			sc->arpcom.ac_if.if_opackets++;
			sc->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL;
		}
	}
	sc->xmit_count = 0;

	/*
	 * If multicast addresses were added or deleted while we were
	 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating
	 * that we should do it.
	 */
	if (sc->want_mcsetup) {
		mc_setup(sc);
		sc->want_mcsetup = 0;
	}
	/* Wish I knew why this seems to be necessary... */
	sc->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL;

	iestart(&sc->arpcom.ac_if);
	return (0);		/* shouldn't be necessary */
}
Example #2
0
int main( void )
{
  uint32_t val = 0;
  char textbuf [ (2*16) + 1 ]; // lcd

  /* setup
   */

  // LCD
  lcd_init();

  // Timer: enable a timer so we can measure passage of time
  //
  // Given: 20MHz clock
  // --> if we want resolution of ms (1/1000th second) .. actually, we want us (1/10th of a ms) so we can measure partial ms
  // --> and we have 1/20000000 clock resolution
  // -----> 2000 ticks will get us there (20,000 will get us ms)
  //
  // Goal: Use CTC interupt mode (CTC -> Clear on Timer Compare)
  // So a compare matches, it clears to zero and triggers interupt
  TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 
  OCR1A = 2000; // number to compare against
  TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt 
  TCCR1B |= (1 << CS10); // Set up timer , with no prescaler (works at full MHz of clock)

  // Receiver setup - set up pin change interupt
#if 1
  EICRA &= ~ ( (1 << ISC01) | (1 << ISC01) ); // clear ISC01+ISC00
  EICRA |= ( (1 << ISC00) ); // 00 set and 01 unset means any edge will make event
  PCMSK0 |= ( (1 << PCINT0) | (1 << PCINT1) ); // Pins to monitor: PA0 and PA1
  PCICR |= (1 << PCIE0); // PA is monitored
#endif

  // Serial - setup (for motor controller)
  mc_setup();

  // TWI - set up
  unsigned char twibuf [ TWI_BUFFER_SIZE ];
  unsigned char TWI_slaveAddress; 
  TWI_slaveAddress = 0x10; // our TWI address
  TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); // Initialise TWI module as slave; include addr+general
  unsigned char twi_heartbeat_counter = 0;

  // setup done - kick up interupts
  sei();

  // lets burn the first couple of seconds, so the receiver can get some signal
  // before we start blasting stuff into the motor controllers
  {
    unsigned int start_sec = g_time_s;
    while ( g_time_s - start_sec < 3 ) {
      nop();
    }
  }

  // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  TWI_Start_Transceiver();

#if 1 // timer test .. show per-second counter update on lcd
  if ( 1 ) {
    unsigned int last_sec = g_time_s;
    unsigned int last_us = _g_time_us_tick;

    unsigned char sent_l = 0, sent_r = 0;
    char message [ 17 ];

    while(1) {
      unsigned int ch1 = g_ch1_duration;
      unsigned int ch2 = g_ch2_duration;

      // 100ms has past?
      if ( _g_time_us_tick - last_us > 1000 ) {

        if ( g_control_twi ) {
          // we're on TWI control, but if nothing comes in.. revert back to RC
          if ( g_time_s - g_control_last_s > 2 ) {
            g_control_twi = 0;
          }
        } else {
          mc_set_by_receiver ( ch1, ch2, &sent_l, &sent_r, message );
        }

        last_us = _g_time_us_tick;
      } // .1sec tick

      // one second has past? update lcd
      if ( g_time_s != last_sec ) {
        //sprintf ( textbuf, "recv %2d %2d     ", g_ch1_duration, g_ch2_duration );
        sprintf ( textbuf, "m %2d %2d th %2d %2d #", sent_l, sent_r, ch1, ch2 );
        lcd_xy ( 0, 0 );
        lcd_puts( textbuf ); // display number right adjusted

        //sprintf ( textbuf, "t%2d #", g_time_s );
        sprintf ( textbuf, "t%2d # %s", g_time_s, message );
        lcd_xy ( 0, 1 );
        lcd_puts( textbuf ); // display number right adjusted

        last_sec = g_time_s;
      } // 1 sec tick

      // TWI/I2C stuff, talk to r-pi
      //

      // Check if the TWI Transceiver has completed an operation.
      if ( ! TWI_Transceiver_Busy() ) {

        // Check if the last operation was successful
        if ( TWI_statusReg.lastTransOK ) {

          // Check if the last operation was a reception
          if ( TWI_statusReg.RxDataInBuf ) {
            TWI_Get_Data_From_Transceiver ( twibuf, 3 );

            // Check if the last operation was a reception as General Call        
            if ( TWI_statusReg.genAddressCall ) {
              // don't care

            } else { // Ends up here if the last operation was a reception as Slave Address Match   
              // Example of how to interpret a command and respond.

#if 0            
              // TWI_CMD_MASTER_WRITE stores the data to PORTB
              if (twibuf[0] == TWI_CMD_MASTER_WRITE) {
                PORTB = twibuf[1];                            
              }
#endif

              // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
              if ( twibuf[0] == tc_heartbeat ) {
                twibuf [ 0 ] = 1;
                twibuf [ 1 ] = twi_heartbeat_counter++;
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );

              } else if ( twibuf[0] == tc_gethello ) {
                sprintf ( twibuf + 1, "hello" );
                twibuf [ 0 ] = strlen ( twibuf + 1 ); // len
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );

              } else if ( twibuf[0] == tc_setmotors ) {
                g_control_last_s = g_time_s;
                mc_speed ( mcm_left, twibuf [ 1 ] );
                mc_speed ( mcm_right, twibuf [ 2 ] );

              } else if ( twibuf[0] == tc_takeover ) {
                g_control_last_s = g_time_s;
                g_control_twi = 1;

              } else if ( twibuf[0] == tc_release ) {
                g_control_twi = 0;

              } else {
                twibuf [ 0 ] = 1;
                twibuf [ 1 ] = 0xde;
                twibuf [ 2 ] = 0xad;
                twibuf [ 3 ] = 0xbe;
                twibuf [ 4 ] = 0xef;
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );
              }

            }

          } else { // Ends up here if the last operation was a transmission  
            // don't care
          }

          // Check if the TWI Transceiver has already been started.
          // If not then restart it to prepare it for new receptions.             
          if ( ! TWI_Transceiver_Busy() ) {
            TWI_Start_Transceiver();
          }

        } else { // Ends up here if the last operation completed unsuccessfully
          TWI_Act_On_Failure_In_Last_Transmission ( TWI_Get_State_Info() );
        } // success/fail

      } // TWI busy?

      // spin
      _delay_ms ( 20 );

    } // while forever

  } // if 1
#endif

  /* churn forever
   */
  while(1);

  return ( 0 );
}