mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-01 17:47:46 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80c89809a9 | |||
| 266d70816f | |||
| 27cedf09e8 | |||
| db9f1182f5 | |||
| f7fd5cf2d8 | |||
| 8d9c9a16e3 | |||
| 82deccac40 | |||
| 0e540dc3da | |||
| 897f2bc5fd | |||
| 750b0e5c18 | |||
| a65ac105cc |
@@ -66,45 +66,3 @@ jobs:
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Trigger Drivers repo build on Github Actions
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{secrets.GHA_ACCESS_TOKEN}}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/tinygo-org/drivers/actions/workflows/build.yml/dispatches \
|
||||
-d '{"ref": "dev"}'
|
||||
- name: Trigger Bluetooth repo build on Github Actions
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{secrets.GHA_ACCESS_TOKEN}}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/tinygo-org/bluetooth/actions/workflows/linux.yml/dispatches \
|
||||
-d '{"ref": "dev"}'
|
||||
- name: Trigger TinyFS repo build on Github Actions
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{secrets.GHA_ACCESS_TOKEN}}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/tinygo-org/tinyfs/actions/workflows/build.yml/dispatches \
|
||||
-d '{"ref": "dev"}'
|
||||
- name: Trigger TinyFont repo build on Github Actions
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{secrets.GHA_ACCESS_TOKEN}}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/tinygo-org/tinyfont/actions/workflows/build.yml/dispatches \
|
||||
-d '{"ref": "dev"}'
|
||||
- name: Trigger TinyDraw repo build on Github Actions
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{secrets.GHA_ACCESS_TOKEN}}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/tinygo-org/tinydraw/actions/workflows/build.yml/dispatches \
|
||||
-d '{"ref": "dev"}'
|
||||
- name: Trigger TinyTerm repo build on Github Actions
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{secrets.GHA_ACCESS_TOKEN}}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/tinygo-org/tinyterm/actions/workflows/build.yml/dispatches \
|
||||
-d '{"ref": "dev"}'
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
url = https://github.com/WebAssembly/wasi-libc
|
||||
[submodule "lib/picolibc"]
|
||||
path = lib/picolibc
|
||||
url = https://github.com/keith-packard/picolibc.git
|
||||
url = https://github.com/picolibc/picolibc.git
|
||||
[submodule "lib/stm32-svd"]
|
||||
path = lib/stm32-svd
|
||||
url = https://github.com/tinygo-org/stm32-svd
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
0.40.1
|
||||
---
|
||||
* **machine**
|
||||
- nrf: fix flash writes when SoftDevice is enabled
|
||||
* **runtime**
|
||||
- runtime: avoid fixed math/rand sequence on RP2040/RP2350 (#5124)
|
||||
- runtime: add calls to initRand() during run() for all schedulers
|
||||
- runtime: call initRand() before initHeap() during initialization
|
||||
- runtime: use rand_hwrng hardwareRand for RP2040/RP2350 (#5135)
|
||||
* **libs**
|
||||
- picolibc: use updated location for git repo
|
||||
|
||||
0.40.0
|
||||
---
|
||||
* **general**
|
||||
|
||||
@@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) {
|
||||
// microcontrollers
|
||||
{"hifive1b", "examples/echo", 3668, 280, 0, 2244},
|
||||
{"microbit", "examples/serial", 2694, 342, 8, 2248},
|
||||
{"wioterminal", "examples/pininterrupt", 7187, 1489, 116, 6888},
|
||||
{"wioterminal", "examples/pininterrupt", 6833, 1491, 120, 6888},
|
||||
|
||||
// TODO: also check wasm. Right now this is difficult, because
|
||||
// wasm binaries are run through wasm-opt and therefore the
|
||||
|
||||
@@ -1599,7 +1599,8 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
|
||||
elemsLen := b.CreateExtractValue(elems, 1, "append.elemsLen")
|
||||
elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem())
|
||||
elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false)
|
||||
result := b.createRuntimeCall("sliceAppend", []llvm.Value{srcBuf, elemsBuf, srcLen, srcCap, elemsLen, elemSize}, "append.new")
|
||||
elemLayout := b.createObjectLayout(elemType, pos)
|
||||
result := b.createRuntimeCall("sliceAppend", []llvm.Value{srcBuf, elemsBuf, srcLen, srcCap, elemsLen, elemSize, elemLayout}, "append.new")
|
||||
newPtr := b.CreateExtractValue(result, 0, "append.newPtr")
|
||||
newLen := b.CreateExtractValue(result, 1, "append.newLen")
|
||||
newCap := b.CreateExtractValue(result, 2, "append.newCap")
|
||||
|
||||
Vendored
+3
-3
@@ -55,7 +55,7 @@ entry:
|
||||
store i32 2, ptr %0, align 4
|
||||
%1 = getelementptr inbounds nuw i8, ptr %varargs, i32 8
|
||||
store i32 3, ptr %1, align 4
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #3
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||
%append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1
|
||||
%append.newCap = extractvalue { ptr, i32, i32 } %append.new, 2
|
||||
@@ -66,13 +66,13 @@ entry:
|
||||
ret { ptr, i32, i32 } %4
|
||||
}
|
||||
|
||||
declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr) #1
|
||||
declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr, ptr) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #2 {
|
||||
entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr undef) #3
|
||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||
%append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1
|
||||
%append.newCap = extractvalue { ptr, i32, i32 } %append.new, 2
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// Version of TinyGo.
|
||||
// Update this value before release of new version of software.
|
||||
const version = "0.40.0"
|
||||
const version = "0.40.1"
|
||||
|
||||
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
||||
// (like 0.30.0-dev-abcd012).
|
||||
|
||||
@@ -1745,7 +1745,7 @@ func memzero(ptr unsafe.Pointer, size uintptr)
|
||||
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
|
||||
|
||||
//go:linkname sliceAppend runtime.sliceAppend
|
||||
func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen uintptr, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr)
|
||||
func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen uintptr, elemSize uintptr, layout unsafe.Pointer) (unsafe.Pointer, uintptr, uintptr)
|
||||
|
||||
//go:linkname sliceCopy runtime.sliceCopy
|
||||
func sliceCopy(dst, src unsafe.Pointer, dstLen, srcLen uintptr, elemSize uintptr) int
|
||||
@@ -1810,7 +1810,7 @@ func buflen(v Value) (unsafe.Pointer, uintptr) {
|
||||
}
|
||||
|
||||
//go:linkname sliceGrow runtime.sliceGrow
|
||||
func sliceGrow(buf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr)
|
||||
func sliceGrow(buf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr, layout unsafe.Pointer) (unsafe.Pointer, uintptr, uintptr)
|
||||
|
||||
// extend slice to hold n new elements
|
||||
func extendSlice(v Value, n int) sliceHeader {
|
||||
@@ -1823,7 +1823,10 @@ func extendSlice(v Value, n int) sliceHeader {
|
||||
old = *(*sliceHeader)(v.value)
|
||||
}
|
||||
|
||||
nbuf, nlen, ncap := sliceGrow(old.data, old.len, old.cap, old.len+uintptr(n), v.typecode.elem().Size())
|
||||
elem := v.typecode.elem()
|
||||
elemSize := elem.Size()
|
||||
elemLayout := elem.gcLayout()
|
||||
nbuf, nlen, ncap := sliceGrow(old.data, old.len, old.cap, old.len+uintptr(n), elemSize, elemLayout)
|
||||
|
||||
return sliceHeader{
|
||||
data: nbuf,
|
||||
@@ -1862,8 +1865,10 @@ func AppendSlice(s, t Value) Value {
|
||||
}
|
||||
sSlice := (*sliceHeader)(s.value)
|
||||
tSlice := (*sliceHeader)(t.value)
|
||||
elemSize := s.typecode.elem().Size()
|
||||
ptr, len, cap := sliceAppend(sSlice.data, tSlice.data, sSlice.len, sSlice.cap, tSlice.len, elemSize)
|
||||
elem := s.typecode.elem()
|
||||
elemSize := elem.Size()
|
||||
elemLayout := elem.gcLayout()
|
||||
ptr, len, cap := sliceAppend(sSlice.data, tSlice.data, sSlice.len, sSlice.cap, tSlice.len, elemSize, elemLayout)
|
||||
result := &sliceHeader{
|
||||
data: ptr,
|
||||
len: len,
|
||||
|
||||
@@ -337,7 +337,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
|
||||
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
|
||||
func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
sendUSBPacket(ep, data, 0)
|
||||
sendUSBPacket(ep, data)
|
||||
|
||||
// clear transfer complete flag
|
||||
setEPINTFLAG(ep, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
|
||||
@@ -351,27 +351,28 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
|
||||
//
|
||||
//go:noinline
|
||||
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
|
||||
l := uint16(len(data))
|
||||
if 0 < maxsize && maxsize < l {
|
||||
l = maxsize
|
||||
func sendUSBPacket(ep uint32, data []byte) {
|
||||
// Select the corresponding buffer.
|
||||
buffer := udd_ep_control_cache_buffer[:]
|
||||
if ep != 0 {
|
||||
buffer = udd_ep_in_cache_buffer[ep][:]
|
||||
}
|
||||
|
||||
// Set endpoint address for sending data
|
||||
if ep == 0 {
|
||||
copy(udd_ep_control_cache_buffer[:], data[:l])
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_control_cache_buffer))))
|
||||
} else {
|
||||
copy(udd_ep_in_cache_buffer[ep][:], data[:l])
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
}
|
||||
// Copy the packet to the buffer.
|
||||
copy(buffer[:len(data)], data)
|
||||
|
||||
// Select the corresponding endpoint descriptor.
|
||||
endpoint := &usbEndpointDescriptors[ep].DeviceDescBank[1]
|
||||
|
||||
// Set the endpoint address.
|
||||
endpoint.ADDR.Set(uint32(uintptr(unsafe.Pointer(unsafe.SliceData(buffer)))))
|
||||
|
||||
// clear multi-packet size which is total bytes already sent
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
||||
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
||||
|
||||
// set byte count, which is total number of bytes to be sent
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
endpoint.PCKSIZE.SetBits((uint32(len(data)) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
}
|
||||
|
||||
func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {
|
||||
|
||||
@@ -340,7 +340,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
|
||||
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
|
||||
func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
sendUSBPacket(ep, data, 0)
|
||||
sendUSBPacket(ep, data)
|
||||
|
||||
// clear transfer complete flag
|
||||
setEPINTFLAG(ep, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1)
|
||||
@@ -354,27 +354,28 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
|
||||
//
|
||||
//go:noinline
|
||||
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
|
||||
l := uint16(len(data))
|
||||
if 0 < maxsize && maxsize < l {
|
||||
l = maxsize
|
||||
func sendUSBPacket(ep uint32, data []byte) {
|
||||
// Select the corresponding buffer.
|
||||
buffer := udd_ep_control_cache_buffer[:]
|
||||
if ep != 0 {
|
||||
buffer = udd_ep_in_cache_buffer[ep][:]
|
||||
}
|
||||
|
||||
// Set endpoint address for sending data
|
||||
if ep == 0 {
|
||||
copy(udd_ep_control_cache_buffer[:], data[:l])
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_control_cache_buffer))))
|
||||
} else {
|
||||
copy(udd_ep_in_cache_buffer[ep][:], data[:l])
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
}
|
||||
// Copy the packet to the buffer.
|
||||
copy(buffer[:len(data)], data)
|
||||
|
||||
// Select the corresponding endpoint descriptor.
|
||||
endpoint := &usbEndpointDescriptors[ep].DeviceDescBank[1]
|
||||
|
||||
// Set the endpoint address.
|
||||
endpoint.ADDR.Set(uint32(uintptr(unsafe.Pointer(unsafe.SliceData(buffer)))))
|
||||
|
||||
// clear multi-packet size which is total bytes already sent
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
||||
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
|
||||
|
||||
// set byte count, which is total number of bytes to be sent
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
endpoint.PCKSIZE.SetBits((uint32(len(data)) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
}
|
||||
|
||||
func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {
|
||||
|
||||
@@ -400,7 +400,8 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
// SoftDevices I've checked.
|
||||
// Documentation:
|
||||
// https://docs.nordicsemi.com/bundle/s140_v6.0.0_api/page/group_n_r_f_s_o_c_f_u_n_c_t_i_o_n_s.html
|
||||
result := arm.SVCall3(0x20+9, address, &p[0], uint32(len(p)))
|
||||
numberOfWords := len(padded) / 4 // flash access goes in 32-bit words
|
||||
result := arm.SVCall3(0x20+9, address, &padded[0], uint32(numberOfWords))
|
||||
if result != 0 {
|
||||
// Could not queue flash operation? Not sure when this can
|
||||
// happen.
|
||||
|
||||
@@ -256,7 +256,7 @@ func initEndpoint(ep, config uint32) {
|
||||
|
||||
// SendUSBInPacket sends a packet for USBHID (interrupt in / bulk in).
|
||||
func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
sendUSBPacket(ep, data, 0)
|
||||
sendUSBPacket(ep, data)
|
||||
|
||||
// clear transfer complete flag
|
||||
nrf.USBD.INTENCLR.Set(nrf.USBD_INTENCLR_ENDEPOUT0 << 4)
|
||||
@@ -267,33 +267,32 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
|
||||
//
|
||||
//go:noinline
|
||||
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
|
||||
func sendUSBPacket(ep uint32, data []byte) {
|
||||
// Select the corresponding buffer.
|
||||
count := len(data)
|
||||
if 0 < int(maxsize) && int(maxsize) < count {
|
||||
count = int(maxsize)
|
||||
}
|
||||
|
||||
var buffer []byte
|
||||
if ep == 0 {
|
||||
copy(udd_ep_control_cache_buffer[:], data[:count])
|
||||
buffer = udd_ep_control_cache_buffer[:]
|
||||
if count > usb.EndpointPacketSize {
|
||||
// The packet must be sent in chunks.
|
||||
sendOnEP0DATADONE.offset = usb.EndpointPacketSize
|
||||
sendOnEP0DATADONE.ptr = &udd_ep_control_cache_buffer[sendOnEP0DATADONE.offset]
|
||||
sendOnEP0DATADONE.ptr = &udd_ep_control_cache_buffer[usb.EndpointPacketSize]
|
||||
sendOnEP0DATADONE.count = count - usb.EndpointPacketSize
|
||||
count = usb.EndpointPacketSize
|
||||
}
|
||||
sendViaEPIn(
|
||||
ep,
|
||||
&udd_ep_control_cache_buffer[0],
|
||||
count,
|
||||
)
|
||||
} else {
|
||||
copy(udd_ep_in_cache_buffer[ep][:], data[:count])
|
||||
sendViaEPIn(
|
||||
ep,
|
||||
&udd_ep_in_cache_buffer[ep][0],
|
||||
count,
|
||||
)
|
||||
buffer = udd_ep_in_cache_buffer[ep][:]
|
||||
}
|
||||
|
||||
// Copy the packet to the buffer.
|
||||
copy(buffer[:len(data)], data)
|
||||
|
||||
// Send the first chunk of the packet.
|
||||
sendViaEPIn(
|
||||
ep,
|
||||
&buffer[0],
|
||||
count,
|
||||
)
|
||||
}
|
||||
|
||||
func handleEndpointRx(ep uint32) []byte {
|
||||
|
||||
@@ -128,7 +128,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
const ackTimeout = 570
|
||||
|
||||
rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_ACK_REC)
|
||||
sendUSBPacket(0, []byte{}, 0)
|
||||
sendUSBPacket(0, []byte{})
|
||||
|
||||
// Wait for transfer to complete with a timeout.
|
||||
t := timer.timeElapsed()
|
||||
|
||||
@@ -131,7 +131,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
const ackTimeout = 570
|
||||
|
||||
rp.USB.SIE_STATUS.Set(rp.USB_SIE_STATUS_ACK_REC)
|
||||
sendUSBPacket(0, []byte{}, 0)
|
||||
sendUSBPacket(0, []byte{})
|
||||
|
||||
// Wait for transfer to complete with a timeout.
|
||||
t := timer.timeElapsed()
|
||||
|
||||
@@ -72,19 +72,15 @@ func initEndpoint(ep, config uint32) {
|
||||
|
||||
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
|
||||
func SendUSBInPacket(ep uint32, data []byte) bool {
|
||||
sendUSBPacket(ep, data, 0)
|
||||
sendUSBPacket(ep, data)
|
||||
return true
|
||||
}
|
||||
|
||||
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
|
||||
//
|
||||
//go:noinline
|
||||
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
|
||||
func sendUSBPacket(ep uint32, data []byte) {
|
||||
count := len(data)
|
||||
if 0 < int(maxsize) && int(maxsize) < count {
|
||||
count = int(maxsize)
|
||||
}
|
||||
|
||||
if ep == 0 {
|
||||
if count > usb.EndpointPacketSize {
|
||||
count = usb.EndpointPacketSize
|
||||
@@ -145,7 +141,7 @@ func setEPDataPID(ep uint32, dataOne bool) {
|
||||
}
|
||||
|
||||
func SendZlp() {
|
||||
sendUSBPacket(0, []byte{}, 0)
|
||||
sendUSBPacket(0, []byte{})
|
||||
}
|
||||
|
||||
func sendViaEPIn(ep uint32, data []byte, count int) {
|
||||
|
||||
+72
-37
@@ -81,21 +81,6 @@ func usbSerial() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// strToUTF16LEDescriptor converts a utf8 string into a string descriptor
|
||||
// note: the following code only converts ascii characters to UTF16LE. In order
|
||||
// to do a "proper" conversion, we would need to pull in the 'unicode/utf16'
|
||||
// package, which at the time this was written added 512 bytes to the compiled
|
||||
// binary.
|
||||
func strToUTF16LEDescriptor(in string, out []byte) {
|
||||
out[0] = byte(len(out))
|
||||
out[1] = descriptor.TypeString
|
||||
for i, rune := range in {
|
||||
out[(i<<1)+2] = byte(rune)
|
||||
out[(i<<1)+3] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const cdcLineInfoSize = 7
|
||||
|
||||
var (
|
||||
@@ -137,51 +122,53 @@ var (
|
||||
usbStallHandler [NumberOfUSBEndpoints]func(usb.Setup) bool
|
||||
)
|
||||
|
||||
var usbLangInfo = [4]byte{
|
||||
// length = 4 bytes
|
||||
0x04,
|
||||
// descriptor type = string
|
||||
0x03,
|
||||
// language codes
|
||||
// 0x0409 = English (United States)
|
||||
0x09, 0x04,
|
||||
}
|
||||
|
||||
// sendDescriptor creates and sends the various USB descriptor types that
|
||||
// can be requested by the host.
|
||||
func sendDescriptor(setup usb.Setup) {
|
||||
switch setup.WValueH {
|
||||
case descriptor.TypeConfiguration:
|
||||
sendUSBPacket(0, usbDescriptor.Configuration, setup.WLength)
|
||||
sendDescriptorData(usbDescriptor.Configuration, setup.WLength)
|
||||
return
|
||||
|
||||
case descriptor.TypeDevice:
|
||||
usbDescriptor.Configure(usbVendorID(), usbProductID())
|
||||
sendUSBPacket(0, usbDescriptor.Device, setup.WLength)
|
||||
sendDescriptorData(usbDescriptor.Device, setup.WLength)
|
||||
return
|
||||
|
||||
case descriptor.TypeString:
|
||||
switch setup.WValueL {
|
||||
case 0:
|
||||
usb_trans_buffer[0] = 0x04
|
||||
usb_trans_buffer[1] = 0x03
|
||||
usb_trans_buffer[2] = 0x09
|
||||
usb_trans_buffer[3] = 0x04
|
||||
sendUSBPacket(0, usb_trans_buffer[:4], setup.WLength)
|
||||
sendDescriptorData(usbLangInfo[:], setup.WLength)
|
||||
|
||||
case usb.IPRODUCT:
|
||||
b := usb_trans_buffer[:(len(usbProduct())<<1)+2]
|
||||
strToUTF16LEDescriptor(usbProduct(), b)
|
||||
sendUSBPacket(0, b, setup.WLength)
|
||||
sendDescriptorString(usbProduct(), setup.WLength)
|
||||
|
||||
case usb.IMANUFACTURER:
|
||||
b := usb_trans_buffer[:(len(usbManufacturer())<<1)+2]
|
||||
strToUTF16LEDescriptor(usbManufacturer(), b)
|
||||
sendUSBPacket(0, b, setup.WLength)
|
||||
sendDescriptorString(usbManufacturer(), setup.WLength)
|
||||
|
||||
case usb.ISERIAL:
|
||||
sz := len(usbSerial())
|
||||
if sz == 0 {
|
||||
serial := usbSerial()
|
||||
if len(serial) == 0 {
|
||||
SendZlp()
|
||||
} else {
|
||||
b := usb_trans_buffer[:(sz<<1)+2]
|
||||
strToUTF16LEDescriptor(usbSerial(), b)
|
||||
sendUSBPacket(0, b, setup.WLength)
|
||||
sendDescriptorString(serial, setup.WLength)
|
||||
}
|
||||
}
|
||||
// TODO: why do we do this when WValueL is unknown?
|
||||
return
|
||||
case descriptor.TypeHIDReport:
|
||||
if h, ok := usbDescriptor.HID[setup.WIndex]; ok {
|
||||
sendUSBPacket(0, h, setup.WLength)
|
||||
sendDescriptorData(h, setup.WLength)
|
||||
return
|
||||
}
|
||||
case descriptor.TypeDeviceQualifier:
|
||||
@@ -194,6 +181,39 @@ func sendDescriptor(setup usb.Setup) {
|
||||
return
|
||||
}
|
||||
|
||||
// sendDescriptorString sends a string descriptor, truncating it to fit maxLen or the buffer size.
|
||||
// note: the following code only converts ascii characters to UTF16LE. In order
|
||||
// to do a "proper" conversion, we would need to pull in the 'unicode/utf16'
|
||||
// package, which at the time this was written added 512 bytes to the compiled
|
||||
// binary.
|
||||
// TODO: old comment, re-evaluate
|
||||
func sendDescriptorString(data string, maxLen uint16) {
|
||||
if maxLen < 2 {
|
||||
// Something has gone horribly wrong.
|
||||
SendZlp()
|
||||
return
|
||||
}
|
||||
|
||||
// Clamp the length.
|
||||
maxEncBytes := min(len(usb_trans_buffer), len(udd_ep_control_cache_buffer), int(maxLen))
|
||||
data = data[:min(len(data), (maxEncBytes-2)/2)]
|
||||
|
||||
// Write the header.
|
||||
buf := usb_trans_buffer[:2*len(data)+2]
|
||||
hdr, body := buf[:2], buf[2:]
|
||||
hdr[0] = byte(len(buf))
|
||||
hdr[1] = descriptor.TypeString
|
||||
|
||||
// Convert the string to UTF16.
|
||||
// NOTE: Using range here would cause the length to disagree when multibyte codepoints are present.
|
||||
for i := 0; i < len(data); i++ {
|
||||
body[2*i] = byte(data[i])
|
||||
body[2*i+1] = 0
|
||||
}
|
||||
|
||||
sendUSBPacket(0, buf)
|
||||
}
|
||||
|
||||
func handleStandardSetup(setup usb.Setup) bool {
|
||||
switch setup.BRequest {
|
||||
case usb.GET_STATUS:
|
||||
@@ -206,7 +226,7 @@ func handleStandardSetup(setup usb.Setup) bool {
|
||||
}
|
||||
}
|
||||
|
||||
sendUSBPacket(0, usb_trans_buffer[:2], setup.WLength)
|
||||
sendDescriptorData(usb_trans_buffer[:2], setup.WLength)
|
||||
return true
|
||||
|
||||
case usb.CLEAR_FEATURE:
|
||||
@@ -251,7 +271,7 @@ func handleStandardSetup(setup usb.Setup) bool {
|
||||
|
||||
case usb.GET_CONFIGURATION:
|
||||
usb_trans_buffer[0] = usbConfiguration
|
||||
sendUSBPacket(0, usb_trans_buffer[:1], setup.WLength)
|
||||
sendDescriptorData(usb_trans_buffer[:1], setup.WLength)
|
||||
return true
|
||||
|
||||
case usb.SET_CONFIGURATION:
|
||||
@@ -271,7 +291,7 @@ func handleStandardSetup(setup usb.Setup) bool {
|
||||
|
||||
case usb.GET_INTERFACE:
|
||||
usb_trans_buffer[0] = usbSetInterface
|
||||
sendUSBPacket(0, usb_trans_buffer[:1], setup.WLength)
|
||||
sendDescriptorData(usb_trans_buffer[:1], setup.WLength)
|
||||
return true
|
||||
|
||||
case usb.SET_INTERFACE:
|
||||
@@ -285,6 +305,21 @@ func handleStandardSetup(setup usb.Setup) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// sendDescriptorData sends a descriptor, truncating it to fit maxLen or the buffer size.
|
||||
func sendDescriptorData(data []byte, maxLen uint16) {
|
||||
data = lenToCap(data)
|
||||
data = data[:min(len(data), len(udd_ep_control_cache_buffer), int(maxLen))]
|
||||
sendUSBPacket(0, data)
|
||||
}
|
||||
|
||||
// Set the cap of the slice to the length.
|
||||
// This is safe, but cannot be proven by the compiler.
|
||||
//
|
||||
//go:nobounds
|
||||
func lenToCap(b []byte) []byte {
|
||||
return b[:len(b):len(b)]
|
||||
}
|
||||
|
||||
func EnableCDC(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool) {
|
||||
if len(usbDescriptor.Device) == 0 {
|
||||
usbDescriptor = descriptor.CDC
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
//go:build baremetal && (nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt))
|
||||
//go:build baremetal && (nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) || rp2040 || rp2350)
|
||||
|
||||
// If you update the above build constraint, you'll probably also need to update
|
||||
// src/crypto/rand/rand_baremetal.go.
|
||||
//
|
||||
// The rp2040 and rp2350 implementations are not included in src/crypto/rand/rand_baremetal.go
|
||||
// due to not being sufficiently random for the Go crypto libs.
|
||||
// However since the randomness here does not provide those same guarantees,
|
||||
// they are included in the list for hardwareRand() implementations.
|
||||
|
||||
package runtime
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build baremetal && !(nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt))
|
||||
//go:build baremetal && !(nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || tkey || (tinygo.riscv32 && virt) || rp2040 || rp2350)
|
||||
|
||||
package runtime
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ func wasmEntryReactor() {
|
||||
// Initialize the heap.
|
||||
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
|
||||
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
|
||||
initHeap()
|
||||
initRand()
|
||||
initHeap()
|
||||
|
||||
if hasScheduler {
|
||||
// A package initializer might do funky stuff like start a goroutine and
|
||||
|
||||
@@ -243,8 +243,8 @@ func sleep(duration int64) {
|
||||
// run is called by the program entry point to execute the go program.
|
||||
// With a scheduler, init and the main function are invoked in a goroutine before starting the scheduler.
|
||||
func run() {
|
||||
initHeap()
|
||||
initRand()
|
||||
initHeap()
|
||||
go func() {
|
||||
initAll()
|
||||
callMain()
|
||||
|
||||
@@ -135,6 +135,7 @@ func sleep(duration int64) {
|
||||
// This function is called on the first core in the system. It will wake up the
|
||||
// other cores when ready.
|
||||
func run() {
|
||||
initRand()
|
||||
initHeap()
|
||||
|
||||
go func() {
|
||||
|
||||
@@ -21,8 +21,8 @@ var schedulerExit bool
|
||||
// run is called by the program entry point to execute the go program.
|
||||
// With the "none" scheduler, init and the main function are invoked directly.
|
||||
func run() {
|
||||
initHeap()
|
||||
initRand()
|
||||
initHeap()
|
||||
initAll()
|
||||
callMain()
|
||||
mainExited = true
|
||||
|
||||
@@ -21,6 +21,7 @@ var (
|
||||
// Because we just use OS threads, we don't need to do anything special here. We
|
||||
// can just initialize everything and run main.main on the main thread.
|
||||
func run() {
|
||||
initRand()
|
||||
initHeap()
|
||||
task.Init(stackTop)
|
||||
initAll()
|
||||
|
||||
+3
-10
@@ -3,19 +3,18 @@ package runtime
|
||||
// This file implements compiler builtins for slices: append() and copy().
|
||||
|
||||
import (
|
||||
"internal/gclayout"
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Builtin append(src, elements...) function: append elements to src and return
|
||||
// the modified (possibly expanded) slice.
|
||||
func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr) {
|
||||
func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen, elemSize uintptr, layout unsafe.Pointer) (unsafe.Pointer, uintptr, uintptr) {
|
||||
newLen := srcLen + elemsLen
|
||||
if elemsLen > 0 {
|
||||
// Allocate a new slice with capacity for elemsLen more elements, if necessary;
|
||||
// otherwise, reuse the passed slice.
|
||||
srcBuf, _, srcCap = sliceGrow(srcBuf, srcLen, srcCap, newLen, elemSize)
|
||||
srcBuf, _, srcCap = sliceGrow(srcBuf, srcLen, srcCap, newLen, elemSize, layout)
|
||||
|
||||
// Append the new elements in-place.
|
||||
memmove(unsafe.Add(srcBuf, srcLen*elemSize), elemsBuf, elemsLen*elemSize)
|
||||
@@ -36,7 +35,7 @@ func sliceCopy(dst, src unsafe.Pointer, dstLen, srcLen uintptr, elemSize uintptr
|
||||
}
|
||||
|
||||
// sliceGrow returns a new slice with space for at least newCap elements
|
||||
func sliceGrow(oldBuf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr) {
|
||||
func sliceGrow(oldBuf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr, layout unsafe.Pointer) (unsafe.Pointer, uintptr, uintptr) {
|
||||
if oldCap >= newCap {
|
||||
// No need to grow, return the input slice.
|
||||
return oldBuf, oldLen, oldCap
|
||||
@@ -48,12 +47,6 @@ func sliceGrow(oldBuf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr)
|
||||
// memory allocators, this causes some difficult to debug issues.
|
||||
newCap = 1 << bits.Len(uint(newCap))
|
||||
|
||||
var layout unsafe.Pointer
|
||||
// less type info here; can only go off element size
|
||||
if elemSize < unsafe.Sizeof(uintptr(0)) {
|
||||
layout = gclayout.NoPtrs.AsPtr()
|
||||
}
|
||||
|
||||
buf := alloc(newCap*elemSize, layout)
|
||||
if oldLen > 0 {
|
||||
// copy any data to new slice
|
||||
|
||||
Vendored
+4
@@ -190,6 +190,7 @@
|
||||
- pkg: tiff
|
||||
- repo: github.com/golang/geo
|
||||
subdirs:
|
||||
- pkg: earth
|
||||
- pkg: r1
|
||||
- pkg: r2
|
||||
- pkg: r3
|
||||
@@ -285,3 +286,6 @@
|
||||
- repo: github.com/julienschmidt/httprouter
|
||||
- repo: github.com/openhistogram/circonusllhist
|
||||
skipwasi: true # math.MaxInt64 (untyped int constant 9223372036854775807) overflows int
|
||||
- repo: github.com/philhofer/fwd
|
||||
- repo: github.com/blevesearch/sear
|
||||
- repo: github.com/steveyen/gtreap
|
||||
|
||||
Reference in New Issue
Block a user