diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj
index b84e58f..3d760b2 100644
--- a/MiSTer.vcxproj
+++ b/MiSTer.vcxproj
@@ -40,6 +40,7 @@
+
@@ -63,6 +64,7 @@
+
diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters
index dc88408..3ca656a 100644
--- a/MiSTer.vcxproj.filters
+++ b/MiSTer.vcxproj.filters
@@ -74,6 +74,9 @@
Source Files
+
+ Source Files
+
@@ -163,6 +166,9 @@
Header Files
+
+ Header Files
+
diff --git a/brightness.c b/brightness.c
new file mode 100644
index 0000000..3b6ee0f
--- /dev/null
+++ b/brightness.c
@@ -0,0 +1,252 @@
+/*
+ * brightness.c
+ *
+ * Copyright 2016 rricharz
+ * MiSTer port. Copyright 2018 Sorgelig
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "brightness.h"
+
+#define MAXCOUNT 10 // maximum number of spi transfer attemps
+
+#define LIDBITMASK 0x04
+#define SCREENOFFMASK 0x02
+#define PARITYMASK 0x80
+#define BRIGHTNESSMASK 0x78
+#define SHUTDOWNMASK 0X01
+
+///////////////////////////////////////////////////
+
+static uint32_t spiSpeed;
+static int spiFd = -1;
+
+static const uint8_t spiBPW = 8;
+static const uint16_t spiDelay = 0;
+
+static int spi_rw(unsigned char *data, int len)
+{
+ struct spi_ioc_transfer spi;
+
+ memset (&spi, 0, sizeof (spi));
+
+ spi.tx_buf = (unsigned long)data;
+ spi.rx_buf = (unsigned long)data;
+ spi.len = len;
+ spi.delay_usecs = spiDelay;
+ spi.speed_hz = spiSpeed;
+ spi.bits_per_word = spiBPW;
+
+ return ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi);
+}
+
+static int spi_open(int speed, int mode)
+{
+ int fd ;
+ mode &= 3; // Mode is 0, 1, 2 or 3
+
+ if ((fd = open ("/dev/spidev32766.0", O_RDWR)) < 0)
+ {
+ printf("Unable to open SPI device: %s\n", strerror (errno));
+ return -1;
+ }
+
+ if (ioctl (fd, SPI_IOC_WR_MODE, &mode) >= 0)
+ {
+ if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) >= 0)
+ {
+ if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) >= 0)
+ {
+ spiSpeed = speed;
+ spiFd = fd;
+ return fd;
+ }
+ else
+ {
+ printf ("SPI Speed Change failure: %s\n", strerror (errno));
+ }
+ }
+ else
+ {
+ printf ("SPI BPW Change failure: %s\n", strerror (errno));
+ }
+ }
+ else
+ {
+ printf ("SPI Mode Change failure: %s\n", strerror (errno));
+ }
+
+ close(fd);
+ fd = -1;
+ return -1;
+}
+
+static int spi_close()
+{
+ if(spiFd >= 0) close(spiFd);
+ spiFd = -1;
+}
+
+///////////////////////////////////////////////////
+
+static int lidbit;
+static int screenoffbit;
+static int parity;
+static int brightness = 6;
+static int shutdown;
+
+//////////////////////////////
+// Calclate the parity of bits 0 - 6
+static int parity7(unsigned char data)
+{
+ int i;
+ int p = 0;
+ for (i = 0; i < 7; i++) {
+ if (data & 1) p = !p;
+ data = data >> 1;
+ }
+ return p;
+}
+
+///////////////////////////////
+// analyze data byte and set global variables
+// return 1 of parity is ok
+// Sending: bit 8 = parity of bit 1-7
+static int analyze(unsigned char data)
+{
+ lidbit = (data & LIDBITMASK) != 0;
+ screenoffbit = (data & SCREENOFFMASK) != 0;
+ parity = (data & PARITYMASK) != 0;
+ brightness = (data & BRIGHTNESSMASK) >> 3;
+ shutdown = (data & SHUTDOWNMASK) != 0;
+
+ // printf("lid = %d, screen = %d, parity = %d, shutdown = %d, brightness = %d\n", lidbit, screenoffbit, parity, shutdown, brightness);
+
+ return (parity7(data) == parity);
+}
+
+///////////////
+// Calculate data byte using global variables
+// Set brightness and status parity bits
+// Receiving: bit 8 = brightness parity, bit 3 = status parity
+static int calculate()
+{
+ int data = brightness << 3;
+ if (parity7(brightness)) data += PARITYMASK;
+ if (shutdown) data += SHUTDOWNMASK;
+ if (screenoffbit) data += SCREENOFFMASK;
+ if (parity7(data & 3)) data += LIDBITMASK; // parity ofthe two state bits
+ return data;
+}
+
+void setBrightness(int cmd, int val)
+{
+ unsigned char data, new_data;
+ int count, ok;
+
+ if (spi_open(9600, 0) < 0)
+ {
+ printf("Cannot initialize spi driver\n");
+ return;
+ }
+
+ // send 0xFF and receive current status of pi-top-hub
+ count = 0;
+ data = 0xff;
+ printf("Brighntess sending: 0x%X\n", data);
+ do
+ {
+ data = 0xff;
+ ok = spi_rw(&data, 1);
+ if (ok) ok = analyze(data);
+ }
+ while ((!ok) && (count++ < MAXCOUNT));
+ // printf("count = %d\n", count);
+
+ if (ok)
+ {
+ printf("Brighntess receiving: 0x%X - ", data);
+ printf("Current brightness = %d, ", brightness);
+ //force to 0 as set to 1 if rebooted while in screenbitoff=0
+ //the state is stored on pi-top-hub, but isn't reinitialised on reboot
+ screenoffbit=0;
+ if(cmd == BRIGHTNESS_UP)
+ {
+ brightness++;
+ }
+ else if (cmd == BRIGHTNESS_DOWN)
+ {
+ brightness--;
+ }
+ else if (cmd == BRIGHTNESS_SET)
+ {
+ if(!val) screenoffbit=1;
+ else screenoffbit = 0;
+ brightness = val;
+ }
+
+ if (brightness < 1) brightness = 1;
+ if (brightness > 10) brightness = 10;
+
+ printf("Requested brightness = %d, ", brightness);
+ printf("Requested off = %d\n", screenoffbit);
+
+ // calculate data to send
+ shutdown = 0;
+ new_data = calculate();
+
+ // send new data until accepted
+ count = 0;
+ data = new_data;
+ printf("Brighntess sending: 0x%X\n", data);
+ do
+ {
+ data = new_data;
+ ok = spi_rw(&data, 1);
+ if (ok) ok = (data & BRIGHTNESSMASK) == (new_data & BRIGHTNESSMASK);
+ }
+ while ((!ok) && (count++ < MAXCOUNT));
+
+ // printf("count = %d\n", count);
+ if (ok)
+ {
+ printf("Brighntess receiving: 0x%X - ", data);
+ printf("New brightness = %d\n", brightness);
+ }
+ }
+ else printf("Reading current brightness not successful\n");
+
+ spi_close();
+}
+
+int getBrightness()
+{
+ if (screenoffbit) return 0;
+ return brightness;
+}
diff --git a/brightness.h b/brightness.h
new file mode 100644
index 0000000..cb69188
--- /dev/null
+++ b/brightness.h
@@ -0,0 +1,11 @@
+#ifndef __BRIGHTNESS_H__
+#define __BRIGHTNESS_H__
+
+#define BRIGHTNESS_SET 0
+#define BRIGHTNESS_UP 1
+#define BRIGHTNESS_DOWN 2
+
+void setBrightness(int cmd, int val);
+int getBrightness();
+
+#endif
diff --git a/user_io.c b/user_io.c
index d09c03c..0760c78 100644
--- a/user_io.c
+++ b/user_io.c
@@ -26,6 +26,7 @@
#include "minimig_boot.h"
#include "minimig_fdd.h"
#include "minimig_hdd.h"
+#include "brightness.h"
#define BREAK 0x8000
@@ -1850,6 +1851,24 @@ void user_io_kbd(uint16_t key, int press)
}
}
else
+ if (key == 0xBE)
+ {
+ if (press)
+ {
+ setBrightness(BRIGHTNESS_DOWN, 0);
+ vol_set_timeout = GetTimer(1000);
+ }
+ }
+ else
+ if (key == 0xBF)
+ {
+ if (press)
+ {
+ setBrightness(BRIGHTNESS_UP, 0);
+ vol_set_timeout = GetTimer(1000);
+ }
+ }
+ else
if ((core_type == CORE_TYPE_MINIMIG2) ||
(core_type == CORE_TYPE_MIST) ||
(core_type == CORE_TYPE_ARCHIE) ||