Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addon/display/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
CIRCLEHOME = ../..

OBJS = hd44780device.o st7789display.o ili9341display.o ssd1306display.o \
ssd1309display.o chardevice.o ssd1306device.o st7789device.o
chardevice.o ssd1306device.o st7789device.o sh1106device.o

libdisplay.a: $(OBJS)
@echo " AR $@"
Expand Down
17 changes: 17 additions & 0 deletions addon/display/sample/sh1106/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Makefile
#

CIRCLEHOME = ../../../..

OBJS = main.o kernel.o

LIBS = $(CIRCLEHOME)/addon/display/libdisplay.a \
$(CIRCLEHOME)/lib/usb/libusb.a \
$(CIRCLEHOME)/lib/input/libinput.a \
$(CIRCLEHOME)/lib/fs/libfs.a \
$(CIRCLEHOME)/lib/libcircle.a

include $(CIRCLEHOME)/Rules.mk

-include $(DEPS)
15 changes: 15 additions & 0 deletions addon/display/sample/sh1106/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
README

This sample program demonstrates how to use a SH1106-controlled I2C OLED display.
Before building you have to configure the program in kernel.cpp according to the
hardware of your LCD display. You have to set the display size (columns, rows)
and the I2C address of hte interface module.

There are two modes of the demo program. If you start it without an USB keyboard
connected, it will display "No keyboard!" on the LCD display and will count the
time from program start on.

With an USB keyboard connected you can type on it and the typed characters will
be echoed to the LCD display. You may have to set-up your keyboard map first,
using the "keymap=" setting in cmdline.txt (see doc/cmdline.txt) to get
reasonable results here.
185 changes: 185 additions & 0 deletions addon/display/sample/sh1106/kernel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
//
// kernel.cpp
//
// Circle - A C++ bare metal environment for Raspberry Pi
// Copyright (C) 2014-2018 R. Stange <rsta2@o2online.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "kernel.h"
#include <circle/usb/usbkeyboard.h>
#include <circle/input/keyboardbuffer.h>
#include <circle/time.h>
#include <circle/string.h>
#include <circle/util.h>
#include <circle/machineinfo.h>

// LCD configuration
#define HEIGHT 64
#define WIDTH 128

#define I2C_ADDR 0x3C

#define I2C_MASTER_DEVICE (CMachineInfo::Get ()->GetDevice (DeviceI2CMaster))

static const char FromKernel[] = "kernel";

// Set to true to enable rotated or mirrored displays
#define ROTATED false
#define MIRRORED false

CKernel::CKernel (void)
: m_Screen (m_Options.GetWidth (), m_Options.GetHeight ()),
m_Timer (&m_Interrupt),
m_Logger (m_Options.GetLogLevel (), &m_Timer),
m_USBHCI (&m_Interrupt, &m_Timer),
m_I2CMaster (I2C_MASTER_DEVICE),
m_LCD (WIDTH, HEIGHT, &m_I2CMaster, I2C_ADDR, ROTATED, MIRRORED)
{
m_ActLED.Blink (5); // show we are alive
}

CKernel::~CKernel (void)
{
}

boolean CKernel::Initialize (void)
{
boolean bOK = TRUE;

if (bOK)
{
bOK = m_Screen.Initialize ();
}

if (bOK)
{
bOK = m_Serial.Initialize (115200);
}

if (bOK)
{
CDevice *pTarget = m_DeviceNameService.GetDevice (m_Options.GetLogDevice (), FALSE);
if (pTarget == 0)
{
pTarget = &m_Screen;
}

bOK = m_Logger.Initialize (pTarget);
}

if (bOK)
{
bOK = m_Interrupt.Initialize ();
}

if (bOK)
{
bOK = m_Timer.Initialize ();
}

if (bOK)
{
bOK = m_USBHCI.Initialize ();
}

if (bOK)
{
bOK = m_I2CMaster.Initialize ();
}

if (bOK)
{
bOK = m_LCD.Initialize ();
}

return bOK;
}

TShutdownMode CKernel::Run (void)
{
m_Logger.Write (FromKernel, LogNotice, "Compile time: " __DATE__ " " __TIME__);

LCDWrite ("01234567890123456789");
LCDWrite (">>>>>>>>>>>>>>>>>>>");

unsigned nTime = 10 + m_Timer.GetTime ();
while (nTime > m_Timer.GetTime ())
{
// just wait a few seconds
}

LCDWrite ("\E[H\E[J"); // Reset cursor and clear display

CUSBKeyboardDevice *pKeyboard =
(CUSBKeyboardDevice *) m_DeviceNameService.GetDevice ("ukbd1", FALSE);
if (pKeyboard == 0)
{
m_Logger.Write (FromKernel, LogError, "Keyboard not found");

TimeDemo ();

return ShutdownHalt;
}

CKeyboardBuffer Keyboard (pKeyboard);

m_Logger.Write (FromKernel, LogNotice, "Just type something!");
LCDWrite ("Just type!\n");

for (unsigned nCount = 0; 1; nCount++)
{
char Buffer[10];
int nResult = Keyboard.Read (Buffer, sizeof Buffer);
if (nResult > 0)
{
m_LCD.Write (Buffer, nResult);
}

m_Screen.Rotor (0, nCount);
}

return ShutdownHalt;
}

void CKernel::TimeDemo (void)
{
LCDWrite ("\x1B[?25l"); // cursor off
LCDWrite ("No keyboard!\n");

unsigned nTime = m_Timer.GetTime ();
while (1)
{
while (nTime == m_Timer.GetTime ())
{
// just wait a second
}

nTime = m_Timer.GetTime ();

CTime Time;
Time.Set (nTime);

CString String;
String.Format ("\r%02u:%02u:%02u",
Time.GetHours (), Time.GetMinutes (), Time.GetSeconds ());

LCDWrite ((const char *) String);
}
}

void CKernel::LCDWrite (const char *pString)
{
m_LCD.Write (pString, strlen (pString));
}
76 changes: 76 additions & 0 deletions addon/display/sample/sh1106/kernel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// kernel.h
//
// Circle - A C++ bare metal environment for Raspberry Pi
// Copyright (C) 2014-2018 R. Stange <rsta2@o2online.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef _kernel_h
#define _kernel_h

#include <circle/actled.h>
#include <circle/koptions.h>
#include <circle/devicenameservice.h>
#include <circle/screen.h>
#include <circle/serial.h>
#include <circle/exceptionhandler.h>
#include <circle/interrupt.h>
#include <circle/timer.h>
#include <circle/logger.h>
#include <circle/usb/usbhcidevice.h>
#include <circle/types.h>
#include <circle/i2cmaster.h>
#include <display/sh1106device.h>

enum TShutdownMode
{
ShutdownNone,
ShutdownHalt,
ShutdownReboot
};

class CKernel
{
public:
CKernel (void);
~CKernel (void);

boolean Initialize (void);

TShutdownMode Run (void);

private:
void TimeDemo (void);

void LCDWrite (const char *pString);

private:
// do not change this order
CActLED m_ActLED;
CKernelOptions m_Options;
CDeviceNameService m_DeviceNameService;
CScreenDevice m_Screen;
CSerialDevice m_Serial;
CExceptionHandler m_ExceptionHandler;
CInterruptSystem m_Interrupt;
CTimer m_Timer;
CLogger m_Logger;
CUSBHCIDevice m_USBHCI;
CI2CMaster m_I2CMaster;

CSH1106Device m_LCD;
};

#endif
47 changes: 47 additions & 0 deletions addon/display/sample/sh1106/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// main.c
//
// Circle - A C++ bare metal environment for Raspberry Pi
// Copyright (C) 2014 R. Stange <rsta2@o2online.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "kernel.h"
#include <circle/startup.h>

int main (void)
{
// cannot return here because some destructors used in CKernel are not implemented

CKernel Kernel;
if (!Kernel.Initialize ())
{
halt ();
return EXIT_HALT;
}

TShutdownMode ShutdownMode = Kernel.Run ();

switch (ShutdownMode)
{
case ShutdownReboot:
reboot ();
return EXIT_REBOOT;

case ShutdownHalt:
default:
halt ();
return EXIT_HALT;
}
}
Loading