@@ -5,11 +5,95 @@ package machine
5
5
6
6
import (
7
7
"device/avr"
8
+ "errors"
8
9
"runtime/interrupt"
9
10
"runtime/volatile"
10
11
"unsafe"
11
12
)
12
13
14
+ // EEPROM on ATMega
15
+ type EEPROM struct {
16
+ }
17
+
18
+ var EEPROM0 = EEPROM {}
19
+
20
+ // setAddress sets the address for a given read or write into the MCUs EEARH/L register.
21
+ func (e EEPROM ) setAddress (addr int16 ) error {
22
+ if addr < 0 || addr > int16 (e .Size ()) {
23
+ return errors .New ("address provided is out of bounds" )
24
+ }
25
+
26
+ avr .EEARH .Set (uint8 (addr >> 8 ))
27
+ avr .EEARL .Set (uint8 (addr & 0xFF ))
28
+
29
+ return nil
30
+ }
31
+
32
+ // WriteAt writes len(data) bytes in the EEPROMs at the provided offset.
33
+ func (e EEPROM ) WriteAt (data []byte , off int64 ) (int , error ) {
34
+ written := 0
35
+ for i , value := range data {
36
+ if err := e .WriteByteAt (value , off + int64 (i )); err != nil {
37
+ return written , err
38
+ }
39
+ written ++
40
+ }
41
+ return written , nil
42
+ }
43
+
44
+ // WriteByteAt performs the logic to writes a byte into the EEPROM at the given address.
45
+ func (e EEPROM ) WriteByteAt (value byte , addr int64 ) error {
46
+ for avr .EECR .HasBits (avr .EECR_EEPE ) {
47
+ }
48
+
49
+ if err := e .setAddress (int16 (addr )); err != nil {
50
+ return err
51
+ }
52
+
53
+ avr .EEDR .Set (value )
54
+
55
+ avr .EECR .SetBits (avr .EECR_EEMPE )
56
+ avr .EECR .SetBits (avr .EECR_EEPE )
57
+
58
+ return nil
59
+ }
60
+
61
+ // ReadAt reads exactly len(buf) into buf at the offset. It will return the amount of bytes copied or an error if one exists.
62
+ // The buffer cannot be empty, and an an error is thrown if fewer bytes are read than the size of the buffer.
63
+ func (e EEPROM ) ReadAt (buf []byte , off int64 ) (int , error ) {
64
+ if len (buf ) == 0 {
65
+ return 0 , nil
66
+ }
67
+
68
+ read := 0
69
+ for i := 0 ; i < len (buf ); i ++ {
70
+ val , err := e .ReadByteAt (off + int64 (i ))
71
+ if err != nil {
72
+ return read , err
73
+ }
74
+
75
+ buf [i ] = val
76
+
77
+ read ++
78
+ }
79
+
80
+ return len (buf ), nil
81
+ }
82
+
83
+ // ReadByteAt reads and returns the byte at the specified address. An error is returned if there is a failure to read.
84
+ func (e EEPROM ) ReadByteAt (addr int64 ) (byte , error ) {
85
+ for avr .EECR .HasBits (avr .EECR_EEPE ) {
86
+ }
87
+
88
+ if err := e .setAddress (int16 (addr )); err != nil {
89
+ return byte (0 ), err
90
+ }
91
+
92
+ avr .EECR .SetBits (avr .EECR_EERE )
93
+
94
+ return avr .EEDR .Get (), nil
95
+ }
96
+
13
97
// I2C on AVR.
14
98
type I2C struct {
15
99
}
0 commit comments