github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/internal/reg/reg16.go (about) 1 // https://github.com/usbarmory/tamago 2 // 3 // Copyright (c) WithSecure Corporation 4 // https://foundry.withsecure.com 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 9 package reg 10 11 import ( 12 "runtime" 13 "time" 14 "unsafe" 15 ) 16 17 // As sync/atomic does not provide 16-bit support, note that these functions do 18 // not necessarily enforce memory ordering. 19 20 func Get16(addr uint32, pos int, mask int) uint16 { 21 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 22 return (*reg >> pos) & uint16(mask) 23 } 24 25 func Set16(addr uint32, pos int) { 26 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 27 *reg |= (1 << pos) 28 } 29 30 func Clear16(addr uint32, pos int) { 31 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 32 *reg &= ^(1 << pos) 33 } 34 35 func SetTo16(addr uint32, pos int, val bool) { 36 if val { 37 Set16(addr, pos) 38 } else { 39 Clear16(addr, pos) 40 } 41 } 42 43 func SetN16(addr uint32, pos int, mask int, val uint16) { 44 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 45 *reg = (*reg & (^(uint16(mask) << pos))) | (val << pos) 46 } 47 48 func ClearN16(addr uint32, pos int, mask int) { 49 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 50 *reg &= ^(uint16(mask) << pos) 51 } 52 53 func Read16(addr uint32) uint16 { 54 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 55 return *reg 56 } 57 58 func Write16(addr uint32, val uint16) { 59 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 60 *reg = val 61 } 62 63 func WriteBack16(addr uint32) { 64 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 65 *reg |= *reg 66 } 67 68 func Or16(addr uint32, val uint16) { 69 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 70 *reg |= val 71 } 72 73 // Wait16 waits for a specific register bit to match a value. This function 74 // cannot be used before runtime initialization with `GOOS=tamago`. 75 func Wait16(addr uint32, pos int, mask int, val uint16) { 76 for Get16(addr, pos, mask) != val { 77 // tamago is single-threaded, give other goroutines a chance 78 runtime.Gosched() 79 } 80 } 81 82 // WaitFor16 waits, until a timeout expires, for a specific register bit to match 83 // a value. The return boolean indicates whether the wait condition was checked 84 // (true) or if it timed out (false). This function cannot be used before 85 // runtime initialization with `GOOS=tamago`. 86 func WaitFor16(timeout time.Duration, addr uint32, pos int, mask int, val uint16) bool { 87 start := time.Now() 88 89 for Get16(addr, pos, mask) != val { 90 // tamago is single-threaded, give other goroutines a chance 91 runtime.Gosched() 92 93 if time.Since(start) >= timeout { 94 return false 95 } 96 } 97 98 return true 99 }