🎨
MadMachine-Examples
  • Introduction
  • About our project
  • Getting Started
  • Tutorial
    • What is SwiftIO
    • How to use IDE
    • Libraries
    • MM SDK
  • Built-In Examples
    • GettingStarted
      • Blink
      • ReadDigitalInput
      • ReadAnalogInput
      • PWMBrightnessControl
    • SimpleIO
      • ButtoncontrolLED
      • BlinkAnalogIn
      • BlinkTimer
      • BrightnessAnalogIn
      • Debounce
      • LEDsBrightnessControl
      • PWMSoundOutput
      • PWMMelody
    • AdvancedIO
      • ILI9341
      • LCD1602
      • MidiPlayer
      • PCA9685
      • SHT3x
      • SSD1315
    • Challenge
      • LCDFamily
      • RobotArm
      • Tetris
    • MakerKit
      • Mission 01 Blink
      • Mission 02 RGB LED
      • Mission 03 Push Button
      • Mission 04 Potentiometer RGB
      • Mission 05 Buzzer
      • Mission 06 Seven Segment Display
      • Mission 07 DC Motor
      • Mission 08 Servo Motor
      • Mission 09 LCD
      • Mission 10 Humiture Sensor
  • Library Reference
  • FAQ
Powered by GitBook
On this page
  • What you need
  • Circuit
  • Tips
  • Code
  • main.swift
  • SSD1315.swift
  • Video
  • See Also
  • References

Was this helpful?

  1. Built-In Examples
  2. AdvancedIO

SSD1315

What you need

Circuit

Tips

Code

main.swift

import SwiftIO

let dc = DigitalOut(Id.D0)
let rst = DigitalOut(Id.D1)
let spi = SPI(Id.SPI0, speed: 20000000)

let oled = SSD1315(spi: spi, dc: dc, rst: rst)

func clearScreenTest() {
    oled.clearScreen(color: true)
    sleep(ms: 1000)
    oled.clearScreen(color: false)
    sleep(ms: 1000)
}

func pixelTest() {
    for y in 0..<oled.height {
        for x in 0..<oled.width {
            oled.writePixel(x: x, y: y, color: true)
        }
    }
}

while true {
    clearScreenTest()
    pixelTest()
}

SSD1315.swift

import SwiftIO

final class SSD1315{

    private enum Command: UInt8 {
        case entireDisplayOff   = 0xA4
        case normalDisplay      = 0xA6
        case displayOff         = 0xAE
        case displayOn          = 0xAF
        case clockDivRatio      = 0xD5
        case multiplexRatio     = 0xA8
        case displayOffset      = 0xD3
        case startLine          = 0x40
        case chargePump         = 0x8D
        case memoryMode         = 0x20
        case mapNormal          = 0xA0
        case mapRemaped         = 0xA1
        case scanNormal         = 0xC0
        case scanFlipped        = 0xC8
        case hwConfig           = 0xDA
        case contrastCtrl       = 0x81
        case chargePeriod       = 0xD9
        case vcomDeselectLevel  = 0xDB
    }

    private let config: [(Command, UInt8?)] = [
        (.displayOff, nil),
        (.clockDivRatio, 0x80),
        (.multiplexRatio, 0x3F),
        (.displayOffset, 0x00),
        (.startLine, nil),
        (.chargePump, 0x14),
        (.memoryMode, 0x00),
        (.mapRemaped, nil),
        (.scanNormal, nil),
        (.hwConfig, 0x12),
        (.contrastCtrl, 0xCF),
        (.chargePeriod, 0xF1),
        (.vcomDeselectLevel, 0x40),
        (.entireDisplayOff, nil),
        (.normalDisplay, nil),
        (.displayOn, nil)
    ]

    private let spi: SPI
    private let rst, dc: DigitalOut
    public let width, height: Int

    private var frameBuffer = Array<UInt8>(repeating: 0x00, count: 128 * 8)

    init(spi: SPI, dc: DigitalOut, rst: DigitalOut) {
        self.spi = spi
        self.dc = dc
        self.rst = rst
        width = 128
        height = 64

        reset()
        config.forEach { item in
            writeConfig(item)
        }
        clearScreen()
    }

    public func reset() {
        rst.write(false)
        sleep(ms: 100)
        rst.write(true)
        sleep(ms: 100)
    }

    @inline(__always)
    private func writePixelToFramBuffer(x: Int, y: Int, color: Bool) {
        if x >= width || y >= height {
            return
        }
        var pos = 0, bx = 0
        var data: UInt8 = 0

        pos = 7 - y / 8
        bx = y % 8
        data = UInt8(1 << (7 - bx))

        if color {
            frameBuffer[pos * width + x] |= data
        } else {
            frameBuffer[pos * width + x] &= ~data
        }
    }

    func writePixel(x: Int, y: Int, color: Bool) {
        writePixelToFramBuffer(x: x, y: y, color: color)
        updateScreen()
    }

    func writeScreen(_ data: [UInt8]) {
        guard data.count >= height * width else {
            return
        }

        for y in 0..<height {
            for x in 0..<width {
                if data[y * width + x] == 0 {
                    writePixelToFramBuffer(x: x, y: y, color: false)
                } else {
                    writePixelToFramBuffer(x: x, y: y, color: true)
                }
            }
        }
        updateScreen()
    }

    func writeScreen(_ data: UnsafeRawBufferPointer) {
        guard data.baseAddress != nil else { return }
        let ptr = data.bindMemory(to: UInt8.self)

        for y in 0..<height {
            for x in 0..<width {
                if ptr[y * width + x] == 0 {
                    writePixelToFramBuffer(x: x, y: y, color: false)
                } else {
                    writePixelToFramBuffer(x: x, y: y, color: true)
                }
            }
        }
        updateScreen()
    }

    func clearScreen(color: Bool = false) {
        let value: UInt8 = color ? 0xFF : 0x00
        for i in 0..<frameBuffer.count {
            frameBuffer[i] = value
        }
        updateScreen()
    }

    func updateScreen() {
        dc.write(true)
        spi.write(frameBuffer)
    }

    private func writeConfig(_ config: (Command, UInt8?)) {
        writeCommand(config.0.rawValue)
        if let value = config.1 {
            writeCommand(value)
        }
    }

    private func writeCommand(_ data: UInt8) {
        dc.write(false)
        spi.write(data)
    }

    private func writeCommand(_ data: [UInt8]) {
        dc.write(false)
        spi.write(data)
    }

    private func writeData(_ data: [UInt8]) {
        dc.write(true)
        spi.write(data)
    }
}

Video

See Also

References

Last revision 2020/09/10 by Johnson

PreviousSHT3xNextChallenge

Last updated 4 years ago

Was this helpful?