Didah Morse Code PDA/Appliance  1.2
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
teensy3_morse_bsp.cpp
Go to the documentation of this file.
1 
4 
5 #include <climits>
6 #include "teensy3_morse_bsp.h"
7 //#include "MK20DZ10.h"
8 #include "mk20dx128.h"
9 #include "cpu.h"
10 #include "libmorse.h"
11 #include "voltage_monitor.h"
12 //---- Teensy 3.0 board support ----
13 
14 char cpuid[] = "012345678911234567892123456789";
15 
17  uint8_t i(0);
18 
19  // Family
20  uint8_t fam((SIM_SDID & SIM_SDID_FAMID(0x7)) >> SIM_SDID_FAMID_SHIFT);
21  cpuid[i++] = (fam < 8) ? 'K' : '?';
22  fam = (fam < 8) ? fam : 8;
23  cpuid[i++] = "1234675?"[fam];
24  cpuid[i++] = "0000003?"[fam];
25 
26  cpuid[i++] = '-';
27 
28  uint8_t pkg(((SIM_SDID & SIM_SDID_PINID(0xF)) >> SIM_SDID_PINID_SHIFT) - 2);
29  uint8_t pinTable[] = {32U, 0, 48U, 64U, 80U, 81U, 100U, 104U, 0, 144U, 196U, 0, uint8_t(256U) };
30  pkg = (pkg < sizeof pinTable) ? pkg : 1;
31  uint8_t pinCount(pinTable[pkg]);
32  if (99 < pinCount) {
33  cpuid[i++] = '0' + pinCount / 100;
34  }
35  if (9 < pinCount) {
36  cpuid[i++] = '0' + pinCount / 10 % 10;
37  }
38  if (0 < pinCount) {
39  cpuid[i++] = '0' + pinCount % 10;
40  } else {
41  cpuid[i++] = '?';
42  }
43 
44  cpuid[i++] = '-';
45 
46  // Silicon revision
47  cpuid[i++] = '1';
48  cpuid[i++] = '.';
49  cpuid[i++] = '0' + ((SIM_SDID & SIM_SDID_REVID(0xF)) >> SIM_SDID_REVID_SHIFT);
50 
51  cpuid[i++] = '-';
52 
53  // P-flash size
54  uint8_t pf(((SIM_FCFG1 & SIM_FCFG1_PFSIZE(0xF)) >> SIM_FCFG1_PFSIZE_SHIFT)
55  - 7);
56  uint16_t pfTable[] = { 128U, 0, 256U, 0, 512U, 0, 0, 0, 512U };
57  if (pf < sizeof pfTable) {
58  cpuid[i++] = '0' + pfTable[pf] / 100;
59  cpuid[i++] = '0' + pfTable[pf] / 10 % 10;
60  cpuid[i++] = '0' + pfTable[pf] % 10;
61  } else {
62  cpuid[i++] = '?';
63  }
64 
65  cpuid[i++] = '-';
66 
67  // FlexNVM size
68  // xxx ???
70  cpuid[i++] = '0';
71  } else {
72  uint8_t fnvm((SIM_FCFG1 & SIM_FCFG1_NVMSIZE(0xF))>>SIM_FCFG1_NVMSIZE_SHIFT);
73  uint8_t fnvmSize(1 << (6 + (fnvm >> 1)));
74  cpuid[i++] = '0' + fnvmSize / 100;
75  cpuid[i++] = '0' + fnvmSize / 10 % 10;
76  cpuid[i++] = '0' + fnvmSize % 10;
77  }
78 
79 #if 0
80  /* Determine the RAM size */
82  {
83  case 0x5:
84  Serial.println("32 kBytes of RAM\n\n");
85  break;
86  case 0x7:
87  Serial.println("64 kBytes of RAM\n\n");
88  break;
89  case 0x8:
90  Serial.println("96 kBytes of RAM\n\n");
91  break;
92  case 0x9:
93  Serial.println("128 kBytes of RAM\n\n");
94  break;
95  default:
96  Serial.print("RAM ");
97  Serial.println((SIM_SOPT1 & SIM_SOPT1_RAMSIZE(0xF))>>SIM_SOPT1_RAMSIZE_SHIFT);
98  break;
99  }
100 
101  /* Determine the last cause(s) of reset */
102  if (MC_SRSH & MC_SRSH_SW_MASK)
103  Serial.println("Software Reset\n");
105  Serial.println("Core Lockup Event Reset\n");
107  Serial.println("JTAG Reset\n");
108 
110  Serial.println("Power-on Reset\n");
112  Serial.println("External Pin Reset\n");
114  Serial.println("Watchdog(COP) Reset\n");
116  Serial.println("Loss of Clock Reset\n");
118  Serial.println("Low-voltage Detect Reset\n");
120  Serial.println("LLWU Reset\n");
121  Serial.println(MC_SRSL);
122 #endif
123  cpuid[i] = 0;
124  return cpuid;
125 }
126 
128 
130 static uint16_t touchBase[24];
131 uint16_t touchMargin(60);
132 
135 void calibrateTouch(uint8_t pin) {
136  touchBase[pin] = 0;
137  for (int i(0); i < 10; ++i) {
138  uint16_t pF20(touchRead(pin));
139  pwmWrite(pF20);
140  touchBase[pin] = touchBase[pin] < pF20 ? pF20 : touchBase[pin];
141  delay(100);
142  }
143 }
144 
146 uint16_t getPinThreshold(uint8_t pin) {
147  return 50 * (touchBase[pin] + touchMargin);
148 }
149 
152 bool touchPoll(uint8_t pin) {
153  uint16_t pF20(touchRead(pin));
154  return touchBase[pin] + touchMargin < pF20;
155 }
156 
157 size_t duty = duty50;
158 
159 size_t getDuty() {
160  return duty;
161 }
162 
163 void setDuty(uint8_t dutyCycle) {
164  duty = dutyCycle;
165 }
166 
167 bool earphonePresent(false);
168 
170  return earphonePresent;
171 }
172 
174  digitalWrite(earphoneRightPin, 0);
176 }
177 
179 void beep(uint32_t frequency, uint32_t durationMicros) {
181  pwmFrequency(frequency);
182  pwmWrite(duty);
183  redLED(1);
184  delayMicroseconds(durationMicros);
185  pwmWrite(0);
186  redLED(0);
187 }
188 
194  const double offset(343.8);
195  const double gain(-0.02258);
196  double reading(analogRead(temperatureSensor));
197  return offset + gain * reading;
198 }
199 
201 
203  return voltageMonitor.getValue();
204 }
205 
207  voltageMonitor.getSample();
208 }
209 
232 void describeRTC() {
233  printLabelValueUnits("RTC_TSR ", RTC_TSR, " time in seconds");
234  printLabelValueUnits("RTC_CR & RTC_CR_CLKO ",
235  !!(RTC_CR & RTC_CR_CLKO), " 1=gated");
236  printLabelValueUnits("RTC_CR & RTC_CR_OSCE ",
237  !!(RTC_CR & RTC_CR_OSCE), " 1=enabled");
238  printLabelValueUnits("RTC_SR & RTC_SR_TCE ",
239  !!(RTC_SR & RTC_SR_TCE), " 1=enabled");
240  printLabelValueUnits("RTC_SR & RTC_SR_TIF ",
241  !!(RTC_SR & RTC_SR_TIF), " 1=invalid");
242  printLabelValueUnits("RTC_SR & RTC_SR_TCE ",
243  !!(RTC_SR & RTC_SR_TCE), " 1=prescale enabled");
244  printLabelValueUnits("RTC_TPR ", RTC_TPR, " prescaler");
245 }
246 
260 bool hasRTC() {
261  uint32_t prescaler(RTC_TPR);
262  delayMicroseconds(33);
263  return prescaler != RTC_TPR;
264 }
265 
266 void initPorts() {
267  pinMode(earphoneRightDetectPin, INPUT_PULLUP);
268 
269  // Pins connected to the mini54. Do this for low power.
270  pinMode(18, INPUT_PULLUP);
271  pinMode(19, INPUT_PULLUP);
272 
273 // analogReference(INTERNAL);
274  analogReference(EXTERNAL);
275 //xxx analogReadAveraging(32);
276  analogReadAveraging(1);
277  analogReadRes(16); // Full resolution
278 
279  ADC0_CFG1 = ADC_CFG1_ADIV(3) // ADC Clock = 24MHz / 8
280  | ADC_CFG1_MODE(3) // 16 bit mode
281  | ADC_CFG1_ADICLK(0) // Use bus clock
282  | ADC_CFG1_ADLSMP;
283 
284  ADC0_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(3);
285  ADC0_SC3 |= ADC_SC3_CAL;
286 
287  analogRead(ditPin); // Allow calibration to complete
288 
289  // Linux:
290  // sudo cu -l /dev/tty.usbserial-* -s 9600
291  // OS X (nee Mac OS X) circa 10.8.4
292  // sudo cu -l /dev/tty.usbmodem* -s 9600 --nostop --parity=none
293  Serial.begin(9600); // Does not block.
294 
295  pinMode(ledPin, OUTPUT);
296  pinMode(beepPin, OUTPUT);
297  pinMode(earphoneRightPin, OUTPUT);
298  pinMode(piezoTxP, OUTPUT);
299  pinMode(piezoTxN, OUTPUT);
300 
301  pinMode(ledGreenN, OUTPUT);
302  pinMode(ledGreenP, OUTPUT);
303  pinMode(ledRedP, OUTPUT);
304  pinMode(ledRedN, OUTPUT);
305  digitalWrite(ledRedN, 0);
306  digitalWrite(ledGreenN, 0);
307  greenLED(1);
308 
311 }
312 
313 void pwmFrequency(int Hz) {
314  analogWriteFrequency(txPin, Hz);
315  analogWriteFrequency(piezoTxP, Hz);
316  analogWriteFrequency(earphoneRightPin, Hz);
317 }
318 
319 void pwmWrite(int duty) {
320  analogWrite(txPin, duty);
321  if (isEarphonePresent()) {
322  analogWrite(earphoneRightPin, duty);
323  } else {
324  analogWrite(piezoTxP, duty);
325  }
326 }
327 
328 void dWrite(int value) {
329  digitalWrite(txPin, value);
330  if (isEarphonePresent()) {
331  digitalWrite(earphoneRightPin, value);
332  } else {
333  digitalWrite(piezoTxP, value);
334  }
335 }
336 
337 void redLED(int value) {
338  digitalWrite(ledRedP, value);
339 }
340 
341 void greenLED(int value) {
342  digitalWrite(ledGreenP, value);
343 }
344 
345 uint16_t activityLight(0);
346 
348  ++activityLight;
349  greenLED(!(activityLight % 6));
350 }
351 
352 void toggleRedLED() {
353  ++activityLight;
354  redLED(!(activityLight % 6));
355 }
356 
357 uint32_t getRawVoltage() {
358  return voltageMonitor.getRawVoltage();
359 }