Переглянути джерело

Ender 3 V2 BL24C16 EEPROM support (#18758)

Scott Lahteine 4 роки тому
джерело
коміт
451f48231d
Аккаунт користувача з таким Email не знайдено

+ 81
- 0
Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp Переглянути файл

@@ -0,0 +1,81 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * PersistentStore for Arduino-style EEPROM interface
25
+ * with simple implementations supplied by Marlin.
26
+ */
27
+
28
+#include "../../inc/MarlinConfig.h"
29
+
30
+#if ENABLED(IIC_BL24CXX_EEPROM)
31
+
32
+#include "../shared/eeprom_if.h"
33
+#include "../shared/eeprom_api.h"
34
+
35
+//
36
+// PersistentStore
37
+//
38
+
39
+#ifndef MARLIN_EEPROM_SIZE
40
+  #error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM."
41
+#endif
42
+
43
+size_t PersistentStore::capacity()    { return MARLIN_EEPROM_SIZE; }
44
+
45
+bool PersistentStore::access_start()  { eeprom_init(); return true; }
46
+bool PersistentStore::access_finish() { return true; }
47
+
48
+bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
49
+  while (size--) {
50
+    uint8_t v = *value;
51
+    uint8_t * const p = (uint8_t * const)pos;
52
+    // EEPROM has only ~100,000 write cycles,
53
+    // so only write bytes that have changed!
54
+    if (v != eeprom_read_byte(p)) {
55
+      eeprom_write_byte(p, v);
56
+      delay(2);
57
+      if (eeprom_read_byte(p) != v) {
58
+        SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
59
+        return true;
60
+      }
61
+    }
62
+    crc16(crc, &v, 1);
63
+    pos++;
64
+    value++;
65
+  }
66
+  return false;
67
+}
68
+
69
+bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
70
+  do {
71
+    uint8_t * const p = (uint8_t * const)pos;
72
+    uint8_t c = eeprom_read_byte(p);
73
+    if (writing) *value = c;
74
+    crc16(crc, &c, 1);
75
+    pos++;
76
+    value++;
77
+  } while (--size);
78
+  return false;
79
+}
80
+
81
+#endif // IIC_BL24CXX_EEPROM

+ 51
- 0
Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp Переглянути файл

@@ -0,0 +1,51 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * Platform-independent Arduino functions for I2C EEPROM.
25
+ * Enable USE_SHARED_EEPROM if not supplied by the framework.
26
+ */
27
+
28
+#include "../../inc/MarlinConfig.h"
29
+
30
+#if ENABLED(IIC_BL24CXX_EEPROM)
31
+
32
+#include "../../libs/BL24CXX.h"
33
+#include "../shared/eeprom_if.h"
34
+
35
+void eeprom_init() { BL24CXX::init(); }
36
+
37
+// ------------------------
38
+// Public functions
39
+// ------------------------
40
+
41
+void eeprom_write_byte(uint8_t *pos, unsigned char value) {
42
+  const unsigned eeprom_address = (unsigned)pos;
43
+  return BL24CXX::writeOneByte(eeprom_address, value);
44
+}
45
+
46
+uint8_t eeprom_read_byte(uint8_t *pos) {
47
+  const unsigned eeprom_address = (unsigned)pos;
48
+  return BL24CXX::readOneByte(eeprom_address);
49
+}
50
+
51
+#endif // IIC_BL24CXX_EEPROM

+ 19
- 1
Marlin/src/HAL/shared/eeprom_api.h Переглянути файл

@@ -29,20 +29,38 @@
29 29
 
30 30
 class PersistentStore {
31 31
 public:
32
+
33
+  // Total available persistent storage space (in bytes)
34
+  static size_t capacity();
35
+
36
+  // Prepare to read or write
32 37
   static bool access_start();
38
+
39
+  // Housecleaning after read or write
33 40
   static bool access_finish();
41
+
42
+  // Write one or more bytes of data and update the CRC
43
+  // Return 'true' on write error
34 44
   static bool write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc);
45
+
46
+  // Read one or more bytes of data and update the CRC
47
+  // Return 'true' on read error
35 48
   static bool read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing=true);
36
-  static size_t capacity();
37 49
 
50
+  // Write one or more bytes of data
51
+  // Return 'true' on write error
38 52
   static inline bool write_data(const int pos, const uint8_t* value, const size_t size=sizeof(uint8_t)) {
39 53
     int data_pos = pos;
40 54
     uint16_t crc = 0;
41 55
     return write_data(data_pos, value, size, &crc);
42 56
   }
43 57
 
58
+  // Write a single byte of data
59
+  // Return 'true' on write error
44 60
   static inline bool write_data(const int pos, const uint8_t value) { return write_data(pos, &value); }
45 61
 
62
+  // Read one or more bytes of data
63
+  // Return 'true' on read error
46 64
   static inline bool read_data(const int pos, uint8_t* value, const size_t size=1) {
47 65
     int data_pos = pos;
48 66
     uint16_t crc = 0;

+ 2
- 2
Marlin/src/MarlinCore.cpp Переглянути файл

@@ -72,7 +72,7 @@
72 72
 #endif
73 73
 
74 74
 #if ENABLED(IIC_BL24CXX_EEPROM)
75
-  #include "lcd/dwin/eeprom_BL24CXX.h"
75
+  #include "libs/BL24CXX.h"
76 76
 #endif
77 77
 
78 78
 #if ENABLED(DIRECT_STEPPING)
@@ -1171,7 +1171,7 @@ void setup() {
1171 1171
   #if ENABLED(IIC_BL24CXX_EEPROM)
1172 1172
     BL24CXX::init();
1173 1173
     const uint8_t err = BL24CXX::check();
1174
-    SERIAL_ECHO_TERNARY(err, "I2C_EEPROM Check ", "failed", "succeeded", "!\n");
1174
+    SERIAL_ECHO_TERNARY(err, "BL24CXX Check ", "failed", "succeeded", "!\n");
1175 1175
   #endif
1176 1176
 
1177 1177
   #if ENABLED(DWIN_CREALITY_LCD)

+ 36
- 0
Marlin/src/gcode/eeprom/M500-M504.cpp Переглянути файл

@@ -58,11 +58,47 @@ void GcodeSuite::M502() {
58 58
 #endif // !DISABLE_M503
59 59
 
60 60
 #if ENABLED(EEPROM_SETTINGS)
61
+
62
+  #if ENABLED(MARLIN_DEV_MODE)
63
+    #include "../../libs/hex_print_routines.h"
64
+  #endif
65
+
61 66
   /**
62 67
    * M504: Validate EEPROM Contents
63 68
    */
64 69
   void GcodeSuite::M504() {
70
+    #if ENABLED(MARLIN_DEV_MODE)
71
+      const bool dowrite = parser.seenval('W');
72
+      if (dowrite || parser.seenval('R')) {
73
+        uint8_t val = 0;
74
+        int addr = parser.value_ushort();
75
+        if (dowrite) {
76
+          val = parser.byteval('V');
77
+          persistentStore.write_data(addr, &val);
78
+          SERIAL_ECHOLNPAIR("Wrote address ", addr, " with ", int(val));
79
+        }
80
+        else {
81
+          if (parser.seenval('T')) {
82
+            const int endaddr = parser.value_ushort();
83
+            while (addr <= endaddr) {
84
+              persistentStore.read_data(addr, &val);
85
+              SERIAL_ECHOLNPAIR("0x", hex_word(addr), ":", hex_byte(val));
86
+              addr++;
87
+              safe_delay(10);
88
+            }
89
+            SERIAL_EOL();
90
+          }
91
+          else {
92
+            persistentStore.read_data(addr, &val);
93
+            SERIAL_ECHOLNPAIR("Read address ", addr, " and got ", int(val));
94
+          }
95
+        }
96
+        return;
97
+      }
98
+    #endif
99
+
65 100
     if (settings.validate())
66 101
       SERIAL_ECHO_MSG("EEPROM OK");
67 102
   }
103
+
68 104
 #endif

+ 3
- 0
Marlin/src/inc/Conditionals_post.h Переглянути файл

@@ -50,6 +50,8 @@
50 50
     #define USE_EMULATED_EEPROM 1
51 51
   #elif ANY(I2C_EEPROM, SPI_EEPROM)
52 52
     #define USE_WIRED_EEPROM    1
53
+  #elif ENABLED(IIC_BL24CXX_EEPROM)
54
+    // nothing
53 55
   #else
54 56
     #define USE_FALLBACK_EEPROM 1
55 57
   #endif
@@ -60,6 +62,7 @@
60 62
   #undef SDCARD_EEPROM_EMULATION
61 63
   #undef SRAM_EEPROM_EMULATION
62 64
   #undef FLASH_EEPROM_EMULATION
65
+  #undef IIC_BL24CXX_EEPROM
63 66
 #endif
64 67
 
65 68
 #ifdef TEENSYDUINO

+ 7
- 2
Marlin/src/inc/SanityCheck.h Переглянути файл

@@ -2131,8 +2131,13 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
2131 2131
  */
2132 2132
 #if ENABLED(EEPROM_SETTINGS)
2133 2133
   #if 1 < 0 \
2134
-    + ENABLED(I2C_EEPROM) + ENABLED(SPI_EEPROM) + ENABLED(QSPI_EEPROM) \
2135
-    + ENABLED(SDCARD_EEPROM_EMULATION) + ENABLED(FLASH_EEPROM_EMULATION) + ENABLED(SRAM_EEPROM_EMULATION)
2134
+    + ENABLED(I2C_EEPROM) \
2135
+    + ENABLED(SPI_EEPROM) \
2136
+    + ENABLED(QSPI_EEPROM) \
2137
+    + ENABLED(SDCARD_EEPROM_EMULATION) \
2138
+    + ENABLED(FLASH_EEPROM_EMULATION) \
2139
+    + ENABLED(SRAM_EEPROM_EMULATION) \
2140
+    + ENABLED(IIC_BL24CXX_EEPROM)
2136 2141
     #error "Please select only one method of EEPROM Persistent Storage."
2137 2142
   #endif
2138 2143
 #endif

+ 5
- 4
Marlin/src/lcd/dwin/dwin.cpp Переглянути файл

@@ -185,10 +185,11 @@ int temphot = 0, tempbed = 0;
185 185
 float zprobe_zoffset = 0;
186 186
 float last_zoffset = 0, last_probe_zoffset = 0;
187 187
 
188
-#define FONT_EEPROM_OFFSET 0
188
+#define DWIN_LANGUAGE_EEPROM_ADDRESS 0x01   // Between 0x01 and 0x63 (EEPROM_OFFSET-1)
189
+                                            // BL24CXX::check() uses 0x00
189 190
 
190 191
 void lcd_select_language(void) {
191
-  BL24CXX::read(FONT_EEPROM_OFFSET, (uint8_t*)&HMI_flag.language_flag, sizeof(HMI_flag.language_flag));
192
+  BL24CXX::read(DWIN_LANGUAGE_EEPROM_ADDRESS, (uint8_t*)&HMI_flag.language_flag, sizeof(HMI_flag.language_flag));
192 193
   if (HMI_flag.language_flag)
193 194
     DWIN_JPG_CacheTo1(Language_Chinese);
194 195
   else
@@ -198,12 +199,12 @@ void lcd_select_language(void) {
198 199
 void set_english_to_eeprom(void) {
199 200
   HMI_flag.language_flag = 0;
200 201
   DWIN_JPG_CacheTo1(Language_English);
201
-  BL24CXX::write(FONT_EEPROM_OFFSET, (uint8_t*)&HMI_flag.language_flag, sizeof(HMI_flag.language_flag));
202
+  BL24CXX::write(DWIN_LANGUAGE_EEPROM_ADDRESS, (uint8_t*)&HMI_flag.language_flag, sizeof(HMI_flag.language_flag));
202 203
 }
203 204
 void set_chinese_to_eeprom(void) {
204 205
   HMI_flag.language_flag = 1;
205 206
   DWIN_JPG_CacheTo1(Language_Chinese);
206
-  BL24CXX::write(FONT_EEPROM_OFFSET, (uint8_t*)&HMI_flag.language_flag, sizeof(HMI_flag.language_flag));
207
+  BL24CXX::write(DWIN_LANGUAGE_EEPROM_ADDRESS, (uint8_t*)&HMI_flag.language_flag, sizeof(HMI_flag.language_flag));
207 208
 }
208 209
 
209 210
 void show_plus_or_minus(uint8_t size, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value) {

+ 1
- 1
Marlin/src/lcd/dwin/dwin.h Переглянути файл

@@ -27,7 +27,7 @@
27 27
 
28 28
 #include "dwin_lcd.h"
29 29
 #include "rotary_encoder.h"
30
-#include "eeprom_BL24CXX.h"
30
+#include "../../libs/BL24CXX.h"
31 31
 
32 32
 #include <stdint.h>
33 33
 

+ 0
- 263
Marlin/src/lcd/dwin/eeprom_BL24CXX.cpp Переглянути файл

@@ -1,263 +0,0 @@
1
-/**
2
- * Marlin 3D Printer Firmware
3
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
- *
5
- * Based on Sprinter and grbl.
6
- * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
- *
8
- * This program is free software: you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation, either version 3 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
- *
21
- */
22
-
23
-/********************************************************************************
24
- * @file     eeprom_BL24CXX.cpp
25
- * @brief    i2c EEPROM for Ender 3 v2 board (4.2.2)
26
- ********************************************************************************/
27
-
28
-#include "../../inc/MarlinConfig.h"
29
-
30
-#if ENABLED(IIC_BL24CXX_EEPROM)
31
-
32
-#include "eeprom_BL24CXX.h"
33
-#include "../../MarlinCore.h"
34
-
35
-#include <stdlib.h>
36
-
37
-/******************** IIC ********************/
38
-
39
-// 初始化IIC
40
-void IIC::init() {
41
-  SET_OUTPUT(IIC_EEPROM_SDA);
42
-  SET_OUTPUT(IIC_EEPROM_SCL);
43
-
44
-  IIC_SCL_1();
45
-  IIC_SDA_1();
46
-}
47
-
48
-// 产生IIC起始信号
49
-void IIC::start() {
50
-  SDA_OUT();      // sda线输出
51
-  IIC_SDA_1();
52
-  IIC_SCL_1();
53
-  delay_us(4);
54
-  IIC_SDA_0(); // START:when CLK is high, DATA change form high to low
55
-  delay_us(4);
56
-  IIC_SCL_0(); // 钳住I2C总线,准备发送或接收数据
57
-}
58
-
59
-// 产生IIC停止信号
60
-void IIC::stop() {
61
-  SDA_OUT(); // sda线输出
62
-  IIC_SCL_0();
63
-  IIC_SDA_0(); // STOP:when CLK is high DATA change form low to high
64
-  delay_us(4);
65
-  IIC_SCL_1();
66
-  IIC_SDA_1(); // 发送I2C总线结束信号
67
-  delay_us(4);
68
-}
69
-
70
-// 等待应答信号到来
71
-// 返回值:1,接收应答失败
72
-//         0,接收应答成功
73
-uint8_t IIC::wait_ack() {
74
-  uint8_t ucErrTime=0;
75
-  SDA_IN();      // SDA设置为输入
76
-  IIC_SDA_1();delay_us(1);
77
-  IIC_SCL_1();delay_us(1);
78
-  while (READ_SDA()) {
79
-    ucErrTime++;
80
-    if (ucErrTime>250) {
81
-      stop();
82
-      return 1;
83
-    }
84
-  }
85
-  IIC_SCL_0(); // 时钟输出0
86
-  return 0;
87
-}
88
-
89
-// 产生ACK应答
90
-void IIC::ack() {
91
-  IIC_SCL_0();
92
-  SDA_OUT();
93
-  IIC_SDA_0();
94
-  delay_us(2);
95
-  IIC_SCL_1();
96
-  delay_us(2);
97
-  IIC_SCL_0();
98
-}
99
-
100
-// 不产生ACK应答
101
-void IIC::nAck() {
102
-  IIC_SCL_0();
103
-  SDA_OUT();
104
-  IIC_SDA_1();
105
-  delay_us(2);
106
-  IIC_SCL_1();
107
-  delay_us(2);
108
-  IIC_SCL_0();
109
-}
110
-
111
-// IIC发送一个字节
112
-// 返回从机有无应答
113
-// 1,有应答
114
-// 0,无应答
115
-void IIC::send_byte(uint8_t txd) {
116
-  SDA_OUT();
117
-  IIC_SCL_0(); // 拉低时钟开始数据传输
118
-  LOOP_L_N(t, 8) {
119
-    // IIC_SDA = (txd & 0x80) >> 7;
120
-    if (txd & 0x80) IIC_SDA_1(); else IIC_SDA_0();
121
-    txd <<= 1;
122
-    delay_us(2);   // 对TEA5767这三个延时都是必须的
123
-    IIC_SCL_1();
124
-    delay_us(2);
125
-    IIC_SCL_0();
126
-    delay_us(2);
127
-  }
128
-}
129
-
130
-// 读1个字节,ack=1时,发送ACK,ack=0,发送nACK
131
-uint8_t IIC::read_byte(unsigned char ack_chr) {
132
-  unsigned char receive = 0;
133
-  SDA_IN(); // SDA设置为输入
134
-  LOOP_L_N(i, 8) {
135
-    IIC_SCL_0();
136
-    delay_us(2);
137
-    IIC_SCL_1();
138
-    receive <<= 1;
139
-    if (READ_SDA()) receive++;
140
-    delay_us(1);
141
-  }
142
-  ack_chr ? ack() : nAck(); // 发送ACK / 发送nACK
143
-  return receive;
144
-}
145
-
146
-/******************** EEPROM ********************/
147
-
148
-// 初始化IIC接口
149
-void BL24CXX::init() { IIC::init(); }
150
-
151
-// 在BL24CXX指定地址读出一个数据
152
-// ReadAddr:开始读数的地址
153
-// 返回值  :读到的数据
154
-uint8_t BL24CXX::readOneByte(uint16_t ReadAddr) {
155
-  uint8_t temp = 0;
156
-  IIC::start();
157
-  if (EE_TYPE > BL24C16) {
158
-    IIC::send_byte(0xA0);     // 发送写命令
159
-    IIC::wait_ack();
160
-    IIC::send_byte(ReadAddr >> 8); // 发送高地址
161
-    IIC::wait_ack();
162
-  }
163
-  else
164
-    IIC::send_byte(0xA0 + ((ReadAddr >> 8) << 1));   // 发送器件地址0xA0,写数据
165
-
166
-  IIC::wait_ack();
167
-  IIC::send_byte(ReadAddr & 0xFF); // 发送低地址
168
-  IIC::wait_ack();
169
-  IIC::start();
170
-  IIC::send_byte(0xA1);           // 进入接收模式
171
-  IIC::wait_ack();
172
-  temp = IIC::read_byte(0);
173
-  IIC::stop(); // 产生一个停止条件
174
-  return temp;
175
-}
176
-
177
-// 在BL24CXX指定地址写入一个数据
178
-// WriteAddr  :写入数据的目的地址
179
-// DataToWrite:要写入的数据
180
-void BL24CXX::writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite) {
181
-  IIC::start();
182
-  if (EE_TYPE > BL24C16) {
183
-    IIC::send_byte(0xA0);      // 发送写命令
184
-    IIC::wait_ack();
185
-    IIC::send_byte(WriteAddr >> 8); // 发送高地址
186
-  }
187
-  else {
188
-    IIC::send_byte(0xA0 + ((WriteAddr >> 8) << 1));   // 发送器件地址0xA0,写数据
189
-  }
190
-  IIC::wait_ack();
191
-  IIC::send_byte(WriteAddr & 0xFF); // 发送低地址
192
-  IIC::wait_ack();
193
-  IIC::send_byte(DataToWrite);     // 发送字节
194
-  IIC::wait_ack();
195
-  IIC::stop(); // 产生一个停止条件
196
-  delay(10);
197
-}
198
-
199
-// 在BL24CXX里面的指定地址开始写入长度为Len的数据
200
-// 该函数用于写入16bit或者32bit的数据.
201
-// WriteAddr  :开始写入的地址
202
-// DataToWrite:数据数组首地址
203
-// Len        :要写入数据的长度2,4
204
-void BL24CXX::writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len) {
205
-  LOOP_L_N(t, Len)
206
-    writeOneByte(WriteAddr + t, (DataToWrite >> (8 * t)) & 0xFF);
207
-}
208
-
209
-// 在BL24CXX里面的指定地址开始读出长度为Len的数据
210
-// 该函数用于读出16bit或者32bit的数据.
211
-// ReadAddr   :开始读出的地址
212
-// 返回值     :数据
213
-// Len        :要读出数据的长度2,4
214
-uint32_t BL24CXX::readLenByte(uint16_t ReadAddr, uint8_t Len) {
215
-  uint32_t temp = 0;
216
-  LOOP_L_N(t, Len) {
217
-    temp <<= 8;
218
-    temp += readOneByte(ReadAddr + Len - t - 1);
219
-  }
220
-  return temp;
221
-}
222
-
223
-// 检查BL24CXX是否正常
224
-// 这里用了24XX的最后一个地址(255)来存储标志字.
225
-// 如果用其他24C系列,这个地址要修改
226
-// 返回1:检测失败
227
-// 返回0:检测成功
228
-uint8_t BL24CXX::check() {
229
-  uint8_t temp;
230
-  temp = readOneByte(255); // 避免每次开机都写BL24CXX
231
-  if (temp == 'U') return 0;
232
-  else { // 排除第一次初始化的情况
233
-    writeOneByte(255, 'U');
234
-    temp = readOneByte(255);
235
-    if (temp == 'U') return 0;
236
-  }
237
-  return 1;
238
-}
239
-
240
-// 在BL24CXX里面的指定地址开始读出指定个数的数据
241
-// ReadAddr :开始读出的地址 对24c02为0~255
242
-// pBuffer  :数据数组首地址
243
-// NumToRead:要读出数据的个数
244
-void BL24CXX::read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead) {
245
-  while (NumToRead) {
246
-    *pBuffer++ = readOneByte(ReadAddr++);
247
-    NumToRead--;
248
-  }
249
-}
250
-
251
-// 在BL24CXX里面的指定地址开始写入指定个数的数据
252
-// WriteAddr :开始写入的地址 对24c02为0~255
253
-// pBuffer   :数据数组首地址
254
-// NumToWrite:要写入数据的个数
255
-void BL24CXX::write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite) {
256
-  while (NumToWrite--) {
257
-    writeOneByte(WriteAddr, *pBuffer);
258
-    WriteAddr++;
259
-    pBuffer++;
260
-  }
261
-}
262
-
263
-#endif // IIC_BL24CXX_EEPROM

+ 273
- 0
Marlin/src/libs/BL24CXX.cpp Переглянути файл

@@ -0,0 +1,273 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ *
4
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
+ *
19
+ */
20
+
21
+#include "../inc/MarlinConfig.h"
22
+
23
+#if ENABLED(IIC_BL24CXX_EEPROM)
24
+
25
+/**
26
+ * PersistentStore for Arduino-style EEPROM interface
27
+ * with simple implementations supplied by Marlin.
28
+ */
29
+
30
+#include "BL24CXX.h"
31
+#include <libmaple/gpio.h>
32
+
33
+#ifndef EEPROM_WRITE_DELAY
34
+  #define EEPROM_WRITE_DELAY    10
35
+#endif
36
+#ifndef EEPROM_DEVICE_ADDRESS
37
+  #define EEPROM_DEVICE_ADDRESS (0x50 << 1)
38
+#endif
39
+
40
+// IO direction setting
41
+#define SDA_IN()  do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 8 << 12; }while(0)
42
+#define SDA_OUT() do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 3 << 12; }while(0)
43
+
44
+// IO ops
45
+#define IIC_SCL_0()   WRITE(IIC_EEPROM_SCL, LOW)
46
+#define IIC_SCL_1()   WRITE(IIC_EEPROM_SCL, HIGH)
47
+#define IIC_SDA_0()   WRITE(IIC_EEPROM_SDA, LOW)
48
+#define IIC_SDA_1()   WRITE(IIC_EEPROM_SDA, HIGH)
49
+#define READ_SDA()    READ(IIC_EEPROM_SDA)
50
+
51
+//
52
+// Simple IIC interface via libmaple
53
+//
54
+
55
+// Initialize IIC
56
+void IIC::init() {
57
+  SET_OUTPUT(IIC_EEPROM_SDA);
58
+  SET_OUTPUT(IIC_EEPROM_SCL);
59
+  IIC_SCL_1();
60
+  IIC_SDA_1();
61
+}
62
+
63
+// Generate IIC start signal
64
+void IIC::start() {
65
+  SDA_OUT();    // SDA line output
66
+  IIC_SDA_1();
67
+  IIC_SCL_1();
68
+  delay_us(4);
69
+  IIC_SDA_0();  // START:when CLK is high, DATA change from high to low
70
+  delay_us(4);
71
+  IIC_SCL_0();  // Clamp the I2C bus, ready to send or receive data
72
+}
73
+
74
+// Generate IIC stop signal
75
+void IIC::stop() {
76
+  SDA_OUT();    // SDA line output
77
+  IIC_SCL_0();
78
+  IIC_SDA_0();  // STOP:when CLK is high DATA change from low to high
79
+  delay_us(4);
80
+  IIC_SCL_1();
81
+  IIC_SDA_1();  // Send I2C bus end signal
82
+  delay_us(4);
83
+}
84
+
85
+// Wait for the response signal to arrive
86
+// 1 = failed to receive response
87
+// 0 = response received
88
+uint8_t IIC::wait_ack() {
89
+  uint8_t ucErrTime = 0;
90
+  SDA_IN();      // SDA is set as input
91
+  IIC_SDA_1(); delay_us(1);
92
+  IIC_SCL_1(); delay_us(1);
93
+  while (READ_SDA()) {
94
+    if (++ucErrTime > 250) {
95
+      stop();
96
+      return 1;
97
+    }
98
+  }
99
+  IIC_SCL_0(); // Clock output 0
100
+  return 0;
101
+}
102
+
103
+// Generate ACK response
104
+void IIC::ack() {
105
+  IIC_SCL_0();
106
+  SDA_OUT();
107
+  IIC_SDA_0();
108
+  delay_us(2);
109
+  IIC_SCL_1();
110
+  delay_us(2);
111
+  IIC_SCL_0();
112
+}
113
+
114
+// No ACK response
115
+void IIC::nAck() {
116
+  IIC_SCL_0();
117
+  SDA_OUT();
118
+  IIC_SDA_1();
119
+  delay_us(2);
120
+  IIC_SCL_1();
121
+  delay_us(2);
122
+  IIC_SCL_0();
123
+}
124
+
125
+// Send one IIC byte
126
+// Return whether the slave responds
127
+// 1 = there is a response
128
+// 0 = no response
129
+void IIC::send_byte(uint8_t txd) {
130
+  SDA_OUT();
131
+  IIC_SCL_0(); // Pull down the clock to start data transmission
132
+  LOOP_L_N(t, 8) {
133
+    // IIC_SDA = (txd & 0x80) >> 7;
134
+    if (txd & 0x80) IIC_SDA_1(); else IIC_SDA_0();
135
+    txd <<= 1;
136
+    delay_us(2);   // All three delays are necessary for TEA5767
137
+    IIC_SCL_1();
138
+    delay_us(2);
139
+    IIC_SCL_0();
140
+    delay_us(2);
141
+  }
142
+}
143
+
144
+// Read 1 byte, when ack=1, send ACK, ack=0, send nACK
145
+uint8_t IIC::read_byte(unsigned char ack_chr) {
146
+  unsigned char receive = 0;
147
+  SDA_IN(); // SDA is set as input
148
+  LOOP_L_N(i, 8) {
149
+    IIC_SCL_0();
150
+    delay_us(2);
151
+    IIC_SCL_1();
152
+    receive <<= 1;
153
+    if (READ_SDA()) receive++;
154
+    delay_us(1);
155
+  }
156
+  ack_chr ? ack() : nAck(); // Send ACK / send nACK
157
+  return receive;
158
+}
159
+
160
+/******************** EEPROM ********************/
161
+
162
+// Initialize the IIC interface
163
+void BL24CXX::init() { IIC::init(); }
164
+
165
+// Read a byte at the specified address
166
+// ReadAddr: the address to start reading
167
+// Return: the byte read
168
+uint8_t BL24CXX::readOneByte(uint16_t ReadAddr) {
169
+  uint8_t temp = 0;
170
+  IIC::start();
171
+  if (EE_TYPE > BL24C16) {
172
+    IIC::send_byte(EEPROM_DEVICE_ADDRESS);        // Send write command
173
+    IIC::wait_ack();
174
+    IIC::send_byte(ReadAddr >> 8);                // Send high address
175
+    IIC::wait_ack();
176
+  }
177
+  else
178
+    IIC::send_byte(EEPROM_DEVICE_ADDRESS + ((ReadAddr >> 8) << 1)); // Send device address 0xA0, write data
179
+
180
+  IIC::wait_ack();
181
+  IIC::send_byte(ReadAddr & 0xFF);                // Send low address
182
+  IIC::wait_ack();
183
+  IIC::start();
184
+  IIC::send_byte(EEPROM_DEVICE_ADDRESS | 0x01);   // Send byte
185
+  IIC::wait_ack();
186
+  temp = IIC::read_byte(0);
187
+  IIC::stop();                                    // Generate a stop condition
188
+  return temp;
189
+}
190
+
191
+// Write a data at the address specified by BL24CXX
192
+// WriteAddr: The destination address for writing data
193
+// DataToWrite: the data to be written
194
+void BL24CXX::writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite) {
195
+  IIC::start();
196
+  if (EE_TYPE > BL24C16) {
197
+    IIC::send_byte(EEPROM_DEVICE_ADDRESS);        // Send write command
198
+    IIC::wait_ack();
199
+    IIC::send_byte(WriteAddr >> 8);               // Send high address
200
+  }
201
+  else
202
+    IIC::send_byte(EEPROM_DEVICE_ADDRESS + ((WriteAddr >> 8) << 1)); // Send device address 0xA0, write data
203
+
204
+  IIC::wait_ack();
205
+  IIC::send_byte(WriteAddr & 0xFF);               // Send low address
206
+  IIC::wait_ack();
207
+  IIC::send_byte(DataToWrite);                    // Receiving mode
208
+  IIC::wait_ack();
209
+  IIC::stop();                                    // Generate a stop condition
210
+  delay(10);
211
+}
212
+
213
+// Start writing data of length Len at the specified address in BL24CXX
214
+// This function is used to write 16bit or 32bit data.
215
+// WriteAddr: the address to start writing
216
+// DataToWrite: the first address of the data array
217
+// Len: The length of the data to be written 2, 4
218
+void BL24CXX::writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len) {
219
+  LOOP_L_N(t, Len)
220
+    writeOneByte(WriteAddr + t, (DataToWrite >> (8 * t)) & 0xFF);
221
+}
222
+
223
+// Start reading data of length Len from the specified address in BL24CXX
224
+// This function is used to read 16bit or 32bit data.
225
+// ReadAddr: the address to start reading
226
+// Return value: data
227
+// Len: The length of the data to be read 2,4
228
+uint32_t BL24CXX::readLenByte(uint16_t ReadAddr, uint8_t Len) {
229
+  uint32_t temp = 0;
230
+  LOOP_L_N(t, Len) {
231
+    temp <<= 8;
232
+    temp += readOneByte(ReadAddr + Len - t - 1);
233
+  }
234
+  return temp;
235
+}
236
+
237
+// Check if BL24CXX is normal
238
+// Return 1: Detection failed
239
+// return 0: detection is successful
240
+#define BL24CXX_TEST_ADDRESS 0x00
241
+#define BL24CXX_TEST_VALUE   0x55
242
+
243
+bool BL24CXX::_check() {
244
+  return (readOneByte(BL24CXX_TEST_ADDRESS) != BL24CXX_TEST_VALUE); // false = success!
245
+}
246
+
247
+bool BL24CXX::check() {
248
+  if (_check()) {                                           // Value was written? Good EEPROM!
249
+    writeOneByte(BL24CXX_TEST_ADDRESS, BL24CXX_TEST_VALUE); // Write now and check.
250
+    return _check();
251
+  }
252
+  return false; // success!
253
+}
254
+
255
+// Start reading the specified number of data at the specified address in BL24CXX
256
+// ReadAddr: The address to start reading is 0~255 for 24c02
257
+// pBuffer: the first address of the data array
258
+// NumToRead: the number of data to be read
259
+void BL24CXX::read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead) {
260
+  for (; NumToRead; NumToRead--)
261
+    *pBuffer++ = readOneByte(ReadAddr++);
262
+}
263
+
264
+// Start writing the specified number of data at the specified address in BL24CXX
265
+// WriteAddr: the address to start writing, 0~255 for 24c02
266
+// pBuffer: the first address of the data array
267
+// NumToWrite: the number of data to be written
268
+void BL24CXX::write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite) {
269
+  for (; NumToWrite; NumToWrite--, WriteAddr++)
270
+    writeOneByte(WriteAddr, *pBuffer++);
271
+}
272
+
273
+#endif // IIC_BL24CXX_EEPROM

Marlin/src/lcd/dwin/eeprom_BL24CXX.h → Marlin/src/libs/BL24CXX.h Переглянути файл

@@ -22,25 +22,12 @@
22 22
 #pragma once
23 23
 
24 24
 /********************************************************************************
25
- * @file     eeprom_BL24CXX.h
25
+ * @file     BL24CXX.h
26 26
  * @brief    i2c EEPROM for Ender 3 v2 board (4.2.2)
27 27
  ********************************************************************************/
28 28
 
29
-#include <libmaple/gpio.h>
30
-
31 29
 /******************** IIC ********************/
32 30
 
33
-//IO direction setting
34
-#define SDA_IN()  do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 8 << 12; }while(0)
35
-#define SDA_OUT() do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 3 << 12; }while(0)
36
-
37
-//IO operation function
38
-#define IIC_SCL_0()   WRITE(IIC_EEPROM_SCL, LOW)
39
-#define IIC_SCL_1()   WRITE(IIC_EEPROM_SCL, HIGH)
40
-#define IIC_SDA_0()   WRITE(IIC_EEPROM_SDA, LOW)
41
-#define IIC_SDA_1()   WRITE(IIC_EEPROM_SDA, HIGH)
42
-#define READ_SDA()    READ(IIC_EEPROM_SDA)
43
-
44 31
 class BL24CXX;
45 32
 
46 33
 // All operation functions of IIC
@@ -55,9 +42,6 @@ protected:
55 42
   static uint8_t wait_ack();         // IIC waits for ACK signal
56 43
   static void ack();                 // IIC sends ACK signal
57 44
   static void nAck();                // IIC does not send ACK signal
58
-
59
-  static void write_one_byte(uint8_t daddr, uint8_t addr, uint8_t data);
60
-  static uint8_t read_one_byte(uint8_t daddr, uint8_t addr);
61 45
 };
62 46
 
63 47
 /******************** EEPROM ********************/
@@ -74,13 +58,15 @@ protected:
74 58
 #define EE_TYPE BL24C16
75 59
 
76 60
 class BL24CXX {
61
+private:
62
+  static bool _check();                                                             // Check the device
77 63
 public:
78
-  static void init(); // Initialize IIC
79
-  static uint8_t check();  // Check the device
80
-  static uint8_t readOneByte(uint16_t ReadAddr);                       // Read a byte at the specified address
81
-  static void writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite);   // Write a byte at the specified address
82
-  static void writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len);// The specified address begins to write the data of the specified length
83
-  static uint32_t readLenByte(uint16_t ReadAddr, uint8_t Len);         // The specified address starts to read the data of the specified length
84
-  static void write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite);  // Write the specified length of data from the specified address
85
-  static void read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead);     // Read the data of the specified length from the specified address
64
+  static void init();                                                               // Initialize IIC
65
+  static bool check();                                                              // Check / recheck the device
66
+  static uint8_t readOneByte(uint16_t ReadAddr);                                    // Read a byte at the specified address
67
+  static void writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite);                // Write a byte at the specified address
68
+  static void writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len);  // The specified address begins to write the data of the specified length
69
+  static uint32_t readLenByte(uint16_t ReadAddr, uint8_t Len);                      // The specified address starts to read the data of the specified length
70
+  static void write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite);     // Write the specified length of data from the specified address
71
+  static void read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead);        // Read the data of the specified length from the specified address
86 72
 };

+ 1
- 1
Marlin/src/libs/hex_print_routines.cpp Переглянути файл

@@ -23,7 +23,7 @@
23 23
 #include "../inc/MarlinConfig.h"
24 24
 #include "../gcode/parser.h"
25 25
 
26
-#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG)
26
+#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE)
27 27
 
28 28
   #include "hex_print_routines.h"
29 29
 

+ 4
- 4
Marlin/src/pins/stm32f1/pins_CREALITY_V4.h Переглянути файл

@@ -47,12 +47,12 @@
47 47
   #if ENABLED(IIC_BL24CXX_EEPROM)
48 48
     #define IIC_EEPROM_SDA                  PA11
49 49
     #define IIC_EEPROM_SCL                  PA12
50
-    //#define MARLIN_EEPROM_SIZE 0x4000           // 16Kb (24c16)
50
+    #define MARLIN_EEPROM_SIZE 0x800              // 2Kb (24C16)
51
+  #else
52
+    #define SDCARD_EEPROM_EMULATION               // SD EEPROM until all EEPROM is BL24CXX
53
+    #define MARLIN_EEPROM_SIZE 0x800              // 2Kb
51 54
   #endif
52 55
 
53
-  #define SDCARD_EEPROM_EMULATION                 // SD EEPROM until all EEPROM is BL24CXX
54
-  #define MARLIN_EEPROM_SIZE 0x1000               // 4Kb
55
-
56 56
   // SPI
57 57
   //#define SPI_EEPROM                            // EEPROM on SPI-0
58 58
   //#define SPI_CHAN_EEPROM1  ?

+ 1
- 0
buildroot/tests/STM32F103RET6_creality-tests Переглянути файл

@@ -10,6 +10,7 @@ set -e
10 10
 # Build with configs included in the PR
11 11
 #
12 12
 use_example_configs "Creality/Ender-3 V2"
13
+opt_enable MARLIN_DEV_MODE
13 14
 exec_test $1 $2 "Ender 3 v2"
14 15
 
15 16
 restore_configs

Завантаження…
Відмінити
Зберегти