|
Good evening Przemyslaw
Here is the code; currently what this does is senses a signal on PA12 which raises an interrupt to turn on LED1 PB23 and to start a TC0 timer which then generates an interrupt after 2 seconds that is used to turn on LED 2 PB27. The ADC will be used to read the input from a potentiometer on PB28 ADC Channel 1 ( Zero Based ) which eventually drive the delay time of TC0. Also a pushbutton PA29 is used to reset both LEDs to off position in preperation for another signal event on PA12. Eventually this circuit will be used to control AC lighting via Phase Trigger controlled Triac. Thank you for taking the time to look at this and everything works fine currently as long as I do not setup my ADC for interrupts. I did have the ACD code reading voltages before but only in a while loop which checked the ADC status register for an available value. Thanks again and touch base..
#define BOARD_ADC_FREQ 5000000 // 5Mhz #define ADC_VREF 3300 // 3.3 * 1000
//------------------------------------------------------------------------------ /// Interrupt handler for pushbutton\#1. Stops Onboard LED //------------------------------------------------------------------------------ void ISR_Pushbutton(void) { // Pointer to SOFTWARE API DEFINITION for Parallel Input Output Controler A AT91S_PIO *ptr_pio_b = AT91C_BASE_PIOB;
// Pointer to SOFTWARE API DEFINITION for Advanced Interrupt Controller AT91S_AIC *ptr_aic = AT91C_BASE_AIC;
// LED Off - ptr_pio_b->PIO_CODR = ( 1 << 23 );
ptr_pio_b->PIO_CODR = ( 1 << 23 );
// Additional LED Off ptr_pio_b->PIO_CODR = ( 1 << 27 );
// Ack Interrupt ptr_aic->AIC_EOICR = 0x00000000;
printf("%s\n\r", "Button Event Handler Called");
}
//------------------------------------------------------------------------------ /// Interrupt handler for Input on D4 Starts Onboard LED //------------------------------------------------------------------------------ void ISR_Signal_Trigger(void) { // Pointer to SOFTWARE API DEFINITION for Parallel Input Output Controler A AT91S_PIO *ptr_pio_b = AT91C_BASE_PIOB;
// Pointer to SOFTWARE API DEFINITION for Advanced Interrupt Controller AT91S_AIC *ptr_aic = AT91C_BASE_AIC;
// Pointer to SOFTWARE API DEFINITION for Timer Counter Channel Interface ( Specifically Pointing to Peripheral TC0 at base address AT91C_BASE_TC0 ); AT91S_TC *ptr_tc0 = AT91C_BASE_TC0;
// LED On - ptr_pio_b->PIO_SODR = ( 1 << 23 );
ptr_pio_b->PIO_SODR = ( 1 << 23 ); // Turn On Timer ptr_tc0->TC_CCR = 0x00000005; // !Channel Control Register - Timer Channel Control ( On, Off ) BIN:101 - Refer to 32.6.3 TC Channel Control Register
// Ack Interrupt ptr_aic->AIC_EOICR = 0x00000000;
printf("%s\n\r", "Signal Event Handler Called");
}
//------------------------------------------------------------------------------ // Interrupt Handling Functions Start //------------------------------------------------------------------------------
static void PIOA_DispatchInterruptHandler(void) {
unsigned int status; // Pointer to SOFTWARE API DEFINITION for Parallel Input Output Controler A AT91S_PIO *ptr_pio_a = AT91C_BASE_PIOA;
// Read PIO controller status status = ptr_pio_a->PIO_ISR; status &= ptr_pio_a->PIO_IMR;
// Pushbutton Input Processing if ( status & ( 1 << 29 ) ) { ISR_Pushbutton();
}
// Input Signal Processing if ( status & ( 1 << 12 ) ) { ISR_Signal_Trigger();
}
}
// Timer Interrupt Handler static void TC0_InterruptHandler(void) { // Pointer to SOFTWARE API DEFINITION for Timer Counter Channel Interface ( Specifically Pointing to Peripheral TC0 at base address AT91C_BASE_TC0 ); AT91S_TC *ptr_tc0 = AT91C_BASE_TC0;
// Pointer to SOFTWARE API DEFINITION for Advanced Interrupt Controller AT91S_AIC *ptr_aic = AT91C_BASE_AIC; unsigned int status;
// Pointer to SOFTWARE API DEFINITION for Parallel Input Output Controler B AT91S_PIO *ptr_pio_b = AT91C_BASE_PIOB;
// Read TC0 Status Register which Clears Interrupt status = ptr_tc0->TC_SR;
// Ack Interrupt ptr_aic->AIC_EOICR = 0x00000000; // AIC Ack Interrupt
// Turn Off/Disable TC0 Timer ptr_tc0->TC_CCR = 0x00000002; // !Channel Control Register - Timer Channel Control ( On, Off ) BIN:101 - Refer to 32.6.3 TC Channel Control Register
// Additional LED On
ptr_pio_b->PIO_SODR = ( 1 << 27 );
printf("%s\n\r", "Timer Event Handler Called");
}
//------------------------------------------------------------------------------ /// Interrupt handler for Input on PIOB PIN 28 ADC Channel 1 Input //------------------------------------------------------------------------------ static void ADC_InterruptHandler(void) {
// Pointer to SOFTWARE API DEFINITION for Advanced Interrupt Controller AT91S_AIC *ptr_aic = AT91C_BASE_AIC;
// Pointer to SOFTWARE API DEFINITION for Analog to Digital Convertor AT91S_ADC *ptr_adc = AT91C_BASE_ADC;
int PowerLevel = 0; int Status = 0;
// Read ADC Status Register which Clears Interrupt Status = ptr_adc->ADC_SR;
// Read Power Output Setting from ADC Channel 1 if ( Status & 0x00000002 ) {
PowerLevel = ptr_adc->ADC_CDR1;
printf("-- Power Input Value: %i --\n\r", PowerLevel );
// Ack Interrupt ptr_aic->AIC_EOICR = 0x00000000; // AIC Ack Interrupt
}
printf("%s\n\r", "ADC Event Handler Called");
}
//------------------------------------------------------------------------------ // Interrupt Handling Functions End //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ // Application entry point. //------------------------------------------------------------------------------ int main(void) {
// DBGU configuration TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK); printf("-- Getting Started Project %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); // Pointer to SOFTWARE API DEFINITION for Parallel Input Output Controler A AT91S_PIO *ptr_pio_a = AT91C_BASE_PIOA;
// Pointer to SOFTWARE API DEFINITION for Parallel Input Output Controler B AT91S_PIO *ptr_pio_b = AT91C_BASE_PIOB;
// Pointer to SOFTWARE API DEFINITION for Advanced Interrupt Controller AT91S_AIC *ptr_aic = AT91C_BASE_AIC;
// Pointer to SOFTWARE API DEFINITION for Power Management Controler AT91S_PMC *ptr_pmc = AT91C_BASE_PMC;
// Pointer to SOFTWARE API DEFINITION for Timer Counter Channel Interface ( Specifically Pointing to Peripheral TC0 at base address AT91C_BASE_TC0 ); AT91S_TC *ptr_tc0 = AT91C_BASE_TC0;
// Pointer to SOFTWARE API DEFINITION for Analog to Digital Convertor AT91S_ADC *ptr_adc = AT91C_BASE_ADC;
int PowerLevel = 0;
// Peripheral Source IDs AT91C_ID_PIOA AT91C_ID_PIOB // PIN PA 29 ONBOARD PUSHBUTTON {1 << 29, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP} -- PushButton // PIN PA12 Digital IO 4 {1 << 12, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEFAULT } -- Input Pin - Zero Crossing Signal
// PIN PB23 {1 << 23, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT} -- Onboard LED // PIN PB27 {1 << 27, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT} -- Additional LED
/******************************************************************************/ // Input PINs PA29 and PA12 PIO A /******************************************************************************/
// Input PINs so we will have interrupts configured in AIC Next Step after PIO Setup
//ptr_pio_a->PIO_IDR = ( 1 << 29 ) | ( 1 << 12 ); // Interrupt Disable Register Disable Interrupts On These Specific Input Pins on Peripheral AT91C_ID_PIOA Done Below
ptr_pio_a->PIO_PER = ( 1 << 29 ) | ( 1 << 12 ); // PIO Enable Register Enable Pins as PIO
ptr_pio_a->PIO_ODR = ( 1 << 29 ) | ( 1 << 12 ); // Output Disable Register for Peripheral AT91C_ID_PIOA - Both Pins Used As Input so Disable Output
ptr_pio_a->PIO_OER = 0x00000000; // Output Enable Register - No Pins Used for Output on Peripheral AT91C_ID_PIOA
ptr_pio_a->PIO_PPUDR = ( 1 << 12 ); // Pull-up Disable Register
ptr_pio_a->PIO_PPUER = ( 1 << 29 ); // Pull-up Enable Register
ptr_pio_a->PIO_IFER = ( 1 << 29 ); // Input Filter Enable Register
ptr_pio_a->PIO_IFDR = ( 1 << 12 ); // Input Filter Disable Register
// Do after AIC Setup // Enable Interrupts for Input PINS for Peripheral AT91C_ID_PIOA // ptr_pio_a->PIO_IER = ( 1 << 29 ) | ( 1 << 12 );
/******************************************************************************/ // Output PINs PB23 and PB27 and Input ADC Pin PB28 ADC Channel 1 ( Just Configure as Input PIN No Interrupt ADC Will Handle That ) /******************************************************************************/
// Output PINs so no Interrupts // The 1 Input PIN will have an interrupt for processing via the ADC so no interrupts need on PIO B
// Enabled For PIO B Output ptr_pio_b->PIO_PER = ( 1 << 23 ) | ( 1 << 27 ) | ( 1 << 28 ); // PIO Enable Register Enable Pins as PIO ptr_pio_b->PIO_OER = ( 1 << 23 ) | ( 1 << 27 ); // Output Enable Register Enable Pins as Output
// No Pins Used as Input // ptr_pio_b->PIO_ODR = 0x00000000; // Output Disable Register for Peripheral AT91C_ID_PIOB -
ptr_pio_b->PIO_ODR = ( 1 << 28 ); // Output Disable Register - Only Pin PB28/ADC Channel 1 Used As Input So Disable this PIN as Output
ptr_pio_b->PIO_PPUDR = ( 1 << 23 ) | ( 1 << 27 ); // Pull-up Disable Register
ptr_pio_b->PIO_PPUER = 0x00000000; // Pull-up Enable Register
ptr_pio_b->PIO_IFDR = ( 1 << 23 ) | ( 1 << 27 ) | ( 1 << 28 ); // Input Filter Disable Register
ptr_pio_b->PIO_IFER = 0x00000000; // Input Filter Enable Register
/******************************************************************************/ // Configure Timer TCO Which Has Been Configured in the AIC Above /******************************************************************************/
/* AT91_REG TC_CCR; // Channel Control Register AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode) AT91_REG Reserved0[2]; // AT91_REG TC_CV; // Counter Value AT91_REG TC_RA; // Register A AT91_REG TC_RB; // Register B AT91_REG TC_RC; // Register C AT91_REG TC_SR; // Status Register AT91_REG TC_IER; // Interrupt Enable Register AT91_REG TC_IDR; // Interrupt Disable Register AT91_REG TC_IMR; // Interrupt Mask Register */
ptr_tc0->TC_CMR = 0x0000C004; // !Channel Mode Register - Timer Mode Settings Including Timer Frequency Refer to 32. Timer Counter (TC) TCCLKS: Clock Selection Using Internal Clock 5 21.368 us ptr_tc0->TC_RC = 0x00016f30; // !Period Value PV * Timer Frequency = Timer Period 94000 x 21.368 us = 2 Seconds
ptr_tc0->TC_IER = 0x00000010; // Interrupt Enable Register - Enable RC Compare Interrupt! 32.6.11 TC Interrupt Enable Register BIN:10000 Enables the RC Compare Interrupt.
// Do after AIC Setup // Do Not Turn On Yet Let the Zero Crossing Signal Enable Timer //*ptr_tc0->CCR = 0x00000005; // !Channel Control Register - Timer Channel Control ( On, Off ) BIN:101 - Refer to 32.6.3 TC Channel Control Register
/******************************************************************************/ // Configure Timer End /******************************************************************************/
/******************************************************************************/ // Configure ADC Which Has Been Configured in the AIC /******************************************************************************/
// ADC Support 8 DAC Channels AD0 -> AD7 Netduino Only Supports AD0->AD5 /*
AT91_REG ADC_CR; // ADC Control Register AT91_REG ADC_MR; // ADC Mode Register AT91_REG Reserved0[2]; // AT91_REG ADC_CHER; // ADC Channel Enable Register AT91_REG ADC_CHDR; // ADC Channel Disable Register AT91_REG ADC_CHSR; // ADC Channel Status Register AT91_REG ADC_SR; // ADC Status Register AT91_REG ADC_LCDR; // ADC Last Converted Data Register AT91_REG ADC_IER; // ADC Interrupt Enable Register AT91_REG ADC_IDR; // ADC Interrupt Disable Register AT91_REG ADC_IMR; // ADC Interrupt Mask Register AT91_REG ADC_CDR0; // ADC Channel Data Register 0 AT91_REG ADC_CDR1; // ADC Channel Data Register 1 AT91_REG ADC_CDR2; // ADC Channel Data Register 2 AT91_REG ADC_CDR3; // ADC Channel Data Register 3 AT91_REG ADC_CDR4; // ADC Channel Data Register 4 AT91_REG ADC_CDR5; // ADC Channel Data Register 5 AT91_REG ADC_CDR6; // ADC Channel Data Register 6 AT91_REG ADC_CDR7; // ADC Channel Data Register 7 AT91_REG Reserved1[44]; // AT91_REG ADC_RPR; // Receive Pointer Register AT91_REG ADC_RCR; // Receive Counter Register AT91_REG ADC_TPR; // Transmit Pointer Register AT91_REG ADC_TCR; // Transmit Counter Register AT91_REG ADC_RNPR; // Receive Next Pointer Register AT91_REG ADC_RNCR; // Receive Next Counter Register AT91_REG ADC_TNPR; // Transmit Next Pointer Register AT91_REG ADC_TNCR; // Transmit Next Counter Register AT91_REG ADC_PTCR; // PDC Transfer Control Register AT91_REG ADC_PTSR; // PDC Transfer Status Register
*/
/// Initialize the ADC controller /// \param pAdc Pointer to an AT91S_ADC instance. /// \param Peripheral ID /// \param trgEn trigger mode, software or Hardware /// \param trgSel hardware trigger selection /// \param sleepMode sleep mode selection /// \param resolution resolution selection 8 bits or 10 bits /// \param mckClock value of MCK in Hz /// \param adcClock value of the ADC clock in Hz /// \param startupTime value of the start up time (in µs) (see datasheet) /// \param sampleAndHoldTime (in ns)
// Hardware Trigger Disabled // Master clock frequency // BOARD_MCK 48000000 48Mhz ADC_Initialize( AT91C_BASE_ADC, AT91C_ID_ADC, AT91C_ADC_TRGEN_DIS, 0, AT91C_ADC_SLEEP_NORMAL_MODE, AT91C_ADC_LOWRES_10_BIT, BOARD_MCK, BOARD_ADC_FREQ, 10, 1200);
ptr_adc->ADC_CHER = 0x00000002; // ADC Channel Enable Register Channel 1 Only Reference 35.6.3
/******************************************************************************/ // Configure ADC End /******************************************************************************/
/******************************************************************************/ // Interrupt Controller For AT91C_ID_PIOA, TC0 and ADC Peripherals /******************************************************************************/
// This will also Enabled a Clock on the PERIPHERAL ID AT91C_ID_PIOA via the PMC // Power Management Controller controls the clocks of each embedded peripheral by the way // of the Peripheral Clock Controller. // Any Input PIO Must Have This Clock Enabled For Sampling The Incoming Voltage
// Allow PMC to Setup Clock Input Into Peripherals AT91C_ID_PIOA AND AT91C_ID_TC0 // Need Clock For Signal Detection ptr_pmc->PMC_PCER = ( 1 << AT91C_ID_PIOA ) | ( 1 << AT91C_ID_TC0 ) | ( 1 << AT91C_ID_ADC ) ;
// Interrup Status Register For Peripheral AT91C_ID_PIOA // ptr_pio_a->PIO_ISR;
// Disable All Interrupts on each PIN of the PIOA Peripheral // ptr_pio_a->PIO_IDR = ( 1 << 29 ) | ( 1 << 12 ); // Interrupt Disable Register Disable Interrupts On These Specific Input Pins on Peripheral AT91C_ID_PIOA Done Below ptr_pio_a->PIO_IDR = 0xFFFFFFFF;
// Disable Interrupts for Peripherals AT91C_ID_PIOA, AT91C_ID_TC0, AND AT91C_ID_ADC ptr_aic->AIC_IDCR = (1 << AT91C_ID_PIOA) | ( 1 << AT91C_ID_TC0 ) | ( 1 << AT91C_ID_ADC );
// Set Interrupt Attributes for Peripheral AT91C_ID_PIOA // Triggering mode and priority of the interrupt. ptr_aic->AIC_SMR[AT91C_ID_PIOA] = AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_HIGH_LEVEL;
// Set Interrupt Attributes for Peripheral AND AT91C_ID_TC0 // Triggering mode and priority of the interrupt. ptr_aic->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE;
// Set Interrupt Attributes for Peripheral AT91C_ID_ADC // Triggering mode and priority of the interrupt. ptr_aic->AIC_SMR[AT91C_ID_ADC] = 0x00000000;
// Set Interrupt Handler for Peripheral AT91C_ID_PIOA ptr_aic->AIC_SVR[AT91C_ID_PIOA] = (unsigned int) PIOA_DispatchInterruptHandler;
// Set Interrupt Handler for Peripheral AT91C_ID_TC0 TCO Timer ptr_aic->AIC_SVR[AT91C_ID_TC0] = (unsigned int) TC0_InterruptHandler;
// Set Interrupt Handler for Peripheral AT91C_ID_ADC ptr_aic->AIC_SVR[AT91C_ID_ADC] = (unsigned int) ADC_InterruptHandler;
// Clear Interrupt for Peripherals AT91C_ID_PIOA, AT91C_ID_TC0 AND AT91C_ID_ADC ptr_aic->AIC_ICCR = 1 << (AT91C_ID_PIOA) | ( 1 << AT91C_ID_TC0 ) | ( 1 << AT91C_ID_ADC );
// Enable Interrupts for Peripherals AT91C_ID_PIOA, AT91C_ID_TC0 AND AT91C_ID_ADC ptr_aic->AIC_IECR = 1 << AT91C_ID_PIOA | ( 1 << AT91C_ID_TC0 ) | ( 1 << AT91C_ID_ADC );
/**********************************************************************************************************************/ // Now Enable Interrupt on all the Peripherals configured into the AIC via the Peripheral's Interrupt Enable Registers /**********************************************************************************************************************/
// Enable Interrupts for Input PINS for Peripheral AT91C_ID_PIOA ptr_pio_a->PIO_IER = ( 1 << 29 ) | ( 1 << 12 );
// Enable Interrupts for ADC Data Ready Interrupt for Peripheral AT91C_ID_ADC ptr_adc->ADC_IER = 0x00000002; // Interrupt Enable Register - 35.6.8 ADC Interrupt Enable Register Set DRDY ( Data Ready ) Interrupt EOC Channel 1 Base 0
ptr_adc->ADC_CR = 0x00000002; // ADC Control Register - Start Turns On All Enabled ADC Channels Reference 35.6.1
/**********************************************************************************************************************/ // Enable Interrupt on all the Peripherals configured into the AIC End /**********************************************************************************************************************/
// Onboard LED Off - ptr_pio_b->PIO_CODR = ( 1 << 23 ); ptr_pio_b->PIO_CODR = ( 1 << 23 );
// LED 2 Off - ptr_pio_b->PIO_CODR = ( 1 << 27 ); ptr_pio_b->PIO_CODR = ( 1 << 27 );
// Main loop while (1) {
}
Last edited by orlanmon on Wed Mar 21, 2012 3:27 pm, edited 3 times in total.
|