Example #1
0
  void rpm2LEDs(DWORD curRate) {
      //if (curRate < 1000)  { SetLEDs(0b00000000); MotorState = FALSE; curRate = 10;}
      //else { MotorState = TRUE; }
      int per = (curRate / PWM_PERIOD) * 100;


      int setting = toSetting(per);

      SetLEDs(setting);
      /*
      SetLEDs(setting);
      if (curRate <  25 ) { SetLEDs(0b00000000); }
      if (curRate >= 50 ) { SetLEDs(0b10000000); }
      if (curRate >= 100) { SetLEDs(0b11000000); }
      if (curRate >= 150) { SetLEDs(0b11100000); }
      if (curRate >= 175) { SetLEDs(0b11110000); }
      if (curRate >= 200) { SetLEDs(0b11111000); }

      */
  }
// Called from userspace to do something, like set the LEDs
IOReturn WirelessHIDDevice::setReport(IOMemoryDescriptor *report, IOHIDReportType reportType, IOOptionBits options)
{
    char data[2];

    if (report->readBytes(0, data, 2) < 2)
        return kIOReturnUnsupported;
    
    switch (data[0]) {
        case 0x01:  // LED
            if ((data[1] != report->getLength()) || (data[1] != 0x03))
                return kIOReturnUnsupported;
            report->readBytes(2, data, 1);
            SetLEDs(data[0]);
            return kIOReturnSuccess;
        case 0x02:  // Power
            PowerOff();
            return kIOReturnSuccess;
        default:
            return super::setReport(report, reportType, options);
    }
}
Example #3
0
int main()
{
	RCC_ClocksTypeDef RCC_Clocks;
	RCC_GetClocksFreq(&RCC_Clocks);

	SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

	InitializeLEDs();
	MyUSART_Init();

	setvbuf(stdout, 0, _IONBF, 0);
	printf("Hello!\r\n");

	char c;
	while(1)
	{
		if(USART_ReceiveChar(&c))
			USART_SendChar(c);

		SetLEDs(c);
	}
}
Example #4
0
int main()
{
	RCC_ClocksTypeDef RCC_Clocks;
	RCC_GetClocksFreq(&RCC_Clocks);

	SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

	InitializeLEDs();
	MyUSART_Init();

	setvbuf(stdout, 0, _IONBF, 0);
	printf("Hello!\r\n");

	InitializeSnesController();

	while(1)
	{
		snes_button_state_t btn = GetControllerState();
		printf("SNES: %02X\r\n", btn.raw);
		printf(
			"%s %s %s %s %s %s %s %s %s %s %s %s\r\n",
			btn.buttons.A ? "A" : "",
			btn.buttons.B ? "B" : "",
			btn.buttons.X ? "X" : "",
			btn.buttons.Y ? "Y" : "",
			btn.buttons.L ? "L" : "",
			btn.buttons.R ? "R" : "",
			btn.buttons.Start ? "Start" : "",
			btn.buttons.Select ? "Select" : "",
			btn.buttons.Left ? "Left" : "",
			btn.buttons.Up ? "Up" : "",
			btn.buttons.Down ? "Down" : "",
			btn.buttons.Right ? "Right" : ""
		);

		SetLEDs(btn.buttons.A << 3 | btn.buttons.B << 2 | btn.buttons.X << 1 | btn.buttons.Y);
	}
}
Example #5
0
void T1init(void)
{
	// Initialize LED pins
	PORTB |= 0x1F;
	DDRB |= 0x1F;
	SetLEDs(50);
	
	//Initialize button input pullup and pin change interrupt
	DDRA &= ~(1<<PORTA3);
	PORTA |= (1<<PORTA3);
	PCMSK0 = 0x08; //Enable Pin change interrupt on pin 3
	PCICR = 0x01; //Enable Pin change 0 interrupt
	
	// Configure the timers used for the LEDs
	TCCR1A = 0;
	TCCR1B = 2;		//prescale = 8
	OCR1A = 10;		//use 75% brightness level so we can see the waveform for testing
	OCR1B = 240;		//available for PWM use by FETs
	
	TIFR1 = 0x0F;		//force all timer interrupt flags to be cleared.
	TIMSK1 = (1<<TOIE1);// (1<<OCIE1A)|(1<<OCIE1B);		//enable interrupts as needed.

}
Example #6
0
static void RunLEDFlow()
{
	int8_t components[3];
	ReadRawAccelerometerData(components);

	int32_t dx=components[0]-zero[0];
	int32_t dy=components[1]-zero[1];
	int32_t r=sqrti(dx*dx+dy*dy);
	dx=(dx<<12)/r;
	dy=(dy<<12)/r;

	x+=r*25;

//	x+=components[0]-zero[0];
//	y+=components[1]-zero[1];

	int leds=0;
	leds|=(((x+dx)>>14)&1)<<1;
	leds|=(((x-dx)>>14)&1)<<3;
	leds|=(((x+dy)>>14)&1)<<0;
	leds|=(((x-dy)>>14)&1)<<2;

	SetLEDs(leds);
}
Example #7
0
int main()
{
	InitializeSystem();
	SysTick_Config(HCLKFrequency()/100);
	InitializeLEDs();

	SetLEDs(0x01);

	uint8_t *framebuffer1=(uint8_t *)0x20000000;
	uint8_t *framebuffer2=(uint8_t *)0x20010000;
	SetLEDs(0x03);
	memset(framebuffer1,0,320*200);
	memset(framebuffer2,0,320*200);

	SetLEDs(0x07);

	IntializeVGAScreenMode320x200(framebuffer1);

	#define NumberOfStars 1050
	static struct Star
	{
		int x,y,dx,f;
	} stars[NumberOfStars];

	for(int i=0;i<NumberOfStars;i++)
	{
		stars[i].x=(RandomInteger()%352-16)<<12;
		stars[i].y=RandomInteger()%200;

		int z=sqrti((NumberOfStars-1-i)*NumberOfStars)*1000/NumberOfStars;
		stars[i].dx=6000*1200/(z+200);

		stars[i].f=(6-(z*7)/1000)+(RandomInteger()%6)*7;
	}

	const RLEBitmap *sprites[7*6]={
		&Star1_0,&Star2_0,&Star3_0,&Star4_0,&Star5_0,&Star6_0,&Star7_0,
		&Star1_1,&Star2_1,&Star3_1,&Star4_1,&Star5_1,&Star6_1,&Star7_1,
		&Star1_2,&Star2_2,&Star3_2,&Star4_2,&Star5_2,&Star6_2,&Star7_2,
		&Star1_3,&Star2_3,&Star3_3,&Star4_3,&Star5_3,&Star6_3,&Star7_3,
		&Star1_4,&Star2_4,&Star3_4,&Star4_4,&Star5_4,&Star6_4,&Star7_4,
		&Star1_5,&Star2_5,&Star3_5,&Star4_5,&Star5_5,&Star6_5,&Star7_5,
	};

	Bitmap frame1,frame2;
	InitializeBitmap(&frame1,320,200,320,framebuffer1);
	InitializeBitmap(&frame2,320,200,320,framebuffer2);

	int frame=0;

	while(1)
	{
		WaitVBL();

		Bitmap *currframe;
		if(frame&1) { currframe=&frame2; SetFrameBuffer(framebuffer1); }
		else { currframe=&frame1; SetFrameBuffer(framebuffer2); }

		ClearBitmap(currframe);

		for(int i=0;i<NumberOfStars;i++)
		{
			DrawRLEBitmap(currframe,sprites[stars[i].f],
			(stars[i].x>>12)-16,stars[i].y-16);

			stars[i].x-=stars[i].dx;
			if(stars[i].x<=-16<<12)
			{
				stars[i].x=(320+16)<<12;
				stars[i].y=RandomInteger()%200;
				stars[i].f=(stars[i].f%7)+(RandomInteger()%6)*7;
			}
		}

		frame++;
	}
}
Example #8
0
File: main.c Project: ByReaL/AVR474
/*! \brief The main function.
 *
 * This contains initialization and the main loop as described in the
 * application note. Interrupt service routines (ISR) supply all data to be
 * processed in the main loop.
 *
 */
int main( void )
{
	/*
	Initialisation of peripheral modules:
	- Watchdog (timeout must be more than longer than the longest conversion period used for the CC-ADC)
	- Turn of unneeded modules (only SPI atm)
	- Bandgap
	- Set Current protection levels/configuration
	- V-ADC
		- Get cell voltages (requires that interrupts are enabled)
		- Get temperature
		- Estimate capacity ("gas gauging")
	- Check battery voltage and release the device from DUVR mode
	- CC-ADC
		- Get initial current reading (momentary and average).
	- Communication
	*/
	// Initialization.
	wdt_reset();
	
	WDT_SetTimeOut( WDTO_2Kms );  //Set Watchdog timeout to 2 sec

#ifdef DEBUG
	if( FAILURE == Reset_Initialization() ){
		// TODO: The Watchdog has triggered several times - might want to shut down the battery?!
		// POWMAN_Shutdown();
	}
#endif
	// Enable power reduction for SPI
	PRR_DISABLE_SPI();
	// Disable digital input for port a
	DIDR0 = (1<<PA0DID) | (1<<PA1DID);
	// Enable pull-ups for port b to avoid floating pins
	PORTB = (1<<PORTB0) | (1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3) | (1<<PORTB4) | (1<<PORTB5) | (1<<PORTB6) | (1<<PORTB7);
	DDRB = (1<<PORTB0) | (1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3) | (1<<PORTB4);
	
	// Check the CRC checksum of the battery parameters struct
	errorFlags.checksumFailure = (! BATTPARAM_CheckCRC()) | (! CheckSignatureCRC());

	// Initialize Bandgap reference.
	if( FAILURE == BANDGAP_Initialization() ){
		errorFlags.criticalConditionDetected = true;
	}
	
	// Initialize the battery protection module (enabled by default - if default settings are good
	// this is not required).
	BATTPROT_SetShortCircuitDetection( battParams.shortcircuitCurrent, battParams.shortcircuitReactionTime );
	BATTPROT_SetOverCurrentDetection( battParams.overcurrentDischarge, battParams.overcurrentCharge, battParams.overcurrentReactionTime );
	BATTPROT_SetHighCurrentDetection( battParams.highcurrentDischarge, battParams.highcurrentCharge, battParams.highcurrentReactionTime );
	
	BATTPROT_DisableDischargeHighCurrentProtection(); // Don't want a high discharging current to disable the FETs (in this example)
	BATTPROT_EnableAllInterrupts();

	//Enable DUVR from the start, so we are always in DUVR mode.
	FETCTRL_EnableDeepUnderVoltageMode();
	
	// On reset, the device is in DUVR mode depending on the fuse setting DUVRINIT
	stateFlags.inDUVR = true;
	
	// Enable the voltage regulator monitor interrupt
	VREGMON_InterruptEnable();
	
	// Initialize V-ADC and configure a full scan
	VADC_InitializeVadcCoefficients();
	VADC_ScanConfig( (vadcIndex_t)HIGHEST_CELL, (vadcIndex_t)HIGHEST_VADC, (vadcIndex_t)VTEMP );

	// This can only fail if the VADC is set-up with an invalid ScanConfig
	if( FAILURE == VADC_StartScan() ){
		errorFlags.criticalConditionDetected = true;
	} else {
		__enable_interrupt();
		while( VADC_RUNNING == VADC_ScanState() );
		__disable_interrupt();
		
		VADC_ClearReadyFlags();
		
		disableDUVRIfPossible();
		VBSoC_Init();
	}
	
	// Calculate the coefficient numbers for ccadc_ticks to mA and gas_gauging to mAh functions
	BATTCUR_CalculateShuntCoeffient(battParams.shuntResistance, CCADC_VOLTREF);
        uint16_t temp = RCCAL_CalculateUlpRCperiod(coreTemperature/10);
	CCGASG_CalculateShuntCoefficients(temp, battParams.shuntResistance, CCADC_VOLTREF);
	
	// Calculate values for the sram battery parameters struct
	BATTPARAM_InitSramParameters();
	
	// Copy key from eeprom to sram if using AES
#if defined(AUTH_USE_AES)
	AUTH_CopyKeyToSram();
#endif
		
	
	// If a critical condition occured, (either bandgap didn't work or VADC was configured wrong)
	// don't do any of the battery related initialization and disable DUVR mode (so charging is impossible)
	if( errorFlags.criticalConditionDetected ) {
		FETCTRL_DisableDeepUnderVoltageMode();
		FETCTRL_DisableFets();
		
	} else {
		// Initialize the CC-ADC (sample every second and set regular current level)
		CCADC_Init( ACCT_1024, RCCI_1024, 10 mA );
		CCADC_SetMode( CCADC_ACC );
		
		// Set initial remaining capacity in the CCGASG module, it is marked as in-
		// accurate and updated the first time the VBSoC have an accurate reading.
		CCGASG_SetStateofCharge(VBSoC_EstimatedSoC());
		stateFlags.remainingCapacityInaccurate = 1;
		
		__enable_interrupt();
		// Needs to run a conversion before the value is correct
		while( !CCADC_isAccResultReady() );
		wdt_reset();
		__disable_interrupt();
		
		
		// Calculate the CCADC Accumulating conversion offset if it is invalid and
		// DUVR mode is disabled
		if(CCADC_GetRawAccOffset() == 32767 && ! stateFlags.inDUVR) {
			FETCTRL_DisableFets(); // Disable FETs when measuring offset as changes in current not is good
			__enable_interrupt();
			CCADC_CalculateAccOffset();
			__disable_interrupt();
		}
		
		// If two or more cells, init the misbalance corrector
#if BATTPARAM_CELLS_IN_SERIES >= 2
		BATTVMON_InitializeBalancing();
#endif
		
		//Store information about the current (to be able to reply if host asks...)
		BATTCUR_StoreCurrent( CCADC_GetAccResult() );
		BATTCUR_InitializeAverageCurrent( BATTCUR_GetOffsetCalibratedCurrent() );
	}
	
	//init communication bus
	T1init();	// Used for SmBus timeout and LED

	Comm_Init();

	// Ready to run - enable interrupts and enter main loop.
	__enable_interrupt();
	
	
	/*******************************************************************
	Main loop:
	If any of the task flags are set the corresponding task should be run.
	
	The following things are done:
	- Reset watchdog
	- If a new CCADC result is ready, start a VADC conversion
	- If the communication interface have a new byte, handle it
	- and if a whole new command has arrived, handle that
	- Handle new CCADC result if it's ready
	- Check new core temperature if ready, and run a fast RC calibration if needed
	- Check new cell temperature if ready
	- Check new cell voltage if ready
	- Set different sleep modes depending on what's running
	  - If in communication or RC calibration (any timer running) can only enter idle mode
	  - If VADC is running, can't go deeper than ADC noise reduction mode
	  - If "nothing" is running, enter power-save
	- Disable/enable fets depeding on various things
	- Go to sleep
	*/
	while(1) {

		//Tickle the watchdog every cycle
		wdt_reset();
		
		if( CCADC_isAccResultReady() )
		{
			// Start a new VADC scan as fast as possible so that all scans hopefully are
			// ready before the main loop ends, to avoid having to cycle again.
			
			
#if BATTPARAM_CELLS_IN_SERIES >= 2
			// Disable cell balancing if more than one cell
			BATTVMON_DisableCellBalancing();
#endif
			
			// Start a new VADC scan
			configureVADC();
			VADC_StartScan();
			
			taskFlags.newCurrentAvailable = true;
		}
		
		//See if there were any received commands.
		taskFlags.newSbsCommandAvailable = Comm_Handle( &sbs );

		
		//If complete sbs command has been received: process it
		if( taskFlags.newSbsCommandAvailable )
		{
			handleSBSCommand();
			// If authentication is needed, run. It will use and change the values in sbs,
			// make sure the communication interrupt does not write directly to it.
			// Note that this can take long time and communication will not work
			// during that time.
			if(taskFlags.doAuthentication) {
				AUTH_Execute(&sbs);
				taskFlags.doAuthentication = false;
			}
		}
		
		
		/*
		A new CC-ADC conversion is available. Update momentary current, average current,
		and calculate new battery capacity. Update discharge_cycle_accumulator (and increment
		cycle_count if required).
		*/
		if( taskFlags.newCurrentAvailable )
		{
			taskFlags.newCurrentAvailable = false;
			
			// We use the CCADC interrupt as counter for the RTC
			runEverySecond();
			BATTCUR_StoreCurrent( CCADC_GetAccResult() );
			handleNewCCADCResult();
			CCGASG_AccumulateCCADCMeasurements( BATTCUR_GetCurrent(), slowRcOscillatorPeriod );
			
			//Set ledstatus
			SoC_State = GASG_StateOfCharge(BATTCUR_GetAverageCurrent(), battParams_sram.capacityInCCAccumulated);
			SetLEDs((uint8_t)SoC_State);
		}

		/*
		New core temperature reading is available and should be processed. If
		temperature has changed set RC_calibration_required flag.
		*/
		if( VADC_VTempReady() )
		{
			handleNewCoreTemperature();
		}

		/*
		RC oscillator requires calibration (new CC_ADC conversion period time should
		be calculated and stored.
		*/
		if( taskFlags.rcCalibrationRequired )
		{
			taskFlags.rcCalibrationRequired = false;
			RCCAL_StartCalibrateFastRC();
			
			// Calculating slow RC period works on whole kelvins
			slowRcOscillatorPeriod = RCCAL_CalculateSlowRCperiod( coreTemperature/10 );
		}
		
		if( RCCAL_GetState() == RCCAL_CALIB_INIT || RCCAL_GetState() == RCCAL_CALIB_WORKING ) {
			RCCAL_CalibrateFastRCruntime(slowRcOscillatorPeriod);
		}
		
		/*
		Battery cell temperature is available. Check it and disable FETs if too high/low
		*/
		if( VADC_CellTempReady() )
		{
			handleNewCellTemperature();
		}
		
		
		/*
		Check battery voltage cell . Check if critical (high/low voltage)
		*/
		if( VADC_Cell1VoltageReady() )
		{
			handleNewCellVoltage(CELL1);
		}
			
		/*
		Check battery voltage cell . Check if critical (high/low voltage) and misbalance
		*/
#if BATTPARAM_CELLS_IN_SERIES >= 2
		if( VADC_Cell2VoltageReady() )
		{
			handleNewCellVoltage(CELL2);
		}

#if BATTPARAM_CELLS_IN_SERIES >= 3
		if( VADC_Cell3VoltageReady() )
		{
			handleNewCellVoltage(CELL3);
		}

#if BATTPARAM_CELLS_IN_SERIES >= 4
		if( VADC_Cell4VoltageReady() )
		{
			handleNewCellVoltage(CELL4);
		}
#endif
#endif
#endif	
		
		// Check what sleep mode we can enter. Needs disable interrupt because otherwise it might
		// overwrite what interrupts write to SMCR (for example, if external interrupt is triggered and
		// wants the sleep mode to be no higher than idle, it should be run after all those checks)
		uint8_t interruptState = __save_interrupt();
		__disable_interrupt();
		if( Comm_IsIdle() && ! RCCAL_IS_RUNNING() ) {
			if( VADC_RUNNING == VADC_ScanState() ) {
				SLEEP_SET_ADC_NR_MODE();
			} else {
				SLEEP_SET_POWER_SAVE_MODE();
			}
		} else {
			SLEEP_SET_IDLE_MODE();
		}
		__restore_interrupt(interruptState);
		
		/*
		Disable FETs if critical condition have been detected.
		Enable them if that is okey, depending om various factors like
		temperature and voltage.
		*/
		if(   errorFlags.criticalConditionDetected
			 || stateFlags.simulatePowerOff)
		{
			FETCTRL_DisableFets();
		}
		else if( ! errorFlags.cellTemperatureTooHigh &&
		         ! errorFlags.cellTemperatureTooLow &&
		         ! stateFlags.inDUVR)
		{
			if(   ! errorFlags.voltageTooHigh
			   && ! errorFlags.reoccuringChargeProtection
			   && ! stateFlags.chargingProhibited
			   && ! sbsFlags.forceChargeFETDisabled)
			{
				FETCTRL_EnableChargeFet();
			}
			
			if(   ! errorFlags.voltageTooLow
			   && ! stateFlags.dischargingProhibited
			   && ! sbsFlags.forceDischargeFETDisabled)
			{
				FETCTRL_EnableDischargeFet();
			}
		}
		
		// The reason to do this is that on short-circuit, the cell voltage reading can
		// be wrong and if that causes both chargingProhibited and dischargingProhibited
		// to get set, they would never be cleared unless we do this.
		// If they should be set, they will be set again before the FETs are enabled again
		// on next cycle.
		if( stateFlags.chargingProhibited && stateFlags.dischargingProhibited ) {
			stateFlags.chargingProhibited = false;
			stateFlags.dischargingProhibited = false;
		}
		
		// Enter sleep if no new byte just have been received on the communication
		// If a byte is received between the check for Comm_Flag and __sleep is
		// executed, the sleep function will have no effect as the software communication
		// interrupt clears sleep mode enable.
		if( (Comm_Flag() == 0 ) && (ShowLedBusy()==false) ){
			__sleep();
		}
	}
}
Example #9
0
/****************************************************************************
  Function:
    int main(void)

  Summary:
    main function

  Description:
    main function

  Precondition:
    None

  Parameters:
    None

  Return Values:
    int - exit code for main function

  Remarks:
    None
  ***************************************************************************/
int main(void)
{
    DWORD size = 0;
    BOOL responseNeeded;

    BYTE mode = 0;

    BYTE wasMode = 0;
    BYTE pushButtonValues = 0xFF;
    BYTE potPercentage = 0xFF;
    BOOL buttonsNeedUpdate = FALSE;
    BOOL potNeedsUpdate = FALSE;
    BOOL motorON = FALSE;
    BOOL readyToRead = TRUE;
    BOOL writeInProgress = FALSE;
    BYTE tempValue = 0xFF;
    BYTE errorCode;
    ACCESSORY_APP_PACKET* command_packet = NULL;

    CLKDIV =  0; /* set for default clock operations Fcyc = 4MHz */
    AD1PCFGL = 0xffff;
    AD1PCFGH = 0x0003;

    BOOL connected_to_app = FALSE;
    BOOL need_to_disconnect_from_app = FALSE;

    #if defined(__PIC32MX__)
        InitPIC32();
    #endif

  #if defined(__dsPIC33EP512MU810__) || defined (__PIC24EP512GU810__)

    // Configure the device PLL to obtain 60 MIPS operation. The crystal
    // frequency is 8MHz. Divide 8MHz by 2, multiply by 60 and divide by
    // 2. This results in Fosc of 120MHz. The CPU clock frequency is
    // Fcy = Fosc/2 = 60MHz. Wait for the Primary PLL to lock and then
    // configure the auxilliary PLL to provide 48MHz needed for USB
    // Operation.

	PLLFBD = 38;				/* M  = 60	*/
	CLKDIVbits.PLLPOST = 0;		/* N1 = 2	*/
	CLKDIVbits.PLLPRE = 0;		/* N2 = 2	*/
	OSCTUN = 0;

    /*	Initiate Clock Switch to Primary
     *	Oscillator with PLL (NOSC= 0x3)*/

    __builtin_write_OSCCONH(0x03);
	__builtin_write_OSCCONL(0x01);
	while (OSCCONbits.COSC != 0x3);

    // Configuring the auxiliary PLL, since the primary
    // oscillator provides the source clock to the auxiliary
    // PLL, the auxiliary oscillator is disabled. Note that
    // the AUX PLL is enabled. The input 8MHz clock is divided
    // by 2, multiplied by 24 and then divided by 2. Wait till
    // the AUX PLL locks.

    ACLKCON3 = 0x24C1;
    ACLKDIV3 = 0x7;
    ACLKCON3bits.ENAPLL = 1;
    while(ACLKCON3bits.APLLCK != 1);

    TRISBbits.TRISB5 = 0;
    LATBbits.LATB5 = 1;

    #endif

    USBInitialize(0);
    AndroidAppStart(&myDeviceInfo);

    responseNeeded = FALSE;
    mInitPOT();
    InitializeTimer2For_PWM();
    PwmInit();

    //InitMOTOR();

    DEBUG_Init(0);

    InitAllLEDs();

    while(1)
    {
        //Keep the USB stack running
        USBTasks();



        //If the device isn't attached yet,
        if(device_attached == FALSE || mode == 1)
        {
            buttonsNeedUpdate = TRUE;
            potNeedsUpdate = TRUE;
            need_to_disconnect_from_app = FALSE;
            connected_to_app = FALSE;
            size = 0;

            /**/
            BYTE curPush = GetPushbuttons();

            if ((curPush == 0x8) || (mode == 1)) {
                LED0_On();

                mode = 1;
                if (wasMode == 0) {

                    pot2LEDs();
                    PwmInit();


                }

                tempValue = ReadPOT();


                wasMode = 1;

                //If it is different than the last time we read the pot, then we need
                //  to send it to the Android device

                if(tempValue != potPercentage) {
                    potNeedsUpdate = TRUE;
                    //setRPM(tempValue);

                    setPWM();
                }
            }
            if ((curPush == 0x4)  || (mode == 0)) {
                    mode = 0;
                    //LED0_Off();

                    if (wasMode == 1) {
                        SetLEDs(0b00000000);
                        wasMode = 0;
                        setRPM(0);
                    }
                    //Reset the accessory state variables
                    InitAllLEDs();

                    //Continue to the top of the while loop to start the check over again.
                    continue;
                }
               /* //Reset the accessory state variables
                InitAllLEDs();

                //Continue to the top of the while loop to start the check over again.
                continue;
            }*/
            //}






        }

        //If the accessory is ready, then this is where we run all of the demo code

        if(readyToRead == TRUE && mode == 0)
        {
            errorCode = AndroidAppRead(device_handle, (BYTE*)&read_buffer, (DWORD)sizeof(read_buffer));
            //If the device is attached, then lets wait for a command from the application
            if( errorCode != USB_SUCCESS)
            {
                //Error
                DEBUG_PrintString("Error trying to start read");
            }
            else
            {
                readyToRead = FALSE;
            }
        }

        size = 0;

        if(AndroidAppIsReadComplete(device_handle, &errorCode, &size) == TRUE)
        {
            //We've received a command over the USB from the Android device.
            if(errorCode == USB_SUCCESS)
            {
                //Maybe process the data here.  Maybe process it somewhere else.
                command_packet = (ACCESSORY_APP_PACKET*)&read_buffer[0];
            }
            else
            {
                //Error
                DEBUG_PrintString("Error trying to complete read request");
            }

        }

        while(size > 0)
        {
            if(connected_to_app == FALSE)
            {
                if(command_packet->command == COMMAND_APP_CONNECT)
                {
                    connected_to_app = TRUE;
                    need_to_disconnect_from_app = FALSE;
                }
            }
            else
            {
                switch(command_packet->command)
                {
                    case COMMAND_SET_LEDS:
                        SetLEDs(command_packet->data);
                        break;

                    case COMMAND_APP_DISCONNECT:
                        need_to_disconnect_from_app = TRUE;
                        break;

                    case COMMAND_SET_PWM:
                        setRPM(command_packet->data);
                        break;

                    default:
                        //Error, unknown command
                        DEBUG_PrintString("Error: unknown command received");
                        break;
                }
            }
            //All commands in this example are two bytes, so remove that from the queue
            size -= 2;
            //And move the pointer to the next packet (this works because
            //  all command packets are 2 bytes.  If variable packet size
            //  then need to handle moving the pointer by the size of the
            //  command type that arrived.
            command_packet++;

            if(need_to_disconnect_from_app == TRUE)
            {
                break;
            }
        }

        if(size == 0)
        {
            readyToRead = TRUE;
        }

        //Get the current pushbutton settings
        tempValue = GetPushbuttons();

        //If the current button settings are different than the last time
        //  we read the button values, then we need to send an update to the
        //  attached Android device
        if(tempValue != pushButtonValues)
        {
            buttonsNeedUpdate = TRUE;
            pushButtonValues = tempValue;
        }

        //Get the current potentiometer setting
        tempValue = ReadPOT();

        //If it is different than the last time we read the pot, then we need
        //  to send it to the Android device
        if(tempValue != potPercentage)
        {
            potNeedsUpdate = TRUE;
            potPercentage = tempValue;
        }

        //If there is a write already in progress, we need to check its status
        if( writeInProgress == TRUE )
        {
            if(AndroidAppIsWriteComplete(device_handle, &errorCode, &size) == TRUE)
            {
                writeInProgress = FALSE;
                if(need_to_disconnect_from_app == TRUE)
                {
                    connected_to_app = FALSE;
                    need_to_disconnect_from_app = FALSE;
                }

                if(errorCode != USB_SUCCESS)
                {
                    //Error
                    DEBUG_PrintString("Error trying to complete write");
                }
            }
        }

        if((need_to_disconnect_from_app == TRUE) && (writeInProgress == FALSE))
        {
            outgoing_packet.command = COMMAND_APP_DISCONNECT;
            outgoing_packet.data = 0;
            writeInProgress = TRUE;

            errorCode = AndroidAppWrite(device_handle,(BYTE*)&outgoing_packet, 2);
            if( errorCode != USB_SUCCESS )
            {
                DEBUG_PrintString("Error trying to send button update");
            }
        }

        if(connected_to_app == FALSE)
        {
            //If the app hasn't told us to start sending data, let's not do anything else.
            continue;
        }

        //If we need up update the button status on the Android device and we aren't
        //  already busy in a write, then we can send the new button data.
        if((buttonsNeedUpdate == TRUE) && (writeInProgress == FALSE))
        {
            outgoing_packet.command = COMMAND_UPDATE_PUSHBUTTONS;
            outgoing_packet.data = pushButtonValues;



            errorCode = AndroidAppWrite(device_handle,(BYTE*)&outgoing_packet, 2);
            if( errorCode != USB_SUCCESS )
            {
                DEBUG_PrintString("Error trying to send button update");
            }

            buttonsNeedUpdate = FALSE;
            writeInProgress = TRUE;
        }

        //If we need up update the pot status on the Android device and we aren't
        //  already busy in a write, then we can send the new pot data.
        if((potNeedsUpdate == TRUE) && (writeInProgress == FALSE))
        {
            outgoing_packet.command = COMMAND_UPDATE_POT;
            outgoing_packet.data = potPercentage;

            errorCode = AndroidAppWrite(device_handle,(BYTE*)&outgoing_packet, 2);
            if( errorCode != USB_SUCCESS )
            {
                DEBUG_PrintString("Error trying to send pot update");
            }

            potNeedsUpdate = FALSE;
            writeInProgress = TRUE;
        }
    } //while(1) main loop
}
// 这里面的IO操作是经过序列化的。一个挨着一个,所以绝不会发生重入问题。
//
VOID CY001Drv::DeviceIoControlSerial(IN WDFQUEUE  Queue,
						 IN WDFREQUEST  Request,
						 IN size_t  OutputBufferLength,
						 IN size_t  InputBufferLength,
						 IN ULONG  IoControlCode)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	ULONG ulRetLen = 0;
	size_t size;

	void* pBufferInput = NULL;
	void* pBufferOutput = NULL;

	KDBG(DPFLTR_INFO_LEVEL, "[DeviceIoControlSerial]");

	// 取得输入/输出缓冲区
	if(InputBufferLength)WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &pBufferInput, &size);
	if(OutputBufferLength)WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &pBufferOutput, &size);

	switch(IoControlCode)
	{
		// 设置数码管
	case IOCTL_USB_SET_DIGITRON:
		{
			CHAR ch = *(CHAR*)pBufferInput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_SET_DIGITRON");
			SetDigitron(ch);
			break;
		}

		// 读数码管
	case IOCTL_USB_GET_DIGITRON:
		{
			UCHAR* pCh = (UCHAR*)pBufferOutput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_GET_DIGITRON");
			GetDigitron(pCh);
			ulRetLen = 1;
			break;
		}

		// 设置LED灯(共4盏)
	case IOCTL_USB_SET_LEDs:
		{
			CHAR ch = *(CHAR*)pBufferInput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_SET_LEDs");
			SetLEDs(ch);
			break;
		}

		// 读取LED灯(共4盏)的当前状态
	case IOCTL_USB_GET_LEDs:
		{
			UCHAR* pCh = (UCHAR*)pBufferOutput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_GET_LEDs");
			GetLEDs(pCh);
			ulRetLen = 1;
			break;
		}

		// 控制命令。
		// 分为:USB协议预定义命令、Vendor自定义命令、特殊类(class)命令。
	case IOCTL_USB_CTL_REQUEST:
		{
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_CTL_REQUEST");
			ntStatus = UsbControlRequest(Request);
			if(NT_SUCCESS(ntStatus))return;
			break;
		}

		// 开启中断读
	case IOCTL_START_INT_READ:	
		KDBG(DPFLTR_INFO_LEVEL, "IOCTL_START_INT_READ");	
		ntStatus = InterruptReadStart();
		break;

		// 控制程序发送读请求。它们是被阻塞的,放至Queue中排队,所以不要即可完成他们。
	case IOCTL_INT_READ_KEYs:
		KDBG(DPFLTR_INFO_LEVEL, "IOCTL_INT_READ_KEYs");
		ntStatus = WdfRequestForwardToIoQueue(Request, m_hInterruptManualQueue);

		if(NT_SUCCESS(ntStatus))
			return;// 成功,直接返回;异步完成。
		break;

		// 终止中断读
	case IOCTL_STOP_INT_READ:
		KDBG(DPFLTR_INFO_LEVEL, "IOCTL_STOP_INT_READ");
		InterruptReadStop();
		ntStatus = STATUS_SUCCESS;
		break;

	default:
		// 不应该到这里。
		// 对于不能识别的IO控制命令,这里做错误处理。
		KDBG(DPFLTR_INFO_LEVEL, "Unknown Request: %08x(%d)!!!", IoControlCode, IoControlCode);
		ntStatus = STATUS_INVALID_PARAMETER;
		break;
	}

	WdfRequestCompleteWithInformation(Request, ntStatus, ulRetLen);
	return;
}
Example #11
0
void main(void)
{
   char cntByte;

   // Declare your local variables here

   // Crystal Oscillator division factor: 1
   #pragma optsize-
   CLKPR=0x80;
   CLKPR=0x00;
   #ifdef _OPTIMIZE_SIZE_
   #pragma optsize+
   #endif

   // Input/Output Ports initialization
   // Port A initialization
   // Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=Out Func0=Out
   // State7=T State6=T State5=0 State4=0 State3=T State2=T State1=0 State0=0
   PORTA=0x00;
   DDRA=0x33;

   // Port B initialization
   // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
   // State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=1
   PORTB=0x01;
   DDRB=0x07;

   // Port C initialization
   // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
   // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
   PORTC=0x00;
   DDRC=0xFF;

   // Port D initialization
   // Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
   // State7=T State6=T State5=0 State4=1 State3=T State2=T State1=T State0=T
   PORTD=0x10;
   DDRD=0x30;

   // Port E initialization
   // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In
   // State7=T State6=T State5=T State4=T State3=T State2=T State1=0 State0=T
   PORTE=0x00;
   DDRE=0x02;

   // Port F initialization
   // Func7=Out Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
   // State7=0 State6=T State5=T State4=T State3=T State2=T State1=T State0=T
   PORTF=0x00;
   DDRF=0x80;

   // Port G initialization
   // Func4=In Func3=Out Func2=In Func1=In Func0=In
   // State4=T State3=0 State2=T State1=T State0=T
   PORTG=0x00;
   DDRG=0x08;

   // Timer/Counter 0 initialization
   // Clock source: System Clock
   // Clock value: 1000,000 kHz
   // Mode: CTC top=OCR0
   // OC0 output: Disconnected
   TCCR0A=0x0A;
   TCNT0=0x00;
   OCR0A=((OSCILLATOR_FREQUENCY/8)*0.0001)-1; //((OSCILLATOR_FREQUENCY/8)*0.0001)-1 => 100uS

   // Timer/Counter 1 initialization
   // Clock source: System Clock
   // Clock value: Timer 1 Stopped
   // Mode: Normal top=FFFFh
   // OC1A output: Discon.
   // OC1B output: Discon.
   // OC1C output: Discon.
   // Noise Canceler: Off
   // Input Capture on Falling Edge
   // Timer 1 Overflow Interrupt: Off
   // Input Capture Interrupt: Off
   // Compare A Match Interrupt: Off
   // Compare B Match Interrupt: Off
   // Compare C Match Interrupt: Off
   TCCR1A=0x00;
   TCCR1B=0x00;
   TCNT1H=0x00;
   TCNT1L=0x00;
   ICR1H=0x00;
   ICR1L=0x00;
   OCR1AH=0x00;
   OCR1AL=0x00;
   OCR1BH=0x00;
   OCR1BL=0x00;
   OCR1CH=0x00;
   OCR1CL=0x00;

   // Timer/Counter 2 initialization
   // Clock source: System Clock
   // Clock value: Timer 2 Stopped
   // Mode: Normal top=FFh
   // OC2 output: Disconnected
   ASSR=0x00;
   TCCR2A=0x00;
   TCNT2=0x00;
   OCR2A=0x00;

   // Timer/Counter 3 initialization
   // Clock source: System Clock
   // Clock value: Timer 3 Stopped
   // Mode: Normal top=FFFFh
   // Noise Canceler: Off
   // Input Capture on Falling Edge
   // OC3A output: Discon.
   // OC3B output: Discon.
   // OC3C output: Discon.
   // Timer 3 Overflow Interrupt: Off
   // Input Capture Interrupt: Off
   // Compare A Match Interrupt: Off
   // Compare B Match Interrupt: Off
   // Compare C Match Interrupt: Off
   TCCR3A=0x00;
   TCCR3B=0x00;
   TCNT3H=0x00;
   TCNT3L=0x00;
   ICR3H=0x00;
   ICR3L=0x00;
   OCR3AH=0x00;
   OCR3AL=0x00;
   OCR3BH=0x00;
   OCR3BL=0x00;
   OCR3CH=0x00;
   OCR3CL=0x00;

   // External Interrupt(s) initialization
   // INT0: Off
   // INT1: Off
   // INT2: Off
   // INT3: Off
   // INT4: Off
   // INT5: Off
   // INT6: Off
   // INT7: Off
   EICRA=0x00;
   EICRB=0x00;
   EIMSK=0x00;

   // Timer/Counter 0 Interrupt(s) initialization
   TIMSK0=0x02;
   // Timer/Counter 1 Interrupt(s) initialization
   TIMSK1=0x00;
   // Timer/Counter 2 Interrupt(s) initialization
   TIMSK2=0x00;
   // Timer/Counter 3 Interrupt(s) initialization
   TIMSK3=0x00;

   // Analog Comparator initialization
   // Analog Comparator: Off
   // Analog Comparator Input Capture by Timer/Counter 1: Off
   ACSR=0x80;
   ADCSRB=0x00;

   PORTA |= 0x0F;
   delay_us(100);
   HardwareMinorRevision = PINA&0x0F;
   PORTA &= 0xF0;

   delay_ms(200);

   nSS = 1;

   ReadFPGA();
   FPGAFirmwareMajorRevision = FPGAData[8];
   FPGAFirmwareMinorRevision = FPGAData[9];
   FPGAFirmwareType = (((unsigned int)FPGAData[10])<<8) | FPGAData[11];

   // CAN Controller initialization
   InitializeCAN();

   LEDState[0] = 0x00;
   LEDState[1] = 0x00;
   LEDState[2] = 0x00;
   LEDState[3] = 0x00;

   LEDMode[0] = 0x00;
   LEDMode[1] = 0x00;
   LEDMode[2] = 0x00;
   LEDMode[3] = 0x00;

   LEDData[0] = 0x01;
   LEDData[1] = 0x01;
   LEDData[2] = 0x01;
   LEDData[3] = 0x01;
   SetLEDs();

   delay_ms(500);

   LEDData[0] = 0x00;
   LEDData[1] = 0x00;
   LEDData[2] = 0x00;
   LEDData[3] = 0x00;
   SetLEDs();

   for (cntByte=0; cntByte<16; cntByte++)
   {
      InputStereoSelect[cntByte] = 0x01<<(cntByte&0x01);
      InputLevel[cntByte] = 0x00;
      InputPhase[cntByte] = 0x00;

      OutputStereoSelect[cntByte] = 0x01<<(cntByte&0x01);
      OutputLevel[cntByte] = 0x00;
      OutputDim[cntByte] = 0x00;
      OutputDimLevel[cntByte] = -10;
      OutputMute[cntByte] = 0x00;
      OutputPhase[cntByte] = 0x00;
      if (cntByte<4)
      {
         OutputTalkback[cntByte] = 0x00;
      }
      OutputTalkbackLevel[cntByte] = 0x00;
      OutputTalkbackStereoSelect[cntByte] = 0x00;
      OutputTalkbackPhase[cntByte] = 0x00;
      SetRoutingAndLevel(cntByte);
   }

   PreviousMilliSecond = 0;

   RackSlotNr = GetSlotNr();

   if (FPGAFirmwareType != DefaultNodeObjects.ProductID)
   {
      LEDData[0] = 0;
      LEDData[1] = 1;
      LEDData[2] = 0;
      LEDData[3] = 1;
//      LEDData[4] = 0;
//      LEDData[5] = 1;
//      LEDData[6] = 0;
//      LEDData[7] = 1;
      SetLEDs();
   }

   // Global enable interrupts
   #asm("sei")

  CheckUniqueIDPerProduct();

   while (1)
   {
      ProcessCAN();

      if (cntMilliSecond - PreviousMilliSecondReservation > 1000)
      {
         PreviousMilliSecondReservation = cntMilliSecond;

         if (LocalCANAddress == 0x00000000)
         {
            SendCANReservationRequest();
         }
         else
         {
            SendMambaNetReservationInfo();
         }
      }

      if (cntMilliSecond - PreviousMilliSecond > 40)
      {  //Send track/relative information maximal 25 times per second.
         PreviousMilliSecond = cntMilliSecond;
      }

      if (cntMilliSecond - PreviousLEDBlinkMilliSecond > 250)
      {  //LED Blink 4 times per second.
         unsigned char cntLED;
         unsigned char DoSetLEDs;
         unsigned char cntChannel;

         DoSetLEDs = 0;
         for (cntLED=0; cntLED<8; cntLED++)
         {
            if (FPGAFirmwareType == DefaultNodeObjects.ProductID)
            {
               if (LEDMode[cntLED])
               {
                  if (LEDState[cntLED])
                  {
                     LEDData[cntLED] ^= 0x01;
                     DoSetLEDs = 1;
                  }
                  else if (LEDData[cntLED])
                  {
                     LEDData[cntLED] = 0;
                     DoSetLEDs = 1;
                  }
               }
            }
            else
            { //wrong FPGA firmware
               LEDData[cntLED] ^= 0x01;
               DoSetLEDs = 1;
            }
         }
         if (DoSetLEDs)
         {
            SetLEDs();
         }

         if (AddressValidated)
         {
            nACT_LED = cntDebug++&0x04;
         }
         else
         {
            nACT_LED = cntDebug++&0x01;
         }

         //read signal
         ReadFPGA();
         NewInputSignalState = (((unsigned int)FPGAData[2])<<8) | FPGAData[3];
         for  (cntChannel=0; cntChannel<16; cntChannel++)
         {
            unsigned char Mask = 0x01<<cntChannel;

            if ((InputSignalState^NewInputSignalState)&Mask)
            {
               unsigned char TransmitBuffer[1];

               TransmitBuffer[0] = 0;
               if (NewInputSignalState&Mask)
               {
                  TransmitBuffer[0] = 1;
               }
               SendSensorChangeToMambaNet(1037+cntChannel, STATE_DATATYPE, 1, TransmitBuffer);
            }
         }
         InputSignalState = NewInputSignalState;

         NewOutputSignalState = (((unsigned int)FPGAData[2])<<8) | FPGAData[3];
         for  (cntChannel=0; cntChannel<16; cntChannel++)
         {
            unsigned char Mask = 0x01<<cntChannel;

            if ((OutputSignalState^NewOutputSignalState)&Mask)
            {
               unsigned char TransmitBuffer[1];

               TransmitBuffer[0] = 0;
               if (NewOutputSignalState&Mask)
               {
                  TransmitBuffer[0] = 1;
               }
               SendSensorChangeToMambaNet(1053+cntChannel, STATE_DATATYPE, 1, TransmitBuffer);
            }
         }
         OutputSignalState = NewOutputSignalState;

         PreviousLEDBlinkMilliSecond = cntMilliSecond;
      }
//      ReadSwitches();
   }
}