// Clock.c // Runs on LM3S811 // Provide functions that initialize the SysTick module, wait at least a // designated number of clock cycles, and wait approximately a multiple // of 1 millisecond. // Daniel Valvano // June 16, 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/ */ #define NVIC_ST_CTRL_R (*((volatile unsigned long *)0xE000E010)) #define NVIC_ST_RELOAD_R (*((volatile unsigned long *)0xE000E014)) #define NVIC_ST_CURRENT_R (*((volatile unsigned long *)0xE000E018)) #define NVIC_ST_CTRL_COUNT 0x00010000 // Count flag #define NVIC_ST_CTRL_CLK_SRC 0x00000004 // Clock Source #define NVIC_ST_CTRL_INTEN 0x00000002 // Interrupt enable #define NVIC_ST_CTRL_ENABLE 0x00000001 // Counter mode #define NVIC_ST_RELOAD_M 0x00FFFFFF // Counter load value // Initialize SysTick with busy wait running at bus clock (assumes 6 MHz). unsigned long CyclesPerMs; // private global void Clock_Init(void){ // public function NVIC_ST_CTRL_R = 0; // disable SysTick during setup NVIC_ST_RELOAD_R = NVIC_ST_RELOAD_M; // maximum reload value NVIC_ST_CURRENT_R = 0; // any write to current clears it // enable SysTick with core clock NVIC_ST_CTRL_R = NVIC_ST_CTRL_ENABLE+NVIC_ST_CTRL_CLK_SRC; CyclesPerMs = 6000; // 6000 counts per ms } // Time delay using busy wait. // The cycles parameter is in units of the 6 MHz core clock. (167 nsec) void wait(unsigned long cycles){ // private function volatile unsigned long elapsedTime; unsigned long startTime = NVIC_ST_CURRENT_R; do{ elapsedTime = (startTime-NVIC_ST_CURRENT_R)&0x00FFFFFF; } while(elapsedTime <= cycles); } // Time delay using busy wait. // The time parameter is in units of 1 ms. void Clock_MsWait(unsigned long time){ // public function for(;time>0;time--){ wait(CyclesPerMs); // 1.00ms wait } } //debug code #define GPIO_PORTD_DATA_R (*((volatile unsigned long *)0x400073FC)) #define GPIO_PORTD_DIR_R (*((volatile unsigned long *)0x40007400)) #define GPIO_PORTD_DEN_R (*((volatile unsigned long *)0x4000751C)) #define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108)) #define SYSCTL_RCGC2_GPIOD 0x00000008 // port D Clock Gating Control int main(void){ SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOD; // activate port D Clock_Init(); // initialize SysTick timer GPIO_PORTD_DIR_R |= 0x02; // make PD1 out GPIO_PORTD_DEN_R |= 0x02; // enable digital I/O on PD1 while(1){ GPIO_PORTD_DATA_R = GPIO_PORTD_DATA_R^0x02; // toggle PD1 Clock_MsWait(1); // approximately 1 ms } }