// ADCSWTrigger.c // Runs on LM3S811 // Provide functions that initialize ADC SS3 to be triggered by // software and trigger a conversion, wait for it to finish, // and return the result. // Daniel Valvano // June 30, 2011 /* This example accompanies the book "Embedded Systems: Real Time Interfacing to the Arm Cortex M3", ISBN: 978-1463590154, Jonathan Valvano, copyright (c) 2011 Copyright 2011 by Jonathan W. Valvano, valvano@mail.utexas.edu You may use, edit, run or distribute this file as long as the above copyright notice remains THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. VALVANO SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. For more information about my classes, my research, and my books, see http://users.ece.utexas.edu/~valvano/ */ // Thumbwheel potentiometer with scaling resistor connected to ADC0 #define ADC_ACTSS_R (*((volatile unsigned long *)0x40038000)) #define ADC0_RIS_R (*((volatile unsigned long *)0x40038004)) #define ADC0_IM_R (*((volatile unsigned long *)0x40038008)) #define ADC0_ISC_R (*((volatile unsigned long *)0x4003800C)) #define ADC0_EMUX_R (*((volatile unsigned long *)0x40038014)) #define ADC0_SSPRI_R (*((volatile unsigned long *)0x40038020)) #define ADC0_PSSI_R (*((volatile unsigned long *)0x40038028)) #define ADC0_SSMUX3_R (*((volatile unsigned long *)0x400380A0)) #define ADC0_SSCTL3_R (*((volatile unsigned long *)0x400380A4)) #define ADC0_SSFIFO3_R (*((volatile unsigned long *)0x400380A8)) #define ADC_ACTSS_ASEN3 0x00000008 // ADC SS3 Enable #define ADC_RIS_INR3 0x00000008 // SS3 Raw Interrupt Status #define ADC_IM_MASK3 0x00000008 // SS3 Interrupt Mask #define ADC_ISC_IN3 0x00000008 // SS3 Interrupt Status and Clear #define ADC_EMUX_EM3_M 0x0000F000 // SS3 Trigger Select mask #define ADC_EMUX_EM3_PROCESSOR 0x00000000 // Processor (default) #define ADC_SSPRI_SS3_4TH 0x00003000 // fourth priority #define ADC_SSPRI_SS2_3RD 0x00000200 // third priority #define ADC_SSPRI_SS1_2ND 0x00000010 // second priority #define ADC_SSPRI_SS0_1ST 0x00000000 // first priority #define ADC_PSSI_SS3 0x00000008 // SS3 Initiate #define ADC_SSMUX3_MUX0_M 0x00000003 // 1st Sample Input Select mask #define ADC_SSMUX3_MUX0_S 0 // 1st Sample Input Select lshift #define ADC_SSCTL3_TS0 0x00000008 // 1st Sample Temp Sensor Select #define ADC_SSCTL3_IE0 0x00000004 // 1st Sample Interrupt Enable #define ADC_SSCTL3_END0 0x00000002 // 1st Sample is End of Sequence #define ADC_SSCTL3_D0 0x00000001 // 1st Sample Diff Input Select #define ADC_SSFIFO3_DATA_M 0x000003FF // Conversion Result Data mask #define SYSCTL_RCGC0_R (*((volatile unsigned long *)0x400FE100)) #define SYSCTL_RCGC0_ADC 0x00010000 // ADC0 Clock Gating Control #define SYSCTL_RCGC0_ADCSPD_M 0x00000300 // ADC Sample Speed mask #define SYSCTL_RCGC0_ADCSPD125K 0x00000000 // 125K samples/second // There are many choices to make when using the ADC, and many // different combinations of settings will all do basically the // same thing. For simplicity, this function makes some choices // for you. When calling this function, be sure that it does // not conflict with any other software that may be running on // the microcontroller. Particularly, ADC sample sequencer 3 // is used here because it only takes one sample, and only one // sample is absolutely needed. Sample sequencer 3 generates a // raw interrupt when the conversion is complete, but it is not // promoted to a controller interrupt. Software triggers the // ADC conversion and waits for the conversion to finish. If // somewhat precise periodic measurements are required, the // software trigger can occur in a periodic interrupt. This // approach has the advantage of being simple. However, it does // not guarantee real-time. // // A better approach would be to use a hardware timer to trigger // the ADC conversion independently from software and generate // an interrupt when the conversion is finished. Then, the // software can transfer the conversion result to memory and // process it after all measurements are complete. // // This initialization function sets up the ADC according to the // following parameters. Any parameters not explicitly listed // below are not modified: // Max sample rate: <=125,000 samples/second // Sequencer 0 priority: 1st (highest) // Sequencer 1 priority: 2nd // Sequencer 2 priority: 3rd // Sequencer 3 priority: 4th (lowest) // SS3 triggering event: software trigger // SS3 1st sample source: programmable using variable 'channelNum' [0:3] // SS3 interrupts: enabled but not promoted to controller void ADC_InitSWTriggerSeq3(unsigned char channelNum){ // channelNum must be 0-3 (inclusive) corresponding to ADC0 through ADC3 if(channelNum > 3){ return; // invalid input, do nothing } // **** general initialization **** SYSCTL_RCGC0_R |= SYSCTL_RCGC0_ADC; // activate ADC SYSCTL_RCGC0_R &= ~SYSCTL_RCGC0_ADCSPD_M; // clear ADC sample speed field SYSCTL_RCGC0_R += SYSCTL_RCGC0_ADCSPD125K;// configure for 125K ADC max sample rate (default setting) // **** ADC initialization **** // sequencer 0 is highest priority (default setting) // sequencer 1 is second-highest priority (default setting) // sequencer 2 is third-highest priority (default setting) // sequencer 3 is lowest priority (default setting) ADC0_SSPRI_R = (ADC_SSPRI_SS0_1ST|ADC_SSPRI_SS1_2ND|ADC_SSPRI_SS2_3RD|ADC_SSPRI_SS3_4TH); ADC_ACTSS_R &= ~ADC_ACTSS_ASEN3; // disable sample sequencer 3 ADC0_EMUX_R &= ~ADC_EMUX_EM3_M; // clear SS3 trigger select field ADC0_EMUX_R += ADC_EMUX_EM3_PROCESSOR; // configure for software trigger event (default setting) ADC0_SSMUX3_R &= ~ADC_SSMUX3_MUX0_M; // clear SS3 1st sample input select field // configure for 'channelNum' as first sample input ADC0_SSMUX3_R += (channelNum<