all: format code according to Go 1.19 rules
Go 1.19 started reformatting code in a way that makes it more obvious how it will be rendered on pkg.go.dev. It gets it almost right, but not entirely. Therefore, I had to modify some of the comments so that they are formatted correctly.
Этот коммит содержится в:
родитель
f936125658
коммит
c7a23183e8
114 изменённых файлов: 509 добавлений и 381 удалений
|
@ -18,7 +18,7 @@ import (
|
||||||
// makeArchive creates an arcive for static linking from a list of object files
|
// makeArchive creates an arcive for static linking from a list of object files
|
||||||
// given as a parameter. It is equivalent to the following command:
|
// given as a parameter. It is equivalent to the following command:
|
||||||
//
|
//
|
||||||
// ar -rcs <archivePath> <objs...>
|
// ar -rcs <archivePath> <objs...>
|
||||||
func makeArchive(arfile *os.File, objs []string) error {
|
func makeArchive(arfile *os.File, objs []string) error {
|
||||||
// Open the archive file.
|
// Open the archive file.
|
||||||
arwriter := ar.NewWriter(arfile)
|
arwriter := ar.NewWriter(arfile)
|
||||||
|
|
|
@ -1367,10 +1367,10 @@ func modifyStackSizes(executable string, stackSizeLoads []string, stackSizes map
|
||||||
//
|
//
|
||||||
// It might print something like the following:
|
// It might print something like the following:
|
||||||
//
|
//
|
||||||
// function stack usage (in bytes)
|
// function stack usage (in bytes)
|
||||||
// Reset_Handler 316
|
// Reset_Handler 316
|
||||||
// examples/blinky2.led1 92
|
// examples/blinky2.led1 92
|
||||||
// runtime.run$1 300
|
// runtime.run$1 300
|
||||||
func printStacks(calculatedStacks []string, stackSizes map[string]functionStackSize) {
|
func printStacks(calculatedStacks []string, stackSizes map[string]functionStackSize) {
|
||||||
// Print the sizes of all stacks.
|
// Print the sizes of all stacks.
|
||||||
fmt.Printf("%-32s %s\n", "function", "stack usage (in bytes)")
|
fmt.Printf("%-32s %s\n", "function", "stack usage (in bytes)")
|
||||||
|
|
|
@ -33,29 +33,29 @@ import (
|
||||||
// Because of this complexity, every file has in fact two cached build outputs:
|
// Because of this complexity, every file has in fact two cached build outputs:
|
||||||
// the file itself, and the list of dependencies. Its operation is as follows:
|
// the file itself, and the list of dependencies. Its operation is as follows:
|
||||||
//
|
//
|
||||||
// depfile = hash(path, compiler, cflags, ...)
|
// depfile = hash(path, compiler, cflags, ...)
|
||||||
// if depfile exists:
|
// if depfile exists:
|
||||||
// outfile = hash of all files and depfile name
|
// outfile = hash of all files and depfile name
|
||||||
// if outfile exists:
|
// if outfile exists:
|
||||||
// # cache hit
|
// # cache hit
|
||||||
// return outfile
|
// return outfile
|
||||||
// # cache miss
|
// # cache miss
|
||||||
// tmpfile = compile file
|
// tmpfile = compile file
|
||||||
// read dependencies (side effect of compile)
|
// read dependencies (side effect of compile)
|
||||||
// write depfile
|
// write depfile
|
||||||
// outfile = hash of all files and depfile name
|
// outfile = hash of all files and depfile name
|
||||||
// rename tmpfile to outfile
|
// rename tmpfile to outfile
|
||||||
//
|
//
|
||||||
// There are a few edge cases that are not handled:
|
// There are a few edge cases that are not handled:
|
||||||
// - If a file is added to an include path, that file may be included instead of
|
// - If a file is added to an include path, that file may be included instead of
|
||||||
// some other file. This would be fixed by also including lookup failures in the
|
// some other file. This would be fixed by also including lookup failures in the
|
||||||
// dependencies file, but I'm not aware of a compiler which does that.
|
// dependencies file, but I'm not aware of a compiler which does that.
|
||||||
// - The Makefile syntax that compilers output has issues, see readDepFile for
|
// - The Makefile syntax that compilers output has issues, see readDepFile for
|
||||||
// details.
|
// details.
|
||||||
// - A header file may be changed to add/remove an include. This invalidates the
|
// - A header file may be changed to add/remove an include. This invalidates the
|
||||||
// depfile but without invalidating its name. For this reason, the depfile is
|
// depfile but without invalidating its name. For this reason, the depfile is
|
||||||
// written on each new compilation (even when it seems unnecessary). However, it
|
// written on each new compilation (even when it seems unnecessary). However, it
|
||||||
// could in rare cases lead to a stale file fetched from the cache.
|
// could in rare cases lead to a stale file fetched from the cache.
|
||||||
func compileAndCacheCFile(abspath, tmpdir string, cflags []string, thinlto bool, printCommands func(string, ...string)) (string, error) {
|
func compileAndCacheCFile(abspath, tmpdir string, cflags []string, thinlto bool, printCommands func(string, ...string)) (string, error) {
|
||||||
// Hash input file.
|
// Hash input file.
|
||||||
fileHash, err := hashFile(abspath)
|
fileHash, err := hashFile(abspath)
|
||||||
|
@ -252,13 +252,14 @@ func hashFile(path string) (string, error) {
|
||||||
// file is assumed to have a single target named deps.
|
// file is assumed to have a single target named deps.
|
||||||
//
|
//
|
||||||
// There are roughly three make syntax variants:
|
// There are roughly three make syntax variants:
|
||||||
// - BSD make, which doesn't support any escaping. This means that many special
|
// - BSD make, which doesn't support any escaping. This means that many special
|
||||||
// characters are not supported in file names.
|
// characters are not supported in file names.
|
||||||
// - GNU make, which supports escaping using a backslash but when it fails to
|
// - GNU make, which supports escaping using a backslash but when it fails to
|
||||||
// find a file it tries to fall back with the literal path name (to match BSD
|
// find a file it tries to fall back with the literal path name (to match BSD
|
||||||
// make).
|
// make).
|
||||||
// - NMake (Visual Studio) and Jom, which simply quote the string if there are
|
// - NMake (Visual Studio) and Jom, which simply quote the string if there are
|
||||||
// any weird characters.
|
// any weird characters.
|
||||||
|
//
|
||||||
// Clang supports two variants: a format that's a compromise between BSD and GNU
|
// Clang supports two variants: a format that's a compromise between BSD and GNU
|
||||||
// make (and is buggy to match GCC which is equally buggy), and NMake/Jom, which
|
// make (and is buggy to match GCC which is equally buggy), and NMake/Jom, which
|
||||||
// is at least somewhat sane. This last format isn't perfect either: it does not
|
// is at least somewhat sane. This last format isn't perfect either: it does not
|
||||||
|
|
30
cgo/cgo.go
30
cgo/cgo.go
|
@ -493,15 +493,15 @@ func (p *cgoPackage) makeUnionField(typ *elaboratedTypeInfo) *ast.StructType {
|
||||||
// createUnionAccessor creates a function that returns a typed pointer to a
|
// createUnionAccessor creates a function that returns a typed pointer to a
|
||||||
// union field for each field in a union. For example:
|
// union field for each field in a union. For example:
|
||||||
//
|
//
|
||||||
// func (union *C.union_1) unionfield_d() *float64 {
|
// func (union *C.union_1) unionfield_d() *float64 {
|
||||||
// return (*float64)(unsafe.Pointer(&union.$union))
|
// return (*float64)(unsafe.Pointer(&union.$union))
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Where C.union_1 is defined as:
|
// Where C.union_1 is defined as:
|
||||||
//
|
//
|
||||||
// type C.union_1 struct{
|
// type C.union_1 struct{
|
||||||
// $union uint64
|
// $union uint64
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// The returned pointer can be used to get or set the field, or get the pointer
|
// The returned pointer can be used to get or set the field, or get the pointer
|
||||||
// to a subfield.
|
// to a subfield.
|
||||||
|
@ -617,9 +617,9 @@ func (p *cgoPackage) createUnionAccessor(field *ast.Field, typeName string) {
|
||||||
|
|
||||||
// createBitfieldGetter creates a bitfield getter function like the following:
|
// createBitfieldGetter creates a bitfield getter function like the following:
|
||||||
//
|
//
|
||||||
// func (s *C.struct_foo) bitfield_b() byte {
|
// func (s *C.struct_foo) bitfield_b() byte {
|
||||||
// return (s.__bitfield_1 >> 5) & 0x1
|
// return (s.__bitfield_1 >> 5) & 0x1
|
||||||
// }
|
// }
|
||||||
func (p *cgoPackage) createBitfieldGetter(bitfield bitfieldInfo, typeName string) {
|
func (p *cgoPackage) createBitfieldGetter(bitfield bitfieldInfo, typeName string) {
|
||||||
// The value to return from the getter.
|
// The value to return from the getter.
|
||||||
// Not complete: this is just an expression to get the complete field.
|
// Not complete: this is just an expression to get the complete field.
|
||||||
|
@ -729,15 +729,15 @@ func (p *cgoPackage) createBitfieldGetter(bitfield bitfieldInfo, typeName string
|
||||||
|
|
||||||
// createBitfieldSetter creates a bitfield setter function like the following:
|
// createBitfieldSetter creates a bitfield setter function like the following:
|
||||||
//
|
//
|
||||||
// func (s *C.struct_foo) set_bitfield_b(value byte) {
|
// func (s *C.struct_foo) set_bitfield_b(value byte) {
|
||||||
// s.__bitfield_1 = s.__bitfield_1 ^ 0x60 | ((value & 1) << 5)
|
// s.__bitfield_1 = s.__bitfield_1 ^ 0x60 | ((value & 1) << 5)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Or the following:
|
// Or the following:
|
||||||
//
|
//
|
||||||
// func (s *C.struct_foo) set_bitfield_c(value byte) {
|
// func (s *C.struct_foo) set_bitfield_c(value byte) {
|
||||||
// s.__bitfield_1 = s.__bitfield_1 & 0x3f | (value << 6)
|
// s.__bitfield_1 = s.__bitfield_1 & 0x3f | (value << 6)
|
||||||
// }
|
// }
|
||||||
func (p *cgoPackage) createBitfieldSetter(bitfield bitfieldInfo, typeName string) {
|
func (p *cgoPackage) createBitfieldSetter(bitfield bitfieldInfo, typeName string) {
|
||||||
// The full field with all bitfields.
|
// The full field with all bitfields.
|
||||||
var field ast.Expr = &ast.SelectorExpr{
|
var field ast.Expr = &ast.SelectorExpr{
|
||||||
|
|
|
@ -120,16 +120,16 @@ func (b *builder) createGo(instr *ssa.Go) {
|
||||||
// createGoroutineStartWrapper creates a wrapper for the task-based
|
// createGoroutineStartWrapper creates a wrapper for the task-based
|
||||||
// implementation of goroutines. For example, to call a function like this:
|
// implementation of goroutines. For example, to call a function like this:
|
||||||
//
|
//
|
||||||
// func add(x, y int) int { ... }
|
// func add(x, y int) int { ... }
|
||||||
//
|
//
|
||||||
// It creates a wrapper like this:
|
// It creates a wrapper like this:
|
||||||
//
|
//
|
||||||
// func add$gowrapper(ptr *unsafe.Pointer) {
|
// func add$gowrapper(ptr *unsafe.Pointer) {
|
||||||
// args := (*struct{
|
// args := (*struct{
|
||||||
// x, y int
|
// x, y int
|
||||||
// })(ptr)
|
// })(ptr)
|
||||||
// add(args.x, args.y)
|
// add(args.x, args.y)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// This is useful because the task-based goroutine start implementation only
|
// This is useful because the task-based goroutine start implementation only
|
||||||
// allows a single (pointer) argument to the newly started goroutine. Also, it
|
// allows a single (pointer) argument to the newly started goroutine. Also, it
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
// operands or return values. It is useful for trivial instructions, like wfi in
|
// operands or return values. It is useful for trivial instructions, like wfi in
|
||||||
// ARM or sleep in AVR.
|
// ARM or sleep in AVR.
|
||||||
//
|
//
|
||||||
// func Asm(asm string)
|
// func Asm(asm string)
|
||||||
//
|
//
|
||||||
// The provided assembly must be a constant.
|
// The provided assembly must be a constant.
|
||||||
func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
|
func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
|
||||||
|
@ -31,17 +31,17 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
|
||||||
// This is a compiler builtin, which allows assembly to be called in a flexible
|
// This is a compiler builtin, which allows assembly to be called in a flexible
|
||||||
// way.
|
// way.
|
||||||
//
|
//
|
||||||
// func AsmFull(asm string, regs map[string]interface{}) uintptr
|
// func AsmFull(asm string, regs map[string]interface{}) uintptr
|
||||||
//
|
//
|
||||||
// The asm parameter must be a constant string. The regs parameter must be
|
// The asm parameter must be a constant string. The regs parameter must be
|
||||||
// provided immediately. For example:
|
// provided immediately. For example:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, {result}",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1
|
// "value": 1
|
||||||
// "result": &dest,
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
|
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
|
||||||
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
|
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
|
||||||
registers := map[string]llvm.Value{}
|
registers := map[string]llvm.Value{}
|
||||||
|
@ -132,11 +132,11 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error)
|
||||||
// This is a compiler builtin which emits an inline SVCall instruction. It can
|
// This is a compiler builtin which emits an inline SVCall instruction. It can
|
||||||
// be one of:
|
// be one of:
|
||||||
//
|
//
|
||||||
// func SVCall0(num uintptr) uintptr
|
// func SVCall0(num uintptr) uintptr
|
||||||
// func SVCall1(num uintptr, a1 interface{}) uintptr
|
// func SVCall1(num uintptr, a1 interface{}) uintptr
|
||||||
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
|
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
|
||||||
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
|
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
|
||||||
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
|
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
|
||||||
//
|
//
|
||||||
// The num parameter must be a constant. All other parameters may be any scalar
|
// The num parameter must be a constant. All other parameters may be any scalar
|
||||||
// value supported by LLVM inline assembly.
|
// value supported by LLVM inline assembly.
|
||||||
|
@ -169,11 +169,11 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
|
||||||
// This is a compiler builtin which emits an inline SVCall instruction. It can
|
// This is a compiler builtin which emits an inline SVCall instruction. It can
|
||||||
// be one of:
|
// be one of:
|
||||||
//
|
//
|
||||||
// func SVCall0(num uintptr) uintptr
|
// func SVCall0(num uintptr) uintptr
|
||||||
// func SVCall1(num uintptr, a1 interface{}) uintptr
|
// func SVCall1(num uintptr, a1 interface{}) uintptr
|
||||||
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
|
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
|
||||||
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
|
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
|
||||||
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
|
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
|
||||||
//
|
//
|
||||||
// The num parameter must be a constant. All other parameters may be any scalar
|
// The num parameter must be a constant. All other parameters may be any scalar
|
||||||
// value supported by LLVM inline assembly.
|
// value supported by LLVM inline assembly.
|
||||||
|
@ -206,10 +206,10 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) {
|
||||||
|
|
||||||
// This is a compiler builtin which emits CSR instructions. It can be one of:
|
// This is a compiler builtin which emits CSR instructions. It can be one of:
|
||||||
//
|
//
|
||||||
// func (csr CSR) Get() uintptr
|
// func (csr CSR) Get() uintptr
|
||||||
// func (csr CSR) Set(uintptr)
|
// func (csr CSR) Set(uintptr)
|
||||||
// func (csr CSR) SetBits(uintptr) uintptr
|
// func (csr CSR) SetBits(uintptr) uintptr
|
||||||
// func (csr CSR) ClearBits(uintptr) uintptr
|
// func (csr CSR) ClearBits(uintptr) uintptr
|
||||||
//
|
//
|
||||||
// The csr parameter (method receiver) must be a constant. Other parameter can
|
// The csr parameter (method receiver) must be a constant. Other parameter can
|
||||||
// be any value.
|
// be any value.
|
||||||
|
|
|
@ -550,8 +550,8 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv
|
||||||
// internally to match interfaces and to call the correct method on an
|
// internally to match interfaces and to call the correct method on an
|
||||||
// interface. Examples:
|
// interface. Examples:
|
||||||
//
|
//
|
||||||
// String() string
|
// String() string
|
||||||
// Read([]byte) (int, error)
|
// Read([]byte) (int, error)
|
||||||
func methodSignature(method *types.Func) string {
|
func methodSignature(method *types.Func) string {
|
||||||
return method.Name() + signature(method.Type().(*types.Signature))
|
return method.Name() + signature(method.Type().(*types.Signature))
|
||||||
}
|
}
|
||||||
|
@ -559,8 +559,8 @@ func methodSignature(method *types.Func) string {
|
||||||
// Make a readable version of a function (pointer) signature.
|
// Make a readable version of a function (pointer) signature.
|
||||||
// Examples:
|
// Examples:
|
||||||
//
|
//
|
||||||
// () string
|
// () string
|
||||||
// (string, int) (int, error)
|
// (string, int) (int, error)
|
||||||
func signature(sig *types.Signature) string {
|
func signature(sig *types.Signature) string {
|
||||||
s := ""
|
s := ""
|
||||||
if sig.Params().Len() == 0 {
|
if sig.Params().Len() == 0 {
|
||||||
|
|
10
compiler/testdata/pragma.go
предоставленный
10
compiler/testdata/pragma.go
предоставленный
|
@ -3,44 +3,53 @@ package main
|
||||||
import _ "unsafe"
|
import _ "unsafe"
|
||||||
|
|
||||||
// Creates an external global with name extern_global.
|
// Creates an external global with name extern_global.
|
||||||
|
//
|
||||||
//go:extern extern_global
|
//go:extern extern_global
|
||||||
var externGlobal [0]byte
|
var externGlobal [0]byte
|
||||||
|
|
||||||
// Creates a
|
// Creates a
|
||||||
|
//
|
||||||
//go:align 32
|
//go:align 32
|
||||||
var alignedGlobal [4]uint32
|
var alignedGlobal [4]uint32
|
||||||
|
|
||||||
// Test conflicting pragmas (the last one counts).
|
// Test conflicting pragmas (the last one counts).
|
||||||
|
//
|
||||||
//go:align 64
|
//go:align 64
|
||||||
//go:align 16
|
//go:align 16
|
||||||
var alignedGlobal16 [4]uint32
|
var alignedGlobal16 [4]uint32
|
||||||
|
|
||||||
// Test exported functions.
|
// Test exported functions.
|
||||||
|
//
|
||||||
//export extern_func
|
//export extern_func
|
||||||
func externFunc() {
|
func externFunc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define a function in a different package using go:linkname.
|
// Define a function in a different package using go:linkname.
|
||||||
|
//
|
||||||
//go:linkname withLinkageName1 somepkg.someFunction1
|
//go:linkname withLinkageName1 somepkg.someFunction1
|
||||||
func withLinkageName1() {
|
func withLinkageName1() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import a function from a different package using go:linkname.
|
// Import a function from a different package using go:linkname.
|
||||||
|
//
|
||||||
//go:linkname withLinkageName2 somepkg.someFunction2
|
//go:linkname withLinkageName2 somepkg.someFunction2
|
||||||
func withLinkageName2()
|
func withLinkageName2()
|
||||||
|
|
||||||
// Function has an 'inline hint', similar to the inline keyword in C.
|
// Function has an 'inline hint', similar to the inline keyword in C.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func inlineFunc() {
|
func inlineFunc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function should never be inlined, equivalent to GCC
|
// Function should never be inlined, equivalent to GCC
|
||||||
// __attribute__((noinline)).
|
// __attribute__((noinline)).
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func noinlineFunc() {
|
func noinlineFunc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function should have the specified section.
|
// This function should have the specified section.
|
||||||
|
//
|
||||||
//go:section .special_function_section
|
//go:section .special_function_section
|
||||||
func functionInSection() {
|
func functionInSection() {
|
||||||
}
|
}
|
||||||
|
@ -51,6 +60,7 @@ func exportedFunctionInSection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function should not: it's only a declaration and not a definition.
|
// This function should not: it's only a declaration and not a definition.
|
||||||
|
//
|
||||||
//go:section .special_function_section
|
//go:section .special_function_section
|
||||||
func undefinedFunctionNotInSection()
|
func undefinedFunctionNotInSection()
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,6 @@ func (r *reader) Read(b []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// void arc4random_buf(void *buf, size_t buflen);
|
// void arc4random_buf(void *buf, size_t buflen);
|
||||||
|
//
|
||||||
//export arc4random_buf
|
//export arc4random_buf
|
||||||
func libc_arc4random_buf(buf unsafe.Pointer, buflen uint)
|
func libc_arc4random_buf(buf unsafe.Pointer, buflen uint)
|
||||||
|
|
|
@ -38,5 +38,6 @@ func (r *reader) Read(b []byte) (n int, err error) {
|
||||||
// Cryptographically secure random number generator.
|
// Cryptographically secure random number generator.
|
||||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170
|
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170
|
||||||
// errno_t rand_s(unsigned int* randomValue);
|
// errno_t rand_s(unsigned int* randomValue);
|
||||||
|
//
|
||||||
//export rand_s
|
//export rand_s
|
||||||
func libc_rand_s(randomValue *uint32) int32
|
func libc_rand_s(randomValue *uint32) int32
|
||||||
|
|
|
@ -2,31 +2,31 @@
|
||||||
//
|
//
|
||||||
// Original copyright:
|
// Original copyright:
|
||||||
//
|
//
|
||||||
// Copyright (c) 2009 - 2015 ARM LIMITED
|
// Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
// modification, are permitted provided that the following conditions are met:
|
||||||
// - Redistributions of source code must retain the above copyright
|
// - Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
// - Redistributions in binary form must reproduce the above copyright
|
// - Redistributions in binary form must reproduce the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer in the
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
// documentation and/or other materials provided with the distribution.
|
// documentation and/or other materials provided with the distribution.
|
||||||
// - Neither the name of ARM nor the names of its contributors may be used
|
// - Neither the name of ARM nor the names of its contributors may be used
|
||||||
// to endorse or promote products derived from this software without
|
// to endorse or promote products derived from this software without
|
||||||
// specific prior written permission.
|
// specific prior written permission.
|
||||||
//
|
//
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
// ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
package arm
|
package arm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -46,12 +46,12 @@ func Asm(asm string)
|
||||||
// effects, as it would otherwise be optimized away. The inline assembly string
|
// effects, as it would otherwise be optimized away. The inline assembly string
|
||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, {result}",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1
|
// "value": 1
|
||||||
// "result": &dest,
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
// return value.
|
// return value.
|
||||||
|
|
|
@ -60,5 +60,6 @@ const (
|
||||||
|
|
||||||
// Call a semihosting function.
|
// Call a semihosting function.
|
||||||
// TODO: implement it here using inline assembly.
|
// TODO: implement it here using inline assembly.
|
||||||
|
//
|
||||||
//go:linkname SemihostingCall SemihostingCall
|
//go:linkname SemihostingCall SemihostingCall
|
||||||
func SemihostingCall(num int, arg uintptr) int
|
func SemihostingCall(num int, arg uintptr) int
|
||||||
|
|
|
@ -9,12 +9,12 @@ func Asm(asm string)
|
||||||
// effects, as it would otherwise be optimized away. The inline assembly string
|
// effects, as it would otherwise be optimized away. The inline assembly string
|
||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, {result}",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1
|
// "value": 1
|
||||||
// "result": &dest,
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
// return value.
|
// return value.
|
||||||
|
|
|
@ -9,12 +9,12 @@ func Asm(asm string)
|
||||||
// effects, as it would otherwise be optimized away. The inline assembly string
|
// effects, as it would otherwise be optimized away. The inline assembly string
|
||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "str {value}, {result}",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1
|
// "value": 1
|
||||||
// "result": &dest,
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
// return value.
|
// return value.
|
||||||
|
|
|
@ -9,12 +9,12 @@ func Asm(asm string)
|
||||||
// effects, as it would otherwise be optimized away. The inline assembly string
|
// effects, as it would otherwise be optimized away. The inline assembly string
|
||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// avr.AsmFull(
|
// avr.AsmFull(
|
||||||
// "str {value}, {result}",
|
// "str {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1
|
// "value": 1
|
||||||
// "result": &dest,
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
// return value.
|
// return value.
|
||||||
|
|
|
@ -9,12 +9,12 @@ func Asm(asm string)
|
||||||
// effects, as it would otherwise be optimized away. The inline assembly string
|
// effects, as it would otherwise be optimized away. The inline assembly string
|
||||||
// recognizes template values in the form {name}, like so:
|
// recognizes template values in the form {name}, like so:
|
||||||
//
|
//
|
||||||
// arm.AsmFull(
|
// arm.AsmFull(
|
||||||
// "st {value}, {result}",
|
// "st {value}, {result}",
|
||||||
// map[string]interface{}{
|
// map[string]interface{}{
|
||||||
// "value": 1
|
// "value": 1
|
||||||
// "result": &dest,
|
// "result": &dest,
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// You can use {} in the asm string (which expands to a register) to set the
|
// You can use {} in the asm string (which expands to a register) to set the
|
||||||
// return value.
|
// return value.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Example using the i2s hardware interface on the Adafruit Circuit Playground Express
|
// Example using the i2s hardware interface on the Adafruit Circuit Playground Express
|
||||||
// to read data from the onboard MEMS microphone.
|
// to read data from the onboard MEMS microphone.
|
||||||
//
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -89,6 +89,7 @@ func swapTask(oldStack uintptr, newStack *uintptr)
|
||||||
// startTask is a small wrapper function that sets up the first (and only)
|
// startTask is a small wrapper function that sets up the first (and only)
|
||||||
// argument to the new goroutine and makes sure it is exited when the goroutine
|
// argument to the new goroutine and makes sure it is exited when the goroutine
|
||||||
// finishes.
|
// finishes.
|
||||||
|
//
|
||||||
//go:extern tinygo_startTask
|
//go:extern tinygo_startTask
|
||||||
var startTask [0]uint8
|
var startTask [0]uint8
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ type calleeSavedRegs struct {
|
||||||
|
|
||||||
// archInit runs architecture-specific setup for the goroutine startup.
|
// archInit runs architecture-specific setup for the goroutine startup.
|
||||||
// Note: adding //go:noinline to work around an AVR backend bug.
|
// Note: adding //go:noinline to work around an AVR backend bug.
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func (s *state) archInit(r *calleeSavedRegs, fn uintptr, args unsafe.Pointer) {
|
func (s *state) archInit(r *calleeSavedRegs, fn uintptr, args unsafe.Pointer) {
|
||||||
// Store the initial sp for the startTask function (implemented in assembly).
|
// Store the initial sp for the startTask function (implemented in assembly).
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
// This contains the pin mappings for the Arduino MKR1000 board.
|
// This contains the pin mappings for the Arduino MKR1000 board.
|
||||||
//
|
//
|
||||||
// For more information, see: https://store.arduino.cc/usa/arduino-mkr1000-with-headers-mounted
|
// For more information, see: https://store.arduino.cc/usa/arduino-mkr1000-with-headers-mounted
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
// This contains the pin mappings for the Arduino MKR WiFi 1010 board.
|
// This contains the pin mappings for the Arduino MKR WiFi 1010 board.
|
||||||
//
|
//
|
||||||
// For more information, see: https://store.arduino.cc/usa/mkr-wifi-1010
|
// For more information, see: https://store.arduino.cc/usa/mkr-wifi-1010
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
// This contains the pin mappings for the Arduino Nano33 IoT board.
|
// This contains the pin mappings for the Arduino Nano33 IoT board.
|
||||||
//
|
//
|
||||||
// For more information, see: https://store.arduino.cc/nano-33-iot
|
// For more information, see: https://store.arduino.cc/nano-33-iot
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
// For more information, see: https://shop.pimoroni.com/products/badger-2040
|
// For more information, see: https://shop.pimoroni.com/products/badger-2040
|
||||||
// Also
|
// Also
|
||||||
// - Badger 2040 schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/badger_2040_schematic.pdf?v=1645702148
|
// - Badger 2040 schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/badger_2040_schematic.pdf?v=1645702148
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -58,14 +57,15 @@ const (
|
||||||
|
|
||||||
// QSPI pins¿?
|
// QSPI pins¿?
|
||||||
const (
|
const (
|
||||||
/* TODO
|
/*
|
||||||
|
TODO
|
||||||
|
|
||||||
SPI0_SD0_PIN Pin = QSPI_SD0
|
SPI0_SD0_PIN Pin = QSPI_SD0
|
||||||
SPI0_SD1_PIN Pin = QSPI_SD1
|
SPI0_SD1_PIN Pin = QSPI_SD1
|
||||||
SPI0_SD2_PIN Pin = QSPI_SD2
|
SPI0_SD2_PIN Pin = QSPI_SD2
|
||||||
SPI0_SD3_PIN Pin = QSPI_SD3
|
SPI0_SD3_PIN Pin = QSPI_SD3
|
||||||
SPI0_SCK_PIN Pin = QSPI_SCLKGPIO6
|
SPI0_SCK_PIN Pin = QSPI_SCLKGPIO6
|
||||||
SPI0_CS_PIN Pin = QSPI_CS
|
SPI0_CS_PIN Pin = QSPI_CS
|
||||||
|
|
||||||
*/
|
*/
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
//
|
//
|
||||||
// Special version of bossac is required.
|
// Special version of bossac is required.
|
||||||
// This executable can be obtained two ways:
|
// This executable can be obtained two ways:
|
||||||
// 1) In Arduino IDE, install support for the board ("Arduino Mbed OS Nano Boards")
|
// 1. In Arduino IDE, install support for the board ("Arduino Mbed OS Nano Boards")
|
||||||
// Search for "tools/bossac/1.9.1-arduino2/bossac" in Arduino IDEs directory
|
// Search for "tools/bossac/1.9.1-arduino2/bossac" in Arduino IDEs directory
|
||||||
// 2) Download https://downloads.arduino.cc/packages/package_index.json
|
// 2. Download https://downloads.arduino.cc/packages/package_index.json
|
||||||
// Search for "bossac-1.9.1-arduino2" in that file
|
// Search for "bossac-1.9.1-arduino2" in that file
|
||||||
// Download tarball for your OS and unpack it
|
// Download tarball for your OS and unpack it
|
||||||
//
|
//
|
||||||
// Once you have the executable, make it accessible in your PATH as "bossac_arduino2".
|
// Once you have the executable, make it accessible in your PATH as "bossac_arduino2".
|
||||||
//
|
//
|
||||||
|
@ -29,7 +29,6 @@
|
||||||
//
|
//
|
||||||
// SoftDevice overwrites original bootloader and flashing method described above is not avalable anymore.
|
// SoftDevice overwrites original bootloader and flashing method described above is not avalable anymore.
|
||||||
// Instead, please use debug probe and flash your code with "nano-33-ble-s140v7" target.
|
// Instead, please use debug probe and flash your code with "nano-33-ble-s140v7" target.
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
const HasLowFrequencyCrystal = true
|
const HasLowFrequencyCrystal = true
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
// Also
|
// Also
|
||||||
// - Datasheets: https://docs.arduino.cc/hardware/nano-rp2040-connect
|
// - Datasheets: https://docs.arduino.cc/hardware/nano-rp2040-connect
|
||||||
// - Nano RP2040 Connect technical reference: https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference
|
// - Nano RP2040 Connect technical reference: https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
// This contains the pin mappings for the ProductivityOpen P1AM-100 board.
|
// This contains the pin mappings for the ProductivityOpen P1AM-100 board.
|
||||||
//
|
//
|
||||||
// For more information, see: https://facts-engineering.github.io/
|
// For more information, see: https://facts-engineering.github.io/
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
//
|
//
|
||||||
// - https://wiki.seeedstudio.com/XIAO_BLE/
|
// - https://wiki.seeedstudio.com/XIAO_BLE/
|
||||||
// - https://github.com/Seeed-Studio/ArduinoCore-mbed/tree/master/variants/SEEED_XIAO_NRF52840_SENSE
|
// - https://github.com/Seeed-Studio/ArduinoCore-mbed/tree/master/variants/SEEED_XIAO_NRF52840_SENSE
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
const HasLowFrequencyCrystal = true
|
const HasLowFrequencyCrystal = true
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
// XIAO RP2040 is a microcontroller using the Raspberry Pi RP2040 chip.
|
// XIAO RP2040 is a microcontroller using the Raspberry Pi RP2040 chip.
|
||||||
//
|
//
|
||||||
// - https://wiki.seeedstudio.com/XIAO-RP2040/
|
// - https://wiki.seeedstudio.com/XIAO-RP2040/
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -264,7 +264,7 @@ func (pwm PWM) Configure(config PWMConfig) error {
|
||||||
// SetPeriod updates the period of this PWM peripheral.
|
// SetPeriod updates the period of this PWM peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// If you use a period of 0, a period that works well for LEDs will be picked.
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
//
|
//
|
||||||
|
@ -694,7 +694,7 @@ func (pwm PWM) SetInverting(channel uint8, inverting bool) {
|
||||||
// cycle, in other words the fraction of time the channel output is high (or low
|
// cycle, in other words the fraction of time the channel output is high (or low
|
||||||
// when inverted). For example, to set it to a 25% duty cycle, use:
|
// when inverted). For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// pwm.Set(channel, pwm.Top() / 4)
|
// pwm.Set(channel, pwm.Top() / 4)
|
||||||
//
|
//
|
||||||
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
|
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
|
||||||
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
|
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
|
||||||
|
|
|
@ -134,7 +134,7 @@ func (pwm PWM) Configure(config PWMConfig) error {
|
||||||
// SetPeriod updates the period of this PWM peripheral.
|
// SetPeriod updates the period of this PWM peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// If you use a period of 0, a period that works well for LEDs will be picked.
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
//
|
//
|
||||||
|
@ -375,7 +375,7 @@ func (pwm PWM) SetInverting(channel uint8, inverting bool) {
|
||||||
// cycle, in other words the fraction of time the channel output is high (or low
|
// cycle, in other words the fraction of time the channel output is high (or low
|
||||||
// when inverted). For example, to set it to a 25% duty cycle, use:
|
// when inverted). For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// pwm.Set(channel, pwm.Top() / 4)
|
// pwm.Set(channel, pwm.Top() / 4)
|
||||||
//
|
//
|
||||||
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
|
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
|
||||||
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
|
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -88,10 +87,11 @@ const (
|
||||||
// SERCOM and SERCOM-ALT.
|
// SERCOM and SERCOM-ALT.
|
||||||
//
|
//
|
||||||
// Observations:
|
// Observations:
|
||||||
// * There are six SERCOMs. Those SERCOM numbers can be encoded in 3 bits.
|
// - There are six SERCOMs. Those SERCOM numbers can be encoded in 3 bits.
|
||||||
// * Even pad numbers are always on even pins, and odd pad numbers are always on
|
// - Even pad numbers are always on even pins, and odd pad numbers are always on
|
||||||
// odd pins.
|
// odd pins.
|
||||||
// * Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
|
// - Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
|
||||||
|
//
|
||||||
// With this information, we can encode SERCOM pin/pad numbers much more
|
// With this information, we can encode SERCOM pin/pad numbers much more
|
||||||
// efficiently. First of all, due to pads coming in pairs, we can ignore half
|
// efficiently. First of all, due to pads coming in pairs, we can ignore half
|
||||||
// the pins: the information for an odd pin can be calculated easily from the
|
// the pins: the information for an odd pin can be calculated easily from the
|
||||||
|
@ -1285,17 +1285,16 @@ var (
|
||||||
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
||||||
// Note that the tx and rx buffers must be the same size:
|
// Note that the tx and rx buffers must be the same size:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, rx)
|
// spi.Tx(tx, rx)
|
||||||
//
|
//
|
||||||
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
||||||
// until all the bytes in the command packet have been received:
|
// until all the bytes in the command packet have been received:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, nil)
|
// spi.Tx(tx, nil)
|
||||||
//
|
//
|
||||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||||
//
|
//
|
||||||
// spi.Tx(nil, rx)
|
// spi.Tx(nil, rx)
|
||||||
//
|
|
||||||
func (spi SPI) Tx(w, r []byte) error {
|
func (spi SPI) Tx(w, r []byte) error {
|
||||||
switch {
|
switch {
|
||||||
case w == nil:
|
case w == nil:
|
||||||
|
@ -1441,7 +1440,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
|
||||||
// SetPeriod updates the period of this TCC peripheral.
|
// SetPeriod updates the period of this TCC peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// If you use a period of 0, a period that works well for LEDs will be picked.
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
//
|
//
|
||||||
|
@ -1709,7 +1708,7 @@ func (tcc *TCC) SetInverting(channel uint8, inverting bool) {
|
||||||
// cycle, in other words the fraction of time the channel output is high (or low
|
// cycle, in other words the fraction of time the channel output is high (or low
|
||||||
// when inverted). For example, to set it to a 25% duty cycle, use:
|
// when inverted). For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// tcc.Set(channel, tcc.Top() / 4)
|
// tcc.Set(channel, tcc.Top() / 4)
|
||||||
//
|
//
|
||||||
// tcc.Set(channel, 0) will set the output to low and tcc.Set(channel,
|
// tcc.Set(channel, 0) will set the output to low and tcc.Set(channel,
|
||||||
// tcc.Top()) will set the output to high, assuming the output isn't inverted.
|
// tcc.Top()) will set the output to high, assuming the output isn't inverted.
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -250,12 +249,13 @@ const (
|
||||||
// SERCOM and SERCOM-ALT.
|
// SERCOM and SERCOM-ALT.
|
||||||
//
|
//
|
||||||
// Observations:
|
// Observations:
|
||||||
// * There are eight SERCOMs. Those SERCOM numbers can be encoded in 4 bits.
|
// - There are eight SERCOMs. Those SERCOM numbers can be encoded in 4 bits.
|
||||||
// * Even pad numbers are usually on even pins, and odd pad numbers are usually
|
// - Even pad numbers are usually on even pins, and odd pad numbers are usually
|
||||||
// on odd pins. The exception is SERCOM-ALT, which sometimes swaps pad 0 and 1.
|
// on odd pins. The exception is SERCOM-ALT, which sometimes swaps pad 0 and 1.
|
||||||
// With that, there is still an invariant that the pad number for an odd pin is
|
// With that, there is still an invariant that the pad number for an odd pin is
|
||||||
// the pad number for the corresponding even pin with the low bit toggled.
|
// the pad number for the corresponding even pin with the low bit toggled.
|
||||||
// * Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
|
// - Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
|
||||||
|
//
|
||||||
// With this information, we can encode SERCOM pin/pad numbers much more
|
// With this information, we can encode SERCOM pin/pad numbers much more
|
||||||
// efficiently. Due to pads coming in pairs, we can ignore half the pins: the
|
// efficiently. Due to pads coming in pairs, we can ignore half the pins: the
|
||||||
// information for an odd pin can be calculated easily from the preceding even
|
// information for an odd pin can be calculated easily from the preceding even
|
||||||
|
@ -1538,17 +1538,16 @@ var (
|
||||||
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
||||||
// Note that the tx and rx buffers must be the same size:
|
// Note that the tx and rx buffers must be the same size:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, rx)
|
// spi.Tx(tx, rx)
|
||||||
//
|
//
|
||||||
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
||||||
// until all the bytes in the command packet have been received:
|
// until all the bytes in the command packet have been received:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, nil)
|
// spi.Tx(tx, nil)
|
||||||
//
|
//
|
||||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||||
//
|
//
|
||||||
// spi.Tx(nil, rx)
|
// spi.Tx(nil, rx)
|
||||||
//
|
|
||||||
func (spi SPI) Tx(w, r []byte) error {
|
func (spi SPI) Tx(w, r []byte) error {
|
||||||
switch {
|
switch {
|
||||||
case w == nil:
|
case w == nil:
|
||||||
|
@ -1672,7 +1671,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
|
||||||
// SetPeriod updates the period of this TCC peripheral.
|
// SetPeriod updates the period of this TCC peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// If you use a period of 0, a period that works well for LEDs will be picked.
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
//
|
//
|
||||||
|
@ -1962,7 +1961,7 @@ func (tcc *TCC) SetInverting(channel uint8, inverting bool) {
|
||||||
// cycle, in other words the fraction of time the channel output is high (or low
|
// cycle, in other words the fraction of time the channel output is high (or low
|
||||||
// when inverted). For example, to set it to a 25% duty cycle, use:
|
// when inverted). For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// tcc.Set(channel, tcc.Top() / 4)
|
// tcc.Set(channel, tcc.Top() / 4)
|
||||||
//
|
//
|
||||||
// tcc.Set(channel, 0) will set the output to low and tcc.Set(channel,
|
// tcc.Set(channel, 0) will set the output to low and tcc.Set(channel,
|
||||||
// tcc.Top()) will set the output to high, assuming the output isn't inverted.
|
// tcc.Top()) will set the output to high, assuming the output isn't inverted.
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
|
||||||
//
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
import "device/sam"
|
import "device/sam"
|
||||||
|
|
|
@ -462,7 +462,6 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||||
// interface, there must always be the same number of bytes written as bytes read.
|
// interface, there must always be the same number of bytes written as bytes read.
|
||||||
// This is accomplished by sending zero bits if r is bigger than w or discarding
|
// This is accomplished by sending zero bits if r is bigger than w or discarding
|
||||||
// the incoming data if w is bigger than r.
|
// the incoming data if w is bigger than r.
|
||||||
//
|
|
||||||
func (spi SPI) Tx(w, r []byte) error {
|
func (spi SPI) Tx(w, r []byte) error {
|
||||||
toTransfer := len(w)
|
toTransfer := len(w)
|
||||||
if len(r) > toTransfer {
|
if len(r) > toTransfer {
|
||||||
|
|
|
@ -726,7 +726,7 @@ func (p Pin) getPad() (pad *volatile.Register32, mux *volatile.Register32) {
|
||||||
//
|
//
|
||||||
// The reference manual refers to this functionality as a "Daisy Chain". The
|
// The reference manual refers to this functionality as a "Daisy Chain". The
|
||||||
// associated docs are found in the i.MX RT1060 Processor Reference Manual:
|
// associated docs are found in the i.MX RT1060 Processor Reference Manual:
|
||||||
// "Chapter 11.3.3 Daisy chain - multi pads driving same module input pin"
|
// "Chapter 11.3.3 Daisy chain - multi pads driving same module input pin"
|
||||||
type muxSelect struct {
|
type muxSelect struct {
|
||||||
mux uint8 // AF mux selection (NOT a Pin type)
|
mux uint8 // AF mux selection (NOT a Pin type)
|
||||||
sel *volatile.Register32 // AF selection register
|
sel *volatile.Register32 // AF selection register
|
||||||
|
|
|
@ -204,7 +204,8 @@ func (spi *SPI) hasHardwareCSPin() bool {
|
||||||
// getClockDivisor finds the SPI prescalar that minimizes the error between
|
// getClockDivisor finds the SPI prescalar that minimizes the error between
|
||||||
// requested frequency and possible frequencies available with the LPSPI clock.
|
// requested frequency and possible frequencies available with the LPSPI clock.
|
||||||
// this routine is based on Teensyduino (libraries/SPI/SPI.cpp):
|
// this routine is based on Teensyduino (libraries/SPI/SPI.cpp):
|
||||||
// `void SPIClass::setClockDivider_noInline(uint32_t clk)`
|
//
|
||||||
|
// void SPIClass::setClockDivider_noInline(uint32_t clk)
|
||||||
func (spi *SPI) getClockDivisor(freq uint32) uint32 {
|
func (spi *SPI) getClockDivisor(freq uint32) uint32 {
|
||||||
const clock = 132000000 // LPSPI root clock frequency (PLL2)
|
const clock = 132000000 // LPSPI root clock frequency (PLL2)
|
||||||
d := uint32(clock)
|
d := uint32(clock)
|
||||||
|
|
|
@ -188,8 +188,10 @@ func (uart *UART) WriteByte(c byte) error {
|
||||||
//
|
//
|
||||||
// This is an integral (non-floating point) translation of the logic at the
|
// This is an integral (non-floating point) translation of the logic at the
|
||||||
// beginning of:
|
// beginning of:
|
||||||
// void HardwareSerial::begin(uint32_t baud, uint16_t format)
|
//
|
||||||
// (from Teensyduino: `cores/teensy4/HardwareSerial.cpp`)
|
// void HardwareSerial::begin(uint32_t baud, uint16_t format)
|
||||||
|
//
|
||||||
|
// (from Teensyduino: cores/teensy4/HardwareSerial.cpp)
|
||||||
//
|
//
|
||||||
// We don't want to use floating point here in case it gets called from an ISR
|
// We don't want to use floating point here in case it gets called from an ISR
|
||||||
// or very early during system init.
|
// or very early during system init.
|
||||||
|
|
|
@ -133,17 +133,16 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||||
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
||||||
// Note that the tx and rx buffers must be the same size:
|
// Note that the tx and rx buffers must be the same size:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, rx)
|
// spi.Tx(tx, rx)
|
||||||
//
|
//
|
||||||
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
||||||
// until all the bytes in the command packet have been received:
|
// until all the bytes in the command packet have been received:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, nil)
|
// spi.Tx(tx, nil)
|
||||||
//
|
//
|
||||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||||
//
|
//
|
||||||
// spi.Tx(nil, rx)
|
// spi.Tx(nil, rx)
|
||||||
//
|
|
||||||
func (spi SPI) Tx(w, r []byte) error {
|
func (spi SPI) Tx(w, r []byte) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,7 @@ func (pwm *PWM) Configure(config PWMConfig) error {
|
||||||
// SetPeriod updates the period of this PWM peripheral.
|
// SetPeriod updates the period of this PWM peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// If you use a period of 0, a period that works well for LEDs will be picked.
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
//
|
//
|
||||||
|
@ -449,7 +449,7 @@ func (pwm *PWM) SetInverting(channel uint8, inverting bool) {
|
||||||
// Set updates the channel value. This is used to control the channel duty
|
// Set updates the channel value. This is used to control the channel duty
|
||||||
// cycle. For example, to set it to a 25% duty cycle, use:
|
// cycle. For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// ch.Set(ch.Top() / 4)
|
// ch.Set(ch.Top() / 4)
|
||||||
//
|
//
|
||||||
// ch.Set(0) will set the output to low and ch.Set(ch.Top()) will set the output
|
// ch.Set(0) will set the output to low and ch.Set(ch.Top()) will set the output
|
||||||
// to high, assuming the output isn't inverted.
|
// to high, assuming the output isn't inverted.
|
||||||
|
|
|
@ -66,10 +66,12 @@ var (
|
||||||
// Passing a nil value for w or r skips the transfer corresponding to write
|
// Passing a nil value for w or r skips the transfer corresponding to write
|
||||||
// or read, respectively.
|
// or read, respectively.
|
||||||
//
|
//
|
||||||
// i2c.Tx(addr, nil, r)
|
// i2c.Tx(addr, nil, r)
|
||||||
|
//
|
||||||
// Performs only a read transfer.
|
// Performs only a read transfer.
|
||||||
//
|
//
|
||||||
// i2c.Tx(addr, w, nil)
|
// i2c.Tx(addr, w, nil)
|
||||||
|
//
|
||||||
// Performs only a write transfer.
|
// Performs only a write transfer.
|
||||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||||
// timeout in microseconds.
|
// timeout in microseconds.
|
||||||
|
@ -79,11 +81,14 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||||
|
|
||||||
// Configure initializes i2c peripheral and configures I2C config's pins passed.
|
// Configure initializes i2c peripheral and configures I2C config's pins passed.
|
||||||
// Here's a list of valid SDA and SCL GPIO pins on bus I2C0 of the rp2040:
|
// Here's a list of valid SDA and SCL GPIO pins on bus I2C0 of the rp2040:
|
||||||
// SDA: 0, 4, 8, 12, 16, 20
|
//
|
||||||
// SCL: 1, 5, 9, 13, 17, 21
|
// SDA: 0, 4, 8, 12, 16, 20
|
||||||
|
// SCL: 1, 5, 9, 13, 17, 21
|
||||||
|
//
|
||||||
// Same as above for I2C1 bus:
|
// Same as above for I2C1 bus:
|
||||||
// SDA: 2, 6, 10, 14, 18, 26
|
//
|
||||||
// SCL: 3, 7, 11, 15, 19, 27
|
// SDA: 2, 6, 10, 14, 18, 26
|
||||||
|
// SCL: 3, 7, 11, 15, 19, 27
|
||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
const defaultBaud uint32 = 100_000 // 100kHz standard mode
|
const defaultBaud uint32 = 100_000 // 100kHz standard mode
|
||||||
if config.SCL == 0 {
|
if config.SCL == 0 {
|
||||||
|
@ -107,6 +112,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
|
|
||||||
// SetBaudRate sets the I2C frequency. It has the side effect of also
|
// SetBaudRate sets the I2C frequency. It has the side effect of also
|
||||||
// enabling the I2C hardware if disabled beforehand.
|
// enabling the I2C hardware if disabled beforehand.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) SetBaudRate(br uint32) error {
|
func (i2c *I2C) SetBaudRate(br uint32) error {
|
||||||
|
|
||||||
|
@ -168,6 +174,7 @@ func (i2c *I2C) enable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implemented as per 4.3.10.3. Disabling DW_apb_i2c section.
|
// Implemented as per 4.3.10.3. Disabling DW_apb_i2c section.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) disable() error {
|
func (i2c *I2C) disable() error {
|
||||||
const MAX_T_POLL_COUNT = 64 // 64 us timeout corresponds to around 1000kb/s i2c transfer rate.
|
const MAX_T_POLL_COUNT = 64 // 64 us timeout corresponds to around 1000kb/s i2c transfer rate.
|
||||||
|
@ -203,6 +210,7 @@ func (i2c *I2C) init(config I2CConfig) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset sets I2C register RESET bits in the reset peripheral and then clears them.
|
// reset sets I2C register RESET bits in the reset peripheral and then clears them.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) reset() {
|
func (i2c *I2C) reset() {
|
||||||
resetVal := i2c.deinit()
|
resetVal := i2c.deinit()
|
||||||
|
@ -213,6 +221,7 @@ func (i2c *I2C) reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// deinit sets reset bit for I2C. Must call reset to reenable I2C after deinit.
|
// deinit sets reset bit for I2C. Must call reset to reenable I2C after deinit.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) deinit() (resetVal uint32) {
|
func (i2c *I2C) deinit() (resetVal uint32) {
|
||||||
switch {
|
switch {
|
||||||
|
@ -348,18 +357,21 @@ func (i2c *I2C) tx(addr uint8, tx, rx []byte, timeout_us uint64) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeAvailable determines non-blocking write space available
|
// writeAvailable determines non-blocking write space available
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) writeAvailable() uint32 {
|
func (i2c *I2C) writeAvailable() uint32 {
|
||||||
return rp.I2C0_IC_COMP_PARAM_1_TX_BUFFER_DEPTH_Pos - i2c.Bus.IC_TXFLR.Get()
|
return rp.I2C0_IC_COMP_PARAM_1_TX_BUFFER_DEPTH_Pos - i2c.Bus.IC_TXFLR.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
// readAvailable determines number of bytes received
|
// readAvailable determines number of bytes received
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) readAvailable() uint32 {
|
func (i2c *I2C) readAvailable() uint32 {
|
||||||
return i2c.Bus.IC_RXFLR.Get()
|
return i2c.Bus.IC_RXFLR.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equivalent to IC_CLR_TX_ABRT.Get() (side effect clears ABORT_REASON)
|
// Equivalent to IC_CLR_TX_ABRT.Get() (side effect clears ABORT_REASON)
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) clearAbortReason() {
|
func (i2c *I2C) clearAbortReason() {
|
||||||
// Note clearing the abort flag also clears the reason, and
|
// Note clearing the abort flag also clears the reason, and
|
||||||
|
@ -369,13 +381,16 @@ func (i2c *I2C) clearAbortReason() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAbortReason reads IC_TX_ABRT_SOURCE register.
|
// getAbortReason reads IC_TX_ABRT_SOURCE register.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) getAbortReason() uint32 {
|
func (i2c *I2C) getAbortReason() uint32 {
|
||||||
return i2c.Bus.IC_TX_ABRT_SOURCE.Get()
|
return i2c.Bus.IC_TX_ABRT_SOURCE.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if RAW_INTR_STAT bits in mask are all set. performs:
|
// returns true if RAW_INTR_STAT bits in mask are all set. performs:
|
||||||
// RAW_INTR_STAT & mask == mask
|
//
|
||||||
|
// RAW_INTR_STAT & mask == mask
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (i2c *I2C) interrupted(mask uint32) bool {
|
func (i2c *I2C) interrupted(mask uint32) bool {
|
||||||
reg := i2c.Bus.IC_RAW_INTR_STAT.Get()
|
reg := i2c.Bus.IC_RAW_INTR_STAT.Get()
|
||||||
|
|
|
@ -45,8 +45,10 @@ type pwmGroup struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equivalent of
|
// Equivalent of
|
||||||
// var pwmSlice []pwmGroup = (*[8]pwmGroup)(unsafe.Pointer(rp.PWM))[:]
|
//
|
||||||
// return &pwmSlice[index]
|
// var pwmSlice []pwmGroup = (*[8]pwmGroup)(unsafe.Pointer(rp.PWM))[:]
|
||||||
|
// return &pwmSlice[index]
|
||||||
|
//
|
||||||
// 0x14 is the size of a pwmGroup.
|
// 0x14 is the size of a pwmGroup.
|
||||||
func getPWMGroup(index uintptr) *pwmGroup {
|
func getPWMGroup(index uintptr) *pwmGroup {
|
||||||
return (*pwmGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(rp.PWM)) + 0x14*index))
|
return (*pwmGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(rp.PWM)) + 0x14*index))
|
||||||
|
@ -112,7 +114,7 @@ func (pwm *pwmGroup) peripheral() uint8 {
|
||||||
// SetPeriod updates the period of this PWM peripheral in nanoseconds.
|
// SetPeriod updates the period of this PWM peripheral in nanoseconds.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// Where frequency is in hertz. If you use a period of 0, a period
|
// Where frequency is in hertz. If you use a period of 0, a period
|
||||||
// that works well for LEDs will be picked.
|
// that works well for LEDs will be picked.
|
||||||
|
@ -167,7 +169,7 @@ func (p *pwmGroup) SetInverting(channel uint8, inverting bool) {
|
||||||
// cycle, in other words the fraction of time the channel output is high (or low
|
// cycle, in other words the fraction of time the channel output is high (or low
|
||||||
// when inverted). For example, to set it to a 25% duty cycle, use:
|
// when inverted). For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// pwm.Set(channel, pwm.Top() / 4)
|
// pwm.Set(channel, pwm.Top() / 4)
|
||||||
//
|
//
|
||||||
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
|
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
|
||||||
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
|
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
|
||||||
|
@ -238,14 +240,17 @@ func (pwm *pwmGroup) setPhaseCorrect(correct bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes any of the following:
|
// Takes any of the following:
|
||||||
// rp.PWM_CH0_CSR_DIVMODE_DIV, rp.PWM_CH0_CSR_DIVMODE_FALL,
|
//
|
||||||
// rp.PWM_CH0_CSR_DIVMODE_LEVEL, rp.PWM_CH0_CSR_DIVMODE_RISE
|
// rp.PWM_CH0_CSR_DIVMODE_DIV, rp.PWM_CH0_CSR_DIVMODE_FALL,
|
||||||
|
// rp.PWM_CH0_CSR_DIVMODE_LEVEL, rp.PWM_CH0_CSR_DIVMODE_RISE
|
||||||
func (pwm *pwmGroup) setDivMode(mode uint32) {
|
func (pwm *pwmGroup) setDivMode(mode uint32) {
|
||||||
pwm.CSR.ReplaceBits(mode<<rp.PWM_CH0_CSR_DIVMODE_Pos, rp.PWM_CH0_CSR_DIVMODE_Msk, 0)
|
pwm.CSR.ReplaceBits(mode<<rp.PWM_CH0_CSR_DIVMODE_Pos, rp.PWM_CH0_CSR_DIVMODE_Msk, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setPeriod sets the pwm peripheral period (frequency). Calculates DIV_INT,DIV_FRAC and sets it from following equation:
|
// setPeriod sets the pwm peripheral period (frequency). Calculates DIV_INT,DIV_FRAC and sets it from following equation:
|
||||||
// cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
//
|
||||||
|
// cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
||||||
|
//
|
||||||
// where cycles is amount of clock cycles per PWM period.
|
// where cycles is amount of clock cycles per PWM period.
|
||||||
func (pwm *pwmGroup) setPeriod(period uint64) error {
|
func (pwm *pwmGroup) setPeriod(period uint64) error {
|
||||||
// This period calculation algorithm consists of
|
// This period calculation algorithm consists of
|
||||||
|
@ -303,7 +308,7 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
|
||||||
// frac's (DIV_FRAC) default value on reset is 0. Max value for frac is 15 (4 bits). This is known as a fixed-point
|
// frac's (DIV_FRAC) default value on reset is 0. Max value for frac is 15 (4 bits). This is known as a fixed-point
|
||||||
// fractional number.
|
// fractional number.
|
||||||
//
|
//
|
||||||
// cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
// cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
||||||
func (pwm *pwmGroup) setClockDiv(Int, frac uint8) {
|
func (pwm *pwmGroup) setClockDiv(Int, frac uint8) {
|
||||||
pwm.DIV.ReplaceBits((uint32(frac)<<rp.PWM_CH0_DIV_FRAC_Pos)|
|
pwm.DIV.ReplaceBits((uint32(frac)<<rp.PWM_CH0_DIV_FRAC_Pos)|
|
||||||
u32max(uint32(Int), 1)<<rp.PWM_CH0_DIV_INT_Pos, rp.PWM_CH0_DIV_FRAC_Msk|rp.PWM_CH0_DIV_INT_Msk, 0)
|
u32max(uint32(Int), 1)<<rp.PWM_CH0_DIV_INT_Pos, rp.PWM_CH0_DIV_FRAC_Msk|rp.PWM_CH0_DIV_INT_Msk, 0)
|
||||||
|
|
|
@ -58,21 +58,21 @@ const _SPITimeout = 10 * 1000 // 10 ms
|
||||||
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
||||||
// Note that the tx and rx buffers must be the same size:
|
// Note that the tx and rx buffers must be the same size:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, rx)
|
// spi.Tx(tx, rx)
|
||||||
//
|
//
|
||||||
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
||||||
// until all the bytes in the command packet have been received:
|
// until all the bytes in the command packet have been received:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, nil)
|
// spi.Tx(tx, nil)
|
||||||
//
|
//
|
||||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||||
//
|
//
|
||||||
// spi.Tx(nil, rx)
|
// spi.Tx(nil, rx)
|
||||||
//
|
//
|
||||||
// Remark: This implementation (RP2040) allows reading into buffer with a custom repeated
|
// Remark: This implementation (RP2040) allows reading into buffer with a custom repeated
|
||||||
// value on tx.
|
// value on tx.
|
||||||
//
|
//
|
||||||
// spi.Tx([]byte{0xff}, rx) // may cause unwanted heap allocations.
|
// spi.Tx([]byte{0xff}, rx) // may cause unwanted heap allocations.
|
||||||
//
|
//
|
||||||
// This form sends 0xff and puts the result into rx buffer. Useful for reading from SD cards
|
// This form sends 0xff and puts the result into rx buffer. Useful for reading from SD cards
|
||||||
// which require 0xff input on SI.
|
// which require 0xff input on SI.
|
||||||
|
@ -150,13 +150,17 @@ func (spi SPI) GetBaudRate() uint32 {
|
||||||
// Default baudrate of 115200 is used if Frequency == 0. Default
|
// Default baudrate of 115200 is used if Frequency == 0. Default
|
||||||
// word length (data bits) is 8.
|
// word length (data bits) is 8.
|
||||||
// Below is a list of GPIO pins corresponding to SPI0 bus on the rp2040:
|
// Below is a list of GPIO pins corresponding to SPI0 bus on the rp2040:
|
||||||
// SI : 0, 4, 17 a.k.a RX and MISO (if rp2040 is master)
|
//
|
||||||
// SO : 3, 7, 19 a.k.a TX and MOSI (if rp2040 is master)
|
// SI : 0, 4, 17 a.k.a RX and MISO (if rp2040 is master)
|
||||||
// SCK: 2, 6, 18
|
// SO : 3, 7, 19 a.k.a TX and MOSI (if rp2040 is master)
|
||||||
|
// SCK: 2, 6, 18
|
||||||
|
//
|
||||||
// SPI1 bus GPIO pins:
|
// SPI1 bus GPIO pins:
|
||||||
// SI : 8, 12
|
//
|
||||||
// SO : 11, 15
|
// SI : 8, 12
|
||||||
// SCK: 10, 14
|
// SO : 11, 15
|
||||||
|
// SCK: 10, 14
|
||||||
|
//
|
||||||
// No pin configuration is needed of SCK, SDO and SDI needed after calling Configure.
|
// No pin configuration is needed of SCK, SDO and SDI needed after calling Configure.
|
||||||
func (spi SPI) Configure(config SPIConfig) error {
|
func (spi SPI) Configure(config SPIConfig) error {
|
||||||
const defaultBaud uint32 = 115200
|
const defaultBaud uint32 = 115200
|
||||||
|
@ -217,6 +221,7 @@ func (spi SPI) setFormat(databits, mode uint8, frameFormat uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset resets SPI and waits until reset is done.
|
// reset resets SPI and waits until reset is done.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (spi SPI) reset() {
|
func (spi SPI) reset() {
|
||||||
resetVal := spi.deinit()
|
resetVal := spi.deinit()
|
||||||
|
@ -240,12 +245,14 @@ func (spi SPI) deinit() (resetVal uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// isWritable returns false if no space is available to write. True if a write is possible
|
// isWritable returns false if no space is available to write. True if a write is possible
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (spi SPI) isWritable() bool {
|
func (spi SPI) isWritable() bool {
|
||||||
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_TNF)
|
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_TNF)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isReadable returns true if a read is possible i.e. data is present
|
// isReadable returns true if a read is possible i.e. data is present
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (spi SPI) isReadable() bool {
|
func (spi SPI) isReadable() bool {
|
||||||
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_RNE)
|
return spi.Bus.SSPSR.HasBits(rp.SPI0_SSPSR_RNE)
|
||||||
|
|
|
@ -72,7 +72,8 @@ func (p Pin) Configure(config PinConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure this pin with the given configuration including alternate
|
// Configure this pin with the given configuration including alternate
|
||||||
// function mapping if necessary.
|
//
|
||||||
|
// function mapping if necessary.
|
||||||
func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
|
func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
|
||||||
// Configure the GPIO pin.
|
// Configure the GPIO pin.
|
||||||
p.enableClock()
|
p.enableClock()
|
||||||
|
|
|
@ -115,7 +115,7 @@ func (t *TIM) SetMatchInterrupt(channel uint8, callback ChannelCallback) error {
|
||||||
// SetPeriod updates the period of this PWM peripheral.
|
// SetPeriod updates the period of this PWM peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// If you use a period of 0, a period that works well for LEDs will be picked.
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
//
|
//
|
||||||
|
@ -195,7 +195,7 @@ func (t *TIM) Channel(pin Pin) (uint8, error) {
|
||||||
// Set updates the channel value. This is used to control the channel duty
|
// Set updates the channel value. This is used to control the channel duty
|
||||||
// cycle. For example, to set it to a 25% duty cycle, use:
|
// cycle. For example, to set it to a 25% duty cycle, use:
|
||||||
//
|
//
|
||||||
// t.Set(ch, t.Top() / 4)
|
// t.Set(ch, t.Top() / 4)
|
||||||
//
|
//
|
||||||
// ch.Set(0) will set the output to low and ch.Set(ch.Top()) will set the output
|
// ch.Set(0) will set the output to low and ch.Set(ch.Top()) will set the output
|
||||||
// to high, assuming the output isn't inverted.
|
// to high, assuming the output isn't inverted.
|
||||||
|
|
|
@ -25,17 +25,16 @@ var (
|
||||||
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
|
||||||
// Note that the tx and rx buffers must be the same size:
|
// Note that the tx and rx buffers must be the same size:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, rx)
|
// spi.Tx(tx, rx)
|
||||||
//
|
//
|
||||||
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
|
||||||
// until all the bytes in the command packet have been received:
|
// until all the bytes in the command packet have been received:
|
||||||
//
|
//
|
||||||
// spi.Tx(tx, nil)
|
// spi.Tx(tx, nil)
|
||||||
//
|
//
|
||||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||||
//
|
//
|
||||||
// spi.Tx(nil, rx)
|
// spi.Tx(nil, rx)
|
||||||
//
|
|
||||||
func (spi SPI) Tx(w, r []byte) error {
|
func (spi SPI) Tx(w, r []byte) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
|
@ -114,24 +114,21 @@ func (kb *keyboard) Write(b []byte) (n int, err error) {
|
||||||
// stateful method with respect to the receiver Keyboard, meaning that its exact
|
// stateful method with respect to the receiver Keyboard, meaning that its exact
|
||||||
// behavior will depend on the current state of its UTF-8 decode state machine:
|
// behavior will depend on the current state of its UTF-8 decode state machine:
|
||||||
//
|
//
|
||||||
// (a) If the given byte is a valid ASCII encoding (0-127), then a keypress
|
// 1. If the given byte is a valid ASCII encoding (0-127), then a keypress
|
||||||
// sequence is immediately transmitted for the respective Keycode.
|
// sequence is immediately transmitted for the respective Keycode.
|
||||||
|
// 2. If the given byte represents the final byte in a multi-byte codepoint,
|
||||||
|
// then a keypress sequence is immediately transmitted by translating the
|
||||||
|
// multi-byte codepoint to its respective Keycode.
|
||||||
|
// 3. If the given byte appears to represent high bits for a multi-byte
|
||||||
|
// codepoint, then the bits are copied to the receiver's internal state
|
||||||
|
// machine buffer for use by a subsequent call to WriteByte() (or Write())
|
||||||
|
// that completes the codepoint.
|
||||||
|
// 4. If the given byte is out of range, or contains illegal bits for the
|
||||||
|
// current state of the UTF-8 decoder, then the UTF-8 decode state machine
|
||||||
|
// is reset to its initial state.
|
||||||
//
|
//
|
||||||
// (b) If the given byte represents the final byte in a multi-byte codepoint,
|
// In cases 3 and 4, a keypress sequence is not generated and no data is
|
||||||
// then a keypress sequence is immediately transmitted by translating the
|
// transmitted. In case 3, additional bytes must be received via WriteByte()
|
||||||
// multi-byte codepoint to its respective Keycode.
|
|
||||||
//
|
|
||||||
// (c) If the given byte appears to represent high bits for a multi-byte
|
|
||||||
// codepoint, then the bits are copied to the receiver's internal state
|
|
||||||
// machine buffer for use by a subsequent call to WriteByte() (or Write())
|
|
||||||
// that completes the codepoint.
|
|
||||||
//
|
|
||||||
// (d) If the given byte is out of range, or contains illegal bits for the
|
|
||||||
// current state of the UTF-8 decoder, then the UTF-8 decode state machine
|
|
||||||
// is reset to its initial state.
|
|
||||||
//
|
|
||||||
// In cases (c) and (d), a keypress sequence is not generated and no data is
|
|
||||||
// transmitted. In case (c), additional bytes must be received via WriteByte()
|
|
||||||
// (or Write()) to complete or discard the current codepoint.
|
// (or Write()) to complete or discard the current codepoint.
|
||||||
func (kb *keyboard) WriteByte(b byte) error {
|
func (kb *keyboard) WriteByte(b byte) error {
|
||||||
switch {
|
switch {
|
||||||
|
@ -211,13 +208,13 @@ func (kb *keyboard) writeKeycode(c Keycode) error {
|
||||||
//
|
//
|
||||||
// The following values of Keycode are supported:
|
// The following values of Keycode are supported:
|
||||||
//
|
//
|
||||||
// 0x0020 - 0x007F ASCII (U+0020 to U+007F) [USES LAYOUT]
|
// 0x0020 - 0x007F ASCII (U+0020 to U+007F) [USES LAYOUT]
|
||||||
// 0x0080 - 0xC1FF Unicode (U+0080 to U+C1FF) [USES LAYOUT]
|
// 0x0080 - 0xC1FF Unicode (U+0080 to U+C1FF) [USES LAYOUT]
|
||||||
// 0xC200 - 0xDFFF UTF-8 packed (U+0080 to U+07FF) [USES LAYOUT]
|
// 0xC200 - 0xDFFF UTF-8 packed (U+0080 to U+07FF) [USES LAYOUT]
|
||||||
// 0xE000 - 0xE0FF Modifier key (bitmap, 8 keys, Shift/Ctrl/Alt/GUI)
|
// 0xE000 - 0xE0FF Modifier key (bitmap, 8 keys, Shift/Ctrl/Alt/GUI)
|
||||||
// 0xE200 - 0xE2FF System key (HID usage code, page 1)
|
// 0xE200 - 0xE2FF System key (HID usage code, page 1)
|
||||||
// 0xE400 - 0xE7FF Media/Consumer key (HID usage code, page 12)
|
// 0xE400 - 0xE7FF Media/Consumer key (HID usage code, page 12)
|
||||||
// 0xF000 - 0xFFFF Normal key (HID usage code, page 7)
|
// 0xF000 - 0xFFFF Normal key (HID usage code, page 7)
|
||||||
func (kb *keyboard) Press(c Keycode) error {
|
func (kb *keyboard) Press(c Keycode) error {
|
||||||
if err := kb.Down(c); nil != err {
|
if err := kb.Down(c); nil != err {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -5,6 +5,7 @@ type Keycode uint16
|
||||||
|
|
||||||
// keycode returns the given Unicode codepoint translated to a Keycode sequence.
|
// keycode returns the given Unicode codepoint translated to a Keycode sequence.
|
||||||
// Unicode codepoints greater than U+FFFF are unsupported.
|
// Unicode codepoints greater than U+FFFF are unsupported.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func keycode(p uint16) Keycode {
|
func keycode(p uint16) Keycode {
|
||||||
if p < 0x80 {
|
if p < 0x80 {
|
||||||
|
|
|
@ -28,6 +28,7 @@ func (a HardwareAddr) String() string {
|
||||||
|
|
||||||
// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, EUI-64, or a 20-octet
|
// ParseMAC parses s as an IEEE 802 MAC-48, EUI-48, EUI-64, or a 20-octet
|
||||||
// IP over InfiniBand link-layer address using one of the following formats:
|
// IP over InfiniBand link-layer address using one of the following formats:
|
||||||
|
//
|
||||||
// 00:00:5e:00:53:01
|
// 00:00:5e:00:53:01
|
||||||
// 02:00:5e:10:00:00:00:01
|
// 02:00:5e:10:00:00:00:01
|
||||||
// 00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01
|
// 00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01
|
||||||
|
|
|
@ -132,7 +132,7 @@ func deepValueEqual(v1, v2 Value, visited map[visit]struct{}) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepEqual reports whether x and y are ``deeply equal,'' defined as follows.
|
// DeepEqual reports whether x and y are “deeply equal”, defined as follows.
|
||||||
// Two values of identical type are deeply equal if one of the following cases applies.
|
// Two values of identical type are deeply equal if one of the following cases applies.
|
||||||
// Values of distinct types are never deeply equal.
|
// Values of distinct types are never deeply equal.
|
||||||
//
|
//
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
// This stores a varint for each named type. Named types are identified by their
|
// This stores a varint for each named type. Named types are identified by their
|
||||||
// name instead of by their type. The named types stored in this struct are
|
// name instead of by their type. The named types stored in this struct are
|
||||||
// non-basic types: pointer, struct, and channel.
|
// non-basic types: pointer, struct, and channel.
|
||||||
|
//
|
||||||
//go:extern reflect.namedNonBasicTypesSidetable
|
//go:extern reflect.namedNonBasicTypesSidetable
|
||||||
var namedNonBasicTypesSidetable uintptr
|
var namedNonBasicTypesSidetable uintptr
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ func unhex(b byte) (v rune, ok bool) {
|
||||||
// or character literal represented by the string s.
|
// or character literal represented by the string s.
|
||||||
// It returns four values:
|
// It returns four values:
|
||||||
//
|
//
|
||||||
// 1) value, the decoded Unicode code point or byte value;
|
// 1. value, the decoded Unicode code point or byte value;
|
||||||
// 2) multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation;
|
// 2. multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation;
|
||||||
// 3) tail, the remainder of the string after the character; and
|
// 3. tail, the remainder of the string after the character; and
|
||||||
// 4) an error that will be nil if the character is syntactically valid.
|
// 4. an error that will be nil if the character is syntactically valid.
|
||||||
//
|
//
|
||||||
// The second argument, quote, specifies the type of literal being parsed
|
// The second argument, quote, specifies the type of literal being parsed
|
||||||
// and therefore which escaped quote character is permitted.
|
// and therefore which escaped quote character is permitted.
|
||||||
|
|
|
@ -139,6 +139,7 @@ func chanMake(elementSize uintptr, bufSize uintptr) *channel {
|
||||||
|
|
||||||
// Return the number of entries in this chan, called from the len builtin.
|
// Return the number of entries in this chan, called from the len builtin.
|
||||||
// A nil chan is defined as having length 0.
|
// A nil chan is defined as having length 0.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func chanLen(c *channel) int {
|
func chanLen(c *channel) int {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
|
@ -155,6 +156,7 @@ func chanLenUnsafePointer(p unsafe.Pointer) int {
|
||||||
|
|
||||||
// Return the capacity of this chan, called from the cap builtin.
|
// Return the capacity of this chan, called from the cap builtin.
|
||||||
// A nil chan is defined as having capacity 0.
|
// A nil chan is defined as having capacity 0.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func chanCap(c *channel) int {
|
func chanCap(c *channel) int {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
|
|
|
@ -5,6 +5,7 @@ package runtime
|
||||||
|
|
||||||
// Update the C environment if cgo is loaded.
|
// Update the C environment if cgo is loaded.
|
||||||
// Called from syscall.Setenv.
|
// Called from syscall.Setenv.
|
||||||
|
//
|
||||||
//go:linkname syscall_setenv_c syscall.setenv_c
|
//go:linkname syscall_setenv_c syscall.setenv_c
|
||||||
func syscall_setenv_c(key string, val string) {
|
func syscall_setenv_c(key string, val string) {
|
||||||
keydata := cstring(key)
|
keydata := cstring(key)
|
||||||
|
@ -16,6 +17,7 @@ func syscall_setenv_c(key string, val string) {
|
||||||
|
|
||||||
// Update the C environment if cgo is loaded.
|
// Update the C environment if cgo is loaded.
|
||||||
// Called from syscall.Unsetenv.
|
// Called from syscall.Unsetenv.
|
||||||
|
//
|
||||||
//go:linkname syscall_unsetenv_c syscall.unsetenv_c
|
//go:linkname syscall_unsetenv_c syscall.unsetenv_c
|
||||||
func syscall_unsetenv_c(key string) {
|
func syscall_unsetenv_c(key string) {
|
||||||
keydata := cstring(key)
|
keydata := cstring(key)
|
||||||
|
@ -34,9 +36,11 @@ func cstring(s string) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// int setenv(const char *name, const char *val, int replace);
|
// int setenv(const char *name, const char *val, int replace);
|
||||||
|
//
|
||||||
//export setenv
|
//export setenv
|
||||||
func libc_setenv(name *byte, val *byte, replace int32) int32
|
func libc_setenv(name *byte, val *byte, replace int32) int32
|
||||||
|
|
||||||
// int unsetenv(const char *name);
|
// int unsetenv(const char *name);
|
||||||
|
//
|
||||||
//export unsetenv
|
//export unsetenv
|
||||||
func libc_unsetenv(name *byte) int32
|
func libc_unsetenv(name *byte) int32
|
||||||
|
|
|
@ -8,7 +8,7 @@ import "unsafe"
|
||||||
|
|
||||||
var inf = float64frombits(0x7FF0000000000000)
|
var inf = float64frombits(0x7FF0000000000000)
|
||||||
|
|
||||||
// isNaN reports whether f is an IEEE 754 ``not-a-number'' value.
|
// isNaN reports whether f is an IEEE 754 “not-a-number” value.
|
||||||
func isNaN(f float64) (is bool) {
|
func isNaN(f float64) (is bool) {
|
||||||
// IEEE 754 says that only NaNs satisfy f != f.
|
// IEEE 754 says that only NaNs satisfy f != f.
|
||||||
return f != f
|
return f != f
|
||||||
|
@ -27,6 +27,7 @@ func isInf(f float64) bool {
|
||||||
// Abs returns the absolute value of x.
|
// Abs returns the absolute value of x.
|
||||||
//
|
//
|
||||||
// Special cases are:
|
// Special cases are:
|
||||||
|
//
|
||||||
// Abs(±Inf) = +Inf
|
// Abs(±Inf) = +Inf
|
||||||
// Abs(NaN) = NaN
|
// Abs(NaN) = NaN
|
||||||
func abs(x float64) float64 {
|
func abs(x float64) float64 {
|
||||||
|
|
|
@ -259,6 +259,7 @@ func calculateHeapAddresses() {
|
||||||
|
|
||||||
// alloc tries to find some free space on the heap, possibly doing a garbage
|
// alloc tries to find some free space on the heap, possibly doing a garbage
|
||||||
// collection cycle if needed. If no space is free, it panics.
|
// collection cycle if needed. If no space is free, it panics.
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
|
|
|
@ -18,6 +18,7 @@ var heapptr = heapStart
|
||||||
|
|
||||||
// Inlining alloc() speeds things up slightly but bloats the executable by 50%,
|
// Inlining alloc() speeds things up slightly but bloats the executable by 50%,
|
||||||
// see https://github.com/tinygo-org/tinygo/issues/2674. So don't.
|
// see https://github.com/tinygo-org/tinygo/issues/2674. So don't.
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
||||||
// TODO: this can be optimized by not casting between pointers and ints so
|
// TODO: this can be optimized by not casting between pointers and ints so
|
||||||
|
|
|
@ -133,6 +133,7 @@ func hashmapShouldGrow(m *hashmap) bool {
|
||||||
|
|
||||||
// Return the number of entries in this hashmap, called from the len builtin.
|
// Return the number of entries in this hashmap, called from the len builtin.
|
||||||
// A nil hashmap is defined as having length 0.
|
// A nil hashmap is defined as having length 0.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func hashmapLen(m *hashmap) int {
|
func hashmapLen(m *hashmap) int {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
@ -148,6 +149,7 @@ func hashmapLenUnsafePointer(p unsafe.Pointer) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a specified key to a given value. Grow the map if necessary.
|
// Set a specified key to a given value. Grow the map if necessary.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func hashmapSet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint32) {
|
func hashmapSet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint32) {
|
||||||
if hashmapShouldGrow(m) {
|
if hashmapShouldGrow(m) {
|
||||||
|
@ -251,6 +253,7 @@ func hashmapGrow(m *hashmap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a specified key, or zero the value if not found.
|
// Get the value of a specified key, or zero the value if not found.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func hashmapGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr, hash uint32) bool {
|
func hashmapGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr, hash uint32) bool {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
@ -298,6 +301,7 @@ func hashmapGet(m *hashmap, key, value unsafe.Pointer, valueSize uintptr, hash u
|
||||||
|
|
||||||
// Delete a given key from the map. No-op when the key does not exist in the
|
// Delete a given key from the map. No-op when the key does not exist in the
|
||||||
// map.
|
// map.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32) {
|
func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
@ -338,6 +342,7 @@ func hashmapDelete(m *hashmap, key unsafe.Pointer, hash uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over a hashmap.
|
// Iterate over a hashmap.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) bool {
|
func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) bool {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
@ -477,6 +482,7 @@ func hashmapStringDelete(m *hashmap, key string) {
|
||||||
// is identical to the Interface() method call, except it doesn't check whether
|
// is identical to the Interface() method call, except it doesn't check whether
|
||||||
// a field is exported and thus allows circumventing the type system.
|
// a field is exported and thus allows circumventing the type system.
|
||||||
// The hash function needs it as it also needs to hash unexported struct fields.
|
// The hash function needs it as it also needs to hash unexported struct fields.
|
||||||
|
//
|
||||||
//go:linkname valueInterfaceUnsafe reflect.valueInterfaceUnsafe
|
//go:linkname valueInterfaceUnsafe reflect.valueInterfaceUnsafe
|
||||||
func valueInterfaceUnsafe(v reflect.Value) interface{}
|
func valueInterfaceUnsafe(v reflect.Value) interface{}
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,9 @@ type State uint8
|
||||||
// Disable disables all interrupts and returns the previous interrupt state. It
|
// Disable disables all interrupts and returns the previous interrupt state. It
|
||||||
// can be used in a critical section like this:
|
// can be used in a critical section like this:
|
||||||
//
|
//
|
||||||
// state := interrupt.Disable()
|
// state := interrupt.Disable()
|
||||||
// // critical section
|
// // critical section
|
||||||
// interrupt.Restore(state)
|
// interrupt.Restore(state)
|
||||||
//
|
//
|
||||||
// Critical sections can be nested. Make sure to call Restore in the same order
|
// Critical sections can be nested. Make sure to call Restore in the same order
|
||||||
// as you called Disable (this happens naturally with the pattern above).
|
// as you called Disable (this happens naturally with the pattern above).
|
||||||
|
|
|
@ -34,9 +34,9 @@ type State uintptr
|
||||||
// Disable disables all interrupts and returns the previous interrupt state. It
|
// Disable disables all interrupts and returns the previous interrupt state. It
|
||||||
// can be used in a critical section like this:
|
// can be used in a critical section like this:
|
||||||
//
|
//
|
||||||
// state := interrupt.Disable()
|
// state := interrupt.Disable()
|
||||||
// // critical section
|
// // critical section
|
||||||
// interrupt.Restore(state)
|
// interrupt.Restore(state)
|
||||||
//
|
//
|
||||||
// Critical sections can be nested. Make sure to call Restore in the same order
|
// Critical sections can be nested. Make sure to call Restore in the same order
|
||||||
// as you called Disable (this happens naturally with the pattern above).
|
// as you called Disable (this happens naturally with the pattern above).
|
||||||
|
|
|
@ -16,11 +16,11 @@ import (
|
||||||
// The Interrupt.New(x, f) (x = [1..31]) attaches CPU interrupt to function f.
|
// The Interrupt.New(x, f) (x = [1..31]) attaches CPU interrupt to function f.
|
||||||
// Caller must map the selected interrupt using following sequence (for example using id 5):
|
// Caller must map the selected interrupt using following sequence (for example using id 5):
|
||||||
//
|
//
|
||||||
// // map interrupt 5 to my XXXX module
|
// // map interrupt 5 to my XXXX module
|
||||||
// esp.INTERRUPT_CORE0.XXXX_INTERRUPT_PRO_MAP.Set( 5 )
|
// esp.INTERRUPT_CORE0.XXXX_INTERRUPT_PRO_MAP.Set( 5 )
|
||||||
// _ = Interrupt.New(5, func(interrupt.Interrupt) {
|
// _ = Interrupt.New(5, func(interrupt.Interrupt) {
|
||||||
// ...
|
// ...
|
||||||
// }).Enable()
|
// }).Enable()
|
||||||
func (i Interrupt) Enable() error {
|
func (i Interrupt) Enable() error {
|
||||||
if i.num < 1 && i.num > 31 {
|
if i.num < 1 && i.num > 31 {
|
||||||
return errors.New("interrupt for ESP32-C3 must be in range of 1 through 31")
|
return errors.New("interrupt for ESP32-C3 must be in range of 1 through 31")
|
||||||
|
@ -49,6 +49,7 @@ func (i Interrupt) Enable() error {
|
||||||
|
|
||||||
// Adding pseudo function calls that is replaced by the compiler with the actual
|
// Adding pseudo function calls that is replaced by the compiler with the actual
|
||||||
// functions registered through interrupt.New.
|
// functions registered through interrupt.New.
|
||||||
|
//
|
||||||
//go:linkname callHandlers runtime/interrupt.callHandlers
|
//go:linkname callHandlers runtime/interrupt.callHandlers
|
||||||
func callHandlers(num int)
|
func callHandlers(num int)
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ func handleInterrupt() {
|
||||||
// Pseudo function call that is replaced by the compiler with the actual
|
// Pseudo function call that is replaced by the compiler with the actual
|
||||||
// functions registered through interrupt.New. If there are none, calls will be
|
// functions registered through interrupt.New. If there are none, calls will be
|
||||||
// replaced with 'unreachablecalls will be replaced with 'unreachable'.
|
// replaced with 'unreachablecalls will be replaced with 'unreachable'.
|
||||||
|
//
|
||||||
//go:linkname callHandlers runtime/interrupt.callHandlers
|
//go:linkname callHandlers runtime/interrupt.callHandlers
|
||||||
func callHandlers(num int)
|
func callHandlers(num int)
|
||||||
|
|
||||||
|
@ -93,9 +94,9 @@ type State uint8
|
||||||
// Disable disables all interrupts and returns the previous interrupt state. It
|
// Disable disables all interrupts and returns the previous interrupt state. It
|
||||||
// can be used in a critical section like this:
|
// can be used in a critical section like this:
|
||||||
//
|
//
|
||||||
// state := interrupt.Disable()
|
// state := interrupt.Disable()
|
||||||
// // critical section
|
// // critical section
|
||||||
// interrupt.Restore(state)
|
// interrupt.Restore(state)
|
||||||
//
|
//
|
||||||
// Critical sections can be nested. Make sure to call Restore in the same order
|
// Critical sections can be nested. Make sure to call Restore in the same order
|
||||||
// as you called Disable (this happens naturally with the pattern above).
|
// as you called Disable (this happens naturally with the pattern above).
|
||||||
|
|
|
@ -9,9 +9,9 @@ type State uintptr
|
||||||
// Disable disables all interrupts and returns the previous interrupt state. It
|
// Disable disables all interrupts and returns the previous interrupt state. It
|
||||||
// can be used in a critical section like this:
|
// can be used in a critical section like this:
|
||||||
//
|
//
|
||||||
// state := interrupt.Disable()
|
// state := interrupt.Disable()
|
||||||
// // critical section
|
// // critical section
|
||||||
// interrupt.Restore(state)
|
// interrupt.Restore(state)
|
||||||
//
|
//
|
||||||
// Critical sections can be nested. Make sure to call Restore in the same order
|
// Critical sections can be nested. Make sure to call Restore in the same order
|
||||||
// as you called Disable (this happens naturally with the pattern above).
|
// as you called Disable (this happens naturally with the pattern above).
|
||||||
|
|
|
@ -11,9 +11,9 @@ type State uintptr
|
||||||
// Disable disables all interrupts and returns the previous interrupt state. It
|
// Disable disables all interrupts and returns the previous interrupt state. It
|
||||||
// can be used in a critical section like this:
|
// can be used in a critical section like this:
|
||||||
//
|
//
|
||||||
// state := interrupt.Disable()
|
// state := interrupt.Disable()
|
||||||
// // critical section
|
// // critical section
|
||||||
// interrupt.Restore(state)
|
// interrupt.Restore(state)
|
||||||
//
|
//
|
||||||
// Critical sections can be nested. Make sure to call Restore in the same order
|
// Critical sections can be nested. Make sure to call Restore in the same order
|
||||||
// as you called Disable (this happens naturally with the pattern above).
|
// as you called Disable (this happens naturally with the pattern above).
|
||||||
|
|
|
@ -11,9 +11,9 @@ type State uintptr
|
||||||
// Disable disables all interrupts and returns the previous interrupt state. It
|
// Disable disables all interrupts and returns the previous interrupt state. It
|
||||||
// can be used in a critical section like this:
|
// can be used in a critical section like this:
|
||||||
//
|
//
|
||||||
// state := interrupt.Disable()
|
// state := interrupt.Disable()
|
||||||
// // critical section
|
// // critical section
|
||||||
// interrupt.Restore(state)
|
// interrupt.Restore(state)
|
||||||
//
|
//
|
||||||
// Critical sections can be nested. Make sure to call Restore in the same order
|
// Critical sections can be nested. Make sure to call Restore in the same order
|
||||||
// as you called Disable (this happens naturally with the pattern above).
|
// as you called Disable (this happens naturally with the pattern above).
|
||||||
|
|
|
@ -49,6 +49,7 @@ type segmentLoadCommand struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MachO header of the currently running process.
|
// MachO header of the currently running process.
|
||||||
|
//
|
||||||
//go:extern _mh_execute_header
|
//go:extern _mh_execute_header
|
||||||
var libc_mh_execute_header machHeader
|
var libc_mh_execute_header machHeader
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,13 @@ import (
|
||||||
|
|
||||||
// trap is a compiler hint that this function cannot be executed. It is
|
// trap is a compiler hint that this function cannot be executed. It is
|
||||||
// translated into either a trap instruction or a call to abort().
|
// translated into either a trap instruction or a call to abort().
|
||||||
|
//
|
||||||
//export llvm.trap
|
//export llvm.trap
|
||||||
func trap()
|
func trap()
|
||||||
|
|
||||||
// Inline assembly stub. It is essentially C longjmp but modified a bit for the
|
// Inline assembly stub. It is essentially C longjmp but modified a bit for the
|
||||||
// purposes of TinyGo. It restores the stack pointer and jumps to the given pc.
|
// purposes of TinyGo. It restores the stack pointer and jumps to the given pc.
|
||||||
|
//
|
||||||
//export tinygo_longjmp
|
//export tinygo_longjmp
|
||||||
func tinygo_longjmp(frame *deferFrame)
|
func tinygo_longjmp(frame *deferFrame)
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ func runtimePanic(msg string) {
|
||||||
// It gets passed in the stack-allocated defer frame and configures it.
|
// It gets passed in the stack-allocated defer frame and configures it.
|
||||||
// Note that the frame is not zeroed yet, so we need to initialize all values
|
// Note that the frame is not zeroed yet, so we need to initialize all values
|
||||||
// that will be used.
|
// that will be used.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func setupDeferFrame(frame *deferFrame, jumpSP unsafe.Pointer) {
|
func setupDeferFrame(frame *deferFrame, jumpSP unsafe.Pointer) {
|
||||||
|
@ -74,6 +77,7 @@ func setupDeferFrame(frame *deferFrame, jumpSP unsafe.Pointer) {
|
||||||
// Called right before the return instruction. It pops the defer frame from the
|
// Called right before the return instruction. It pops the defer frame from the
|
||||||
// linked list of defer frames. It also re-raises a panic if the goroutine is
|
// linked list of defer frames. It also re-raises a panic if the goroutine is
|
||||||
// still panicking.
|
// still panicking.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func destroyDeferFrame(frame *deferFrame) {
|
func destroyDeferFrame(frame *deferFrame) {
|
||||||
|
|
|
@ -44,6 +44,7 @@ func memzero(ptr unsafe.Pointer, size uintptr)
|
||||||
// This intrinsic returns the current stack pointer.
|
// This intrinsic returns the current stack pointer.
|
||||||
// It is normally used together with llvm.stackrestore but also works to get the
|
// It is normally used together with llvm.stackrestore but also works to get the
|
||||||
// current stack pointer in a platform-independent way.
|
// current stack pointer in a platform-independent way.
|
||||||
|
//
|
||||||
//export llvm.stacksave
|
//export llvm.stacksave
|
||||||
func stacksave() unsafe.Pointer
|
func stacksave() unsafe.Pointer
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ func nanotime() int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copied from the Go runtime source code.
|
// Copied from the Go runtime source code.
|
||||||
|
//
|
||||||
//go:linkname os_sigpipe os.sigpipe
|
//go:linkname os_sigpipe os.sigpipe
|
||||||
func os_sigpipe() {
|
func os_sigpipe() {
|
||||||
runtimePanic("too many writes on closed pipe")
|
runtimePanic("too many writes on closed pipe")
|
||||||
|
|
|
@ -40,6 +40,7 @@ var _sidata [0]byte
|
||||||
var _edata [0]byte
|
var _edata [0]byte
|
||||||
|
|
||||||
// Entry point for Go. Initialize all packages and call main.main().
|
// Entry point for Go. Initialize all packages and call main.main().
|
||||||
|
//
|
||||||
//export main
|
//export main
|
||||||
func main() {
|
func main() {
|
||||||
// Initialize .data and .bss sections.
|
// Initialize .data and .bss sections.
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
// For details, see:
|
// For details, see:
|
||||||
// https://community.arm.com/developer/ip-products/system/f/embedded-forum/3257/debugging-a-cortex-m0-hard-fault
|
// https://community.arm.com/developer/ip-products/system/f/embedded-forum/3257/debugging-a-cortex-m0-hard-fault
|
||||||
// https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
|
// https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
|
||||||
|
//
|
||||||
//export handleHardFault
|
//export handleHardFault
|
||||||
func handleHardFault(sp *interruptStack) {
|
func handleHardFault(sp *interruptStack) {
|
||||||
print("fatal error: ")
|
print("fatal error: ")
|
||||||
|
|
|
@ -18,6 +18,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// See runtime_cortexm_hardfault.go
|
// See runtime_cortexm_hardfault.go
|
||||||
|
//
|
||||||
//go:export handleHardFault
|
//go:export handleHardFault
|
||||||
func handleHardFault(sp *interruptStack) {
|
func handleHardFault(sp *interruptStack) {
|
||||||
fault := GetFaultStatus()
|
fault := GetFaultStatus()
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
// This is the function called on startup right after the stack pointer has been
|
// This is the function called on startup right after the stack pointer has been
|
||||||
// set.
|
// set.
|
||||||
|
//
|
||||||
//export main
|
//export main
|
||||||
func main() {
|
func main() {
|
||||||
// Disable the protection on the watchdog timer (needed when started from
|
// Disable the protection on the watchdog timer (needed when started from
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
// This is the function called on startup after the flash (IROM/DROM) is
|
// This is the function called on startup after the flash (IROM/DROM) is
|
||||||
// initialized and the stack pointer has been set.
|
// initialized and the stack pointer has been set.
|
||||||
|
//
|
||||||
//export main
|
//export main
|
||||||
func main() {
|
func main() {
|
||||||
// This initialization configures the following things:
|
// This initialization configures the following things:
|
||||||
|
|
|
@ -33,6 +33,7 @@ func buffered() int {
|
||||||
// Write to the internal control bus (using I2C?).
|
// Write to the internal control bus (using I2C?).
|
||||||
// Signature found here:
|
// Signature found here:
|
||||||
// https://github.com/espressif/ESP8266_RTOS_SDK/blob/14171de0/components/esp8266/include/esp8266/rom_functions.h#L54
|
// https://github.com/espressif/ESP8266_RTOS_SDK/blob/14171de0/components/esp8266/include/esp8266/rom_functions.h#L54
|
||||||
|
//
|
||||||
//export rom_i2c_writeReg
|
//export rom_i2c_writeReg
|
||||||
func rom_i2c_writeReg(block, host_id, reg_add, data uint8)
|
func rom_i2c_writeReg(block, host_id, reg_add, data uint8)
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ func preinit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point for Go. Initialize all packages and call main.main().
|
// Entry point for Go. Initialize all packages and call main.main().
|
||||||
|
//
|
||||||
//export main
|
//export main
|
||||||
func main() {
|
func main() {
|
||||||
preinit()
|
preinit()
|
||||||
|
@ -274,31 +275,37 @@ func getMainThreadHandle() uintptr {
|
||||||
func getArmSystemTick() int64
|
func getArmSystemTick() int64
|
||||||
|
|
||||||
// nxExit exits the program to homebrew launcher
|
// nxExit exits the program to homebrew launcher
|
||||||
|
//
|
||||||
//export __nx_exit
|
//export __nx_exit
|
||||||
func nxExit(code int, stackTop uintptr, exitFunction uintptr)
|
func nxExit(code int, stackTop uintptr, exitFunction uintptr)
|
||||||
|
|
||||||
// Horizon System Calls
|
// Horizon System Calls
|
||||||
// svcSetHeapSize Set the process heap to a given size. It can both extend and shrink the heap.
|
// svcSetHeapSize Set the process heap to a given size. It can both extend and shrink the heap.
|
||||||
// svc 0x01
|
// svc 0x01
|
||||||
|
//
|
||||||
//export svcSetHeapSize
|
//export svcSetHeapSize
|
||||||
func svcSetHeapSize(addr *uintptr, length uint64) uint64
|
func svcSetHeapSize(addr *uintptr, length uint64) uint64
|
||||||
|
|
||||||
// svcExitProcess Exits the current process.
|
// svcExitProcess Exits the current process.
|
||||||
// svc 0x07
|
// svc 0x07
|
||||||
|
//
|
||||||
//export svcExitProcess
|
//export svcExitProcess
|
||||||
func svcExitProcess(code int)
|
func svcExitProcess(code int)
|
||||||
|
|
||||||
// svcSleepThread Sleeps the current thread for the specified amount of time.
|
// svcSleepThread Sleeps the current thread for the specified amount of time.
|
||||||
// svc 0x0B
|
// svc 0x0B
|
||||||
|
//
|
||||||
//export svcSleepThread
|
//export svcSleepThread
|
||||||
func svcSleepThread(nanos uint64)
|
func svcSleepThread(nanos uint64)
|
||||||
|
|
||||||
// svcOutputDebugString Outputs debug text, if used during debugging.
|
// svcOutputDebugString Outputs debug text, if used during debugging.
|
||||||
// svc 0x27
|
// svc 0x27
|
||||||
|
//
|
||||||
//export svcOutputDebugString
|
//export svcOutputDebugString
|
||||||
func svcOutputDebugString(str *uint8, size uint64) uint64
|
func svcOutputDebugString(str *uint8, size uint64) uint64
|
||||||
|
|
||||||
// svcGetInfo Retrieves information about the system, or a certain kernel object.
|
// svcGetInfo Retrieves information about the system, or a certain kernel object.
|
||||||
// svc 0x29
|
// svc 0x29
|
||||||
|
//
|
||||||
//export svcGetInfo
|
//export svcGetInfo
|
||||||
func svcGetInfo(output *uint64, id0 uint32, handle uint32, id1 uint64) uint64
|
func svcGetInfo(output *uint64, id0 uint32, handle uint32, id1 uint64) uint64
|
||||||
|
|
|
@ -62,6 +62,7 @@ func nanosecondsToTicks(ns int64) timeUnit {
|
||||||
}
|
}
|
||||||
|
|
||||||
// number of ticks since start.
|
// number of ticks since start.
|
||||||
|
//
|
||||||
//go:linkname ticks runtime.ticks
|
//go:linkname ticks runtime.ticks
|
||||||
func ticks() timeUnit {
|
func ticks() timeUnit {
|
||||||
// For some ways of capturing the time atomically, see this thread:
|
// For some ways of capturing the time atomically, see this thread:
|
||||||
|
|
|
@ -6,14 +6,15 @@ package runtime
|
||||||
import "device/stm32"
|
import "device/stm32"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock settings
|
clock settings
|
||||||
+-------------+--------+
|
|
||||||
| HSE | 8mhz |
|
+-------------+--------+
|
||||||
| SYSCLK | 168mhz |
|
| HSE | 8mhz |
|
||||||
| HCLK | 168mhz |
|
| SYSCLK | 168mhz |
|
||||||
| APB2(PCLK2) | 84mhz |
|
| HCLK | 168mhz |
|
||||||
| APB1(PCLK1) | 42mhz |
|
| APB2(PCLK2) | 84mhz |
|
||||||
+-------------+--------+
|
| APB1(PCLK1) | 42mhz |
|
||||||
|
+-------------+--------+
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
HSE_STARTUP_TIMEOUT = 0x0500
|
HSE_STARTUP_TIMEOUT = 0x0500
|
||||||
|
|
|
@ -6,14 +6,15 @@ package runtime
|
||||||
import "device/stm32"
|
import "device/stm32"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock settings
|
clock settings
|
||||||
+-------------+--------+
|
|
||||||
| HSE | 8mhz |
|
+-------------+--------+
|
||||||
| SYSCLK | 180mhz |
|
| HSE | 8mhz |
|
||||||
| HCLK | 180mhz |
|
| SYSCLK | 180mhz |
|
||||||
| APB2(PCLK2) | 90mhz |
|
| HCLK | 180mhz |
|
||||||
| APB1(PCLK1) | 45mhz |
|
| APB2(PCLK2) | 90mhz |
|
||||||
+-------------+--------+
|
| APB1(PCLK1) | 45mhz |
|
||||||
|
+-------------+--------+
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
HSE_STARTUP_TIMEOUT = 0x0500
|
HSE_STARTUP_TIMEOUT = 0x0500
|
||||||
|
|
|
@ -9,14 +9,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock settings
|
clock settings
|
||||||
+-------------+--------+
|
|
||||||
| HSE | 8mhz |
|
+-------------+--------+
|
||||||
| SYSCLK | 216mhz |
|
| HSE | 8mhz |
|
||||||
| HCLK | 216mhz |
|
| SYSCLK | 216mhz |
|
||||||
| APB1(PCLK1) | 27mhz |
|
| HCLK | 216mhz |
|
||||||
| APB2(PCLK2) | 108mhz |
|
| APB1(PCLK1) | 27mhz |
|
||||||
+-------------+--------+
|
| APB2(PCLK2) | 108mhz |
|
||||||
|
+-------------+--------+
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
HSE_STARTUP_TIMEOUT = 0x0500
|
HSE_STARTUP_TIMEOUT = 0x0500
|
||||||
|
|
|
@ -8,14 +8,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock settings
|
clock settings
|
||||||
+-------------+-----------+
|
|
||||||
| LSE | 32.768khz |
|
+-------------+-----------+
|
||||||
| SYSCLK | 80mhz |
|
| LSE | 32.768khz |
|
||||||
| HCLK | 80mhz |
|
| SYSCLK | 80mhz |
|
||||||
| APB1(PCLK1) | 80mhz |
|
| HCLK | 80mhz |
|
||||||
| APB2(PCLK2) | 80mhz |
|
| APB1(PCLK1) | 80mhz |
|
||||||
+-------------+-----------+
|
| APB2(PCLK2) | 80mhz |
|
||||||
|
+-------------+-----------+
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
HSE_STARTUP_TIMEOUT = 0x0500
|
HSE_STARTUP_TIMEOUT = 0x0500
|
||||||
|
|
|
@ -8,14 +8,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock settings
|
clock settings
|
||||||
+-------------+-----------+
|
|
||||||
| LSE | 32.768khz |
|
+-------------+-----------+
|
||||||
| SYSCLK | 120mhz |
|
| LSE | 32.768khz |
|
||||||
| HCLK | 120mhz |
|
| SYSCLK | 120mhz |
|
||||||
| APB1(PCLK1) | 120mhz |
|
| HCLK | 120mhz |
|
||||||
| APB2(PCLK2) | 120mhz |
|
| APB1(PCLK1) | 120mhz |
|
||||||
+-------------+-----------+
|
| APB2(PCLK2) | 120mhz |
|
||||||
|
+-------------+-----------+
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
HSE_STARTUP_TIMEOUT = 0x0500
|
HSE_STARTUP_TIMEOUT = 0x0500
|
||||||
|
|
|
@ -9,14 +9,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
clock settings
|
clock settings
|
||||||
+-------------+-----------+
|
|
||||||
| LSE | 32.768khz |
|
+-------------+-----------+
|
||||||
| SYSCLK | 110mhz |
|
| LSE | 32.768khz |
|
||||||
| HCLK | 110mhz |
|
| SYSCLK | 110mhz |
|
||||||
| APB1(PCLK1) | 110mhz |
|
| HCLK | 110mhz |
|
||||||
| APB2(PCLK2) | 110mhz |
|
| APB1(PCLK1) | 110mhz |
|
||||||
+-------------+-----------+
|
| APB2(PCLK2) | 110mhz |
|
||||||
|
+-------------+-----------+
|
||||||
*/
|
*/
|
||||||
const (
|
const (
|
||||||
HSE_STARTUP_TIMEOUT = 0x0500
|
HSE_STARTUP_TIMEOUT = 0x0500
|
||||||
|
|
|
@ -19,6 +19,7 @@ func fd_write(id uint32, iovs *__wasi_iovec_t, iovs_len uint, nwritten *uint) (e
|
||||||
|
|
||||||
// See:
|
// See:
|
||||||
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-proc_exitrval-exitcode
|
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-proc_exitrval-exitcode
|
||||||
|
//
|
||||||
//go:wasm-module wasi_snapshot_preview1
|
//go:wasm-module wasi_snapshot_preview1
|
||||||
//export proc_exit
|
//export proc_exit
|
||||||
func proc_exit(exitcode uint32)
|
func proc_exit(exitcode uint32)
|
||||||
|
|
|
@ -18,6 +18,7 @@ func usleep(usec uint) int
|
||||||
// Note: off_t is defined as int64 because:
|
// Note: off_t is defined as int64 because:
|
||||||
// - musl (used on Linux) always defines it as int64
|
// - musl (used on Linux) always defines it as int64
|
||||||
// - darwin is practically always 64-bit anyway
|
// - darwin is practically always 64-bit anyway
|
||||||
|
//
|
||||||
//export mmap
|
//export mmap
|
||||||
func mmap(addr unsafe.Pointer, length uintptr, prot, flags, fd int, offset int64) unsafe.Pointer
|
func mmap(addr unsafe.Pointer, length uintptr, prot, flags, fd int, offset int64) unsafe.Pointer
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ type timespec struct {
|
||||||
var stackTop uintptr
|
var stackTop uintptr
|
||||||
|
|
||||||
// Entry point for Go. Initialize all packages and call main.main().
|
// Entry point for Go. Initialize all packages and call main.main().
|
||||||
|
//
|
||||||
//export main
|
//export main
|
||||||
func main(argc int32, argv *unsafe.Pointer) int {
|
func main(argc int32, argv *unsafe.Pointer) int {
|
||||||
preinit()
|
preinit()
|
||||||
|
@ -113,6 +115,7 @@ func os_runtime_args() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must be a separate function to get the correct stack pointer.
|
// Must be a separate function to get the correct stack pointer.
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func runMain() {
|
func runMain() {
|
||||||
run()
|
run()
|
||||||
|
|
|
@ -44,6 +44,7 @@ func nanosecondsToTicks(ns int64) timeUnit {
|
||||||
|
|
||||||
// This function is called by the scheduler.
|
// This function is called by the scheduler.
|
||||||
// Schedule a call to runtime.scheduler, do not actually sleep.
|
// Schedule a call to runtime.scheduler, do not actually sleep.
|
||||||
|
//
|
||||||
//export runtime.sleepTicks
|
//export runtime.sleepTicks
|
||||||
func sleepTicks(d timeUnit)
|
func sleepTicks(d timeUnit)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
type timeUnit int64
|
type timeUnit int64
|
||||||
|
|
||||||
// libc constructors
|
// libc constructors
|
||||||
|
//
|
||||||
//export __wasm_call_ctors
|
//export __wasm_call_ctors
|
||||||
func __wasm_call_ctors()
|
func __wasm_call_ctors()
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ func _start() {
|
||||||
// Read the command line arguments from WASI.
|
// Read the command line arguments from WASI.
|
||||||
// For example, they can be passed to a program with wasmtime like this:
|
// For example, they can be passed to a program with wasmtime like this:
|
||||||
//
|
//
|
||||||
// wasmtime ./program.wasm arg1 arg2
|
// wasmtime ./program.wasm arg1 arg2
|
||||||
func init() {
|
func init() {
|
||||||
__wasm_call_ctors()
|
__wasm_call_ctors()
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ func _VirtualAlloc(lpAddress unsafe.Pointer, dwSize uintptr, flAllocationType, f
|
||||||
func _QueryUnbiasedInterruptTime(UnbiasedTime *uint64) bool
|
func _QueryUnbiasedInterruptTime(UnbiasedTime *uint64) bool
|
||||||
|
|
||||||
// The parameter is really a LPFILETIME, but *uint64 should be compatible.
|
// The parameter is really a LPFILETIME, but *uint64 should be compatible.
|
||||||
|
//
|
||||||
//export GetSystemTimeAsFileTime
|
//export GetSystemTimeAsFileTime
|
||||||
func _GetSystemTimeAsFileTime(lpSystemTimeAsFileTime *uint64)
|
func _GetSystemTimeAsFileTime(lpSystemTimeAsFileTime *uint64)
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ func mainCRTStartup() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must be a separate function to get the correct stack pointer.
|
// Must be a separate function to get the correct stack pointer.
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func runMain() {
|
func runMain() {
|
||||||
run()
|
run()
|
||||||
|
|
|
@ -54,7 +54,8 @@ func scheduleLogChan(msg string, ch *channel, t *task.Task) {
|
||||||
// not exited (so deferred calls won't run). This can happen for example in code
|
// not exited (so deferred calls won't run). This can happen for example in code
|
||||||
// like this, that blocks forever:
|
// like this, that blocks forever:
|
||||||
//
|
//
|
||||||
// select{}
|
// select{}
|
||||||
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func deadlock() {
|
func deadlock() {
|
||||||
// call yield without requesting a wakeup
|
// call yield without requesting a wakeup
|
||||||
|
@ -65,6 +66,7 @@ func deadlock() {
|
||||||
// Goexit terminates the currently running goroutine. No other goroutines are affected.
|
// Goexit terminates the currently running goroutine. No other goroutines are affected.
|
||||||
//
|
//
|
||||||
// Unlike the main Go implementation, no deffered calls will be run.
|
// Unlike the main Go implementation, no deffered calls will be run.
|
||||||
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func Goexit() {
|
func Goexit() {
|
||||||
// its really just a deadlock
|
// its really just a deadlock
|
||||||
|
|
|
@ -6,6 +6,7 @@ package runtime
|
||||||
import "internal/task"
|
import "internal/task"
|
||||||
|
|
||||||
// Pause the current task for a given time.
|
// Pause the current task for a given time.
|
||||||
|
//
|
||||||
//go:linkname sleep time.Sleep
|
//go:linkname sleep time.Sleep
|
||||||
func sleep(duration int64) {
|
func sleep(duration int64) {
|
||||||
if duration <= 0 {
|
if duration <= 0 {
|
||||||
|
|
|
@ -18,6 +18,7 @@ type stringIterator struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true iff the strings match.
|
// Return true iff the strings match.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func stringEqual(x, y string) bool {
|
func stringEqual(x, y string) bool {
|
||||||
if len(x) != len(y) {
|
if len(x) != len(y) {
|
||||||
|
@ -32,6 +33,7 @@ func stringEqual(x, y string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true iff x < y.
|
// Return true iff x < y.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func stringLess(x, y string) bool {
|
func stringLess(x, y string) bool {
|
||||||
l := len(x)
|
l := len(x)
|
||||||
|
@ -181,6 +183,7 @@ func encodeUTF8(x rune) ([4]byte, uintptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a single UTF-8 character from a string.
|
// Decode a single UTF-8 character from a string.
|
||||||
|
//
|
||||||
//go:nobounds
|
//go:nobounds
|
||||||
func decodeUTF8(s string, index uintptr) (rune, uintptr) {
|
func decodeUTF8(s string, index uintptr) (rune, uintptr) {
|
||||||
remaining := uintptr(len(s)) - index // must be >= 1 before calling this function
|
remaining := uintptr(len(s)) - index // must be >= 1 before calling this function
|
||||||
|
|
|
@ -50,10 +50,10 @@ func nanosecondsToTicks(ns int64) timeUnit {
|
||||||
return timeUnit(ns / 1000)
|
return timeUnit(ns / 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cyclesPerMilli-1 is used for the systick reset value
|
// cyclesPerMilli-1 is used for the systick reset value.
|
||||||
// the systick current value will be decremented on every clock cycle
|
// The systick current value will be decremented on every clock cycle.
|
||||||
// an interrupt is generated when the current value reaches 0
|
// An interrupt is generated when the current value reaches 0.
|
||||||
// a value of freq/1000 generates a tick (irq) every millisecond (1/1000 s)
|
// A value of freq/1000 generates a tick (irq) every millisecond (1/1000 s).
|
||||||
var cyclesPerMilli = machine.CPUFrequency() / 1000
|
var cyclesPerMilli = machine.CPUFrequency() / 1000
|
||||||
|
|
||||||
// number of systick irqs (milliseconds) since boot
|
// number of systick irqs (milliseconds) since boot
|
||||||
|
|
|
@ -28,7 +28,7 @@ type BitRegister struct {
|
||||||
|
|
||||||
// Get returns the of the mapped register bit. It is the volatile equivalent of:
|
// Get returns the of the mapped register bit. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg
|
// *r.Reg
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *BitRegister) Get() bool {
|
func (r *BitRegister) Get() bool {
|
||||||
|
@ -37,7 +37,7 @@ func (r *BitRegister) Get() bool {
|
||||||
|
|
||||||
// Set sets the mapped register bit. It is the volatile equivalent of:
|
// Set sets the mapped register bit. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg = 1
|
// *r.Reg = 1
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *BitRegister) Set(v bool) {
|
func (r *BitRegister) Set(v bool) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ type Register8 struct {
|
||||||
|
|
||||||
// Get returns the value in the register. It is the volatile equivalent of:
|
// Get returns the value in the register. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg
|
// *r.Reg
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register8) Get() uint8 {
|
func (r *Register8) Get() uint8 {
|
||||||
|
@ -20,7 +20,7 @@ func (r *Register8) Get() uint8 {
|
||||||
|
|
||||||
// Set updates the register value. It is the volatile equivalent of:
|
// Set updates the register value. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg = value
|
// *r.Reg = value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register8) Set(value uint8) {
|
func (r *Register8) Set(value uint8) {
|
||||||
|
@ -30,7 +30,7 @@ func (r *Register8) Set(value uint8) {
|
||||||
// SetBits reads the register, sets the given bits, and writes it back. It is
|
// SetBits reads the register, sets the given bits, and writes it back. It is
|
||||||
// the volatile equivalent of:
|
// the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg |= value
|
// r.Reg |= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register8) SetBits(value uint8) {
|
func (r *Register8) SetBits(value uint8) {
|
||||||
|
@ -40,7 +40,7 @@ func (r *Register8) SetBits(value uint8) {
|
||||||
// ClearBits reads the register, clears the given bits, and writes it back. It
|
// ClearBits reads the register, clears the given bits, and writes it back. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg &^= value
|
// r.Reg &^= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register8) ClearBits(value uint8) {
|
func (r *Register8) ClearBits(value uint8) {
|
||||||
|
@ -50,7 +50,7 @@ func (r *Register8) ClearBits(value uint8) {
|
||||||
// HasBits reads the register and then checks to see if the passed bits are set. It
|
// HasBits reads the register and then checks to see if the passed bits are set. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// (*r.Reg & value) > 0
|
// (*r.Reg & value) > 0
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register8) HasBits(value uint8) bool {
|
func (r *Register8) HasBits(value uint8) bool {
|
||||||
|
@ -60,7 +60,7 @@ func (r *Register8) HasBits(value uint8) bool {
|
||||||
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
||||||
// once. It is the volatile equivalent of:
|
// once. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
||||||
//
|
//
|
||||||
// go:inline
|
// go:inline
|
||||||
func (r *Register8) ReplaceBits(value uint8, mask uint8, pos uint8) {
|
func (r *Register8) ReplaceBits(value uint8, mask uint8, pos uint8) {
|
||||||
|
@ -73,7 +73,7 @@ type Register16 struct {
|
||||||
|
|
||||||
// Get returns the value in the register. It is the volatile equivalent of:
|
// Get returns the value in the register. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg
|
// *r.Reg
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register16) Get() uint16 {
|
func (r *Register16) Get() uint16 {
|
||||||
|
@ -82,7 +82,7 @@ func (r *Register16) Get() uint16 {
|
||||||
|
|
||||||
// Set updates the register value. It is the volatile equivalent of:
|
// Set updates the register value. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg = value
|
// *r.Reg = value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register16) Set(value uint16) {
|
func (r *Register16) Set(value uint16) {
|
||||||
|
@ -92,7 +92,7 @@ func (r *Register16) Set(value uint16) {
|
||||||
// SetBits reads the register, sets the given bits, and writes it back. It is
|
// SetBits reads the register, sets the given bits, and writes it back. It is
|
||||||
// the volatile equivalent of:
|
// the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg |= value
|
// r.Reg |= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register16) SetBits(value uint16) {
|
func (r *Register16) SetBits(value uint16) {
|
||||||
|
@ -102,7 +102,7 @@ func (r *Register16) SetBits(value uint16) {
|
||||||
// ClearBits reads the register, clears the given bits, and writes it back. It
|
// ClearBits reads the register, clears the given bits, and writes it back. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg &^= value
|
// r.Reg &^= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register16) ClearBits(value uint16) {
|
func (r *Register16) ClearBits(value uint16) {
|
||||||
|
@ -112,7 +112,7 @@ func (r *Register16) ClearBits(value uint16) {
|
||||||
// HasBits reads the register and then checks to see if the passed bits are set. It
|
// HasBits reads the register and then checks to see if the passed bits are set. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// (*r.Reg & value) > 0
|
// (*r.Reg & value) > 0
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register16) HasBits(value uint16) bool {
|
func (r *Register16) HasBits(value uint16) bool {
|
||||||
|
@ -122,7 +122,7 @@ func (r *Register16) HasBits(value uint16) bool {
|
||||||
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
||||||
// once. It is the volatile equivalent of:
|
// once. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
||||||
//
|
//
|
||||||
// go:inline
|
// go:inline
|
||||||
func (r *Register16) ReplaceBits(value uint16, mask uint16, pos uint8) {
|
func (r *Register16) ReplaceBits(value uint16, mask uint16, pos uint8) {
|
||||||
|
@ -135,7 +135,7 @@ type Register32 struct {
|
||||||
|
|
||||||
// Get returns the value in the register. It is the volatile equivalent of:
|
// Get returns the value in the register. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg
|
// *r.Reg
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register32) Get() uint32 {
|
func (r *Register32) Get() uint32 {
|
||||||
|
@ -144,7 +144,7 @@ func (r *Register32) Get() uint32 {
|
||||||
|
|
||||||
// Set updates the register value. It is the volatile equivalent of:
|
// Set updates the register value. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg = value
|
// *r.Reg = value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register32) Set(value uint32) {
|
func (r *Register32) Set(value uint32) {
|
||||||
|
@ -154,7 +154,7 @@ func (r *Register32) Set(value uint32) {
|
||||||
// SetBits reads the register, sets the given bits, and writes it back. It is
|
// SetBits reads the register, sets the given bits, and writes it back. It is
|
||||||
// the volatile equivalent of:
|
// the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg |= value
|
// r.Reg |= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register32) SetBits(value uint32) {
|
func (r *Register32) SetBits(value uint32) {
|
||||||
|
@ -164,7 +164,7 @@ func (r *Register32) SetBits(value uint32) {
|
||||||
// ClearBits reads the register, clears the given bits, and writes it back. It
|
// ClearBits reads the register, clears the given bits, and writes it back. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg &^= value
|
// r.Reg &^= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register32) ClearBits(value uint32) {
|
func (r *Register32) ClearBits(value uint32) {
|
||||||
|
@ -174,7 +174,7 @@ func (r *Register32) ClearBits(value uint32) {
|
||||||
// HasBits reads the register and then checks to see if the passed bits are set. It
|
// HasBits reads the register and then checks to see if the passed bits are set. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// (*r.Reg & value) > 0
|
// (*r.Reg & value) > 0
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register32) HasBits(value uint32) bool {
|
func (r *Register32) HasBits(value uint32) bool {
|
||||||
|
@ -184,7 +184,7 @@ func (r *Register32) HasBits(value uint32) bool {
|
||||||
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
||||||
// once. It is the volatile equivalent of:
|
// once. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
||||||
//
|
//
|
||||||
// go:inline
|
// go:inline
|
||||||
func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) {
|
func (r *Register32) ReplaceBits(value uint32, mask uint32, pos uint8) {
|
||||||
|
@ -197,7 +197,7 @@ type Register64 struct {
|
||||||
|
|
||||||
// Get returns the value in the register. It is the volatile equivalent of:
|
// Get returns the value in the register. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg
|
// *r.Reg
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register64) Get() uint64 {
|
func (r *Register64) Get() uint64 {
|
||||||
|
@ -206,7 +206,7 @@ func (r *Register64) Get() uint64 {
|
||||||
|
|
||||||
// Set updates the register value. It is the volatile equivalent of:
|
// Set updates the register value. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// *r.Reg = value
|
// *r.Reg = value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register64) Set(value uint64) {
|
func (r *Register64) Set(value uint64) {
|
||||||
|
@ -216,7 +216,7 @@ func (r *Register64) Set(value uint64) {
|
||||||
// SetBits reads the register, sets the given bits, and writes it back. It is
|
// SetBits reads the register, sets the given bits, and writes it back. It is
|
||||||
// the volatile equivalent of:
|
// the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg |= value
|
// r.Reg |= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register64) SetBits(value uint64) {
|
func (r *Register64) SetBits(value uint64) {
|
||||||
|
@ -226,7 +226,7 @@ func (r *Register64) SetBits(value uint64) {
|
||||||
// ClearBits reads the register, clears the given bits, and writes it back. It
|
// ClearBits reads the register, clears the given bits, and writes it back. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg &^= value
|
// r.Reg &^= value
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register64) ClearBits(value uint64) {
|
func (r *Register64) ClearBits(value uint64) {
|
||||||
|
@ -236,7 +236,7 @@ func (r *Register64) ClearBits(value uint64) {
|
||||||
// HasBits reads the register and then checks to see if the passed bits are set. It
|
// HasBits reads the register and then checks to see if the passed bits are set. It
|
||||||
// is the volatile equivalent of:
|
// is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// (*r.Reg & value) > 0
|
// (*r.Reg & value) > 0
|
||||||
//
|
//
|
||||||
//go:inline
|
//go:inline
|
||||||
func (r *Register64) HasBits(value uint64) bool {
|
func (r *Register64) HasBits(value uint64) bool {
|
||||||
|
@ -246,7 +246,7 @@ func (r *Register64) HasBits(value uint64) bool {
|
||||||
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
// ReplaceBits is a helper to simplify setting multiple bits high and/or low at
|
||||||
// once. It is the volatile equivalent of:
|
// once. It is the volatile equivalent of:
|
||||||
//
|
//
|
||||||
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
// r.Reg = (r.Reg & ^(mask << pos)) | value << pos
|
||||||
//
|
//
|
||||||
// go:inline
|
// go:inline
|
||||||
func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) {
|
func (r *Register64) ReplaceBits(value uint64, mask uint64, pos uint8) {
|
||||||
|
|
Показаны не все изменённые файлы, т.к. их слишком много Показать больше
Загрузка…
Создание таблицы
Сослаться в новой задаче