github.com/aykevl/tinygo@v0.5.0/src/device/arm/arm.go (about) 1 // CMSIS abstraction functions. 2 // 3 // Original copyright: 4 // 5 // Copyright (c) 2009 - 2015 ARM LIMITED 6 // 7 // All rights reserved. 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions are met: 10 // - Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // - Redistributions in binary form must reproduce the above copyright 13 // notice, this list of conditions and the following disclaimer in the 14 // documentation and/or other materials provided with the distribution. 15 // - Neither the name of ARM nor the names of its contributors may be used 16 // to endorse or promote products derived from this software without 17 // specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 // ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 // POSSIBILITY OF SUCH DAMAGE. 30 package arm 31 32 import ( 33 "unsafe" 34 ) 35 36 // Run the given assembly code. The code will be marked as having side effects, 37 // as it doesn't produce output and thus would normally be eliminated by the 38 // optimizer. 39 func Asm(asm string) 40 41 // Run the given inline assembly. The code will be marked as having side 42 // effects, as it would otherwise be optimized away. The inline assembly string 43 // recognizes template values in the form {name}, like so: 44 // 45 // arm.AsmFull( 46 // "str {value}, {result}", 47 // map[string]interface{}{ 48 // "value": 1 49 // "result": &dest, 50 // }) 51 func AsmFull(asm string, regs map[string]interface{}) 52 53 // ReadRegister returns the contents of the specified register. The register 54 // must be a processor register, reachable with the "mov" instruction. 55 func ReadRegister(name string) uintptr 56 57 // Run the following system call (SVCall) with 0 arguments. 58 func SVCall0(num uintptr) uintptr 59 60 // Run the following system call (SVCall) with 1 argument. 61 func SVCall1(num uintptr, a1 interface{}) uintptr 62 63 // Run the following system call (SVCall) with 2 arguments. 64 func SVCall2(num uintptr, a1, a2 interface{}) uintptr 65 66 // Run the following system call (SVCall) with 3 arguments. 67 func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr 68 69 // Run the following system call (SVCall) with 4 arguments. 70 func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr 71 72 //go:volatile 73 type RegValue uint32 74 75 const ( 76 SCS_BASE = 0xE000E000 77 NVIC_BASE = SCS_BASE + 0x0100 78 ) 79 80 // Nested Vectored Interrupt Controller (NVIC). 81 // 82 // Source: 83 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.html 84 type NVIC_Type struct { 85 ISER [8]RegValue // Interrupt Set-enable Registers 86 _ [24]uint32 87 ICER [8]RegValue // Interrupt Clear-enable Registers 88 _ [24]uint32 89 ISPR [8]RegValue // Interrupt Set-pending Registers 90 _ [24]uint32 91 ICPR [8]RegValue // Interrupt Clear-pending Registers 92 _ [24]uint32 93 IABR [8]RegValue // Interrupt Active Bit Registers 94 _ [56]uint32 95 IPR [60]RegValue // Interrupt Priority Registers 96 } 97 98 var NVIC = (*NVIC_Type)(unsafe.Pointer(uintptr(NVIC_BASE))) 99 100 // Enable the given interrupt number. 101 func EnableIRQ(irq uint32) { 102 NVIC.ISER[irq>>5] = 1 << (irq & 0x1F) 103 } 104 105 // Set the priority of the given interrupt number. 106 // Note that the priority is given as a 0-255 number, where some of the lower 107 // bits are not implemented by the hardware. For example, to set a low interrupt 108 // priority, use 0xc0, which is equivalent to using priority level 5 when the 109 // hardware has 8 priority levels. Also note that the priority level is inverted 110 // in ARM: a lower number means it is a more important interrupt and will 111 // interrupt ISRs with a higher interrupt priority. 112 func SetPriority(irq uint32, priority uint32) { 113 // Details: 114 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Cihgjeed.html 115 regnum := irq / 4 116 regpos := irq % 4 117 mask := uint32(0xff) << (regpos * 8) // bits to clear 118 priority = priority << (regpos * 8) // bits to set 119 NVIC.IPR[regnum] = RegValue((uint32(NVIC.IPR[regnum]) &^ mask) | priority) 120 } 121 122 // DisableInterrupts disables all interrupts, and returns the old state. 123 // 124 // TODO: it doesn't actually return the old state, meaning that it cannot be 125 // nested. 126 func DisableInterrupts() uintptr { 127 Asm("cpsid if") 128 return 0 129 } 130 131 // EnableInterrupts enables all interrupts again. The value passed in must be 132 // the mask returned by DisableInterrupts. 133 // 134 // TODO: it doesn't actually use the old state, meaning that it cannot be 135 // nested. 136 func EnableInterrupts(mask uintptr) { 137 Asm("cpsie if") 138 }