Pololu3piPlus32U4 library
Pololu3piPlus32U4OLED.h
1 // Copyright (C) Pololu Corporation. See www.pololu.com for details.
2 
3 #pragma once
4 
5 #include <Arduino.h>
6 #include <FastGPIO.h>
7 #include <USBPause.h>
8 #include <PololuSH1106Main.h>
9 #include <util/delay.h>
10 
11 // This asm inside the macro below is an optimized version of
12 // FastGPIO::Pin<mosPin>::setOutputValue(d >> b & 1);
13 // It prevents the compiler from using slow branches to implement the
14 // conditional logic, and also ensures that the writing speed doesn't depend
15 // on the data.
16 #define _P3PP_OLED_SEND_BIT(b) \
17  FastGPIO::Pin<clkPin>::setOutputValueLow(); \
18  asm volatile( \
19  "sbrc %2, %3\n" "sbi %0, %1\n" \
20  "sbrs %2, %3\n" "cbi %0, %1\n" \
21  : : \
22  "I" (FastGPIO::pinStructs[mosPin].portAddr - __SFR_OFFSET), \
23  "I" (FastGPIO::pinStructs[mosPin].bit), \
24  "r" (d), \
25  "I" (b)); \
26  FastGPIO::Pin<clkPin>::setOutputValueHigh();
27 
28 namespace Pololu3piPlus32U4
29 {
30 
33 class OLEDCore
34 {
35  // Pin assignments
36  static const uint8_t clkPin = 1, mosPin = IO_D5, resPin = 0, dcPin = 17;
37 
38 public:
39  void initPins()
40  {
41  FastGPIO::Pin<clkPin>::setOutputLow();
42  }
43 
44  void reset()
45  {
46  FastGPIO::Pin<resPin>::setOutputLow();
47  _delay_us(10);
48  FastGPIO::Pin<resPin>::setOutputHigh();
49  _delay_us(10);
50  }
51 
52  void sh1106TransferStart()
53  {
54  // From https://github.com/pololu/usb-pause-arduino/blob/master/USBPause.h:
55  // Disables USB interrupts because the Arduino USB interrupts use some of
56  // the OLED pins.
57  savedUDIEN = UDIEN;
58  UDIEN = 0;
59  savedUENUM = UENUM;
60  UENUM = 0;
61  savedUEIENX0 = UEIENX;
62  UEIENX = 0;
63 
64  savedStateMosi = FastGPIO::Pin<mosPin>::getState();
65  savedStateDc = FastGPIO::Pin<dcPin>::getState();
66 
67  FastGPIO::Pin<mosPin>::setOutputLow();
68  }
69 
70  void sh1106TransferEnd()
71  {
72  FastGPIO::Pin<mosPin>::setState(savedStateMosi);
73  FastGPIO::Pin<dcPin>::setState(savedStateDc);
74 
75  // From https://github.com/pololu/usb-pause-arduino/blob/master/USBPause.h
76  UENUM = 0;
77  UEIENX = savedUEIENX0;
78  UENUM = savedUENUM;
79  UDIEN = savedUDIEN;
80  }
81 
82  void sh1106CommandMode()
83  {
84  FastGPIO::Pin<dcPin>::setOutputLow();
85  }
86 
87  void sh1106DataMode()
88  {
89  FastGPIO::Pin<dcPin>::setOutputHigh();
90  }
91 
92  void sh1106Write(uint8_t d)
93  {
94  _P3PP_OLED_SEND_BIT(7);
95  _P3PP_OLED_SEND_BIT(6);
96  _P3PP_OLED_SEND_BIT(5);
97  _P3PP_OLED_SEND_BIT(4);
98  _P3PP_OLED_SEND_BIT(3);
99  _P3PP_OLED_SEND_BIT(2);
100  _P3PP_OLED_SEND_BIT(1);
101  _P3PP_OLED_SEND_BIT(0);
102  }
103 
104 private:
105  uint8_t savedStateMosi, savedStateDc;
106  uint8_t savedUDIEN, savedUENUM, savedUEIENX0;
107 };
108 
122 class OLED : public PololuSH1106Main<OLEDCore>
123 {
124 };
125 
126 }
Low-level functions for writing data to the SH1106 OLED on the Pololu 3pi+ 32U4 OLED robot.
Makes it easy to show text and graphics on the SH1106 OLED of the Pololu 3pi+ 32U4 OLED robot.
Top-level namespace for the Pololu3piPlus32U4 library.