Skip to content

Commit bfe9ee3

Browse files
committed
rp2040: move flash related functions into separate file from C imports for correct LSP. Fixes #3852
Signed-off-by: deadprogram <[email protected]>
1 parent 37a4fa2 commit bfe9ee3

File tree

2 files changed

+100
-81
lines changed

2 files changed

+100
-81
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//go:build rp2040
2+
3+
package machine
4+
5+
import (
6+
"bytes"
7+
"unsafe"
8+
)
9+
10+
// EnterBootloader should perform a system reset in preparation
11+
// to switch to the bootloader to flash new firmware.
12+
func EnterBootloader() {
13+
enterBootloader()
14+
}
15+
16+
// compile-time check for ensuring we fulfill BlockDevice interface
17+
var _ BlockDevice = flashBlockDevice{}
18+
19+
var Flash flashBlockDevice
20+
21+
type flashBlockDevice struct {
22+
}
23+
24+
// ReadAt reads the given number of bytes from the block device.
25+
func (f flashBlockDevice) ReadAt(p []byte, off int64) (n int, err error) {
26+
if readAddress(off) > FlashDataEnd() {
27+
return 0, errFlashCannotReadPastEOF
28+
}
29+
30+
data := unsafe.Slice((*byte)(unsafe.Pointer(readAddress(off))), len(p))
31+
copy(p, data)
32+
33+
return len(p), nil
34+
}
35+
36+
// WriteAt writes the given number of bytes to the block device.
37+
// Only word (32 bits) length data can be programmed.
38+
// If the length of p is not long enough it will be padded with 0xFF bytes.
39+
// This method assumes that the destination is already erased.
40+
func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
41+
return f.writeAt(p, off)
42+
}
43+
44+
// Size returns the number of bytes in this block device.
45+
func (f flashBlockDevice) Size() int64 {
46+
return int64(FlashDataEnd() - FlashDataStart())
47+
}
48+
49+
const writeBlockSize = 1 << 8
50+
51+
// WriteBlockSize returns the block size in which data can be written to
52+
// memory. It can be used by a client to optimize writes, non-aligned writes
53+
// should always work correctly.
54+
func (f flashBlockDevice) WriteBlockSize() int64 {
55+
return writeBlockSize
56+
}
57+
58+
const eraseBlockSizeValue = 1 << 12
59+
60+
func eraseBlockSize() int64 {
61+
return eraseBlockSizeValue
62+
}
63+
64+
// EraseBlockSize returns the smallest erasable area on this particular chip
65+
// in bytes. This is used for the block size in EraseBlocks.
66+
func (f flashBlockDevice) EraseBlockSize() int64 {
67+
return eraseBlockSize()
68+
}
69+
70+
// EraseBlocks erases the given number of blocks. An implementation may
71+
// transparently coalesce ranges of blocks into larger bundles if the chip
72+
// supports this. The start and len parameters are in block numbers, use
73+
// EraseBlockSize to map addresses to blocks.
74+
func (f flashBlockDevice) EraseBlocks(start, length int64) error {
75+
return f.eraseBlocks(start, length)
76+
}
77+
78+
// pad data if needed so it is long enough for correct byte alignment on writes.
79+
func (f flashBlockDevice) pad(p []byte) []byte {
80+
overflow := int64(len(p)) % f.WriteBlockSize()
81+
if overflow == 0 {
82+
return p
83+
}
84+
85+
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
86+
return append(p, padding...)
87+
}
88+
89+
// return the correct address to be used for write
90+
func writeAddress(off int64) uintptr {
91+
return readAddress(off) - uintptr(memoryStart)
92+
}
93+
94+
// return the correct address to be used for reads
95+
func readAddress(off int64) uintptr {
96+
return FlashDataStart() + uintptr(off)
97+
}

src/machine/machine_rp2040_rom.go

Lines changed: 3 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
package machine
44

55
import (
6-
"bytes"
76
"runtime/interrupt"
87
"unsafe"
98
)
@@ -136,40 +135,14 @@ void ram_func flash_erase_blocks(uint32_t offset, size_t count)
136135
*/
137136
import "C"
138137

139-
// EnterBootloader should perform a system reset in preparation
140-
// to switch to the bootloader to flash new firmware.
141-
func EnterBootloader() {
138+
func enterBootloader() {
142139
C.reset_usb_boot(0, 0)
143140
}
144141

145142
// Flash related code
146143
const memoryStart = C.XIP_BASE // memory start for purpose of erase
147144

148-
// compile-time check for ensuring we fulfill BlockDevice interface
149-
var _ BlockDevice = flashBlockDevice{}
150-
151-
var Flash flashBlockDevice
152-
153-
type flashBlockDevice struct {
154-
}
155-
156-
// ReadAt reads the given number of bytes from the block device.
157-
func (f flashBlockDevice) ReadAt(p []byte, off int64) (n int, err error) {
158-
if readAddress(off) > FlashDataEnd() {
159-
return 0, errFlashCannotReadPastEOF
160-
}
161-
162-
data := unsafe.Slice((*byte)(unsafe.Pointer(readAddress(off))), len(p))
163-
copy(p, data)
164-
165-
return len(p), nil
166-
}
167-
168-
// WriteAt writes the given number of bytes to the block device.
169-
// Only word (32 bits) length data can be programmed.
170-
// If the length of p is not long enough it will be padded with 0xFF bytes.
171-
// This method assumes that the destination is already erased.
172-
func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
145+
func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) {
173146
if writeAddress(off)+uintptr(C.XIP_BASE) > FlashDataEnd() {
174147
return 0, errFlashCannotWritePastEOF
175148
}
@@ -190,37 +163,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
190163
return len(padded), nil
191164
}
192165

193-
// Size returns the number of bytes in this block device.
194-
func (f flashBlockDevice) Size() int64 {
195-
return int64(FlashDataEnd() - FlashDataStart())
196-
}
197-
198-
const writeBlockSize = 1 << 8
199-
200-
// WriteBlockSize returns the block size in which data can be written to
201-
// memory. It can be used by a client to optimize writes, non-aligned writes
202-
// should always work correctly.
203-
func (f flashBlockDevice) WriteBlockSize() int64 {
204-
return writeBlockSize
205-
}
206-
207-
const eraseBlockSizeValue = 1 << 12
208-
209-
func eraseBlockSize() int64 {
210-
return eraseBlockSizeValue
211-
}
212-
213-
// EraseBlockSize returns the smallest erasable area on this particular chip
214-
// in bytes. This is used for the block size in EraseBlocks.
215-
func (f flashBlockDevice) EraseBlockSize() int64 {
216-
return eraseBlockSize()
217-
}
218-
219-
// EraseBlocks erases the given number of blocks. An implementation may
220-
// transparently coalesce ranges of blocks into larger bundles if the chip
221-
// supports this. The start and len parameters are in block numbers, use
222-
// EraseBlockSize to map addresses to blocks.
223-
func (f flashBlockDevice) EraseBlocks(start, length int64) error {
166+
func (f flashBlockDevice) eraseBlocks(start, length int64) error {
224167
address := writeAddress(start * f.EraseBlockSize())
225168
if address+uintptr(C.XIP_BASE) > FlashDataEnd() {
226169
return errFlashCannotErasePastEOF
@@ -233,24 +176,3 @@ func (f flashBlockDevice) EraseBlocks(start, length int64) error {
233176

234177
return nil
235178
}
236-
237-
// pad data if needed so it is long enough for correct byte alignment on writes.
238-
func (f flashBlockDevice) pad(p []byte) []byte {
239-
overflow := int64(len(p)) % f.WriteBlockSize()
240-
if overflow == 0 {
241-
return p
242-
}
243-
244-
padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow))
245-
return append(p, padding...)
246-
}
247-
248-
// return the correct address to be used for write
249-
func writeAddress(off int64) uintptr {
250-
return readAddress(off) - uintptr(C.XIP_BASE)
251-
}
252-
253-
// return the correct address to be used for reads
254-
func readAddress(off int64) uintptr {
255-
return FlashDataStart() + uintptr(off)
256-
}

0 commit comments

Comments
 (0)