mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-09-29 09:54:57 +00:00
first pass at Teensy 4.1 support
This commit is contained in:
parent
e8b77c8aff
commit
c9fe8edc29
@ -2,7 +2,9 @@
|
||||
#define __NIBUTIL_H
|
||||
|
||||
#include <unistd.h>
|
||||
#ifndef TEENSYDUINO
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
@ -1,218 +0,0 @@
|
||||
#include "parallelsram.h"
|
||||
|
||||
// Assumes any Output Enable pin is hardwired-enabled;
|
||||
// any Chip Enable pin is hardwared-enabled.
|
||||
//
|
||||
// Uses the low 8 bits of Port D as I/O lines (2, 14, 7, 8, 6, 20, 21, 5).
|
||||
//
|
||||
// R/W (aka WriteEnable) is on pin 31.
|
||||
|
||||
#define RAM_RW 34
|
||||
|
||||
// The Address pins (19 of them). It would be nice to have these
|
||||
// easily bitwise-manipulable, instead of having to set each bit
|
||||
// individually.
|
||||
//
|
||||
// We can use 12 bits of Port C: 15, 22, 23, 9, 10, 13, 11, 12, 35, 36, 37, 38
|
||||
// And then 6 bits of Port B: 16 17 19 18 49 50
|
||||
//
|
||||
// And hard wire one bit low (we don't need all 19 lines). That gets us
|
||||
// 256 Kb of RAM which should be sufficient.
|
||||
|
||||
static uint8_t addrPins[] = { 15, 22, 23, 9, 10, 13, 11, 12, 35, 36, 37, 38,
|
||||
16, 17, 19, 18, 49, 50
|
||||
};
|
||||
|
||||
#if 0
|
||||
#define DELAY { delayMicroseconds(1); /* overkill, but useful for debugging */ }
|
||||
#else
|
||||
#define DELAY { __asm__ volatile ("nop"); __asm__ volatile ("nop"); \
|
||||
__asm__ volatile ("nop"); __asm__ volatile ("nop"); \
|
||||
__asm__ volatile ("nop"); __asm__ volatile ("nop"); \
|
||||
__asm__ volatile ("nop"); __asm__ volatile ("nop"); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OE_ON { /*if (noe != 255) {digitalWrite(noe, LOW);}*/ }
|
||||
#define OE_OFF { /*if (noe != 255) {digitalWrite(noe, HIGH);}*/ }
|
||||
|
||||
#define CE_ON { /*if (n_ce != 255) {digitalWrite(n_ce, LOW);} if (p_ce != 255) { digitalWrite(p_ce, HIGH); }*/ }
|
||||
#define CE_OFF { /*if (n_ce != 255) {digitalWrite(n_ce, HIGH);} if (p_ce != 255) { digitalWrite(p_ce, LOW); }*/ }
|
||||
|
||||
#define WE_ON { digitalWriteFast(RAM_RW, LOW); }
|
||||
#define WE_OFF { digitalWriteFast(RAM_RW, HIGH); }
|
||||
|
||||
ParallelSRAM::ParallelSRAM()
|
||||
{
|
||||
pinMode(RAM_RW, OUTPUT);
|
||||
|
||||
// Port D is our I/O port. Use the AVR emulation layer to set up the
|
||||
// pins once, and then we'll just fiddle with the DDR, input, and
|
||||
// output directly.
|
||||
|
||||
// Enable it as a digital port...
|
||||
// SIM_SCGC5 |= SIM_SCGC5_PORTD;
|
||||
//... what else? How do we set PORTD_PCR[0-7]?
|
||||
|
||||
pinMode(2, INPUT);
|
||||
pinMode(14, INPUT);
|
||||
pinMode(7, INPUT);
|
||||
pinMode(8, INPUT);
|
||||
pinMode(6, INPUT);
|
||||
pinMode(20, INPUT);
|
||||
pinMode(21, INPUT);
|
||||
pinMode(5, INPUT);
|
||||
isInput = true;
|
||||
|
||||
// Set up the address pins
|
||||
for (int i=0; i<sizeof(addrPins); i++) {
|
||||
pinMode(addrPins[i], INPUT); // disable pull-ups
|
||||
pinMode(addrPins[i], OUTPUT);
|
||||
digitalWrite(addrPins[i], LOW);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ParallelSRAM::SetPins()
|
||||
{
|
||||
pinMode(RAM_RW, OUTPUT);
|
||||
|
||||
// Port D is our I/O port. Use the AVR emulation layer to set up the
|
||||
// pins once, and then we'll just fiddle with the DDR, input, and
|
||||
// output directly.
|
||||
|
||||
// Enable it as a digital port...
|
||||
// SIM_SCGC5 |= SIM_SCGC5_PORTD;
|
||||
//... what else? How do we set PORTD_PCR[0-7]?
|
||||
|
||||
pinMode(2, INPUT);
|
||||
pinMode(14, INPUT);
|
||||
pinMode(7, INPUT);
|
||||
pinMode(8, INPUT);
|
||||
pinMode(6, INPUT);
|
||||
pinMode(20, INPUT);
|
||||
pinMode(21, INPUT);
|
||||
pinMode(5, INPUT);
|
||||
isInput = true;
|
||||
|
||||
// Set up the address pins
|
||||
for (int i=0; i<sizeof(addrPins); i++) {
|
||||
pinMode(addrPins[i], INPUT); // disable pull-ups
|
||||
pinMode(addrPins[i], OUTPUT);
|
||||
digitalWrite(addrPins[i], LOW);
|
||||
}
|
||||
}
|
||||
|
||||
ParallelSRAM::~ParallelSRAM()
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t ParallelSRAM::read(uint32_t addr)
|
||||
{
|
||||
cli();
|
||||
// Read cycle 2
|
||||
setAddress(addr);
|
||||
|
||||
// make sure address is valid before CE is asserted
|
||||
DELAY;
|
||||
|
||||
CE_ON;
|
||||
OE_ON;
|
||||
|
||||
DELAY;
|
||||
|
||||
uint8_t ret = getInput();
|
||||
|
||||
// Optional; can leave these lines asserted...
|
||||
OE_OFF;
|
||||
CE_OFF;
|
||||
|
||||
sei();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ParallelSRAM::write(uint32_t addr, uint8_t v)
|
||||
{
|
||||
cli();
|
||||
setAddress(addr);
|
||||
|
||||
DELAY;
|
||||
|
||||
WE_ON;
|
||||
CE_ON;
|
||||
|
||||
setOutput(v);
|
||||
|
||||
DELAY;
|
||||
|
||||
CE_OFF;
|
||||
WE_OFF;
|
||||
sei();
|
||||
}
|
||||
|
||||
uint8_t ParallelSRAM::getInput()
|
||||
{
|
||||
if (!isInput) {
|
||||
#if 1
|
||||
// Directly set the direction bits. The rest of the port setup
|
||||
// should be fine from the initial config.
|
||||
*(volatile uint8_t *)(&GPIOD_PDDR) = 0x00; // inputs
|
||||
#else
|
||||
pinMode(2, INPUT);
|
||||
pinMode(14, INPUT);
|
||||
pinMode(7, INPUT);
|
||||
pinMode(8, INPUT);
|
||||
pinMode(6, INPUT);
|
||||
pinMode(20, INPUT);
|
||||
pinMode(21, INPUT);
|
||||
pinMode(5, INPUT);
|
||||
#endif
|
||||
isInput = true;
|
||||
}
|
||||
|
||||
return GPIOD_PDIR & 0xFF;
|
||||
}
|
||||
|
||||
void ParallelSRAM::setOutput(uint8_t v)
|
||||
{
|
||||
// FIXME: is there a faster way to do this?
|
||||
if (isInput) {
|
||||
#if 1
|
||||
// FIMXE: would this be correct?
|
||||
*(volatile uint8_t *)(&GPIOD_PDDR) |= 0xFF; // outputs
|
||||
#else
|
||||
pinMode(2, OUTPUT);
|
||||
pinMode(14, OUTPUT);
|
||||
pinMode(7, OUTPUT);
|
||||
pinMode(8, OUTPUT);
|
||||
pinMode(6, OUTPUT);
|
||||
pinMode(20, OUTPUT);
|
||||
pinMode(21, OUTPUT);
|
||||
pinMode(5, OUTPUT);
|
||||
#endif
|
||||
isInput = false;
|
||||
}
|
||||
|
||||
// Directly set the low 8 bits of D.
|
||||
*(volatile uint8_t *)(&GPIOD_PDOR) = v;
|
||||
}
|
||||
|
||||
void ParallelSRAM::setAddress(uint32_t addr)
|
||||
{
|
||||
// The low 12 bits of the address go right in to Port C. Set these
|
||||
// by doing a clear of the bitmask, and then set the bits...
|
||||
GPIOC_PCOR = 0x00000FFF;
|
||||
GPIOC_PSOR = (addr & 0xFFF);
|
||||
|
||||
// The high 6 bits of the address go in to Port B, bits 0..5.
|
||||
// We do that the same way...
|
||||
GPIOB_PCOR = 0x0000003F;
|
||||
GPIOB_PSOR = (addr >> 12);
|
||||
|
||||
#if 0
|
||||
for (uint8_t i=0; i<sizeof(addrPins); i++) {
|
||||
digitalWrite(addrPins[i],
|
||||
addr & (1 << i) ? HIGH : LOW);
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#ifndef __PARALLELSRAM_H
|
||||
#define __PARALLELSRAM_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class ParallelSRAM {
|
||||
public:
|
||||
ParallelSRAM();
|
||||
~ParallelSRAM();
|
||||
|
||||
void SetPins();
|
||||
|
||||
uint8_t read(uint32_t addr);
|
||||
void write(uint32_t addr, uint8_t v);
|
||||
|
||||
protected:
|
||||
uint8_t getInput();
|
||||
void setOutput(uint8_t v);
|
||||
void setAddress(uint32_t addr);
|
||||
|
||||
private:
|
||||
bool isInput;
|
||||
};
|
||||
|
||||
#endif
|
@ -4,208 +4,91 @@
|
||||
#include "bios-font.h"
|
||||
#include "appleui.h"
|
||||
|
||||
#define RS 16
|
||||
#define WR 17
|
||||
#define CS 18
|
||||
#define RST 19
|
||||
#define _clock 65000000
|
||||
|
||||
// Ports C&D of the Teensy connected to DB of the display
|
||||
#define DB_0 15
|
||||
#define DB_1 22
|
||||
#define DB_2 23
|
||||
#define DB_3 9
|
||||
#define DB_4 10
|
||||
#define DB_5 13
|
||||
#define DB_6 11
|
||||
#define DB_7 12
|
||||
#define DB_8 2
|
||||
#define DB_9 14
|
||||
#define DB_10 7
|
||||
#define DB_11 8
|
||||
#define DB_12 6
|
||||
#define DB_13 20
|
||||
#define DB_14 21
|
||||
#define DB_15 5
|
||||
#define PIN_RST 8
|
||||
#define PIN_DC 9
|
||||
#define PIN_CS 10
|
||||
#define PIN_MOSI 11
|
||||
#define PIN_MISO 12
|
||||
#define PIN_SCK 13
|
||||
|
||||
#define disp_x_size 239
|
||||
#define disp_y_size 319
|
||||
|
||||
#define setPixel(color) { LCD_Write_DATA(((color)>>8),((color)&0xFF)); } // 565 RGB
|
||||
|
||||
#include "globals.h"
|
||||
#include "applevm.h"
|
||||
|
||||
ILI9341_t3 tft = ILI9341_t3(PIN_CS, PIN_DC, PIN_RST, PIN_MOSI, PIN_SCK, PIN_MISO);
|
||||
|
||||
// RGB map of each of the lowres colors
|
||||
const uint8_t loresPixelColors[16*2] = { 0x00,0x00, // 0 black
|
||||
0xC0,0x06, // 1 magenta
|
||||
0x00,0x10, // 2 dark blue
|
||||
0xA1,0xB5, // 3 purple
|
||||
0x04,0x80, // 4 dark green
|
||||
0x6B,0x4D, // 5 dark grey
|
||||
0x1B,0x9F, // 6 med blue
|
||||
0x0D,0xFD, // 7 light blue
|
||||
0x92,0xA5, // 8 brown
|
||||
0xF8,0xC5, // 9 orange
|
||||
0x95,0x55, // 10 light gray
|
||||
0xFC,0xF2, // 11 pink
|
||||
0x07,0xE0, // 12 green
|
||||
0xFF,0xE0, // 13 yellow
|
||||
0x87,0xF0, // 14 aqua
|
||||
0xFF,0xFF // 15 white
|
||||
const uint16_t loresPixelColors[16] = { 0x0000, // 0 black
|
||||
0xC006, // 1 magenta
|
||||
0x0010, // 2 dark blue
|
||||
0xA1B5, // 3 purple
|
||||
0x0480, // 4 dark green
|
||||
0x6B4D, // 5 dark grey
|
||||
0x1B9F, // 6 med blue
|
||||
0x0DFD, // 7 light blue
|
||||
0x92A5, // 8 brown
|
||||
0xF8C5, // 9 orange
|
||||
0x9555, // 10 light gray
|
||||
0xFCF2, // 11 pink
|
||||
0x07E0, // 12 green
|
||||
0xFFE0, // 13 yellow
|
||||
0x87F0, // 14 aqua
|
||||
0xFFFF // 15 white
|
||||
};
|
||||
|
||||
const uint8_t loresPixelColorsGreen[16*2] = { 0x00, 0x00,
|
||||
0x01, 0x40,
|
||||
0x00, 0x40,
|
||||
0x02, 0x80,
|
||||
0x03, 0x00,
|
||||
0x03, 0x40,
|
||||
0x03, 0x00,
|
||||
0x04, 0x80,
|
||||
0x02, 0xC0,
|
||||
0x02, 0x40,
|
||||
0x05, 0x00,
|
||||
0x05, 0x40,
|
||||
0x05, 0x80,
|
||||
0x07, 0x00,
|
||||
0x06, 0x80,
|
||||
0x07, 0xC0
|
||||
const uint16_t loresPixelColorsGreen[16] = { 0x0000,
|
||||
0x0140,
|
||||
0x0040,
|
||||
0x0280,
|
||||
0x0300,
|
||||
0x0340,
|
||||
0x0300,
|
||||
0x0480,
|
||||
0x02C0,
|
||||
0x0240,
|
||||
0x0500,
|
||||
0x0540,
|
||||
0x0580,
|
||||
0x0700,
|
||||
0x0680,
|
||||
0x07C0
|
||||
};
|
||||
|
||||
const uint8_t loresPixelColorsWhite[16*2] = { 0x00, 0x00,
|
||||
0x29, 0x45,
|
||||
0x08, 0x41,
|
||||
0x52, 0x8A,
|
||||
0x63, 0x0C,
|
||||
0x6B, 0x4D,
|
||||
0x63, 0x0C,
|
||||
0x94, 0x92,
|
||||
0x5A, 0xCB,
|
||||
0x4A, 0x49,
|
||||
0xA5, 0x14,
|
||||
0xAD, 0x55,
|
||||
0xB5, 0x96,
|
||||
0xE7, 0x1C,
|
||||
0xD6, 0x9A,
|
||||
0xFF, 0xDF
|
||||
const uint16_t loresPixelColorsWhite[16] = { 0x0000,
|
||||
0x2945,
|
||||
0x0841,
|
||||
0x528A,
|
||||
0x630C,
|
||||
0x6B4D,
|
||||
0x630C,
|
||||
0x9492,
|
||||
0x5ACB,
|
||||
0x4A49,
|
||||
0xA514,
|
||||
0xAD55,
|
||||
0xB596,
|
||||
0xE71C,
|
||||
0xD69A,
|
||||
0xFFDF
|
||||
};
|
||||
|
||||
TeensyDisplay::TeensyDisplay()
|
||||
{
|
||||
memset(videoBuffer, 0, sizeof(videoBuffer));
|
||||
|
||||
pinMode(DB_8, OUTPUT);
|
||||
pinMode(DB_9, OUTPUT);
|
||||
pinMode(DB_10, OUTPUT);
|
||||
pinMode(DB_11, OUTPUT);
|
||||
pinMode(DB_12, OUTPUT);
|
||||
pinMode(DB_13, OUTPUT);
|
||||
pinMode(DB_14, OUTPUT);
|
||||
pinMode(DB_15, OUTPUT);
|
||||
pinMode(DB_0, OUTPUT);
|
||||
pinMode(DB_1, OUTPUT);
|
||||
pinMode(DB_2, OUTPUT);
|
||||
pinMode(DB_3, OUTPUT);
|
||||
pinMode(DB_4, OUTPUT);
|
||||
pinMode(DB_5, OUTPUT);
|
||||
pinMode(DB_6, OUTPUT);
|
||||
pinMode(DB_7, OUTPUT);
|
||||
|
||||
P_RS = portOutputRegister(digitalPinToPort(RS));
|
||||
B_RS = digitalPinToBitMask(RS);
|
||||
P_WR = portOutputRegister(digitalPinToPort(WR));
|
||||
B_WR = digitalPinToBitMask(WR);
|
||||
P_CS = portOutputRegister(digitalPinToPort(CS));
|
||||
B_CS = digitalPinToBitMask(CS);
|
||||
P_RST = portOutputRegister(digitalPinToPort(RST));
|
||||
B_RST = digitalPinToBitMask(RST);
|
||||
|
||||
pinMode(RS,OUTPUT);
|
||||
pinMode(WR,OUTPUT);
|
||||
pinMode(CS,OUTPUT);
|
||||
pinMode(RST,OUTPUT);
|
||||
|
||||
// begin initialization
|
||||
|
||||
sbi(P_RST, B_RST);
|
||||
delay(5);
|
||||
cbi(P_RST, B_RST);
|
||||
delay(15);
|
||||
sbi(P_RST, B_RST);
|
||||
delay(15);
|
||||
|
||||
cbi(P_CS, B_CS);
|
||||
|
||||
// Setup here is from the document "Driver IC SSD1289.pdf"
|
||||
// https://forum.allaboutcircuits.com/attachments/driver-ic-ssd1289-pdf.71570/
|
||||
LCD_Write_COM_DATA(0x00,0x0001); // R00h: enable the oscillator
|
||||
LCD_Write_COM_DATA(0x03,0xA8A4); // power control [%1010 1000 1010 1000] == DCT3, DCT1, BT2, DC3, DC1, AP2
|
||||
|
||||
LCD_Write_COM_DATA(0x0C,0x0000); // power control2 [0]
|
||||
LCD_Write_COM_DATA(0x0D,0x080C); // power control3 [VRH3, VRH2, invalid bits]
|
||||
LCD_Write_COM_DATA(0x0E,0x2B00); // power control4 VCOMG, VDV3, VDV1, VDV0
|
||||
LCD_Write_COM_DATA(0x1E,0x00B7); // power control5 nOTP, VCM5, VCM4, VCM2, VCM1, VCM0
|
||||
// LCD_Write_COM_DATA(0x01,0x2B3F); // driver control output REV, BGR, TB, MUX8, MUX5, MUX4, MUX3, MUX2, MUX1, MUX0
|
||||
|
||||
// This sets the direction of the scan. These two are mirror
|
||||
// opposites. The first is right in my setup.
|
||||
LCD_Write_COM_DATA(0x01,0x293F); // driver control output REV, BGR, TB, MUX8, MUX5, MUX4, MUX3, MUX2, MUX1, MUX0
|
||||
// LCD_Write_COM_DATA(0x01,0x693F); // driver control output RL, REV, BGR, TB, MUX8, MUX5, MUX4, MUX3, MUX2, MUX1, MUX0
|
||||
|
||||
|
||||
LCD_Write_COM_DATA(0x02,0x0600); // LCD drive AC control B/C, EOR
|
||||
LCD_Write_COM_DATA(0x10,0x0000); // sleep mode 0
|
||||
// Change the (Y) order here to match above (TB=0)
|
||||
//LCD_Write_COM_DATA(0x11,0x6070); // Entry mode DFM1, DFM0, TY0, ID1, ID0
|
||||
//LCD_Write_COM_DATA(0x11,0x6050); // Entry mode DFM1, DFM0, TY0, ID0
|
||||
LCD_Write_COM_DATA(0x11,0x6078); // Entry mode DFM1, DFM0, TY0, ID1, ID0, AM
|
||||
|
||||
LCD_Write_COM_DATA(0x05,0x0000); // compare reg1
|
||||
LCD_Write_COM_DATA(0x06,0x0000); // compare reg2
|
||||
LCD_Write_COM_DATA(0x16,0xEF1C); // horiz porch (default)
|
||||
LCD_Write_COM_DATA(0x17,0x0003); // vertical porch
|
||||
LCD_Write_COM_DATA(0x07,0x0233); // display control VLE1, GON, DTE, D1, D0
|
||||
LCD_Write_COM_DATA(0x0B,0x5308); // frame cycle control: %0101 0011 0000 1000
|
||||
|
||||
LCD_Write_COM_DATA(0x0F,0x0000); // gate scan start posn
|
||||
LCD_Write_COM_DATA(0x41,0x0000); // vertical scroll control1
|
||||
LCD_Write_COM_DATA(0x42,0x0000); // vertical scroll control2
|
||||
LCD_Write_COM_DATA(0x48,0x0000); // first window start
|
||||
LCD_Write_COM_DATA(0x49,0x013F); // first window end (0x13f == 319)
|
||||
LCD_Write_COM_DATA(0x4A,0x0000); // second window start
|
||||
LCD_Write_COM_DATA(0x4B,0x0000); // second window end
|
||||
LCD_Write_COM_DATA(0x44,0xEF00); // horiz ram addr posn
|
||||
LCD_Write_COM_DATA(0x45,0x0000); // vert ram start posn
|
||||
LCD_Write_COM_DATA(0x46,0x013F); // vert ram end posn
|
||||
LCD_Write_COM_DATA(0x30,0x0707); // γ control
|
||||
LCD_Write_COM_DATA(0x31,0x0204);//
|
||||
LCD_Write_COM_DATA(0x32,0x0204);//
|
||||
LCD_Write_COM_DATA(0x33,0x0502);//
|
||||
LCD_Write_COM_DATA(0x34,0x0507);//
|
||||
LCD_Write_COM_DATA(0x35,0x0204);//
|
||||
LCD_Write_COM_DATA(0x36,0x0204);//
|
||||
LCD_Write_COM_DATA(0x37,0x0502);//
|
||||
LCD_Write_COM_DATA(0x3A,0x0302);//
|
||||
LCD_Write_COM_DATA(0x3B,0x0302);//
|
||||
LCD_Write_COM_DATA(0x23,0x0000);// RAM write data mask1
|
||||
LCD_Write_COM_DATA(0x24,0x0000); // RAM write data mask2
|
||||
LCD_Write_COM_DATA(0x25,0x8000); // frame frequency (OSC3)
|
||||
LCD_Write_COM_DATA(0x4f,0x0000); // Set GDDRAM Y address counter
|
||||
LCD_Write_COM_DATA(0x4e,0x0000); // Set GDDRAM X address counter
|
||||
#if 1
|
||||
// Set data access speed optimization (?) per pg. 50; doesn't actually seem to change anything though?
|
||||
LCD_Write_COM_DATA(0x28, 0x0006);
|
||||
LCD_Write_COM_DATA(0x2F, 0x12BE);
|
||||
LCD_Write_COM_DATA(0x12, 0x6CEB);
|
||||
#endif
|
||||
|
||||
LCD_Write_COM(0x22); // RAM data write
|
||||
sbi(P_CS, B_CS);
|
||||
tft.begin();
|
||||
tft.setRotation(3);
|
||||
tft.setClock(_clock);
|
||||
|
||||
// Could set up an automatic DMA transfer here; cf.
|
||||
// https://forum.pjrc.com/threads/25778-Could-there-be-something-like-an-ISR-template-function/page4
|
||||
|
||||
// LCD initialization complete
|
||||
|
||||
setColor(255, 255, 255);
|
||||
|
||||
clrScr();
|
||||
|
||||
driveIndicator[0] = driveIndicator[1] = false;
|
||||
@ -216,196 +99,37 @@ TeensyDisplay::~TeensyDisplay()
|
||||
{
|
||||
}
|
||||
|
||||
void TeensyDisplay::_fast_fill_16(int ch, int cl, long pix)
|
||||
{
|
||||
*(volatile uint8_t *)(&GPIOD_PDOR) = ch;
|
||||
*(volatile uint8_t *)(&GPIOC_PDOR) = cl;
|
||||
uint16_t blocks = pix / 16;
|
||||
|
||||
for (uint16_t i=0; i<blocks; i++) {
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
pulse_low(P_WR, B_WR);
|
||||
}
|
||||
if ((pix % 16) != 0) {
|
||||
for (int i=0; i<(pix % 16); i++)
|
||||
{
|
||||
pulse_low(P_WR, B_WR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeensyDisplay::redraw()
|
||||
{
|
||||
cbi(P_CS, B_CS);
|
||||
clrXY();
|
||||
sbi(P_RS, B_RS);
|
||||
|
||||
moveTo(0, 0);
|
||||
|
||||
g_ui->drawStaticUIElement(UIeOverlay);
|
||||
|
||||
if (g_vm) {
|
||||
g_ui->drawOnOffUIElement(UIeDisk1_state, ((AppleVM *)g_vm)->DiskName(0)[0] == '\0');
|
||||
g_ui->drawOnOffUIElement(UIeDisk2_state, ((AppleVM *)g_vm)->DiskName(1)[0] == '\0');
|
||||
}
|
||||
|
||||
cbi(P_CS, B_CS);
|
||||
clrXY();
|
||||
sbi(P_RS, B_RS);
|
||||
}
|
||||
|
||||
void TeensyDisplay::clrScr()
|
||||
{
|
||||
cbi(P_CS, B_CS);
|
||||
clrXY();
|
||||
sbi(P_RS, B_RS);
|
||||
_fast_fill_16(0, 0, ((disp_x_size+1)*(disp_y_size+1)));
|
||||
sbi(P_CS, B_CS);
|
||||
}
|
||||
|
||||
// The display flips X and Y, so expect to see "x" as "vertical"
|
||||
// and "y" as "horizontal" here...
|
||||
void TeensyDisplay::setYX(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
||||
{
|
||||
LCD_Write_COM_DATA(0x44, (y2<<8)+y1); // Horiz start addr, Horiz end addr
|
||||
LCD_Write_COM_DATA(0x45, x1); // vert start pos
|
||||
LCD_Write_COM_DATA(0x46, x2); // vert end pos
|
||||
LCD_Write_COM_DATA(0x4e,y1); // RAM address set (horiz)
|
||||
LCD_Write_COM_DATA(0x4f,x1); // RAM address set (vert)
|
||||
LCD_Write_COM(0x22);
|
||||
}
|
||||
|
||||
void TeensyDisplay::clrXY()
|
||||
{
|
||||
setYX(0, 0, disp_y_size, disp_x_size);
|
||||
}
|
||||
|
||||
void TeensyDisplay::setColor(byte r, byte g, byte b)
|
||||
{
|
||||
fch=((r&248)|g>>5);
|
||||
fcl=((g&28)<<3|b>>3);
|
||||
}
|
||||
|
||||
void TeensyDisplay::setColor(uint16_t color)
|
||||
{
|
||||
fch = (uint8_t)(color >> 8);
|
||||
fcl = (uint8_t)(color & 0xFF);
|
||||
}
|
||||
|
||||
void TeensyDisplay::fillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
||||
{
|
||||
if (x1>x2) {
|
||||
swap(uint16_t, x1, x2);
|
||||
}
|
||||
if (y1 > y2) {
|
||||
swap(uint16_t, y1, y2);
|
||||
}
|
||||
|
||||
cbi(P_CS, B_CS);
|
||||
setYX(x1, y1, x2, y2);
|
||||
sbi(P_RS, B_RS);
|
||||
_fast_fill_16(fch,fcl,((long(x2-x1)+1)*(long(y2-y1)+1)));
|
||||
sbi(P_CS, B_CS);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawPixel(uint16_t x, uint16_t y)
|
||||
{
|
||||
cbi(P_CS, B_CS);
|
||||
setYX(x, y, x, y);
|
||||
setPixel((fch<<8)|fcl);
|
||||
sbi(P_CS, B_CS);
|
||||
clrXY();
|
||||
// FIXME: only fill the area that's got our "terminal"
|
||||
tft.fillScreen(ILI9341_BLACK);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawUIPixel(uint16_t x, uint16_t y, uint16_t color)
|
||||
{
|
||||
drawPixel(x,y,color);
|
||||
tft.drawPixel(x,y,color);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawPixel(uint16_t x, uint16_t y, uint16_t color)
|
||||
{
|
||||
cbi(P_CS, B_CS);
|
||||
setYX(x, y, x, y);
|
||||
setPixel(color);
|
||||
sbi(P_CS, B_CS);
|
||||
clrXY();
|
||||
tft.drawPixel(x,y,color);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
uint16_t color16 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
|
||||
|
||||
cbi(P_CS, B_CS);
|
||||
setYX(x, y, x, y);
|
||||
setPixel(color16);
|
||||
sbi(P_CS, B_CS);
|
||||
clrXY();
|
||||
}
|
||||
|
||||
void TeensyDisplay::LCD_Writ_Bus(uint8_t ch, uint8_t cl)
|
||||
{
|
||||
*(volatile uint8_t *)(&GPIOD_PDOR) = ch;
|
||||
*(volatile uint8_t *)(&GPIOC_PDOR) = cl;
|
||||
pulse_low(P_WR, B_WR);
|
||||
}
|
||||
|
||||
void TeensyDisplay::LCD_Write_COM(uint8_t VL)
|
||||
{
|
||||
cbi(P_RS, B_RS);
|
||||
LCD_Writ_Bus(0x00, VL);
|
||||
}
|
||||
|
||||
void TeensyDisplay::LCD_Write_DATA(uint8_t VH, uint8_t VL)
|
||||
{
|
||||
sbi(P_RS, B_RS);
|
||||
LCD_Writ_Bus(VH,VL);
|
||||
}
|
||||
|
||||
void TeensyDisplay::LCD_Write_DATA(uint8_t VL)
|
||||
{
|
||||
sbi(P_RS, B_RS);
|
||||
LCD_Writ_Bus(0x00, VL);
|
||||
}
|
||||
|
||||
void TeensyDisplay::LCD_Write_COM_DATA(uint8_t com1, uint16_t dat1)
|
||||
{
|
||||
LCD_Write_COM(com1);
|
||||
LCD_Write_DATA(dat1>>8, dat1);
|
||||
}
|
||||
|
||||
void TeensyDisplay::moveTo(uint16_t col, uint16_t row)
|
||||
{
|
||||
cbi(P_CS, B_CS);
|
||||
|
||||
// FIXME: eventually set drawing to the whole screen and leave it that way
|
||||
|
||||
// set drawing to the whole screen
|
||||
// setYX(0, 0, disp_y_size, disp_x_size);
|
||||
LCD_Write_COM_DATA(0x4e,row); // RAM address set (horiz)
|
||||
LCD_Write_COM_DATA(0x4f,col); // RAM address set (vert)
|
||||
|
||||
LCD_Write_COM(0x22);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawNextPixel(uint16_t color)
|
||||
{
|
||||
// Anything inside this object should call setPixel directly. This
|
||||
// is primarily for the BIOS.
|
||||
setPixel(color);
|
||||
drawPixel(x,y,color16);
|
||||
}
|
||||
|
||||
void TeensyDisplay::blit(AiieRect r)
|
||||
@ -413,20 +137,7 @@ void TeensyDisplay::blit(AiieRect r)
|
||||
// remember these are "starts at pixel number" values, where 0 is the first.
|
||||
#define HOFFSET 18
|
||||
#define VOFFSET 13
|
||||
|
||||
// Define the horizontal area that we're going to draw in
|
||||
LCD_Write_COM_DATA(0x45, HOFFSET+r.left); // offset by 20 to center it...
|
||||
LCD_Write_COM_DATA(0x46, HOFFSET+r.right);
|
||||
|
||||
// position the "write" address
|
||||
LCD_Write_COM_DATA(0x4e,VOFFSET+r.top); // row
|
||||
LCD_Write_COM_DATA(0x4f,HOFFSET+r.left); // col
|
||||
|
||||
// prepare the LCD to receive data bytes for its RAM
|
||||
LCD_Write_COM(0x22);
|
||||
|
||||
// send the pixel data
|
||||
sbi(P_RS, B_RS);
|
||||
|
||||
uint8_t *vbufPtr;
|
||||
for (uint8_t y=r.top; y<=r.bottom; y++) {
|
||||
vbufPtr = &videoBuffer[y * TEENSY_DRUN + r.left];
|
||||
@ -440,19 +151,17 @@ void TeensyDisplay::blit(AiieRect r)
|
||||
}
|
||||
colorIdx <<= 1;
|
||||
|
||||
// The colors are broken up in to two 8-bit values to speed things up.
|
||||
const uint8_t *p;
|
||||
|
||||
uint16_t c;
|
||||
if (g_displayType == m_monochrome) {
|
||||
p = &loresPixelColorsGreen[colorIdx];
|
||||
c = loresPixelColorsGreen[colorIdx];
|
||||
}
|
||||
else if (g_displayType == m_blackAndWhite) {
|
||||
p = &loresPixelColorsWhite[colorIdx];
|
||||
c = loresPixelColorsWhite[colorIdx];
|
||||
} else {
|
||||
p = &loresPixelColors[colorIdx];
|
||||
c = loresPixelColors[colorIdx];
|
||||
}
|
||||
|
||||
LCD_Writ_Bus(*p, *(p+1));
|
||||
drawPixel(x+HOFFSET,y+VOFFSET,c);
|
||||
|
||||
if (x & 0x01) {
|
||||
// When we do the odd pixels, then move the pixel pointer to the next pixel
|
||||
@ -460,14 +169,9 @@ void TeensyDisplay::blit(AiieRect r)
|
||||
}
|
||||
}
|
||||
}
|
||||
cbi(P_CS, B_CS);
|
||||
|
||||
// draw overlay, if any
|
||||
if (overlayMessage[0]) {
|
||||
// reset the viewport in order to draw the overlay...
|
||||
LCD_Write_COM_DATA(0x45, 0);
|
||||
LCD_Write_COM_DATA(0x46, 319);
|
||||
|
||||
drawString(M_SELECTDISABLED, 1, 240 - 16 - 12, overlayMessage);
|
||||
}
|
||||
}
|
||||
@ -504,30 +208,17 @@ void TeensyDisplay::drawCharacter(uint8_t mode, uint16_t x, uint8_t y, char c)
|
||||
|
||||
temp=(c*ysize);
|
||||
|
||||
// FIXME: the embedded moveTo() and setPixel() calls *should* work
|
||||
// -- and do, for the most part. But in the BIOS they cut off after
|
||||
// about half the screen. Using drawPixel() is substantially less
|
||||
// efficient, but works properly.
|
||||
|
||||
for (int8_t y_off = 0; y_off <= ysize; y_off++) {
|
||||
//moveTo(x, y + y_off); // does a cbi(P_CS, B_CS)
|
||||
uint8_t ch = pgm_read_byte(&BiosFont[temp]);
|
||||
for (int8_t x_off = 0; x_off <= xsize; x_off++) {
|
||||
if (ch & (1 << (7-x_off))) {
|
||||
drawPixel(x+x_off, y+y_off, onPixel);
|
||||
//setPixel(onPixel);
|
||||
} else {
|
||||
drawPixel(x+x_off, y+y_off, offPixel);
|
||||
//setPixel(offPixel);
|
||||
}
|
||||
}
|
||||
temp++;
|
||||
}
|
||||
|
||||
// Need to leave cbi set for the next draw operation. Particularly important
|
||||
// on startup, when transitioning from '@' to 'Apple //e', while also drawing
|
||||
// overlay text.
|
||||
cbi(P_CS, B_CS);
|
||||
}
|
||||
|
||||
void TeensyDisplay::drawString(uint8_t mode, uint16_t x, uint8_t y, const char *str)
|
||||
@ -546,19 +237,12 @@ void TeensyDisplay::drawImageOfSizeAt(const uint8_t *img,
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
|
||||
if (sizex == DISPLAYWIDTH) {
|
||||
moveTo(0,0);
|
||||
}
|
||||
|
||||
for (uint8_t y=0; y<sizey; y++) {
|
||||
if (sizex != DISPLAYWIDTH) {
|
||||
moveTo(wherex, wherey + y);
|
||||
}
|
||||
for (uint16_t x=0; x<sizex; x++) {
|
||||
r = pgm_read_byte(&img[(y*sizex + x)*3 + 0]);
|
||||
g = pgm_read_byte(&img[(y*sizex + x)*3 + 1]);
|
||||
b = pgm_read_byte(&img[(y*sizex + x)*3 + 2]);
|
||||
setPixel((((r&248)|g>>5) << 8) | ((g&28)<<3|b>>3));
|
||||
drawPixel(wherex+x, wherey+y, (((r&248)|g>>5) << 8) | ((g&28)<<3|b>>3));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -616,4 +300,3 @@ void TeensyDisplay::cachePixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
cacheDoubleWidePixel(x/2, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __TEENSY_DISPLAY_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ILI9341_t3.h>
|
||||
#include "physicaldisplay.h"
|
||||
|
||||
#define TEENSY_DHEIGHT 192
|
||||
@ -12,16 +13,6 @@
|
||||
#define regtype volatile uint8_t
|
||||
#define regsize uint8_t
|
||||
|
||||
#define cbi(reg, bitmask) *reg &= ~bitmask
|
||||
#define sbi(reg, bitmask) *reg |= bitmask
|
||||
#define pulse_high(reg, bitmask) { sbi(reg, bitmask); cbi(reg, bitmask); }
|
||||
#define pulse_low(reg, bitmask) { cbi(reg, bitmask); sbi(reg, bitmask); }
|
||||
|
||||
#define cport(port, data) port &= data
|
||||
#define sport(port, data) port |= data
|
||||
|
||||
#define swap(type, i, j) {type t = i; i = j; j = t;}
|
||||
|
||||
class UTFT;
|
||||
class BIOS;
|
||||
|
||||
@ -47,40 +38,15 @@ class TeensyDisplay : public PhysicalDisplay {
|
||||
virtual void cache2DoubleWidePixels(uint16_t x, uint16_t y, uint8_t colorA, uint8_t colorB);
|
||||
virtual void cachePixel(uint16_t x, uint16_t y, uint8_t color);
|
||||
|
||||
protected:
|
||||
void moveTo(uint16_t col, uint16_t row);
|
||||
void drawNextPixel(uint16_t color);
|
||||
|
||||
private:
|
||||
regtype *P_RS, *P_WR, *P_CS, *P_RST, *P_SDA, *P_SCL, *P_ALE;
|
||||
regsize B_RS, B_WR, B_CS, B_RST, B_SDA, B_SCL, B_ALE;
|
||||
|
||||
uint8_t fch, fcl; // high and low foreground colors
|
||||
|
||||
void _fast_fill_16(int ch, int cl, long pix);
|
||||
|
||||
void setYX(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
|
||||
void clrXY();
|
||||
|
||||
void setColor(byte r, byte g, byte b);
|
||||
void setColor(uint16_t color);
|
||||
void fillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
|
||||
virtual void drawPixel(uint16_t x, uint16_t y);
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint16_t color);
|
||||
virtual void drawPixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual void drawUIPixel(uint16_t x, uint16_t y, uint16_t color);
|
||||
|
||||
inline void LCD_Writ_Bus(uint8_t VH,uint8_t VL) __attribute__((always_inline));
|
||||
inline void LCD_Write_COM(uint8_t VL) __attribute__((always_inline));
|
||||
inline void LCD_Write_DATA(uint8_t VH,uint8_t VL) __attribute__((always_inline));
|
||||
inline void LCD_Write_DATA(uint8_t VL) __attribute__((always_inline));
|
||||
inline void LCD_Write_COM_DATA(uint8_t com1,uint16_t dat1) __attribute__((always_inline));
|
||||
|
||||
bool needsRedraw;
|
||||
bool driveIndicator[2];
|
||||
bool driveIndicatorDirty;
|
||||
|
||||
// video buffer is 4bpp
|
||||
uint8_t videoBuffer[TEENSY_DHEIGHT * TEENSY_DWIDTH / 2];
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include <Arduino.h>
|
||||
#include <wchar.h>
|
||||
#include <SdFat.h>
|
||||
#include "teensy-filemanager.h"
|
||||
#include <string.h> // strcpy
|
||||
#include <TeensyThreads.h>
|
||||
@ -15,7 +14,7 @@ TeensyFileManager::TeensyFileManager()
|
||||
// FIXME: used to have 'enabled = sd.begin()' here, but we weren't
|
||||
// using the enabled flag, so I've removed it to save the RAM for
|
||||
// now; but eventually we need better error handling here
|
||||
sd.begin();
|
||||
SD.begin(BUILTIN_SDCARD);
|
||||
}
|
||||
|
||||
TeensyFileManager::~TeensyFileManager()
|
||||
@ -94,7 +93,7 @@ int8_t TeensyFileManager::readDir(const char *where, const char *suffix, char *o
|
||||
}
|
||||
|
||||
int8_t idxCount = 1;
|
||||
File f = sd.open(where);
|
||||
File f = SD.open(where, FILE_READ);
|
||||
|
||||
while (1) {
|
||||
File e = f.openNextFile();
|
||||
@ -105,7 +104,8 @@ int8_t TeensyFileManager::readDir(const char *where, const char *suffix, char *o
|
||||
}
|
||||
|
||||
// Skip MAC fork files
|
||||
e.getName(outputFN, maxlen-1); // -1 for trailing '/' on directories
|
||||
// FIXME: strncpy
|
||||
strcpy(outputFN, e.name()); // and we need maxlen-1 for trailing '/' on directories
|
||||
if (outputFN[0] == '.') {
|
||||
e.close();
|
||||
continue;
|
||||
@ -166,8 +166,8 @@ bool TeensyFileManager::_prepCache(int8_t fd)
|
||||
}
|
||||
|
||||
// Open the new one
|
||||
cacheFile = sd.open(cachedNames[fd], O_RDWR | O_CREAT);
|
||||
if (!cacheFile.isOpen()) {
|
||||
cacheFile = SD.open(cachedNames[fd], FILE_WRITE);
|
||||
if (!cacheFile) {
|
||||
return false;
|
||||
}
|
||||
cacheFd = fd; // cache is live
|
||||
@ -198,12 +198,12 @@ bool TeensyFileManager::setSeekPosition(int8_t fd, uint32_t pos)
|
||||
// FIXME: this should be private
|
||||
void TeensyFileManager::seekToEnd(int8_t fd)
|
||||
{
|
||||
FatFile f = sd.open(cachedNames[fd], FILE_READ);
|
||||
if (!f.isOpen()) {
|
||||
File f = SD.open(cachedNames[fd], FILE_READ);
|
||||
if (!f) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileSeekPositions[fd] = f.fileSize();
|
||||
fileSeekPositions[fd] = f.size();
|
||||
f.close();
|
||||
}
|
||||
|
||||
@ -223,11 +223,11 @@ int TeensyFileManager::write(int8_t fd, const void *buf, int nbyte)
|
||||
|
||||
uint32_t pos = fileSeekPositions[fd];
|
||||
|
||||
if (!cacheFile.seekSet(pos)) {
|
||||
if (!cacheFile.seek(pos)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cacheFile.write(buf, nbyte) != nbyte) {
|
||||
if (cacheFile.write((const uint8_t *)buf, (size_t)nbyte) != (size_t)nbyte) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ int TeensyFileManager::read(int8_t fd, void *buf, int nbyte)
|
||||
_prepCache(fd);
|
||||
|
||||
uint32_t pos = fileSeekPositions[fd];
|
||||
if (!cacheFile.seekSet(pos)) {
|
||||
if (!cacheFile.seek(pos)) {
|
||||
return -1;
|
||||
}
|
||||
fileSeekPositions[fd] += nbyte;
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
#include "filemanager.h"
|
||||
#include <stdint.h>
|
||||
#include <SdFat.h>
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
class TeensyFileManager : public FileManager {
|
||||
public:
|
||||
@ -30,11 +31,10 @@ class TeensyFileManager : public FileManager {
|
||||
bool _prepCache(int8_t fd);
|
||||
|
||||
private:
|
||||
volatile int8_t numCached;
|
||||
int8_t numCached;
|
||||
|
||||
volatile SdFatSdio sd;
|
||||
volatile int8_t cacheFd;
|
||||
volatile FatFile cacheFile;
|
||||
int8_t cacheFd;
|
||||
File cacheFile;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,7 +23,8 @@ void TeensySpeaker::toggle(uint32_t c)
|
||||
mixerValue >>= (16-g_volume);
|
||||
|
||||
// FIXME: glad it's DAC0 and all, but... how does that relate to the pin passed in the constructor?
|
||||
analogWriteDAC0(mixerValue);
|
||||
// FIXME: really doesn't work for the Teensy 4 at all
|
||||
// analogWriteDAC0(mixerValue);
|
||||
}
|
||||
|
||||
void TeensySpeaker::maintainSpeaker(uint32_t c, uint64_t runtimeInMicros)
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#define RESETPIN 39
|
||||
#define BATTERYPIN 32
|
||||
#define SPEAKERPIN A21
|
||||
#define SPEAKERPIN 19 // FIXME this isn't right
|
||||
|
||||
#include "globals.h"
|
||||
#include "teensy-crash.h"
|
||||
@ -35,13 +35,6 @@ BIOS bios;
|
||||
|
||||
static time_t getTeensy3Time() { return Teensy3Clock.get(); }
|
||||
|
||||
#define ESP_TXD 51
|
||||
#define ESP_CHPD 52
|
||||
#define ESP_RST 53
|
||||
#define ESP_RXD 40
|
||||
#define ESP_GPIO0 41
|
||||
#define ESP_GPIO2 42
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(230400);
|
||||
@ -65,6 +58,8 @@ void setup()
|
||||
pinMode(RESETPIN, INPUT);
|
||||
digitalWrite(RESETPIN, HIGH);
|
||||
|
||||
println("FIXME: skipping analogReference, speaker, battery for Teensy 4");
|
||||
/*
|
||||
analogReference(EXTERNAL); // 3.3v external, or 1.7v internal. We need 1.7 internal for the battery level, which means we're gonna have to do something about the paddles :/
|
||||
analogReadRes(8); // We only need 8 bits of resolution (0-255) for battery & paddles
|
||||
analogReadAveraging(4); // ?? dunno if we need this or not.
|
||||
@ -72,6 +67,7 @@ void setup()
|
||||
|
||||
pinMode(SPEAKERPIN, OUTPUT); // analog speaker output, used as digital volume control
|
||||
pinMode(BATTERYPIN, INPUT);
|
||||
*/
|
||||
|
||||
println("creating virtual hardware");
|
||||
g_speaker = new TeensySpeaker(SPEAKERPIN);
|
||||
@ -111,7 +107,7 @@ void setup()
|
||||
g_keyboard = new TeensyKeyboard(g_vm->getKeyboard());
|
||||
|
||||
println(" paddles");
|
||||
g_paddles = new TeensyPaddles(A23, A24, 1, 1);
|
||||
g_paddles = new TeensyPaddles(A3, A4, 1, 1);
|
||||
|
||||
// Now that all the virtual hardware is glued together, reset the VM
|
||||
println("Resetting VM");
|
||||
@ -293,9 +289,12 @@ void loop()
|
||||
|
||||
// This is a bit disruptive - but the external 3.3v will drop along with the battery level, so we should use the more stable (I hope) internal 1.7v.
|
||||
// The alternative is to build a more stable buck/boost regulator for reference...
|
||||
|
||||
println("FIXME: analogReference for Teensy 4.0 => batteryLevel");
|
||||
/*
|
||||
analogReference(INTERNAL);
|
||||
batteryLevel = analogRead(BATTERYPIN);
|
||||
analogReference(EXTERNAL);
|
||||
analogReference(EXTERNAL);*/
|
||||
|
||||
/* LiIon charge to a max of 4.2v; and we should not let them discharge below about 3.5v.
|
||||
* With a resistor voltage divider of Z1=39k, Z2=10k we're looking at roughly 20.4% of
|
||||
|
Loading…
Reference in New Issue
Block a user