Wixel SDK
board.c
1 // board.c: Basic function and variables for interacting with the
2 // hardware on the Wixel. Includes LED, power detection, and common
3 // timing/delay functions.
4 
5 // TODO: Allow for getting into bootloader mode when the yellow LED is on
6 // (need to turn it off for a brief time).
7 // TODO: only go into bootloader mode if there is USB power
8 // TODO: add a section of the library for using the watchdog timer
9 // TODO: let delayMicroseconds take a 16-bit argument
10 // TODO: WHY does this interrupt only result in a 6 us pulse?
11 // ISR(P0INT, 1)
12 // {
13 // P1_0 ^= 1;
14 // delayMicroseconds(40);
15 // P1_0 ^= 1;
16 // }
17 
18 #include <cc2511_map.h>
19 #include <cc2511_types.h>
20 #include <board.h>
21 #include <time.h>
22 #include <dma.h>
23 
24 /* vbusHigh: 0 if VBUS is low (USB not connected).
25  * 1 if VBUS is high (USB connected).
26  * This variable is updated by wixelDetectVbus(). */
27 static BIT vbusHighBit;
28 
29 void systemInit()
30 {
31  boardIoInit();
33  timeInit();
34  dmaInit();
35 }
36 
38 {
40 }
41 
42 /* Starts up the external 48 MHz oscillator and configures
43  * the processor to run at 24 MHz.
44  */
46 {
47  // OSC_PD=0: Power up both high-speed oscillators: XOSC and HS RCOSC.
48  SLEEP &= ~0x04;
49 
50  // Wait until the high speed crystal oscillator is stable (SLEEP.XOSC_STB=1)
51  // This condition is required to use the radio or USB.
52  // According to Table 6.4.2, the waiting should take about 650 microseconds.
53  while(!(SLEEP & 0x40));
54 
55  // OSC32K = 1: Use low power 32kHz oscillator for the 32 kHz signal.
56  // OSC=0: Select high speed crystal oscillator for system clock (24 MHz).
57  // TICKSPD=000: Set the timer tick speed to its fastest possible value.
58  // CLKSPD=000: Set system clock speed to its fastest possible value (24 MHz).
59  // This is required for using the Forward Error Correction radio feature (which we don't use anymore).
60  CLKCON = 0x80;
61 
62  // Power down the HS RCOSC (the one that is not currently selected by
63  // CLKCON.OSC).
64  SLEEP |= 0x04;
65 
66  // Enable pre-fetching of instructions from flash,
67  // which makes the code execute much faster.
68  MEMCTR = 0;
69 }
70 
72 {
73  P2DIR = 0; // Make all the Port 2 pins be inputs.
74  P2 = 0b00000110; // P2_1 = 1: drive the red LED line high LATER (when LED_RED(1) is called)
75  // P2_2 = 1: drive the yellow LED line high LATER (when LED_YELLOW(1) is called)
76  // P2_4 = 0: drive the VBUS_IN/GREEN_LED line low LATER (when LED_GREEN(1) is called)
77  P2INP = 0b10011001; // Pull down LED pins (P2_2, P2_1), and tristate the other Port 2 pins.
78 }
79 
80 /* Checks to see if USB is connected (VBUS_IN line is high).
81  * The check is only performed if it has not been performed within the last 25 milliseconds.
82  * (USB spec says we have to detect power loss within 100 ms).
83  * This function updates the bit variable vbusHigh. */
84 static void boardDetectVbus()
85 {
86  static uint8 lastCheck = 128;
87  if ((uint8)(getMs() - lastCheck) > 25)
88  {
89  BIT savedState = (P2DIR >> 4) & 1;
90  if (savedState == 0)
91  {
92  P2DIR |= (1<<4); // Drive the VBUS_IN low
94  }
95  P2INP &= ~(1<<4); // Set input mode to pull-down
96  P2DIR &= ~(1<<4); // Make the line an input.
98 
99  vbusHighBit = P2_4; // Measure the voltage.
100 
101  P2INP |= (1<<4); // Set input mode to tristate.
102  if (savedState)
103  {
104  P2DIR |= (1<<4); // LED was on previously so turn it back on.
105  }
106 
107  lastCheck = getMs();
108  }
109 }
110 
112 {
113  EA = 0; // Disable interrupts.
114 
115  DMAARM = 0x9F; // Disarm all DMA channels.
116 
117  delayMicroseconds(10); // Probably not necessary anymore. Used to be 10 milliseconds.
118 
119  // Make all the IO lines be inputs. That's going to happen later in
120  // the bootloader anyway. We might as well do it now so that any devices
121  // such as motors stop running right away. This also signals to the USB host
122  // that we are disconnecting.
123  P0DIR = P1DIR = P2DIR = 0;
124  P0SEL = P1SEL = P2SEL = 0;
125 
126  delayMs(100); // Delay to give the USB host a chance to detect that we disconnected.
127  __asm ljmp 6 __endasm;
128 }
129 
131 {
132  if (!(P2DIR & (1<<2))) // If the yellow LED is off...
133  {
134  delayMicroseconds(10);
135  if (P2_2)
136  {
138  }
139  }
140 }
141 
143 {
144  boardDetectVbus();
145  return vbusHighBit;
146 }
147 
149 {
150  return P2_3; // Read VIN_IN.
151 }
152 
154 {
155  P2DIR &= ~(1<<0); // Make P2_0 be a floating input.
156 }
157 
159 {
160  P2_0 = 1;
161  P2DIR |= (1<<0); // Drive P2_0 high.
162 }
void systemInit()
Definition: board.c:29
void dmaInit(void)
Definition: dma.c:7
void boardStartBootloader()
Definition: board.c:111
BIT usbPowerPresent()
Definition: board.c:142
void boardIoInit()
Definition: board.c:71
void delayMs(uint16 milliseconds)
Definition: time.c:43
void boardClockInit()
Definition: board.c:45
__bit BIT
Definition: cc2511_types.h:32
void delayMicroseconds(uint8 microseconds)
unsigned char uint8
Definition: cc2511_types.h:9
void enableUsbPullup()
Definition: board.c:158
uint32 getMs()
Definition: time.c:19
void boardStartBootloaderIfNeeded()
Definition: board.c:130
BIT vinPowerPresent()
Definition: board.c:148
void timeInit()
Definition: time.c:29
void disableUsbPullup()
Definition: board.c:153
void boardService()
Definition: board.c:37