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
|
/*
* Copyright © 2012 Keith Packard <keithp@keithp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#ifndef _AO_ARCH_H_
#define _AO_ARCH_H_
#include <stdio.h>
#include <stm32l.h>
/*
* STM32L definitions and code fragments for AltOS
*/
#define AO_STACK_SIZE 1024
/* Various definitions to make GCC look more like SDCC */
#define ao_arch_naked_declare __attribute__((naked))
#define ao_arch_naked_define
#define __pdata
#define __data
#define __xdata
#define __code const
#define __reentrant
#define __critical
#define __interrupt(n)
#define __at(n)
#define ao_arch_reboot() /* XXX */
#define ao_arch_nop() asm("nop")
#define ao_arch_interrupt(n) /* nothing */
#undef putchar
#undef getchar
#define putchar(c) ao_putchar(c)
#define getchar ao_getchar
extern void putchar(char c);
extern char getchar(void);
extern void ao_avr_stdio_init(void);
extern const uint16_t ao_serial_number;
#define ARM_PUSH32(stack, val) (*(--(stack)) = (val))
#define ao_arch_task_members\
uint32_t *sp; /* saved stack pointer */
#define cli() asm("cpsid i")
#define sei() asm("cpsie i")
#define ao_arch_init_stack(task, start) do { \
uint32_t *sp = (uint32_t *) (task->stack + AO_STACK_SIZE); \
uint32_t a = (uint32_t) start; \
int i; \
\
/* APSR */ \
ARM_PUSH32(sp, 0); \
\
/* PRIMASK with interrupts enabled */ \
ARM_PUSH32(sp, 0); \
\
/* Return address (goes into LR) */ \
ARM_PUSH32(sp, a); \
\
/* Clear register values r0-r12 */ \
i = 13; \
while (i--) \
ARM_PUSH32(sp, 0); \
\
task->sp = sp; \
} while (0);
#define ao_arch_save_regs() do { \
uint32_t apsr; \
uint32_t primask; \
\
/* Save APSR */ \
asm("mrs %0,apsr" : "=&r" (apsr)); \
asm("push {%0}" : : "r" (apsr)); \
\
/* Save PRIMASK */ \
asm("mrs %0,primask" : "=&r" (primask)); \
asm("push {%0}" : : "r" (primask)); \
\
/* Save general registers */ \
asm("push {r0-r12,lr}\n"); \
} while (0)
#define ao_arch_save_stack() do { \
uint32_t *sp; \
asm("mov %0,sp" : "=&r" (sp) ); \
ao_cur_task->sp = (sp); \
if ((uint8_t *) sp < ao_cur_task->stack) \
ao_panic (AO_PANIC_STACK); \
} while (0)
#define ao_arch_isr_stack() /* nothing */
#define ao_arch_cpu_idle() do { \
asm("wfi"); \
} while (0)
#define ao_arch_restore_stack() do { \
uint32_t sp; \
uint32_t primask; \
uint32_t apsr; \
sp = (uint32_t) ao_cur_task->sp; \
\
/* Switch stacks */ \
asm("mov sp, %0" : : "r" (sp) ); \
\
/* Restore general registers */ \
asm("pop {r0-r12,lr}\n"); \
\
/* Restore PRIMASK */ \
asm("pop {%0}" : "=&r" (primask) ); \
asm("msr primask,%0" : : "r" (primask) ); \
\
/* Restore APSR */ \
asm("pop {%0}" : "=&r" (apsr) ); \
asm("msr apsr,%0" : : "r" (apsr) ); \
\
/* Return to calling function */ \
asm("bx lr"); \
} while(0)
#define ao_arch_critical(b) do { cli(); do { b } while (0); sei(); } while (0)
#define AO_ARM_NUM_ADC 12
struct ao_adc {
uint16_t tick; /* tick when the sample was read */
uint16_t adc[AO_ARM_NUM_ADC]; /* samples */
};
/*
* For now, we're running at a weird frequency
*/
#define STM_APB1 (16000000 * 6 / 4)
void ao_lcd_stm_init(void);
void ao_lcd_font_string(char *s);
#endif /* _AO_ARCH_H_ */
|