Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MAXREFDES131_Qt_Demo MAX32630FTHR_iButton_uSD_Logger MAX32630FTHR_DS18B20_uSD_Logger MAXREFDES130_131_Demo ... more
OneWire_Masters/GPIO/owlink.s@53:071ae5d090d1, 2016-04-12 (annotated)
- Committer:
- IanBenzMaxim
- Date:
- Tue Apr 12 10:51:20 2016 -0500
- Revision:
- 53:071ae5d090d1
- Parent:
- 52:4cba20c21941
- Child:
- 57:1635f247ceae
Added functionality for cross-platform assembly macros. Attempted to switch pin manipulation functions to inline for performance, but this actually doubled the first bit time when tested in IAR. Tweak ow_bit() types to please GCC.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
IanBenzMaxim | 52:4cba20c21941 | 1 | // ow_usdelay configuration |
IanBenzMaxim | 40:590791ecac1c | 2 | #define PROC_CLOCK_MHZ (__SYSTEM_HFX / 1000000) // Processor clock in MHz |
IanBenzMaxim | 31:7c684e49fa8f | 3 | #define OVERHEAD_TUNING 21 // Fraction where OverheadTime(us) = OVERHEAD_TUNING / PROC_CLOCK_MHZ |
IanBenzMaxim | 31:7c684e49fa8f | 4 | // Make PROC_CLOCK_MHZ and OVERHEAD_TUNING divisible by PROC_CYCLES_PER_LOOP for best results |
IanBenzMaxim | 28:057bb14d3cee | 5 | |
IanBenzMaxim | 52:4cba20c21941 | 6 | // ow_usdelay constants |
IanBenzMaxim | 31:7c684e49fa8f | 7 | #define PIPELINE_REFILL_PROC_CYCLES 1 // ARM specifies 1-3 cycles for pipeline refill following a branch |
IanBenzMaxim | 31:7c684e49fa8f | 8 | #define PROC_CYCLES_PER_LOOP (2 + PIPELINE_REFILL_PROC_CYCLES) |
IanBenzMaxim | 31:7c684e49fa8f | 9 | #define LOOPS_PER_US (PROC_CLOCK_MHZ / PROC_CYCLES_PER_LOOP) // Number of loop passes for a 1 us delay |
IanBenzMaxim | 31:7c684e49fa8f | 10 | #define LOOPS_REMOVED_TUNING (OVERHEAD_TUNING / PROC_CYCLES_PER_LOOP) |
IanBenzMaxim | 46:afe466c96069 | 11 | |
IanBenzMaxim | 52:4cba20c21941 | 12 | // OwTiming offsets |
IanBenzMaxim | 52:4cba20c21941 | 13 | #define tRSTL_OFFSET 0 |
IanBenzMaxim | 52:4cba20c21941 | 14 | #define tMSP_OFFSET 2 |
IanBenzMaxim | 52:4cba20c21941 | 15 | #define tW0L_OFFSET 4 |
IanBenzMaxim | 52:4cba20c21941 | 16 | #define tW1L_OFFSET 6 |
IanBenzMaxim | 52:4cba20c21941 | 17 | #define tMSR_OFFSET 8 |
IanBenzMaxim | 52:4cba20c21941 | 18 | #define tSLOT_OFFSET 10 |
IanBenzMaxim | 52:4cba20c21941 | 19 | |
IanBenzMaxim | 46:afe466c96069 | 20 | // LABEL macro |
IanBenzMaxim | 46:afe466c96069 | 21 | #ifdef TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 46:afe466c96069 | 22 | #define LABEL(x) x: |
IanBenzMaxim | 46:afe466c96069 | 23 | #else // TOOLCHAIN_IAR or TOOLCHAIN_ARM_STD |
IanBenzMaxim | 46:afe466c96069 | 24 | #define LABEL(x) x |
IanBenzMaxim | 46:afe466c96069 | 25 | #endif |
IanBenzMaxim | 46:afe466c96069 | 26 | |
IanBenzMaxim | 46:afe466c96069 | 27 | // EXPORT_LABEL macro |
IanBenzMaxim | 46:afe466c96069 | 28 | #ifdef TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 46:afe466c96069 | 29 | #define EXPORT_LABEL(x) .global x |
IanBenzMaxim | 46:afe466c96069 | 30 | #else // TOOLCHAIN_IAR or TOOLCHAIN_ARM_STD |
IanBenzMaxim | 46:afe466c96069 | 31 | #define EXPORT_LABEL(x) EXPORT x |
IanBenzMaxim | 46:afe466c96069 | 32 | #endif |
IanBenzMaxim | 46:afe466c96069 | 33 | |
IanBenzMaxim | 46:afe466c96069 | 34 | // THUMB_FUNC macro |
IanBenzMaxim | 46:afe466c96069 | 35 | #ifdef TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 46:afe466c96069 | 36 | #define THUMB_FUNC .thumb_func |
IanBenzMaxim | 46:afe466c96069 | 37 | #else // TOOLCHAIN_IAR or TOOLCHAIN_ARM_STD |
IanBenzMaxim | 46:afe466c96069 | 38 | #define THUMB_FUNC |
IanBenzMaxim | 46:afe466c96069 | 39 | #endif |
IanBenzMaxim | 52:4cba20c21941 | 40 | |
IanBenzMaxim | 53:071ae5d090d1 | 41 | // MACRO_ARM_BEGIN macro |
IanBenzMaxim | 53:071ae5d090d1 | 42 | #ifdef TOOLCHAIN_ARM_STD |
IanBenzMaxim | 53:071ae5d090d1 | 43 | #define MACRO_ARM_BEGIN MACRO |
IanBenzMaxim | 53:071ae5d090d1 | 44 | #else // TOOLCHAIN_IAR or TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 53:071ae5d090d1 | 45 | #define MACRO_ARM_BEGIN |
IanBenzMaxim | 53:071ae5d090d1 | 46 | #endif |
IanBenzMaxim | 53:071ae5d090d1 | 47 | |
IanBenzMaxim | 53:071ae5d090d1 | 48 | // MACRO_BEGIN macro |
IanBenzMaxim | 53:071ae5d090d1 | 49 | #if defined TOOLCHAIN_IAR |
IanBenzMaxim | 53:071ae5d090d1 | 50 | #define MACRO_BEGIN(name) name MACRO |
IanBenzMaxim | 53:071ae5d090d1 | 51 | #elif defined TOOLCHAIN_ARM_STD |
IanBenzMaxim | 53:071ae5d090d1 | 52 | #define MACRO_BEGIN(name) $label name |
IanBenzMaxim | 53:071ae5d090d1 | 53 | #else // TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 53:071ae5d090d1 | 54 | #define MACRO_BEGIN(name) .macro name |
IanBenzMaxim | 53:071ae5d090d1 | 55 | #endif |
IanBenzMaxim | 53:071ae5d090d1 | 56 | |
IanBenzMaxim | 53:071ae5d090d1 | 57 | // ENDM macro |
IanBenzMaxim | 53:071ae5d090d1 | 58 | #if defined TOOLCHAIN_IAR |
IanBenzMaxim | 53:071ae5d090d1 | 59 | // Use ENDM since IAR processes macros before #define directives. |
IanBenzMaxim | 53:071ae5d090d1 | 60 | #elif defined TOOLCHAIN_ARM_STD |
IanBenzMaxim | 53:071ae5d090d1 | 61 | #define ENDM MEND |
IanBenzMaxim | 53:071ae5d090d1 | 62 | #else // TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 53:071ae5d090d1 | 63 | #define ENDM .endm |
IanBenzMaxim | 53:071ae5d090d1 | 64 | #endif |
IanBenzMaxim | 53:071ae5d090d1 | 65 | |
IanBenzMaxim | 52:4cba20c21941 | 66 | // Define a code section |
IanBenzMaxim | 31:7c684e49fa8f | 67 | #if defined TOOLCHAIN_IAR |
IanBenzMaxim | 30:fdd7a0f82f2f | 68 | SECTION owlink : CODE |
IanBenzMaxim | 31:7c684e49fa8f | 69 | #elif defined TOOLCHAIN_ARM_STD |
IanBenzMaxim | 29:5c51a17cfbf5 | 70 | AREA owlink, CODE |
IanBenzMaxim | 31:7c684e49fa8f | 71 | #else // TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 31:7c684e49fa8f | 72 | .syntax unified |
IanBenzMaxim | 31:7c684e49fa8f | 73 | .section .text |
IanBenzMaxim | 30:fdd7a0f82f2f | 74 | #endif |
IanBenzMaxim | 28:057bb14d3cee | 75 | |
IanBenzMaxim | 31:7c684e49fa8f | 76 | // void ow_usdelay(unsigned int time_us) |
IanBenzMaxim | 46:afe466c96069 | 77 | THUMB_FUNC |
IanBenzMaxim | 46:afe466c96069 | 78 | EXPORT_LABEL(ow_usdelay) |
IanBenzMaxim | 46:afe466c96069 | 79 | LABEL(ow_usdelay) |
IanBenzMaxim | 40:590791ecac1c | 80 | cmp R0, #0 // Return if time_us equals zero |
IanBenzMaxim | 52:4cba20c21941 | 81 | beq ow_usdelay_return |
IanBenzMaxim | 52:4cba20c21941 | 82 | mov R2, #LOOPS_PER_US |
IanBenzMaxim | 52:4cba20c21941 | 83 | mul R0, R0, R2 |
IanBenzMaxim | 28:057bb14d3cee | 84 | sub R0, R0, #LOOPS_REMOVED_TUNING |
IanBenzMaxim | 46:afe466c96069 | 85 | LABEL(loop) |
IanBenzMaxim | 28:057bb14d3cee | 86 | subs R0, R0, #1 |
IanBenzMaxim | 28:057bb14d3cee | 87 | bne loop |
IanBenzMaxim | 52:4cba20c21941 | 88 | LABEL(ow_usdelay_return) |
IanBenzMaxim | 52:4cba20c21941 | 89 | bx R14 |
IanBenzMaxim | 52:4cba20c21941 | 90 | |
IanBenzMaxim | 52:4cba20c21941 | 91 | // static void write_ow_gpio_low(unsigned int * portReg, unsigned int pinMask) |
IanBenzMaxim | 52:4cba20c21941 | 92 | THUMB_FUNC |
IanBenzMaxim | 52:4cba20c21941 | 93 | LABEL(write_ow_gpio_low) |
IanBenzMaxim | 52:4cba20c21941 | 94 | ldr R2, [R0] |
IanBenzMaxim | 52:4cba20c21941 | 95 | bic R2, R2, R1 |
IanBenzMaxim | 52:4cba20c21941 | 96 | str R2, [R0] |
IanBenzMaxim | 52:4cba20c21941 | 97 | bx R14 |
IanBenzMaxim | 52:4cba20c21941 | 98 | |
IanBenzMaxim | 52:4cba20c21941 | 99 | // static void write_ow_gpio_high(unsigned int * portReg, unsigned int pinMask) |
IanBenzMaxim | 52:4cba20c21941 | 100 | THUMB_FUNC |
IanBenzMaxim | 52:4cba20c21941 | 101 | LABEL(write_ow_gpio_high) |
IanBenzMaxim | 52:4cba20c21941 | 102 | ldr R2, [R0] |
IanBenzMaxim | 52:4cba20c21941 | 103 | orr R2, R2, R1 |
IanBenzMaxim | 52:4cba20c21941 | 104 | str R2, [R0] |
IanBenzMaxim | 52:4cba20c21941 | 105 | bx R14 |
IanBenzMaxim | 52:4cba20c21941 | 106 | |
IanBenzMaxim | 52:4cba20c21941 | 107 | // static unsigned int read_ow_gpio(unsigned int * portReg, unsigned int pinMask) |
IanBenzMaxim | 52:4cba20c21941 | 108 | THUMB_FUNC |
IanBenzMaxim | 52:4cba20c21941 | 109 | LABEL(read_ow_gpio) |
IanBenzMaxim | 52:4cba20c21941 | 110 | ldr R0, [R0] |
IanBenzMaxim | 52:4cba20c21941 | 111 | and R0, R0, R1 |
IanBenzMaxim | 28:057bb14d3cee | 112 | bx R14 |
IanBenzMaxim | 28:057bb14d3cee | 113 | |
IanBenzMaxim | 53:071ae5d090d1 | 114 | // void ow_bit(uint8_t * sendrecvbit, volatile uint32_t * inPortReg, volatile uint32_t * outPortReg, unsigned int pinMask, const OwTiming * timing) |
IanBenzMaxim | 52:4cba20c21941 | 115 | THUMB_FUNC |
IanBenzMaxim | 52:4cba20c21941 | 116 | EXPORT_LABEL(ow_bit) |
IanBenzMaxim | 52:4cba20c21941 | 117 | LABEL(ow_bit) |
IanBenzMaxim | 52:4cba20c21941 | 118 | push {R4-R8, R14} |
IanBenzMaxim | 52:4cba20c21941 | 119 | // Retrive extra parameters from stack |
IanBenzMaxim | 52:4cba20c21941 | 120 | add R6, SP, #24 // Find beginning of stack: 6 scratch registers * 4 bytes each |
IanBenzMaxim | 52:4cba20c21941 | 121 | ldr R6, [R6] // Load timing struct |
IanBenzMaxim | 52:4cba20c21941 | 122 | ldrh R4, [R6, #tSLOT_OFFSET] |
IanBenzMaxim | 52:4cba20c21941 | 123 | ldrh R5, [R6, #tMSR_OFFSET] |
IanBenzMaxim | 52:4cba20c21941 | 124 | // R0: sendrecvbit |
IanBenzMaxim | 52:4cba20c21941 | 125 | // R1: inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 126 | // R2: outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 127 | // R3: pinMask |
IanBenzMaxim | 52:4cba20c21941 | 128 | // R4: tSLOT |
IanBenzMaxim | 52:4cba20c21941 | 129 | // R5: tMSR |
IanBenzMaxim | 52:4cba20c21941 | 130 | // R6: timing |
IanBenzMaxim | 52:4cba20c21941 | 131 | // R7: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 132 | // R8: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 133 | // R14: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 134 | |
IanBenzMaxim | 52:4cba20c21941 | 135 | // Reorganize registers for upcoming function calls |
IanBenzMaxim | 52:4cba20c21941 | 136 | mov R8, R1 // inPortReg to R8 |
IanBenzMaxim | 52:4cba20c21941 | 137 | mov R7, R2 // outPortReg to R7 |
IanBenzMaxim | 52:4cba20c21941 | 138 | mov R1, R3 // pinMask to R1 |
IanBenzMaxim | 52:4cba20c21941 | 139 | mov R3, R0 // sendrecvbit to R3 |
IanBenzMaxim | 52:4cba20c21941 | 140 | // R0: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 141 | // R1: pinMask |
IanBenzMaxim | 52:4cba20c21941 | 142 | // R2: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 143 | // R3: sendrecvbit |
IanBenzMaxim | 52:4cba20c21941 | 144 | // R4: tSLOT |
IanBenzMaxim | 52:4cba20c21941 | 145 | // R5: tMSR |
IanBenzMaxim | 52:4cba20c21941 | 146 | // R6: timing |
IanBenzMaxim | 52:4cba20c21941 | 147 | // R7: outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 148 | // R8: inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 149 | // R14: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 150 | |
IanBenzMaxim | 52:4cba20c21941 | 151 | // if (*sendrecvbit & 1) |
IanBenzMaxim | 52:4cba20c21941 | 152 | ldrb R14, [R3] |
IanBenzMaxim | 52:4cba20c21941 | 153 | tst R14, #1 |
IanBenzMaxim | 52:4cba20c21941 | 154 | beq write_zero |
IanBenzMaxim | 52:4cba20c21941 | 155 | ldrh R6, [R6, #tW1L_OFFSET] // tW1L |
IanBenzMaxim | 52:4cba20c21941 | 156 | sub R4, R4, R5 // tREC = tSLOT - tMSR |
IanBenzMaxim | 52:4cba20c21941 | 157 | sub R5, R5, R6 // delay2 = tMSR - tLW1L |
IanBenzMaxim | 52:4cba20c21941 | 158 | // R0: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 159 | // R1: pinMask |
IanBenzMaxim | 52:4cba20c21941 | 160 | // R2: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 161 | // R3: sendrecvbit |
IanBenzMaxim | 52:4cba20c21941 | 162 | // R4: tREC |
IanBenzMaxim | 52:4cba20c21941 | 163 | // R5: delay2 |
IanBenzMaxim | 52:4cba20c21941 | 164 | // R6: tW1L |
IanBenzMaxim | 52:4cba20c21941 | 165 | // R7: outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 166 | // R8: inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 167 | // R14: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 168 | mov R0, R7 // outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 169 | bl write_ow_gpio_low // Pull low |
IanBenzMaxim | 52:4cba20c21941 | 170 | mov R0, R6 // tLOW |
IanBenzMaxim | 52:4cba20c21941 | 171 | bl ow_usdelay // Delay for tLOW |
IanBenzMaxim | 52:4cba20c21941 | 172 | mov R0, R7 // outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 173 | bl write_ow_gpio_high // Release pin |
IanBenzMaxim | 52:4cba20c21941 | 174 | mov R0, R5 // delay2 |
IanBenzMaxim | 52:4cba20c21941 | 175 | bl ow_usdelay // Delay for sample time |
IanBenzMaxim | 52:4cba20c21941 | 176 | mov R0, R8 // inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 177 | bl read_ow_gpio // Read pin |
IanBenzMaxim | 52:4cba20c21941 | 178 | mov R5, R0 // Store read value for later |
IanBenzMaxim | 52:4cba20c21941 | 179 | b recovery_delay |
IanBenzMaxim | 52:4cba20c21941 | 180 | // else |
IanBenzMaxim | 52:4cba20c21941 | 181 | LABEL(write_zero) |
IanBenzMaxim | 52:4cba20c21941 | 182 | ldrh R6, [R6, #tW0L_OFFSET] // tW0L |
IanBenzMaxim | 52:4cba20c21941 | 183 | sub R4, R4, R6 // tREC = tSLOT - tLW0L |
IanBenzMaxim | 52:4cba20c21941 | 184 | sub R6, R6, R5 // delay2 = tW0L - tMSR |
IanBenzMaxim | 52:4cba20c21941 | 185 | // R0: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 186 | // R1: pinMask |
IanBenzMaxim | 52:4cba20c21941 | 187 | // R2: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 188 | // R3: sendrecvbit |
IanBenzMaxim | 52:4cba20c21941 | 189 | // R4: tREC |
IanBenzMaxim | 52:4cba20c21941 | 190 | // R5: tMSR |
IanBenzMaxim | 52:4cba20c21941 | 191 | // R6: delay2 |
IanBenzMaxim | 52:4cba20c21941 | 192 | // R7: outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 193 | // R8: inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 194 | // R14: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 195 | mov R0, R7 // outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 196 | bl write_ow_gpio_low // Pull low |
IanBenzMaxim | 52:4cba20c21941 | 197 | mov R0, R5 // tMSR |
IanBenzMaxim | 52:4cba20c21941 | 198 | bl ow_usdelay // Delay for tMSR |
IanBenzMaxim | 52:4cba20c21941 | 199 | mov R0, R8 // inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 200 | bl read_ow_gpio // Read pin |
IanBenzMaxim | 52:4cba20c21941 | 201 | mov R5, R0 // Store read value for later |
IanBenzMaxim | 52:4cba20c21941 | 202 | mov R0, R6 // delay2 |
IanBenzMaxim | 52:4cba20c21941 | 203 | bl ow_usdelay // Delay for release |
IanBenzMaxim | 52:4cba20c21941 | 204 | mov R0, R7 // outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 205 | bl write_ow_gpio_high // Release pin |
IanBenzMaxim | 52:4cba20c21941 | 206 | // endif (*sendrecvbit & 1) |
IanBenzMaxim | 52:4cba20c21941 | 207 | // R0: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 208 | // R1: pinMask |
IanBenzMaxim | 52:4cba20c21941 | 209 | // R2: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 210 | // R3: sendrecvbit |
IanBenzMaxim | 52:4cba20c21941 | 211 | // R4: tREC |
IanBenzMaxim | 52:4cba20c21941 | 212 | // R5: read value |
IanBenzMaxim | 52:4cba20c21941 | 213 | // R6: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 214 | // R7: outPortReg |
IanBenzMaxim | 52:4cba20c21941 | 215 | // R8: inPortReg |
IanBenzMaxim | 52:4cba20c21941 | 216 | // R14: Scratch |
IanBenzMaxim | 52:4cba20c21941 | 217 | |
IanBenzMaxim | 52:4cba20c21941 | 218 | LABEL(recovery_delay) |
IanBenzMaxim | 52:4cba20c21941 | 219 | mov R0, R4 |
IanBenzMaxim | 52:4cba20c21941 | 220 | bl ow_usdelay // Delay for tREC |
IanBenzMaxim | 52:4cba20c21941 | 221 | |
IanBenzMaxim | 52:4cba20c21941 | 222 | strb R5, [R3] |
IanBenzMaxim | 52:4cba20c21941 | 223 | pop {R4-R8, R14} |
IanBenzMaxim | 52:4cba20c21941 | 224 | bx R14 |
IanBenzMaxim | 31:7c684e49fa8f | 225 | #ifdef TOOLCHAIN_GCC_ARM |
IanBenzMaxim | 31:7c684e49fa8f | 226 | .end |
IanBenzMaxim | 31:7c684e49fa8f | 227 | #else // TOOLCHAIN_IAR or TOOLCHAIN_ARM_STD |
IanBenzMaxim | 31:7c684e49fa8f | 228 | END |
IanBenzMaxim | 40:590791ecac1c | 229 | #endif |