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  }