Esempio n. 1
0
int main(void)
{
	DDRA = (1 << PA0) | (1 << PA1) | (1 << PA3) | (1 << PA2);

	ShiftRegister shiftRegister(&PORTA, PA1, &PORTA, PA3, &PORTA, PA2);
	Pin ledPin(&PORTA, PA0);

	// lcd initialization goes here
	KS0066 lcd(shiftRegister);

	while(1)
	{
		ledPin.toggle();
		_delay_ms(125);
	}
}
void spintronicsStateMachine()
{
    volatile _Q15 bridgeSample;
    volatile _Q15 coilSample;
    static unsigned char state = IDLE;
    static uint32_t timer;
    static uint8_t sensor;
    _Q15 cosOmega1T;//fractions of full-scale //aligned to compensate for ADCDAC_GROUP_DELAY
    _Q15 cosOmega2T;//fractions of full-scale //aligned to compensate for ADCDAC_GROUP_DELAY
    static _Q15 cosOmega1TTimeAligned;//fractions of full-scale
    static _Q15 cosOmega2TTimeAligned;//fractions of full-scale
    static _Q15 freqT[6];//array contents: 2*f1*t, 2*f2*t, 2*f1*(t + ADCDAC_GROUP_DELAY), 2*f2*(t + ADCDAC_GROUP_DELAY), 2*fdiff*(t + ADCDAC_GROUP_DELAY), 2*fsum*(t + ADCDAC_GROUP_DELAY)
    static int64_t cosAccumulator[5];
    static int64_t sinAccumulator[5];
    static _Q15 phaseAngle[5];//units are radians divided by PI
    static _Q15 amplitude[5];//fractions of full-scale
    static bool bridgeADCClipFlag;
    static bool coilADCClipFlag;
    static bool bridgeDigitalClipFlag;

#ifdef SIMULATION_MODE
    uint16_t RXBUF2 = rand();//only to give random stimulus during simulation
#endif


    if (RXBUF0 == 0x7FFF || RXBUF0 == 0x8000)
    {
        bridgeADCClipFlag = true;
    }
    if (RXBUF2 == 0x7FFF || RXBUF2 == 0x8000)
    {
        coilADCClipFlag = true;
    }
    bridgeSample = readBridgeSampleAndApplyGain(&bridgeDigitalClipFlag);
    coilSample = RXBUF2;

    if (GUIRequestingRun == false)
    {
        state = IDLE;
    }
    
    switch (state)
    {
    case IDLE:
            timer = 0;
            sensor = 0;
            configSensor(sensor);
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0;
            sinAccumulator[0] = 0; sinAccumulator[1] = 0; sinAccumulator[2] = 0; sinAccumulator[3] = 0; sinAccumulator[4] = 0;
            phaseAngle[0] = 0; phaseAngle[1] = 0; phaseAngle[2] = 0; phaseAngle[3] = 0; phaseAngle[4] = 0;
            amplitude[0] = 0; amplitude[1] = 0; amplitude[2] = 0; amplitude[3] = 0; amplitude[4] = 0;
            bridgeADCClipFlag = false;
            coilADCClipFlag = false;
            bridgeDigitalClipFlag = false;

#ifdef CS4272_CONTROL_PORT_MODE
            state = CALIBRATE_ADC;
            enableADCHpf(true);//enable the hpf to calibrate for systematic DC offset
#else
            state = START_SIGNAL_GEN;
#endif

            break;

#ifdef CS4272_CONTROL_PORT_MODE
        case CALIBRATE_ADC:
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == ADC_CALIBRATION_TIME)
            {
                timer = 0;
                state = WAIT_FOR_HPF_DISABLE_MESSAGE_TX;
                enableADCHpf(false);//DC calibration complete; disable hpf
            }
            break;

         case WAIT_FOR_HPF_DISABLE_MESSAGE_TX:
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == CS4272_SPI_TX_LATENCY)
            {
                timer = 0;
                state = START_SIGNAL_GEN;
            }
            break;
#endif

        case START_SIGNAL_GEN:
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == SETUP_TIME)
            {
                timer = 0;
                state = MEASURE_PHASE;
            }
            break;            

        case MEASURE_PHASE:
            measurePhase(bridgeSample, coilSample, freqT, cosOmega1TTimeAligned, cosOmega2TTimeAligned, cosAccumulator, sinAccumulator);
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == phaseMeasurementTime)
            {
                timer = 0;
                state = CALCULATE_PHASE;
            }
            break;

        case CALCULATE_PHASE:
        {
            static uint8_t shiftAmt[5];
            if (timer < 5)
            {
                calculateShiftAmount(timer, cosAccumulator, sinAccumulator, shiftAmt);
            }
			else
            {
                calculatePhase(timer - 5, cosAccumulator, sinAccumulator, phaseAngle, shiftAmt);
            }
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == 10)
            {    
                cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0; 
                sinAccumulator[0] = 0; sinAccumulator[1] = 0; sinAccumulator[2] = 0; sinAccumulator[3] = 0; sinAccumulator[4] = 0; 
                timer = 0;
                state = MEASURE_AMPLITUDE;
            }
            break;
        }

        case MEASURE_AMPLITUDE:
            measureAmplitude(bridgeSample, coilSample, freqT, cosAccumulator, phaseAngle);
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;
            if (timer == amplitudeMeasurementTime)
            {
                timer = 0;
                state = CALCULATE_AMPLITUDE;
            }
            break;

        case CALCULATE_AMPLITUDE:
            calculateAmplitude(timer, cosAccumulator, amplitude);
            signalGenerator(RUN, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            ++timer;  
            if (timer == 5)
            {
                uint8_t index;
                uint8_t txSensor;//temporary variable to store the value for transmission
                _Q15 txPhaseAngle[5];//temporary array to store values for transmission
                _Q15 txAmplitude[5];//temporary array to store values for transmission
                bool txBridgeADCClipFlag;//temporary variable to store the flag for transmission
                bool txCoilADCClipFlag;//temporary variable to store the flag for transmission
                bool txBridgeDigitalClipFlag;//temporary variable to store the flag for transmission

                //store variables for transmission
                txSensor = sensor;
                for (index = 0; index < 5; ++index)
                {
                    txPhaseAngle[index] = phaseAngle[index];
                    txAmplitude[index] = amplitude[index];
                }
                txBridgeADCClipFlag = bridgeADCClipFlag;
                txCoilADCClipFlag = coilADCClipFlag;
                txBridgeDigitalClipFlag = bridgeDigitalClipFlag;

                //clear static variables for next iteration of the state machine
                cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0; 
                timer = 0;
                                bridgeADCClipFlag = false;
                                coilADCClipFlag = false;
                                bridgeDigitalClipFlag = false;

                state = START_SIGNAL_GEN;
                ++sensor;
                if (sensor == NUMBER_OF_SENSORS)
                {
                    sensor = 0;
                }
                configSensor(sensor);

                //transmit results
                transmitResults(txSensor, txPhaseAngle, txAmplitude, txBridgeADCClipFlag, txCoilADCClipFlag, txBridgeDigitalClipFlag);//don't do this until the state machine is ready for the next measurment period; transmitting results takes more than one sample period.
            }
            break;
            
        default:
            timer = 0;
            sensor = 0;
            configSensor(sensor);
            signalGenerator(RESET, freqT, &cosOmega1T, &cosOmega2T);
            shiftRegister(cosOmega1T, cosOmega2T, &cosOmega1TTimeAligned, &cosOmega2TTimeAligned);
            cosAccumulator[0] = 0; cosAccumulator[1] = 0; cosAccumulator[2] = 0; cosAccumulator[3] = 0; cosAccumulator[4] = 0; 
            sinAccumulator[0] = 0; sinAccumulator[1] = 0; sinAccumulator[2] = 0; sinAccumulator[3] = 0; sinAccumulator[4] = 0; 
            phaseAngle[0] = 0; phaseAngle[1] = 0; phaseAngle[2] = 0; phaseAngle[3] = 0; phaseAngle[4] = 0;
            amplitude[0] = 0; amplitude[1] = 0; amplitude[2] = 0; amplitude[3] = 0; amplitude[4] = 0; 
            break;
    }
}