ESPHome  2025.2.0
waveshare_epaper.h
Go to the documentation of this file.
1 #pragma once
2 
6 
7 namespace esphome {
8 namespace waveshare_epaper {
9 
11  public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
12  spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_2MHZ> {
13  public:
14  void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
15  float get_setup_priority() const override;
17  void set_busy_pin(GPIOPin *busy) { this->busy_pin_ = busy; }
18  void set_reset_duration(uint32_t reset_duration) { this->reset_duration_ = reset_duration; }
19 
20  void command(uint8_t value);
21  void data(uint8_t value);
22  void cmd_data(const uint8_t *data, size_t length);
23 
24  virtual void display() = 0;
25  virtual void initialize() = 0;
26  virtual void deep_sleep() = 0;
27 
28  void update() override;
29 
30  void setup() override;
31 
32  void on_safe_shutdown() override;
33 
34  protected:
35  bool wait_until_idle_();
36 
37  void setup_pins_();
38 
39  void reset_() {
40  if (this->reset_pin_ != nullptr) {
41  this->reset_pin_->digital_write(false);
42  delay(reset_duration_); // NOLINT
43  this->reset_pin_->digital_write(true);
44  delay(20);
45  }
46  }
47 
48  virtual int get_width_controller() { return this->get_width_internal(); };
49 
50  virtual uint32_t get_buffer_length_() = 0; // NOLINT(readability-identifier-naming)
51  uint32_t reset_duration_{200};
52 
53  void start_command_();
54  void end_command_();
55  void start_data_();
56  void end_data_();
57 
58  GPIOPin *reset_pin_{nullptr};
60  GPIOPin *busy_pin_{nullptr};
61  virtual uint32_t idle_timeout_() { return 1000u; } // NOLINT(readability-identifier-naming)
62 };
63 
65  public:
66  void fill(Color color) override;
67 
69 
70  protected:
71  void draw_absolute_pixel_internal(int x, int y, Color color) override;
72  uint32_t get_buffer_length_() override;
73 };
74 
76  public:
77  void fill(Color color) override;
78 
80 
81  protected:
82  void draw_absolute_pixel_internal(int x, int y, Color color) override;
83  uint32_t get_buffer_length_() override;
84 };
85 
87  public:
88  uint8_t color_to_hex(Color color);
89  void fill(Color color) override;
90 
92 
93  protected:
94  void draw_absolute_pixel_internal(int x, int y, Color color) override;
95  uint32_t get_buffer_length_() override;
96  void setup() override;
97  void init_internal_7c_(uint32_t buffer_length);
98 
99  static const int NUM_BUFFERS = 10;
100  uint8_t *buffers_[NUM_BUFFERS];
101 };
102 
114 };
115 
117  public:
119 
120  void initialize() override;
121 
122  void dump_config() override;
123 
124  void display() override;
125 
126  void deep_sleep() override {
127  switch (this->model_) {
128  // Models with specific deep sleep command and data
133  // COMMAND DEEP SLEEP MODE
134  this->command(0x10);
135  this->data(0x01);
136  break;
137  // Other models default to simple deep sleep command
138  default:
139  // COMMAND DEEP SLEEP
140  this->command(0x10);
141  break;
142  }
143  if (this->model_ != WAVESHARE_EPAPER_2_13_IN_V2) {
144  // From panel specification:
145  // "After this command initiated, the chip will enter Deep Sleep Mode, BUSY pad will keep output high."
146  this->wait_until_idle_();
147  }
148  }
149 
150  void set_full_update_every(uint32_t full_update_every);
151 
152  protected:
153  void write_lut_(const uint8_t *lut, uint8_t size);
154 
155  void init_display_();
156 
157  int get_width_internal() override;
158 
159  int get_height_internal() override;
160 
161  int get_width_controller() override;
162 
163  uint32_t full_update_every_{30};
164  uint32_t at_update_{0};
166  uint32_t idle_timeout_() override;
167 
168  bool deep_sleep_between_updates_{false};
169 };
170 
182 };
183 
185  public:
186  void initialize() override;
187 
188  void display() override;
189 
190  void dump_config() override;
191 
192  void deep_sleep() override {
193  this->command(0x10);
194  this->data(0x01);
195  }
196 
197  protected:
198  int get_width_internal() override;
199  int get_height_internal() override;
200 };
201 
203  public:
204  void initialize() override;
205 
206  void display() override;
207 
208  void dump_config() override;
209 
210  void deep_sleep() override {
211  // COMMAND DEEP SLEEP
212  this->command(0x07);
213  this->data(0xA5); // check byte
214  }
215 
216  protected:
217  int get_width_internal() override;
218  int get_height_internal() override;
219 };
220 
222  public:
223  void initialize() override;
224 
225  void display() override;
226 
227  void dump_config() override;
228 
229  void deep_sleep() override {
230  // COMMAND VCOM_AND_DATA_INTERVAL_SETTING
231  this->command(0x50);
232  // COMMAND POWER OFF
233  this->command(0x02);
234  this->wait_until_idle_();
235  // COMMAND DEEP SLEEP
236  this->command(0x07); // deep sleep
237  this->data(0xA5); // check byte
238  }
239 
240  protected:
241  int get_width_internal() override;
242  int get_height_internal() override;
243 };
244 
246  public:
247  void initialize() override;
248 
249  void display() override;
250 
251  void dump_config() override;
252 
253  void deep_sleep() override {
254  // COMMAND DEEP SLEEP
255  this->command(0x10);
256  this->data(0x01);
257  }
258 
259  protected:
260  int get_width_internal() override;
261  int get_height_internal() override;
262 };
263 
264 class GDEW029T5 : public WaveshareEPaper {
265  public:
266  void initialize() override;
267 
268  void display() override;
269 
270  void dump_config() override;
271 
272  void deep_sleep() override;
273  void set_full_update_every(uint32_t full_update_every);
274 
275  protected:
276  void init_display_();
277  void init_full_();
278  void init_partial_();
279  void write_lut_(const uint8_t *lut, uint8_t size);
280  void power_off_();
281  void power_on_();
282  int get_width_internal() override;
283 
284  int get_height_internal() override;
285 
286  private:
287  uint32_t full_update_every_{30};
288  uint32_t at_update_{0};
289  bool deep_sleep_between_updates_{false};
290  bool power_is_on_{false};
291  bool is_deep_sleep_{false};
292  uint8_t *old_buffer_{nullptr};
293 };
294 
295 class GDEY029T94 : public WaveshareEPaper {
296  public:
297  void initialize() override;
298 
299  void display() override;
300 
301  void dump_config() override;
302 
303  void deep_sleep() override {
304  this->command(0x10); // Enter deep sleep
305  this->data(0x01);
306  }
307 
308  protected:
309  int get_width_internal() override;
310 
311  int get_height_internal() override;
312 };
313 
315  public:
316  void initialize() override;
317 
318  void display() override;
319 
320  void dump_config() override;
321 
322  void deep_sleep() override { ; }
323 
324  protected:
325  int get_width_internal() override;
326 
327  int get_height_internal() override;
328 };
329 
330 class GDEW0154M09 : public WaveshareEPaper {
331  public:
332  void initialize() override;
333  void display() override;
334  void dump_config() override;
335  void deep_sleep() override;
336 
337  protected:
338  int get_width_internal() override;
339  int get_height_internal() override;
340 
341  private:
342  static const uint8_t CMD_DTM1_DATA_START_TRANS = 0x10;
343  static const uint8_t CMD_DTM2_DATA_START_TRANS2 = 0x13;
344  static const uint8_t CMD_DISPLAY_REFRESH = 0x12;
345  static const uint8_t CMD_AUTO_SEQ = 0x17;
346  static const uint8_t DATA_AUTO_PON_DSR_POF_DSLP = 0xA7;
347  static const uint8_t CMD_PSR_PANEL_SETTING = 0x00;
348  static const uint8_t CMD_UNDOCUMENTED_0x4D = 0x4D; // NOLINT
349  static const uint8_t CMD_UNDOCUMENTED_0xAA = 0xaa; // NOLINT
350  static const uint8_t CMD_UNDOCUMENTED_0xE9 = 0xe9; // NOLINT
351  static const uint8_t CMD_UNDOCUMENTED_0xB6 = 0xb6; // NOLINT
352  static const uint8_t CMD_UNDOCUMENTED_0xF3 = 0xf3; // NOLINT
353  static const uint8_t CMD_TRES_RESOLUTION_SETTING = 0x61;
354  static const uint8_t CMD_TCON_TCONSETTING = 0x60;
355  static const uint8_t CMD_CDI_VCOM_DATA_INTERVAL = 0x50;
356  static const uint8_t CMD_POF_POWER_OFF = 0x02;
357  static const uint8_t CMD_DSLP_DEEP_SLEEP = 0x07;
358  static const uint8_t DATA_DSLP_DEEP_SLEEP = 0xA5;
359  static const uint8_t CMD_PWS_POWER_SAVING = 0xe3;
360  static const uint8_t CMD_PON_POWER_ON = 0x04;
361  static const uint8_t CMD_PTL_PARTIAL_WINDOW = 0x90;
362 
363  uint8_t *lastbuff_ = nullptr;
364  void reset_();
365  void clear_();
366  void write_init_list_(const uint8_t *list);
367  void init_internal_();
368 };
369 
371  public:
372  void initialize() override;
373 
374  void display() override;
375 
376  void dump_config() override;
377 
378  void deep_sleep() override {
379  // COMMAND DEEP SLEEP
380  this->command(0x07);
381  this->data(0xA5); // check byte
382  }
383 
384  protected:
385  int get_width_internal() override;
386 
387  int get_height_internal() override;
388 };
389 
391  public:
392  void initialize() override;
393 
394  void display() override;
395 
396  void dump_config() override;
397 
398  void deep_sleep() override {
399  // COMMAND DEEP SLEEP
400  this->command(0x07);
401  this->data(0xA5); // check byte
402  }
403 
404  protected:
405  int get_width_internal() override;
406 
407  int get_height_internal() override;
408 };
409 
411  public:
413 
414  void initialize() override;
415 
416  void display() override;
417 
418  void dump_config() override;
419 
420  void deep_sleep() override;
421 
422  void set_full_update_every(uint32_t full_update_every);
423 
424  protected:
425  void write_lut_(const uint8_t *lut, uint8_t size);
426 
427  int get_width_internal() override;
428 
429  int get_height_internal() override;
430 
431  int get_width_controller() override;
432 
433  uint32_t full_update_every_{30};
434  uint32_t at_update_{0};
435 
436  private:
437  void reset_();
438 };
439 
441  public:
442  void initialize() override;
443 
444  void display() override;
445 
446  void dump_config() override;
447 
448  void deep_sleep() override {
449  // COMMAND DEEP SLEEP
450  this->command(0x10);
451  this->data(0x01);
452  }
453 
454  void set_full_update_every(uint32_t full_update_every);
455 
456  protected:
457  uint32_t full_update_every_{30};
458  uint32_t at_update_{0};
459  int get_width_internal() override;
460 
461  int get_height_internal() override;
462 };
463 
465  public:
466  void initialize() override;
467 
468  void display() override;
469 
470  void dump_config() override;
471 
472  void deep_sleep() override {
473  // COMMAND DEEP SLEEP
474  this->command(0x07);
475  this->data(0xA5);
476  }
477 
478  protected:
479  int get_width_internal() override;
480 
481  int get_height_internal() override;
482 };
483 
484 class GDEY042T81 : public WaveshareEPaper {
485  public:
486  GDEY042T81();
487 
488  void initialize() override;
489 
490  void display() override;
491 
492  void dump_config() override;
493 
494  void deep_sleep() override {
495  // COMMAND POWER OFF
496  this->command(0x22);
497  this->data(0x83);
498  this->command(0x20);
499  // COMMAND DEEP SLEEP
500  this->command(0x10);
501  this->data(0x01);
502  }
503 
504  void set_full_update_every(uint32_t full_update_every);
505 
506  protected:
507  uint32_t full_update_every_{30};
508  uint32_t at_update_{0};
509 
510  int get_width_internal() override;
511  int get_height_internal() override;
512  uint32_t idle_timeout_() override;
513 
514  private:
515  void reset_();
516  void update_full_();
517  void update_part_();
518  void init_display_();
519 };
520 
522  public:
523  void initialize() override;
524 
525  void display() override;
526 
527  void dump_config() override;
528 
529  void deep_sleep() override {
530  // COMMAND VCOM AND DATA INTERVAL SETTING
531  this->command(0x50);
532  this->data(0x17); // border floating
533 
534  // COMMAND VCM DC SETTING
535  this->command(0x82);
536  // COMMAND PANEL SETTING
537  this->command(0x00);
538 
539  delay(100); // NOLINT
540 
541  // COMMAND POWER SETTING
542  this->command(0x01);
543  this->data(0x00);
544  this->data(0x00);
545  this->data(0x00);
546  this->data(0x00);
547  this->data(0x00);
548  delay(100); // NOLINT
549 
550  // COMMAND POWER OFF
551  this->command(0x02);
552  this->wait_until_idle_();
553  // COMMAND DEEP SLEEP
554  this->command(0x07);
555  this->data(0xA5); // check byte
556  }
557 
558  protected:
559  int get_width_internal() override;
560 
561  int get_height_internal() override;
562 };
563 
565  public:
566  void initialize() override;
567 
568  void display() override;
569 
570  void dump_config() override;
571 
572  void deep_sleep() override {
573  // COMMAND VCOM AND DATA INTERVAL SETTING
574  this->command(0x50);
575  this->data(0xF7); // border floating
576 
577  // COMMAND POWER OFF
578  this->command(0x02);
579  this->wait_until_idle_();
580 
581  // COMMAND DEEP SLEEP
582  this->command(0x07);
583  this->data(0xA5); // check code
584  }
585 
586  protected:
587  int get_width_internal() override;
588 
589  int get_height_internal() override;
590 };
591 
593  public:
594  void initialize() override;
595 
596  void display() override;
597 
598  void dump_config() override;
599 
600  void deep_sleep() override {
601  // COMMAND VCOM AND DATA INTERVAL SETTING
602  this->command(0x50);
603  this->data(0xF7); // border floating
604 
605  // COMMAND POWER OFF
606  this->command(0x02);
607  this->wait_until_idle_();
608 
609  // COMMAND DEEP SLEEP
610  this->command(0x07);
611  this->data(0xA5); // check code
612  }
613 
614  protected:
615  int get_width_internal() override;
616 
617  int get_height_internal() override;
618 };
619 
621  public:
622  void initialize() override;
623 
624  void display() override;
625 
626  void dump_config() override;
627 
628  void deep_sleep() override {
629  // COMMAND POWER OFF
630  this->command(0x02);
631  this->wait_until_idle_();
632  // COMMAND DEEP SLEEP
633  this->command(0x07);
634  this->data(0xA5); // check byte
635  }
636 
637  protected:
638  int get_width_internal() override;
639 
640  int get_height_internal() override;
641 };
642 
644  public:
645  void initialize() override;
646 
647  void display() override;
648 
649  void dump_config() override;
650 
651  void deep_sleep() override {
652  // COMMAND VCOM AND DATA INTERVAL SETTING
653  this->command(0x50);
654  this->data(0x17); // border floating
655 
656  // COMMAND VCM DC SETTING
657  this->command(0x82);
658  // COMMAND PANEL SETTING
659  this->command(0x00);
660 
661  delay(100); // NOLINT
662 
663  // COMMAND POWER SETTING
664  this->command(0x01);
665  this->data(0x00);
666  this->data(0x00);
667  this->data(0x00);
668  this->data(0x00);
669  this->data(0x00);
670  delay(100); // NOLINT
671 
672  // COMMAND POWER OFF
673  this->command(0x02);
674  this->wait_until_idle_();
675  // COMMAND DEEP SLEEP
676  this->command(0x07);
677  this->data(0xA5); // check byte
678  }
679 
680  protected:
681  int get_width_internal() override;
682 
683  int get_height_internal() override;
684 };
685 
687  public:
688  void initialize() override;
689 
690  void display() override;
691 
692  void dump_config() override;
693 
694  protected:
695  int get_width_internal() override;
696 
697  int get_height_internal() override;
698 
699  uint32_t idle_timeout_() override;
700 
701  void deep_sleep() override { ; }
702 
703  bool wait_until_idle_();
704 
705  bool deep_sleep_between_updates_{true};
706 
707  void reset_() {
708  if (this->reset_pin_ != nullptr) {
709  this->reset_pin_->digital_write(true);
710  delay(20);
711  this->reset_pin_->digital_write(false);
712  delay(1);
713  this->reset_pin_->digital_write(true);
714  delay(20);
715  }
716  };
717 };
718 
720  public:
721  void initialize() override;
722 
723  void display() override;
724 
725  void dump_config() override;
726 
727  void deep_sleep() override {
728  // COMMAND POWER OFF
729  this->command(0x02);
730  this->wait_until_idle_();
731  // COMMAND DEEP SLEEP
732  this->command(0x07);
733  this->data(0xA5); // check byte
734  }
735 
736  protected:
737  int get_width_internal() override;
738 
739  int get_height_internal() override;
740 };
741 
743  public:
744  void initialize() override;
745 
746  void display() override;
747 
748  void dump_config() override;
749 
750  void deep_sleep() override {
751  // COMMAND POWER OFF
752  this->command(0x02);
753  this->wait_until_idle_();
754  // COMMAND DEEP SLEEP
755  this->command(0x07); // deep sleep
756  this->data(0xA5); // check byte
757  }
758 
759  protected:
760  int get_width_internal() override;
761 
762  int get_height_internal() override;
763 };
764 
766  public:
767  bool wait_until_idle_();
768 
769  void initialize() override;
770 
771  void display() override;
772 
773  void dump_config() override;
774 
775  void deep_sleep() override {
776  this->command(0x02); // Power off
777  this->wait_until_idle_();
778  this->command(0x07); // Deep sleep
779  this->data(0xA5);
780  }
781 
782  void clear_screen();
783 
784  protected:
785  int get_width_internal() override;
786 
787  int get_height_internal() override;
788 
789  void reset_() {
790  if (this->reset_pin_ != nullptr) {
791  this->reset_pin_->digital_write(true);
792  delay(200); // NOLINT
793  this->reset_pin_->digital_write(false);
794  delay(5);
795  this->reset_pin_->digital_write(true);
796  delay(200); // NOLINT
797  }
798  };
799 
800  void init_display_();
801 };
802 
804  public:
805  bool wait_until_idle_();
806 
807  void initialize() override;
808 
809  void display() override;
810 
811  void dump_config() override;
812 
813  void deep_sleep() override {
814  this->command(0x02); // Power off
815  this->wait_until_idle_();
816  this->command(0x07); // Deep sleep
817  this->data(0xA5);
818  }
819 
820  void clear_screen();
821 
822  protected:
823  int get_width_internal() override;
824 
825  int get_height_internal() override;
826 
827  void reset_() {
828  if (this->reset_pin_ != nullptr) {
829  this->reset_pin_->digital_write(true);
830  delay(200); // NOLINT
831  this->reset_pin_->digital_write(false);
832  delay(5);
833  this->reset_pin_->digital_write(true);
834  delay(200); // NOLINT
835  }
836  };
837 
838  void init_display_();
839 };
840 
842  public:
843  void initialize() override;
844 
845  void display() override;
846 
847  void dump_config() override;
848 
849  void deep_sleep() override {
850  // COMMAND POWER OFF
851  this->command(0x02);
852  this->wait_until_idle_();
853  // COMMAND DEEP SLEEP
854  this->command(0x07);
855  this->data(0xA5); // check byte
856  }
857 
858  protected:
859  int get_width_internal() override;
860 
861  int get_height_internal() override;
862 };
863 
865  public:
866  bool wait_until_idle_();
867 
868  void initialize() override;
869 
870  void display() override;
871 
872  void dump_config() override;
873 
874  void deep_sleep() override {
875  // COMMAND POWER OFF
876  this->command(0x02);
877  this->wait_until_idle_();
878  // COMMAND DEEP SLEEP
879  this->command(0x07);
880  this->data(0xA5); // check byte
881  }
882 
883  protected:
884  int get_width_internal() override;
885 
886  int get_height_internal() override;
887 
888  uint32_t idle_timeout_() override;
889 };
890 
892  public:
893  bool wait_until_idle_();
894  void initialize() override;
895  void dump_config() override;
896 
897  protected:
898  void reset_() {
899  if (this->reset_pin_ != nullptr) {
900  this->reset_pin_->digital_write(true);
901  delay(200); // NOLINT
902  this->reset_pin_->digital_write(false);
903  delay(2);
904  this->reset_pin_->digital_write(true);
905  delay(20);
906  }
907  };
908 };
909 
911  public:
912  bool wait_until_idle_();
913 
914  void initialize() override;
915 
916  void display() override;
917 
918  void dump_config() override;
919 
920  void deep_sleep() override {
921  // COMMAND POWER OFF
922  this->command(0x02);
923  this->wait_until_idle_();
924  // COMMAND DEEP SLEEP
925  this->command(0x07);
926  this->data(0xA5); // check byte
927  }
928 
929  void set_full_update_every(uint32_t full_update_every);
930 
931  protected:
932  int get_width_internal() override;
933 
934  int get_height_internal() override;
935 
936  uint32_t idle_timeout_() override;
937 
938  uint32_t full_update_every_{30};
939  uint32_t at_update_{0};
940 
941  private:
942  void reset_();
943 
944  void turn_on_display_();
945 };
946 
948  public:
949  void initialize() override;
950 
951  void display() override;
952 
953  void dump_config() override;
954 
955  void deep_sleep() override {
956  // deep sleep
957  this->command(0x10);
958  this->data(0x01);
959  }
960 
961  protected:
962  int get_width_internal() override;
963 
964  int get_height_internal() override;
965 };
966 
968  public:
969  void initialize() override;
970 
971  void display() override;
972 
973  void dump_config() override;
974 
975  void deep_sleep() override {
976  // COMMAND POWER DOWN
977  this->command(0x10);
978  this->data(0x01);
979  // cannot wait until idle here, the device no longer responds
980  }
981 
982  void set_full_update_every(uint32_t full_update_every);
983 
984  protected:
985  int get_width_internal() override;
986 
987  int get_height_internal() override;
988 
989  uint32_t idle_timeout_() override;
990 
991  uint32_t full_update_every_{30};
992  uint32_t at_update_{0};
993 };
994 
996  public:
997  void display() override;
998 
999  void dump_config() override;
1000 
1001  void deep_sleep() override {
1002  // COMMAND POWER DOWN
1003  this->command(0x10);
1004  this->data(0x01);
1005  // cannot wait until idle here, the device no longer responds
1006  }
1007 
1008  void set_full_update_every(uint32_t full_update_every);
1009 
1010  void setup() override;
1011  void initialize() override;
1012 
1013  protected:
1014  int get_width_controller() override;
1015  int get_width_internal() override;
1016  int get_height_internal() override;
1017  uint32_t idle_timeout_() override;
1018 
1019  void write_buffer_(uint8_t cmd, int top, int bottom);
1020  void set_window_(int t, int b);
1021  void send_reset_();
1022  void partial_update_();
1023  void full_update_();
1024 
1025  uint32_t full_update_every_{30};
1026  uint32_t at_update_{0};
1027  bool is_busy_{false};
1028  void write_lut_(const uint8_t *lut);
1029 };
1030 
1032  public:
1033  void initialize() override;
1034 
1035  void display() override;
1036 
1037  void dump_config() override;
1038 
1039  void deep_sleep() override {
1040  // COMMAND DEEP SLEEP
1041  this->command(0x10);
1042  this->data(0x01);
1043  }
1044 
1045  protected:
1046  int get_width_internal() override;
1047 
1048  int get_height_internal() override;
1049 
1050  uint32_t idle_timeout_() override;
1051 };
1052 
1053 } // namespace waveshare_epaper
1054 } // namespace esphome
virtual void digital_write(bool value)=0
void set_reset_duration(uint32_t reset_duration)
virtual void draw_absolute_pixel_internal(int x, int y, Color color)=0
uint16_t x
Definition: tt21100.cpp:17
display::DisplayType get_display_type() override
virtual void fill(Color color)
Fill the entire screen with the given color.
Definition: display.cpp:15
virtual void dump_config()
Definition: component.cpp:186
uint16_t y
Definition: tt21100.cpp:18
void init_internal_(uint32_t buffer_length)
display::DisplayType get_display_type() override
The SPIDevice is what components using the SPI will create.
Definition: spi.h:410
virtual int get_height_internal()=0
virtual int get_width_internal()=0
uint16_t reset
Definition: ina226.h:39
display::DisplayType get_display_type() override
uint16_t length
Definition: tt21100.cpp:12
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
stm32_cmd_t * cmd
Definition: stm32flash.h:96
void cmd_data(const uint8_t *data, size_t length)
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26