diff --git a/main.c b/main.c index 3121cef..8c956ce 100644 --- a/main.c +++ b/main.c @@ -26,28 +26,34 @@ uint32_t gSystemClock; // [Hz] system clock frequency volatile uint32_t gTime = 0; // time in hundredths of a second -int main(void) -{ +// start a pwm test signal +void start_signal() { + // configure M0PWM2, at GPIO PF2, BoosterPack 1 header C1 pin 2 + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); + GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2); + GPIOPinConfigure(GPIO_PF2_M0PWM2); + GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, + GPIO_PIN_TYPE_STD); + // configure the PWM0 peripheral, gen 1, outputs 2 and 3 + SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); + // use system clock without division + PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1); + PWMGenConfigure(PWM0_BASE, PWM_GEN_1, + PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); + PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, + roundf((float)gSystemClock / PWM_FREQUENCY)); + PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, + roundf((float)gSystemClock / PWM_FREQUENCY * 0.4f)); + PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true); + PWMGenEnable(PWM0_BASE, PWM_GEN_1); +} + +int main(void) { IntMasterDisable(); - // configure M0PWM2, at GPIO PF2, BoosterPack 1 header C1 pin 2 - SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); - GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2); - GPIOPinConfigure(GPIO_PF2_M0PWM2); - GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_2, - GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); - // configure the PWM0 peripheral, gen 1, outputs 2 and 3 - SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); - // use system clock without division - PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1); - PWMGenConfigure(PWM0_BASE, PWM_GEN_1, - PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); - PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, roundf((float)gSystemClock/PWM_FREQUENCY)); - PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, - roundf((float)gSystemClock/PWM_FREQUENCY*0.4f)); - PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true); - PWMGenEnable(PWM0_BASE, PWM_GEN_1); + start_signal(); + start_sampler(); // Enable the Floating Point Unit, and permit ISRs to use it FPUEnable(); @@ -103,4 +109,4 @@ int main(void) GrFlush(&sContext); // flush the frame buffer to the LCD } -} +} \ No newline at end of file diff --git a/sampling.c b/sampling.c new file mode 100644 index 0000000..2adcea6 --- /dev/null +++ b/sampling.c @@ -0,0 +1,60 @@ +#include +#include +#include "inc/tm4c1294ncpdt.h" +#include "driverlib/adc.h" +#include "sysctl_pll.h" + + +#define ADC_BUFFER_SIZE 2048 // size must be a power of 2 +// index wrapping macro +#define ADC_BUFFER_WRAP(i) ((i) & (ADC_BUFFER_SIZE - 1)) +// latest sample index +volatile int32_t gADCBufferIndex = ADC_BUFFER_SIZE - 1; +volatile uint16_t gADCBuffer[ADC_BUFFER_SIZE]; // circular buffer +volatile uint32_t gADCErrors = 0; // number of missed ADC deadlines +void ADC_ISR(void) +{ + // clear ADC1 sequence0 interrupt flag in the ADCISC register + <...>; + // check for ADC FIFO overflow + if(ADC1_OSTAT_R & ADC_OSTAT_OV0) { + gADCErrors++; // count errors + ADC1_OSTAT_R = ADC_OSTAT_OV0; // clear overflow condition + } + gADCBufferIndex = ADC_BUFFER_WRAP(gADCBufferIndex + 1) + // read sample from the ADC1 sequence 0 FIFO + gADCBuffer[gADCBufferIndex] = <...>; +} + + +void start_sampler() { + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); + GPIOPinTypeADC(GPIO_PORTE_BASE, + GPIO_PIN_0); // GPIO setup for analog input AIN3 + // initialize ADC peripherals + SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); + SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1); + // ADC clock + uint32_t pll_frequency = SysCtlFrequencyGet(CRYSTAL_FREQUENCY); + uint32_t pll_divisor = + (pll_frequency - 1) / (16 * ADC_SAMPLING_RATE) + 1; // round up + ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, + pll_divisor); + ADCClockConfigSet(ADC1_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, + pll_divisor); + // choose ADC1 sequence 0; disable before configuring + ADCSequenceDisable(ADC1_BASE, 0); + ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_ALWAYS, + 0); // specify the "Always" trigger + // in the 0th step, sample channel 3 (AIN3) + // enable interrupt, and make it the end of sequence + ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH3)); + // enable the sequence. it is now sampling + ADCSequenceEnable(ADC0_BASE, 0); + // enable sequence 0 interrupt in the ADC1 peripheral + ADCIntEnable(INT_ADC1SS0); + IntPrioritySet(INT_ADC1SS0, 0); // set ADC1 sequence 0 interrupt priority + // enable ADC1 sequence 0 interrupt in int. controller + IntEnable(INT_ADC1SS0); + +} \ No newline at end of file diff --git a/tm4c1294ncpdt_startup_ccs.c b/tm4c1294ncpdt_startup_ccs.c index 42a068c..942f192 100644 --- a/tm4c1294ncpdt_startup_ccs.c +++ b/tm4c1294ncpdt_startup_ccs.c @@ -34,6 +34,7 @@ static void NmiSR(void); static void FaultISR(void); static void IntDefaultHandler(void); void ButtonISR(void); +void ADC_ISR(void); //***************************************************************************** // @@ -99,7 +100,7 @@ void (* const g_pfnVectors[])(void) = IntDefaultHandler, // PWM Generator 1 IntDefaultHandler, // PWM Generator 2 IntDefaultHandler, // Quadrature Encoder 0 - IntDefaultHandler, // ADC Sequence 0 + ADC_ISR, // ADC Sequence 0 IntDefaultHandler, // ADC Sequence 1 IntDefaultHandler, // ADC Sequence 2 IntDefaultHandler, // ADC Sequence 3