-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patharmduino.c
More file actions
172 lines (143 loc) · 5.04 KB
/
armduino.c
File metadata and controls
172 lines (143 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "armduino.h" //we use aruidno port for stm8s
//global definitions
//global variables
//for time base off SysTick (24-bit counter)
//volatile uint32_t timer1_millis = 0;
volatile uint32_t timer_ticks = 1ul<<24; //time base on Systick -> SysTick->VAL being the lowest 24-bits (SysTick is a downcounter)
//static uint16_t timer1_fract = 0;
//volatile uint32_t SystemCoreClock=16000000ul/8; //systemcoreclock, use CMSIS' value
//systick handler - to provide time base for millis()/micros()
void SysTick_Handler(void) {
//clear the flag
timer_ticks += 1ul<<24; //increment systick counter - 24bit, 1:1 prescaler
}
//user-supplied code prototype
extern void setup(void); //user set-up
extern void loop(void); //user loop
//Arduino Functions: GPIO
//see chip-specific source/header files
//end GPIO
//Arduino Functions: Time
//return microseconds
uint32_t micros(void) {
uint32_t m; //stores overflow count
uint32_t f; //return the fractions / Systick->VAL
//use double reads
do {
m = timer_ticks;
f = SysTick->VAL; //24-bit only
} while (m != timer_ticks);
//now m and f are atomic
return (m - f) / clockCyclesPerMicrosecond(); //SysTick is a 24-bit downcounter
}
//return milliseconds
//not exact -> 1024us rather than 1000us
uint32_t millis(void) {
uint32_t m;
uint32_t f;
//use double reads
do {
m = timer_ticks;
f = SysTick->VAL; //24-bit only
} while (m != timer_ticks);
//not m and f are atomic
//return ((m + ((1ul<<24) - f)) >> 10) / clockCyclesPerMicrosecond(); //SysTick is a 24-bit downcounter
return (m - f) / clockCyclesPerMicrosecond() / 1000; //SysTick is a 24-bit downcounter
}
//return timebase ticks
uint32_t ticks(void) {
uint32_t m;
uint32_t f;
//use double reads
do {
m = timer_ticks;
f = SysTick->VAL; //24-bit only
} while (m != timer_ticks);
//not m and f are atomic
//return ((m + ((1ul<<24) - f)) >> 10) / clockCyclesPerMicrosecond(); //SysTick is a 24-bit downcounter
return (m - f);
}
//delay milliseconds
void delay(uint32_t ms) {
uint32_t start_time = millis();
while (millis() - start_time < ms) continue; //wait until desired time runs out
}
//delay micro seconds
void delayMicroseconds(uint32_t us) {
uint32_t start_time = micros();
while (micros() - start_time < us) continue; //wait until desired time runs out
}
//end Time
//Arduino Functions: Advanced IO
//shift in - from arduino code base / not optimized
uint8_t shiftIn(PIN_TypeDef dataPin, PIN_TypeDef clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
}
return value;
}
//shift out - from arduino code base / not optimized
void shiftOut(PIN_TypeDef dataPin, PIN_TypeDef clockPin, uint8_t bitOrder, uint8_t val) {
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
//wait for a pulse and return timing
uint32_t pulseIn(PIN_TypeDef pin, uint8_t state) {
uint32_t tmp;
uint8_t state1;
state = (state == LOW)?LOW:HIGH;
state1= (state == LOW)?HIGH:LOW;
while (digitalRead(pin) == state) continue; //wait for the pin to opposite
//now pin is _state
tmp = micros();
//state = (state == LOW)?HIGH:LOW; //calculate the state to end the wait
while (digitalRead(pin) == state1) continue; //wait for the pin to go back to its original state
tmp = micros() - tmp; //calculate the pulse width
return tmp;
}
//end Advanced IO
//initialize the mcu
//reset the mcu
void mcu_init(void){
//arm core initialization
//configure Systick as the time base for millis()/micros()
timer_ticks = 1ul<<24; //SysTick is a 24-bit downcounter
//for chips where SysTick_Config() is not defined in cmsis
SysTick->LOAD = (timer_ticks - 1)/*ticks*/ & SysTick_LOAD_RELOAD_Msk; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
//alternative - for CMSIS-equip'd chips
//SysTick_Config(SysTick_LOAD_RELOAD_Msk); //reload all 24 bits
//enable interrupts
interrupts();
//chip initialization
chip_init(); //defined in chip-specific files
//Update SystemCoreClock
SystemCoreClockUpdate();
}
//stylized code for main()
int main(void) {
mcu_init(); //reset the chip
setup(); //user-set up the code
while (1) {
loop(); //user specified loop
}
return 0;
}