The codebase to run the *spark d-fuser controller www.sparkav.co.uk/dvimixer

Dependencies:   SPK-TVOne DMX DmxArtNet NetServicesMin OSC PinDetect mRotaryEncoder iniparser mbed spk_oled_ssd1305 filter

Committer:
tobyspark
Date:
Sat Mar 10 19:26:44 2012 +0000
Revision:
0:87aab40d5806
v15 - PCB a la toby; OLED a la toby

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tobyspark 0:87aab40d5806 1 // *spark audio-visual
tobyspark 0:87aab40d5806 2 // OLED display using SSD1305 driver
tobyspark 0:87aab40d5806 3 // Copyright *spark audio-visual 2012
tobyspark 0:87aab40d5806 4
tobyspark 0:87aab40d5806 5 #include "spk_oled_ssd1305.h"
tobyspark 0:87aab40d5806 6 #include "spk_oled_gfx.h"
tobyspark 0:87aab40d5806 7 #include "mbed.h"
tobyspark 0:87aab40d5806 8
tobyspark 0:87aab40d5806 9 SPKDisplay::SPKDisplay(PinName mosiPin, PinName clkPin, PinName csPin, PinName dcPin, PinName resPin, Serial *debugSerial)
tobyspark 0:87aab40d5806 10 {
tobyspark 0:87aab40d5806 11 spi = new SPI(mosiPin, NC, clkPin);
tobyspark 0:87aab40d5806 12 spi->format(8,3);
tobyspark 0:87aab40d5806 13 spi->frequency(2000000);
tobyspark 0:87aab40d5806 14
tobyspark 0:87aab40d5806 15 cs = new DigitalOut(csPin);
tobyspark 0:87aab40d5806 16 dc = new DigitalOut(dcPin);
tobyspark 0:87aab40d5806 17 res = new DigitalOut(resPin);
tobyspark 0:87aab40d5806 18
tobyspark 0:87aab40d5806 19 // Link up debug Serial object
tobyspark 0:87aab40d5806 20 // Passing in shared object as debugging is shared between all DVI mixer functions
tobyspark 0:87aab40d5806 21 debug = debugSerial;
tobyspark 0:87aab40d5806 22
tobyspark 0:87aab40d5806 23 setup();
tobyspark 0:87aab40d5806 24
tobyspark 0:87aab40d5806 25 clearBuffer();
tobyspark 0:87aab40d5806 26
tobyspark 0:87aab40d5806 27 if (debug) debug->printf("SPKDisplay loaded\n\r");
tobyspark 0:87aab40d5806 28 }
tobyspark 0:87aab40d5806 29
tobyspark 0:87aab40d5806 30 void SPKDisplay::clearBuffer()
tobyspark 0:87aab40d5806 31 {
tobyspark 0:87aab40d5806 32 memset(buffer, 0, bufferCount);
tobyspark 0:87aab40d5806 33 }
tobyspark 0:87aab40d5806 34
tobyspark 0:87aab40d5806 35 void SPKDisplay::imageToBuffer()
tobyspark 0:87aab40d5806 36 {
tobyspark 0:87aab40d5806 37 memcpy(buffer, image, bufferCount);
tobyspark 0:87aab40d5806 38 }
tobyspark 0:87aab40d5806 39
tobyspark 0:87aab40d5806 40 void SPKDisplay::clearBufferRow(int row)
tobyspark 0:87aab40d5806 41 {
tobyspark 0:87aab40d5806 42 // Range check
tobyspark 0:87aab40d5806 43 if (row >= 8)
tobyspark 0:87aab40d5806 44 {
tobyspark 0:87aab40d5806 45 if (debug) debug->printf("SPKDisplay::clearBufferRow sent out of bounds row");
tobyspark 0:87aab40d5806 46 return;
tobyspark 0:87aab40d5806 47 }
tobyspark 0:87aab40d5806 48 int bStart = row*bufferWidth;
tobyspark 0:87aab40d5806 49 int bEnd = bStart + pixelWidth;
tobyspark 0:87aab40d5806 50
tobyspark 0:87aab40d5806 51 for (int bPos = bStart; bPos <= bEnd; bPos++)
tobyspark 0:87aab40d5806 52 {
tobyspark 0:87aab40d5806 53 buffer[bPos] = 0x00;
tobyspark 0:87aab40d5806 54 }
tobyspark 0:87aab40d5806 55 }
tobyspark 0:87aab40d5806 56
tobyspark 0:87aab40d5806 57 void SPKDisplay::horizLineToBuffer(int y)
tobyspark 0:87aab40d5806 58 {
tobyspark 0:87aab40d5806 59 if (y >= pixelHeight)
tobyspark 0:87aab40d5806 60 {
tobyspark 0:87aab40d5806 61 if (debug) debug->printf("SPKDisplay::clearBufferRow sent out of bounds y");
tobyspark 0:87aab40d5806 62 return;
tobyspark 0:87aab40d5806 63 }
tobyspark 0:87aab40d5806 64
tobyspark 0:87aab40d5806 65 int row = (y*pixInPage) / pixelHeight;
tobyspark 0:87aab40d5806 66 int posInRow = y % pixInPage;
tobyspark 0:87aab40d5806 67
tobyspark 0:87aab40d5806 68 int bStart = row*bufferWidth;
tobyspark 0:87aab40d5806 69 int bEnd = bStart + pixelWidth;
tobyspark 0:87aab40d5806 70
tobyspark 0:87aab40d5806 71 for (int bPos = bStart; bPos <= bEnd; bPos++)
tobyspark 0:87aab40d5806 72 {
tobyspark 0:87aab40d5806 73 // Need to bitwise OR as setting single bit (the line) in byte (the row)
tobyspark 0:87aab40d5806 74 buffer[bPos] = buffer[bPos] | 0x01 << posInRow;
tobyspark 0:87aab40d5806 75 }
tobyspark 0:87aab40d5806 76 }
tobyspark 0:87aab40d5806 77
tobyspark 0:87aab40d5806 78 void SPKDisplay::textToBuffer(std::string message, int row)
tobyspark 0:87aab40d5806 79 {
tobyspark 0:87aab40d5806 80 // Range check
tobyspark 0:87aab40d5806 81 if (row >= 8) row = 7;
tobyspark 0:87aab40d5806 82 int bStart = row*bufferWidth;
tobyspark 0:87aab40d5806 83 int bEnd = bStart + pixelWidth;
tobyspark 0:87aab40d5806 84
tobyspark 0:87aab40d5806 85 int bPos = bStart;
tobyspark 0:87aab40d5806 86 for (int i = 0; i < message.size(); i++)
tobyspark 0:87aab40d5806 87 {
tobyspark 0:87aab40d5806 88 char character = message.at(i);
tobyspark 0:87aab40d5806 89
tobyspark 0:87aab40d5806 90 // Is it outside the range we have glyphs for?
tobyspark 0:87aab40d5806 91 if ((character < characterBytesStartChar) || (character > characterBytesEndChar))
tobyspark 0:87aab40d5806 92 {
tobyspark 0:87aab40d5806 93 // Treat as a space
tobyspark 0:87aab40d5806 94 for (int j = 0; j < 5; j++)
tobyspark 0:87aab40d5806 95 {
tobyspark 0:87aab40d5806 96 if (bPos >= bEnd) break;
tobyspark 0:87aab40d5806 97 buffer[bPos++] = 0x00;
tobyspark 0:87aab40d5806 98 }
tobyspark 0:87aab40d5806 99
tobyspark 0:87aab40d5806 100 // Warn if not
tobyspark 0:87aab40d5806 101 if (debug)
tobyspark 0:87aab40d5806 102 {
tobyspark 0:87aab40d5806 103 if (character != ' ') debug->printf("No glyph for character %c at position %i", character, i);
tobyspark 0:87aab40d5806 104 }
tobyspark 0:87aab40d5806 105 }
tobyspark 0:87aab40d5806 106 // If not, typeset it!
tobyspark 0:87aab40d5806 107 else
tobyspark 0:87aab40d5806 108 {
tobyspark 0:87aab40d5806 109 // Shift into our array's indexing
tobyspark 0:87aab40d5806 110 character -= characterBytesStartChar;
tobyspark 0:87aab40d5806 111
tobyspark 0:87aab40d5806 112 // Write each byte's vertical column of 8bits into the buffer.
tobyspark 0:87aab40d5806 113 for (int j = 0; j < characterBytes[character][0]; j++)
tobyspark 0:87aab40d5806 114 {
tobyspark 0:87aab40d5806 115 if (bPos >= bEnd) break;
tobyspark 0:87aab40d5806 116 buffer[bPos++] = characterBytes[character][j+1];
tobyspark 0:87aab40d5806 117 }
tobyspark 0:87aab40d5806 118
tobyspark 0:87aab40d5806 119 // Put 1px letter spacing at end
tobyspark 0:87aab40d5806 120 if (bPos >= bEnd) break;
tobyspark 0:87aab40d5806 121 buffer[bPos++] = 0x00; // 1 px letter spacing
tobyspark 0:87aab40d5806 122 }
tobyspark 0:87aab40d5806 123 }
tobyspark 0:87aab40d5806 124 }
tobyspark 0:87aab40d5806 125
tobyspark 0:87aab40d5806 126 void SPKDisplay::sendBuffer()
tobyspark 0:87aab40d5806 127 {
tobyspark 0:87aab40d5806 128 // Select the device by seting chip select low
tobyspark 0:87aab40d5806 129 *cs = 0;
tobyspark 0:87aab40d5806 130
tobyspark 0:87aab40d5806 131 // Set to receive DATA not commands
tobyspark 0:87aab40d5806 132 *dc = 1;
tobyspark 0:87aab40d5806 133
tobyspark 0:87aab40d5806 134 for (int i = 0; i < bufferCount; i++)
tobyspark 0:87aab40d5806 135 {
tobyspark 0:87aab40d5806 136 spi->write(buffer[i]);
tobyspark 0:87aab40d5806 137 }
tobyspark 0:87aab40d5806 138
tobyspark 0:87aab40d5806 139 // Deselect the device
tobyspark 0:87aab40d5806 140 *cs = 1;
tobyspark 0:87aab40d5806 141 }
tobyspark 0:87aab40d5806 142
tobyspark 0:87aab40d5806 143 void SPKDisplay::setup()
tobyspark 0:87aab40d5806 144 {
tobyspark 0:87aab40d5806 145 // TASK: SCREEN OFF, Run pre-flight
tobyspark 0:87aab40d5806 146
tobyspark 0:87aab40d5806 147 // Hard reset the OLED
tobyspark 0:87aab40d5806 148 *res = 0;
tobyspark 0:87aab40d5806 149 wait_ms(1);
tobyspark 0:87aab40d5806 150 *res = 1;
tobyspark 0:87aab40d5806 151
tobyspark 0:87aab40d5806 152 // Select the device by seting chip select low
tobyspark 0:87aab40d5806 153 *cs = 0;
tobyspark 0:87aab40d5806 154
tobyspark 0:87aab40d5806 155 // Set to receive COMMANDS not data
tobyspark 0:87aab40d5806 156 *dc = 0;
tobyspark 0:87aab40d5806 157
tobyspark 0:87aab40d5806 158 spi->write(0xAE); // set display off
tobyspark 0:87aab40d5806 159 spi->write(0xD5); // set display clock divide ratio
tobyspark 0:87aab40d5806 160 spi->write(0xA0);
tobyspark 0:87aab40d5806 161 spi->write(0xA8); // set multiplex ratio
tobyspark 0:87aab40d5806 162 spi->write(0x3F);
tobyspark 0:87aab40d5806 163 spi->write(0xD3); // set display offset
tobyspark 0:87aab40d5806 164 spi->write(0x00);
tobyspark 0:87aab40d5806 165 spi->write(0x40); // set display start line
tobyspark 0:87aab40d5806 166 spi->write(0xAD); // set master configuration
tobyspark 0:87aab40d5806 167 spi->write(0x8E);
tobyspark 0:87aab40d5806 168 spi->write(0xD8); // set area color mode
tobyspark 0:87aab40d5806 169 spi->write(0x05);
tobyspark 0:87aab40d5806 170 spi->write(0xA1); // set segment re-map
tobyspark 0:87aab40d5806 171 spi->write(0xC8); // set com output scan direction
tobyspark 0:87aab40d5806 172 spi->write(0xDA); // set com pins hardware configuration
tobyspark 0:87aab40d5806 173 spi->write(0x12);
tobyspark 0:87aab40d5806 174 spi->write(0x91); // set look-up table
tobyspark 0:87aab40d5806 175 spi->write(0x3F);
tobyspark 0:87aab40d5806 176 spi->write(0x3F);
tobyspark 0:87aab40d5806 177 spi->write(0x3F);
tobyspark 0:87aab40d5806 178 spi->write(0x3F);
tobyspark 0:87aab40d5806 179 spi->write(0x81); // set current control for bank 0
tobyspark 0:87aab40d5806 180 spi->write(0x8F);
tobyspark 0:87aab40d5806 181 spi->write(0xD9); // set pre-charge period
tobyspark 0:87aab40d5806 182 spi->write(0xD2);
tobyspark 0:87aab40d5806 183 spi->write(0xDB); //set vcomh deselect level
tobyspark 0:87aab40d5806 184 spi->write(0x34);
tobyspark 0:87aab40d5806 185 spi->write(0xA4); // set entire display on/off
tobyspark 0:87aab40d5806 186 spi->write(0xA6); // set normal/inverse display
tobyspark 0:87aab40d5806 187
tobyspark 0:87aab40d5806 188 spi->write(0x20); // page mode
tobyspark 0:87aab40d5806 189 spi->write(0x00);
tobyspark 0:87aab40d5806 190
tobyspark 0:87aab40d5806 191 // TASK: Clear screen's content buffer
tobyspark 0:87aab40d5806 192
tobyspark 0:87aab40d5806 193 // Is this neccessary when switching command/data?
tobyspark 0:87aab40d5806 194 *cs = 1;
tobyspark 0:87aab40d5806 195 wait_ms(1);
tobyspark 0:87aab40d5806 196 *cs = 0;
tobyspark 0:87aab40d5806 197
tobyspark 0:87aab40d5806 198 // Set to receive DATA not commands
tobyspark 0:87aab40d5806 199 *dc = 1;
tobyspark 0:87aab40d5806 200
tobyspark 0:87aab40d5806 201 for (int i = 0; i < bufferCount; i++)
tobyspark 0:87aab40d5806 202 {
tobyspark 0:87aab40d5806 203 spi->write(0x00);
tobyspark 0:87aab40d5806 204 }
tobyspark 0:87aab40d5806 205
tobyspark 0:87aab40d5806 206 // TASK: SCREEN ON
tobyspark 0:87aab40d5806 207
tobyspark 0:87aab40d5806 208 // Is this neccessary when switching command/data?
tobyspark 0:87aab40d5806 209 *cs = 1;
tobyspark 0:87aab40d5806 210 wait_ms(1);
tobyspark 0:87aab40d5806 211 *cs = 0;
tobyspark 0:87aab40d5806 212
tobyspark 0:87aab40d5806 213 // Set to receive COMMANDS not data
tobyspark 0:87aab40d5806 214 *dc = 0;
tobyspark 0:87aab40d5806 215
tobyspark 0:87aab40d5806 216 spi->write(0xAF); // set display on
tobyspark 0:87aab40d5806 217
tobyspark 0:87aab40d5806 218 // Deselect the device
tobyspark 0:87aab40d5806 219 *cs = 1;
tobyspark 0:87aab40d5806 220 }