diff options
Diffstat (limited to 'SrcShared/Hardware/EmRegsVZHandEra330.cpp')
-rw-r--r-- | SrcShared/Hardware/EmRegsVZHandEra330.cpp | 608 |
1 files changed, 608 insertions, 0 deletions
diff --git a/SrcShared/Hardware/EmRegsVZHandEra330.cpp b/SrcShared/Hardware/EmRegsVZHandEra330.cpp new file mode 100644 index 0000000..598320e --- /dev/null +++ b/SrcShared/Hardware/EmRegsVZHandEra330.cpp @@ -0,0 +1,608 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 2000-2001 Palm, Inc. or its subsidiaries. + All rights reserved. + + This file is part of the Palm OS Emulator. + + 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. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmRegsVZTemp.h" +#include "EmRegsVZPrv.h" +#include "EmTRGSD.h" +#include "EmRegsVZHandEra330.h" +#include "EmRegs330CPLD.h" +#include "EmBankRegs.h" // EmBankRegs::DisableSubBank +#include "EmSPISlaveADS784x.h" // EmSPISlaveADS784x +#include "EmSPISlave330Current.h" +#include "EmScreen.h" // EmScreenUpdateInfo +#include "EmDlg.h" // EmDlg::DoCommonDialog + + +#pragma mark - + +const int kNumButtonRows = 4; +const int kNumButtonCols = 4; + +const uint16 kButtonMap[kNumButtonRows][kNumButtonCols] = +{ + { keyBitHard1, keyBitHard2, keyBitHard3, keyBitHard4 }, + { keyBitPageUp, keyBitPageDown, 0, keyBitThumbDown}, + { keyBitPower, 0, keyBitContrast, keyBitThumbPush}, + { 0, 0, 0, keyBitThumbUp}, +}; + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::EmRegsVZHandEra330 +// --------------------------------------------------------------------------- + +EmRegsVZHandEra330::EmRegsVZHandEra330 (HandEra330PortManager ** fPortManager) : + EmRegsVZ (), + fSPISlaveADC (new EmSPISlaveADS784x (kChannelSet2)), + fSPISlaveCurrent (new EmSPISlave330Current ()) +{ + PortD = PortD_DOCK_BTN | + PortD_CD_IRQ | + PortD_CF_IRQ | + PortD_POWER_FAIL; + PortF = PortF_PEN_IO | + PortF_CPLD_CS_F; + PortG = PortG_DTACK | + PortG_A0 | + PortG_Unused | + // PortG_LION | + PortG_Unused2; + PortJ = PortJ_AD_CS; + PortK = PortK_LED_GREEN | + PortK_LED_RED | + PortK_CPLD_TDO | + PortK_CPLD_TCK; + PortM = PortM_CPLD_TDI; + *fPortManager = &PortMgr; + PortMgr.Keys.Row[0] = 1; + PortMgr.Keys.Row[1] = 1; + PortMgr.Keys.Row[2] = 1; + PortMgr.Keys.Row[3] = 1; + PortMgr.LCDOn = false; + PortMgr.BacklightOn = false; + PortMgr.IRPortOn = false; + PortMgr.CFBus.bEnabled = false; + PortMgr.CFBus.Width = kCFBusWidth16; + PortMgr.CFBus.bSwapped = false; + PortMgr.CFInserted = true; + PortMgr.SDInserted = true; + PortMgr.pendingIRQ2 = false; + PortMgr.SDChipSelect = false; + PortMgr.PowerConnected = false; + + // make sure SPI1 fifos are empty + rxHead = rxTail = txHead = txTail = 0; + txFifoEmpty = true; + rxFifoEmpty = true; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::~EmRegsVZHandEra330 +// --------------------------------------------------------------------------- + +EmRegsVZHandEra330::~EmRegsVZHandEra330 (void) +{ + delete fSPISlaveADC; +} + +void EmRegsVZHandEra330::Initialize(void) +{ + EmRegsVZ::Initialize(); + + SD.Initialize(); +} + +void EmRegsVZHandEra330::Dispose (void) +{ + EmRegsVZ::Dispose(); + + SD.Dispose(); +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetLCDScreenOn +// --------------------------------------------------------------------------- + +Bool EmRegsVZHandEra330::GetLCDScreenOn (void) +{ + // TRG LCD on is determined by LCD contrast on in the CPLD + return PortMgr.LCDOn; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetLCDBacklightOn +// --------------------------------------------------------------------------- + +Bool EmRegsVZHandEra330::GetLCDBacklightOn (void) +{ + // TRG CPLD controls the backlight + return PortMgr.BacklightOn; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetLineDriverState +// --------------------------------------------------------------------------- +// Return whether or not the line drivers for the given object are open or +// closed. + +Bool EmRegsVZHandEra330::GetLineDriverState (EmUARTDeviceType type) +{ + if (type == kUARTSerial) + return (READ_REGISTER (portBData) & PortB_RS232_ON) != 0; + + if (type == kUARTIR) + return PortMgr.IRPortOn; + + return false; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetUARTDevice +// --------------------------------------------------------------------------- +// Return what sort of device is hooked up to the given UART. + +EmUARTDeviceType EmRegsVZHandEra330::GetUARTDevice (int /*uartNum*/) +{ + Bool serEnabled = this->GetLineDriverState (kUARTSerial); + Bool irEnabled = this->GetLineDriverState (kUARTIR); + + // It's probably an error to have them both enabled at the same + // time. !!! TBD: make this an error message. + + EmAssert (!(serEnabled && irEnabled)); + + // !!! Which UART are they using? + +// if (uartNum == ???) + { + if (serEnabled) + return kUARTSerial; + + if (irEnabled) + return kUARTIR; + } + + return kUARTNone; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetVibrateOn +// --------------------------------------------------------------------------- + +Bool EmRegsVZHandEra330::GetVibrateOn (void) +{ + return false; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetInterruptLevel +// --------------------------------------------------------------------------- + +int32 EmRegsVZHandEra330::GetInterruptLevel (void) +{ + int32 retval; + + retval = EmRegsVZ::GetInterruptLevel (); + + if (PortMgr.pendingIRQ2 && (retval < 2)) + retval = 2; + + return retval; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetLEDState +// --------------------------------------------------------------------------- + +uint16 EmRegsVZHandEra330::GetLEDState (void) +{ + uint16 result = kLEDOff; + uint8 portKData = READ_REGISTER (portKData); + + if ((portKData & PortK_LED_GREEN) == 0) + result |= kLEDGreen; + + if ((portKData & PortK_LED_RED) == 0) + result |= kLEDRed; + + return result; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetPortD +// --------------------------------------------------------------------------- + +uint8 EmRegsVZHandEra330::GetPortD (uint8 result) +{ + return result | + PortD_DOCK_BTN | + PortD_CD_IRQ | + PortD_CF_IRQ | + PortD_POWER_FAIL; +} + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetPortInputValue +// --------------------------------------------------------------------------- +// Return the GPIO values for the pins on the port. These values are used +// if the select pins are high. + +uint8 EmRegsVZHandEra330::GetPortInputValue (int port) +{ + uint8 result = EmRegsVZ::GetPortInputValue (port); + + switch (port) + { + case 'D' : + result = GetPortD (result); + break; + case 'F' : + result = PortF; + break; + case 'G' : + result = PortG; + break; + case 'J' : + result = PortJ; + break; + case 'K' : + result = PortK; + break; + case 'M' : + result = PortM; + break; + + } + + return result; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetPortInternalValue +// --------------------------------------------------------------------------- +// Return the dedicated values for the pins on the port. These values are +// used if the select pins are low. + +uint8 EmRegsVZHandEra330::GetPortInternalValue (int port) +{ + uint8 result = EmRegsVZ::GetPortInternalValue (port); + + switch (port) + { + case 'D' : + result = GetPortD(result); + break; + case 'F' : + result = PortF; + break; + case 'G' : + result = PortG; + break; + case 'J' : + result = PortJ; + break; + case 'K' : + result = PortK; + break; + case 'M' : + result = PortM; + break; + } + + return result; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetKeyInfo +// --------------------------------------------------------------------------- + +void EmRegsVZHandEra330::GetKeyInfo (int* numRows, int* numCols, + uint16* keyMap, Bool* rows) +{ + *numRows = kNumButtonRows; + *numCols = kNumButtonCols; + + memcpy (keyMap, kButtonMap, sizeof (kButtonMap)); + + // Determine what row is being asked for. + rows[0] = PortMgr.Keys.Row[0]; + rows[1] = PortMgr.Keys.Row[1]; + rows[2] = PortMgr.Keys.Row[2]; + rows[3] = PortMgr.Keys.Row[3]; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetSPISlave +// --------------------------------------------------------------------------- + +EmSPISlave* EmRegsVZHandEra330::GetSPISlave (void) +{ + if ((READ_REGISTER (portJData) & PortJ_AD_CS) == 0) + { + if (PortMgr.SenseCurrent) + return fSPISlaveCurrent; + else + return fSPISlaveADC; + } + + return NULL; +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::GetROMSize +// --------------------------------------------------------------------------- + +int32 EmRegsVZHandEra330::GetROMSize (void) +{ + return (2 * 1024 * 1024); +} + + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::ButtonToBits +// --------------------------------------------------------------------------- + +uint16 EmRegsVZHandEra330::ButtonToBits (SkinElementType button) +{ + uint16 bitNumber = 0; + static Bool CF_button_pushed = false; + static Bool SD_button_pushed = false; + static Bool power_button_pushed = false; + + switch (button) + { + default: + bitNumber = EmRegsVZ::ButtonToBits (button); + break; + + // Borrow some skin elements from Symbol for our Thumb wheel + // NOTE: Borrowed Palm's contrast for our aux, so above case already handles it. + case kElement_TriggerLeft : + bitNumber = keyBitThumbUp; break; + case kElement_TriggerCenter : + bitNumber = keyBitThumbPush; break; + case kElement_TriggerRight : + bitNumber = keyBitThumbDown; break; + + // Borrow some additional skin elements to trigger a CF removal or insert. + case kElement_DownButtonLeft : + bitNumber = 0; + // we get called twice here, don't handle the event on the button release + if(!CF_button_pushed) + { + PortMgr.CFInserted = !PortMgr.CFInserted; + + if (PortMgr.CFInserted) + EmDlg::DoCommonDialog("The CF card has been installed.", kDlgFlags_OK); + else + EmDlg::DoCommonDialog("The CF card has been removed.", kDlgFlags_OK); + + PortMgr.pendingIRQ2 = true; + CF_button_pushed = true; + } + else + CF_button_pushed = false; + break; + + // SD + case kElement_DownButtonRight : + bitNumber = 0; + if (!SD_button_pushed) + { + PortMgr.SDInserted = !PortMgr.SDInserted; + + if (PortMgr.SDInserted) + EmDlg::DoCommonDialog("The SD card has been installed.\n\nIt will take a second for the OS to mount it.", + kDlgFlags_OK); + else + EmDlg::DoCommonDialog("The SD card has been removed.", kDlgFlags_OK); + + PortMgr.pendingIRQ2 = true; + SD_button_pushed = true; + } + else + SD_button_pushed = false; + break; + + // power + case kElement_UpButtonLeft : + bitNumber = 0; + if (!power_button_pushed) + { + if (!PortMgr.PowerConnected) + { + if (PortG & PortG_LION) + PortG &= ~PortG_LION; + else + PortG |= PortG_LION; + } + PortMgr.PowerConnected = !PortMgr.PowerConnected; + PortMgr.pendingIRQ2 = true; + ((EmSPISlave330Current *)fSPISlaveCurrent)->SetMode(PortMgr.PowerConnected); + + power_button_pushed = true; + } + else + power_button_pushed = false; + break; + } + + return bitNumber; +} + + +/********************************************************************************** + * SD support: + * HandEra 330 SD is attached to the DragonballVZ SPI1 which is otherwise unused. + **********************************************************************************/ +uint32 EmRegsVZHandEra330::spiRxDRead(emuptr /* address */, int /* size */) +{ + uint32 retval; + + // there is an 8 word fifo here, read back the first in. + + if ((rxHead == rxTail) && rxFifoEmpty) + { + // invalid read, fifo empty + return 0; + } + + retval = rxFifo[rxTail++]; + if (rxTail == 8) + rxTail = 0; + if (rxTail == rxHead) + txFifoEmpty = true; + return retval; +} + +void EmRegsVZHandEra330::spiTxDWrite(emuptr address, int size, uint32 value) +{ + // Do a standard update of the register. (so reading the last value back works) + EmRegsVZ::StdWrite (address, size, value); + + if (!txFifoEmpty && (txHead == txTail)) + { + // fifo full, do nothing + return; + } + + txFifoEmpty = false; + + // there is an 8 word fifo here. + txFifo[txHead++] = value; + if (txHead == 8) + txHead = 0; +} + +void EmRegsVZHandEra330::spiCont1Write(emuptr address, int size, uint32 value) +{ + // if we were not enabled before, flush fifos + if ((value & hwrVZ328SPIMControlEnable)==0) + { + txTail = txHead; + rxTail = rxHead; + txFifoEmpty = rxFifoEmpty = true; + } + + // Do a standard update of the register. + EmRegsVZ::StdWrite (address, size, value); + + // Get the current value. + uint16 spiCont1 = READ_REGISTER (spiCont1); + + // Check to see if data exchange and enable are enabled. + #define BIT_MASK (hwrVZ328SPIMControlExchange | hwrVZ328SPIMControlEnable) + if ((spiCont1 & BIT_MASK) == BIT_MASK) + { + // do the exchange + if (!txFifoEmpty) + { + // is SD chip selected? + if (PortMgr.SDChipSelect) + { + uint16 rxData, txData; + + do + { + txData = txFifo[txTail++]; + if (txTail == 8) + txTail = 0; + SD.ExchangeBits(txData, &rxData, (spiCont1 & 0x000f)+1); + rxFifo[rxHead++] = rxData; + if (rxHead == 8) + rxHead = 0; + } while (txTail != txHead); + txFifoEmpty = true; + rxFifoEmpty = false; + } + else + { + // nothing else is connected here, just stuff the rx fifo and flush the tx fifo + do + { + txTail++; + if (txTail == 8) + txTail = 0; + rxFifo[rxHead++] = 0xff; + if (rxHead == 8) + rxHead = 0; + } while (txTail != txHead); + rxFifoEmpty = false; + txFifoEmpty = true; + } + } + + // Clear the exchange bit. + spiCont1 &= ~hwrVZ328SPIMControlExchange; + WRITE_REGISTER (spiCont1, spiCont1); + } +} + +uint32 EmRegsVZHandEra330::spiCont1Read(emuptr /* address */, int /* size */) +{ + return 0; +} + +void EmRegsVZHandEra330::spiIntCSWrite(emuptr /* address */, int /* size */, uint32 /* value */) +{ +} + +uint32 EmRegsVZHandEra330::spiIntCSRead(emuptr /* address */, int /* size */) +{ + return 0; +} + +// --------------------------------------------------------------------------- +// ¥ EmRegsVZHandEra330::SetSubBankHandlers +// --------------------------------------------------------------------------- + +void EmRegsVZHandEra330::SetSubBankHandlers(void) +{ + //HwrM68VZ328Type regs; + + EmRegsVZ::SetSubBankHandlers(); + + // SD support + this->SetHandler((ReadFunction)&EmRegsVZHandEra330::spiRxDRead, + (WriteFunction)&EmRegsVZ::StdWrite, + addressof(spiRxD), + sizeof(UInt16)); + this->SetHandler((ReadFunction)&EmRegsVZ::StdRead, + (WriteFunction)&EmRegsVZHandEra330::spiTxDWrite, + addressof(spiTxD), + sizeof(UInt16)); + this->SetHandler((ReadFunction)&EmRegsVZ::StdRead, + (WriteFunction)&EmRegsVZHandEra330::spiCont1Write, + addressof(spiCont1), + sizeof(UInt16)); +/* + this->SetHandler((ReadFunction)&EmRegsVZHandEra330::spiIntCSRead, + (WriteFunction)&EmRegsVZHandEra330::spiIntCSWrite, + addressof(spiIntCS), + sizeof(regs.spiIntCS)); +*/ +} |