/** Update the continuous controllers. Each time this function is called we process one of the ADC inputs and send a message to the host. **/ void ctrl_update( void ) { unsigned char low, high; unsigned char curr_ctrl, next_ctrl; unsigned char sus; /* Wait for conversion to complete (in theory should already be done) */ while ( !( ADCSRA & ( 1 << ADIF ) ) ) /* spin */ ; /* Read 10-bit ADC and channel number */ low = ADCL; high = ADCH; curr_ctrl = ( ADMUX & 0x0F ) - ADC_OFFSET; /* Also read the sustain pedal input */ sus = !( PINC & ( 1 << PINC5 ) ); /* Switch to next channel */ next_ctrl = curr_ctrl + 1; if ( next_ctrl >= MAX_CTRL ) next_ctrl = 0; ADMUX = ADMUX_CONFIG | ADC_CHAN( next_ctrl ); /* Kick off the next conversion */ ADCSR |= ( 1 << ADSC ); /* Send the value to the master processor */ hostif_msg_ctrl( curr_ctrl, sus, ( ( high << 8 ) | low ) << 2 ); }
static cyg_uint32 adc_sample(int chan) { cyg_uint32 val; *(volatile cyg_uint32 *)SYNCIO = SYNCIO_TXFRMEN | SYNCIO_FRAMELEN(24) | ADC_START | ADC_CHAN(chan) | ADC_UNIPOLAR | ADC_SINGLE | ADC_EXT_CLOCK; while (*(volatile cyg_uint32 *)SYSFLG1 & SYSFLG1_SSIBUSY) ; val = *(volatile cyg_uint32 *)SYNCIO; return (val & 0xFFFF); }
/** Initialise the control reading task. **/ void ctrl_init( void ) { /* Clear all but the bottom two bits of DDRC */ DDRC &= ~0x03; /* Enable the ADC with a conversion clock of 125kHz. */ ADCSRA = ( 1 << ADEN ) | ( 1 << ADPS2 ) | ( 1 << ADPS1 ) | ( 0 << ADPS0 ); /* Select initial channel */ ADMUX = ADMUX_CONFIG | ADC_CHAN( 0 ); /* Kick-off the first conversion */ ADCSR |= ( 1 << ADSC ); }