// FunctionRobot.c // Runs on LM3S811 // Use a function pointer implementation of a Mealy finite state machine // to control a robot. Use bit-banded I/O. // 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 Example 3.2, Program 3.5 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/ */ // robot mood sensors connected to PB1-0 (00=fine, 01=tired, 10=curious, 11=anxious) // pulse PD3 to sit down while standing // pulse PD2 to stand up while sitting // pulse PD1 to lie down while sitting // pulse PD0 to sit up while sleeping #define GPIO_PORTB_DATA_R (*((volatile unsigned long *)0x400053FC)) #define GPIO_PORTB_DIR_R (*((volatile unsigned long *)0x40005400)) #define GPIO_PORTB_DEN_R (*((volatile unsigned long *)0x4000551C)) #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 GPIO_PORTD0 (*((volatile unsigned long *)0x40007004)) #define GPIO_PORTD1 (*((volatile unsigned long *)0x40007008)) #define GPIO_PORTD2 (*((volatile unsigned long *)0x40007010)) #define GPIO_PORTD3 (*((volatile unsigned long *)0x40007020)) #define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108)) #define SYSCTL_RCGC2_GPIOD 0x00000008 // port D Clock Gating Control #define SYSCTL_RCGC2_GPIOB 0x00000002 // port B Clock Gating Control struct State{ void *CmdPt[4]; // outputs are function pointers const struct State *Next[4]; // next }; typedef const struct State StateType; #define Stand &FSM[0] #define Sit &FSM[1] #define Sleep &FSM[2] void None(void){}; void SitDown(void){ GPIO_PORTD3 = 0x08; GPIO_PORTD3 = 0x00; // GPIO_PORTD_DATA_R |= 0x08; // GPIO_PORTD_DATA_R &= ~0x08; // pulse on PD3 } void StandUp(void){ GPIO_PORTD2 = 0x04; GPIO_PORTD2 = 0x00; // GPIO_PORTD_DATA_R |= 0x04; // GPIO_PORTD_DATA_R &= ~0x04; // pulse on PD2 } void LieDown(void){ GPIO_PORTD1 = 0x02; GPIO_PORTD1 = 0x00; // GPIO_PORTD_DATA_R |= 0x02; // GPIO_PORTD_DATA_R &= ~0x02; // pulse on PD1 } void SitUp(void) { GPIO_PORTD0 = 0x01; GPIO_PORTD0 = 0x00; // GPIO_PORTD_DATA_R |= 0x01; // GPIO_PORTD_DATA_R &= ~0x01; // pulse on PD0 } StateType FSM[3]={ {{(void*)&None,(void*)&SitDown,(void*)&None,(void*)&None}, //Standing {Stand,Sit,Stand,Stand}}, {{(void*)&None,(void*)LieDown,(void*)&None,(void*)&StandUp},//Sitting {Sit,Sleep,Sit,Stand }}, {{(void*)&None,(void*)&None,(void*)&SitUp,(void*)&SitUp}, //Sleeping {Sleep,Sleep,Sit,Sit}} }; int main(void){ StateType *Pt; // current state unsigned long Input; // activate port D and port B SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOD+SYSCTL_RCGC2_GPIOB; Pt = Stand; // initial state GPIO_PORTB_DIR_R &= ~0x03;// make PB1-0 input from mood sensor GPIO_PORTB_DEN_R |= 0x03; // enable digital I/O on PB1-0 GPIO_PORTD_DIR_R |= 0x0F; // make PD3-0 output to robot control GPIO_PORTD_DEN_R |= 0x0F; // enable digital I/O on PD3-0 while(1){ Input = GPIO_PORTB_DATA_R&0x03; // input=0-3 ((void(*)(void))Pt->CmdPt[Input])(); // function Pt = Pt->Next[Input]; // next state } }