leon-myuart.c
5.16 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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/* -----------------------------------------------------------------------------
* Copyright (C) 2015-2018 daiteq s.r.o. http://www.daiteq.com
*
* This program is distributed WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE.
*
* -----------------------------------------------------------------------------
* Filename : leon-myuart.c
* Authors : Martin Danek
* Description : leon2 uart I/O routines
* Release :
* Version : 1.0
* Date : 10.05.2018
* -----------------------------------------------------------------------------
*/
#include "leon-myuart.h"
void delay(int i)
{
#ifndef SIM
int k = 0, j = 0;
for(k = 0; k < i; k++)
{
for(j = 0; j < 40; j++);
__asm__ volatile ("\t nop\n");
}
#endif
}
/* ***************** */
/* UART ROUTINES */
/* */
void init_uart(void) {
cpu_reg_write(APBPIO_DIRECTION,DIRECTION_UARTS);
cpu_reg_write(APBUART1_PRESCALER,SCALER_RELOAD_VALUE);
cpu_reg_write(APBUART1_CONTROL,ENABLE_RX|ENABLE_TX);
}
void m_putchar(unsigned char s) {
int status = 0;
while ((status=(cpu_reg_read(APBUART1_STATUS))&STAT_TH)==0) {
delay(10);
;
}
cpu_reg_write(APBUART1_DATA,s);
while ((status=(cpu_reg_read(APBUART1_STATUS))&STAT_TH)==0) {
delay(10);
;
}
}
unsigned char m_getchar(void) {
int status = 0;
while ((status=(cpu_reg_read(APBUART1_STATUS))&STAT_DR)==0) {
delay(10);
;
}
return cpu_reg_read(APBUART1_DATA);
}
void m_print(unsigned char* s) {
unsigned cnt=200;
unsigned char *l;
l=s;
while ((cnt>0)&&(*l!='\0')) {
if (*l=='\n') {
// m_putchar(0x0D);
m_putchar(0x0A);
}
else {
m_putchar(*l);
}
l++;
cnt--;
}
}
void i_print(int i) {
unsigned char buf[22];
unsigned idx=20;
unsigned neg=0;
buf[21]='\0';
// buf[20]='\n';
if (i==0) {
buf[idx--]='0';
}
else {
if (i<0) {
neg=1;
i=-i;
}
while ((i>0)&&(idx>0)) {
buf[idx--]='0'+(i%10);
i=i/10;
}
if (neg)
buf[idx--]='-';
}
buf[idx]=' ';
m_print(&buf[idx+1]);
}
void i_hexprint(unsigned i) {
unsigned char buf[22];
unsigned idx=20;
unsigned char dgt;
buf[21]='\0';
// buf[20]='\n';
if (i==0) {
buf[idx--]='0';
}
else {
while ((i>0)&&(idx>0)) {
dgt=(i%16);
if (dgt>9)
buf[idx--]='A'+dgt-10;
else
buf[idx--]='0'+dgt;
i=i/16;
}
}
if (idx==19)
buf[idx--]='0';
buf[idx]=' ';
m_print(&buf[idx]);
}
unsigned i_conv(char *s) {
unsigned val=0;
unsigned i=0;
while (*(s+i)!='\0') {
val*=10;
val+=*(s+i)-'0';
i++;
}
return val;
}
unsigned i_hexconv(char *s) {
unsigned val=0;
unsigned i=0;
while (*(s+i)!='\0') {
val*=16;
if ((*(s+i)>='0')&&(*(s+i)<='9'))
val+=*(s+i)-'0';
else if ((*(s+i)>='A')&&(*(s+i)<='F'))
val+=*(s+i)-'A'+10;
else if ((*(s+i)>='a')&&(*(s+i)<='f'))
val+=*(s+i)-'a'+10;
i++;
}
return val;
}
unsigned getval(unsigned char* s, unsigned base) {
char str[25];
char *p_s;
unsigned i=0;
unsigned val=0;
p_s=str;
m_print(s);
do {
str[i++]=m_getchar();
} while ((str[i-1]!=0x0D)&&(str[i-1]!=0x0A)&&(i<25));
str[i-1]='\0';
if (base==16) {
val=i_hexconv(p_s);
i_hexprint(val);
}
else {
val=i_conv(p_s);
i_print(val);
}
m_print("\n");
return val;
}
void dumpMem(unsigned count, void *address, unsigned len) {
unsigned i,j;
for (i=0;i<len;i++) {
if (i%16==0) {
m_print("\nDUMP");
i_print(count);
m_print(": ");
i_hexprint((unsigned)address+i);
}
i_hexprint(*((unsigned char*)address+i));
}
m_print("\nDUMP DONE\n");
}
void dataError(void* a, unsigned sz, unsigned i, unsigned expected) {
m_print("ADDR: ");i_hexprint((unsigned)(a+i*sz));
m_print(" EXPECTED ");i_hexprint(expected);
m_print(" ACTUAL ");i_hexprint(*((unsigned*)a+i));
m_print("\n");
}
/* ***************** */
/* TIMER ROUTINES */
/* */
void init_timer(void) {
cpu_reg_write(APBPRESCALER_RELOAD, TMR_PRESCALER_VALUE);
cpu_reg_write(APBTIMER1_COUNTER, 0);
cpu_reg_write(APBTIMER1_RELOAD, TMR_RELOAD_VALUE); //TIMER_RELOAD_VALUE);
#ifdef USE_BSP_INTERRUPTS
cpu_reg_write(APBINTCTRL_CLEAR, 1<<8);
cpu_reg_write(APBINTCTRL_MASK, 1<<8);
#endif
cpu_reg_write(APBTIMER1_CONTROL, TMR_RUN);
}
void timer_start(void)
{
cpu_reg_write(APBTIMER1_CONTROL, TMR_ENABLE | TMR_LOAD);
}
void timer_stop(void)
{
cpu_reg_write(APBTIMER1_CONTROL, TMR_DISABLE);
}
unsigned int clock(void) {
unsigned int val;
val=cpu_reg_read(APBTIMER1_COUNTER);
return TMR_RELOAD_VALUE-val;
}
#ifdef USE_BSP_INTERRUPTS
extern unsigned int _tmrcnt;
#endif
unsigned int get_time(unsigned int *sec)
{
unsigned int val;
unsigned int tctrl = cpu_reg_read(APBTIMER1_CONTROL);
#ifdef USE_BSP_INTERRUPTS
// disable timer to avoid inconsistency
if (sec && (tctrl & TMR_ENABLE)) cpu_reg_write(APBTIMER1_CONTROL, (tctrl & ~TMR_ENABLE));
#endif
val=cpu_reg_read(APBTIMER1_COUNTER);
val = TMR_RELOAD_VALUE-val;
#ifdef USE_BSP_INTERRUPTS
if (sec) {
*sec = _tmrcnt;
if (tctrl & TMR_ENABLE) cpu_reg_write(APBTIMER1_CONTROL, tctrl);
}
#endif
return val;
}