basic command implementation traditional way
[cortex-from-scratch] / lib / regfunc.c
1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
2  * 
3  * $LOG$
4  * 2019/7/20 - ROBIN KRENS      
5  * Initial version 
6  * 
7  * $DESCRIPTION$
8  * Helper functions to set registers 
9  *
10  * */
11
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15
16 #include <lib/regfunc.h>
17 #include <lib/string.h>
18 #include <lib/stdio.h>
19
20 #include <lib/tinyprintf.h>
21
22 #include <sys/mmap.h>
23 #include <sys/robsys.h>
24
25 // register set bit at position
26 void rsetbit(volatile uint32_t * reg, short pos) {
27         *reg = *reg | (0x1 << pos);
28 }
29
30 // register set bits from certain pos
31 void rsetbitsfrom(volatile uint32_t * reg, short pos, int val) {
32         *reg = *reg | (val << pos);
33 }
34
35 // register clear bit at position
36 void rclrbit(volatile uint32_t * reg, short pos) {
37         *reg = *reg & ~(0x1 << pos);
38 }
39
40 // check if a bit is set 
41 int rchkbit(volatile uint32_t * reg, short pos) {
42         if ((*reg >> pos) & 0x1)
43                 return 1;
44         return 0;
45 }
46
47 // register (over)write
48 void rwrite(volatile uint32_t * reg, uint32_t val) {
49         *reg = val;
50 }
51
52
53 /* Deprecated use printf instead
54 char hexbuf[8];
55 char * regtohex(uint32_t addr) {
56         char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
57         memset(&hexbuf, 0, sizeof(uint32_t) * 8);
58
59
60         for (int i = 0; i < 8 ; i++) {
61                 uint32_t tmp = addr;
62                 tmp = tmp >> (28 - (i * 4));
63                 tmp = tmp & 0xF;
64                 if ((tmp >= 0) && tmp < 10) {
65                         hexbuf[i] = (char) tmp + 48;
66                 }
67                 else {
68                         hexbuf[i] = tmpbuf[tmp - 10];
69                 }
70         }
71         return &hexbuf[0];      
72 } */
73
74 // TODO: implement simple scanf functions
75 int singlehextoreg(char  hex) {
76
77         int conv = 0;
78         if (hex >= 'A' && hex <= 'F') 
79                 conv = hex - '7';
80
81         else {
82                 conv = hex - '0';
83         }
84         return conv;
85
86 }
87
88 uint32_t hextoreg(char * a) {
89         
90         uint32_t x = 0;
91         int tmp;
92         for(int i = 0; i < 8; i++) {
93                 tmp = singlehextoreg(*a++);
94                 x += tmp << (28 - (i * 4));
95         }
96         return x;
97
98 }
99
100 /* Busy-loop block implementation. Each iteration will take 3 CPU cycles.
101  * Of course, when interrupts are enabled, the exact delay time will be 
102  * uncertain. 
103  *
104  * Example: for a standard STM32x config board (8MHz) the maximum delay is
105  * 0xFFFF * (1/8,000,000) * 3 = 24.58ms 
106  * */
107 static void __block(uint16_t count) {
108
109         asm volatile("b1: subs %0, %1, #1" "\n\t"
110                 "bne b1" : "=r" (count) : "r" (count));
111 }
112
113 /* Delay us microsecond
114  * Note: delay includes setup time (about 4 clockcycles), so is quite
115  * inaccurate  */
116 void _block(uint16_t us) {
117         
118         uint16_t count = (us/3) * CLKSPEED_MHZ; // x cycles 
119         __block(count);
120
121 }
122