X-Git-Url: https://robinkrens.nl/gitweb/?a=blobdiff_plain;f=lib%2Fregfunc.c;h=2e2468927f4213e352249b39c99c0aeb52aab1d2;hb=fac4700036ceaafe0d4a2b40d4c9f590d3c407b7;hp=6add22082eeb70fcc6b52c8c795699a5a4ebd324;hpb=918e9bbf26d44cb0087d35637e2e0f90ca37d7c3;p=cortex-from-scratch diff --git a/lib/regfunc.c b/lib/regfunc.c index 6add220..2e24689 100644 --- a/lib/regfunc.c +++ b/lib/regfunc.c @@ -1,3 +1,14 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/7/20 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Helper functions to set registers + * + * */ + #include #include #include @@ -6,43 +17,40 @@ #include #include +#include + #include +#include -/* write value (uint8_t) to register */ -void regw_u8(volatile uint32_t * reg, uint8_t val, short shift, short flag) { - - switch(flag) { - case OWRITE: - *reg = (val << shift); - break; - case SETBIT: - *reg = *reg | (val << shift); - break; - case CLRBIT: - *reg = (val << shift); - break; - } +// register set bit at position +void rsetbit(volatile uint32_t * reg, short pos) { + *reg = *reg | (0x1 << pos); } -/* write value (uint32_t) to register */ -void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) { - - switch(flag) { - case OWRITE: - *reg = (val << shift); - break; - case SETBIT: - *reg = *reg | (val << shift); - break; - case CLRBIT: - break; - } +// register set bits from certain pos +void rsetbitsfrom(volatile uint32_t * reg, short pos, int val) { + *reg = *reg | (val << pos); } -/* Print out the hexidecimal representation of an integer - After implementation of a printf function, this code - will be obsolete. */ +// register clear bit at position +void rclrbit(volatile uint32_t * reg, short pos) { + *reg = *reg & ~(0x1 << pos); +} + +// check if a bit is set +int rchkbit(volatile uint32_t * reg, short pos) { + if ((*reg >> pos) & 0x1) + return 1; + return 0; +} +// register (over)write +void rwrite(volatile uint32_t * reg, uint32_t val) { + *reg = val; +} + + +/* Deprecated use printf instead char hexbuf[8]; char * regtohex(uint32_t addr) { char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'}; @@ -61,4 +69,54 @@ char * regtohex(uint32_t addr) { } } return &hexbuf[0]; +} */ + +// TODO: implement simple scanf functions +int singlehextoreg(char hex) { + + int conv = 0; + if (hex >= 'A' && hex <= 'F') + conv = hex - '7'; + + else { + conv = hex - '0'; + } + return conv; + } + +uint32_t hextoreg(char * a) { + + uint32_t x = 0; + int tmp; + for(int i = 0; i < 8; i++) { + tmp = singlehextoreg(*a++); + x += tmp << (28 - (i * 4)); + } + return x; + +} + +/* Busy-loop block implementation. Each iteration will take 3 CPU cycles. + * Of course, when interrupts are enabled, the exact delay time will be + * uncertain. + * + * Example: for a standard STM32x config board (8MHz) the maximum delay is + * 0xFFFF * (1/8,000,000) * 3 = 24.58ms + * */ +static void __block(uint16_t count) { + + asm volatile("b1: subs %0, %1, #1" "\n\t" + "bne b1" : "=r" (count) : "r" (count)); +} + +/* Delay us microsecond + * Note: delay includes setup time (about 4 clockcycles), so is quite + * inaccurate */ +void _block(uint16_t us) { + + uint16_t count = (us/3) * CLKSPEED_MHZ; // x cycles + __block(count); + +} +