Breakup GPIOBUS (#843)

* moved gpiobus

* moved gpiobus and systimer into hardware abstraction layer

* split up gpiobus by connection type

* merge develop changes

* revert compiler setting change

* registers working

* updates

* updates

* Revert "updates"

This reverts commit 0134b81061.

* Revert "updates"

This reverts commit 4bf0416ab4.

* Revert "registers working"

This reverts commit f5ee073eaf.

* Address comment in #843. Restore -Wextra

Co-authored-by: Tony Kuker <akuker@gmail.com>
This commit is contained in:
akuker 2022-09-10 16:40:24 -05:00 committed by GitHub
parent f0c36fba77
commit e64c2f7254
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 434 additions and 341 deletions

View File

@ -87,7 +87,6 @@ SRC_PROTOBUF = \
SRC_RASCSI_CORE = \
scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp \
rascsi_version.cpp \
@ -98,6 +97,7 @@ SRC_RASCSI_CORE = \
localizer.cpp
SRC_RASCSI_CORE += $(shell find ./controllers -name '*.cpp')
SRC_RASCSI_CORE += $(shell find ./devices -name '*.cpp')
SRC_RASCSI_CORE += $(shell find ./hal -name '*.cpp')
SRC_RASCSI_CORE += $(SRC_PROTOBUF)
SRC_RASCSI = rascsi.cpp
@ -105,9 +105,9 @@ SRC_RASCSI = rascsi.cpp
SRC_SCSIMON = \
scsimon.cpp \
scsi.cpp \
gpiobus.cpp \
rascsi_version.cpp
SRC_SCSIMON += $(shell find ./monitor -name '*.cpp')
SRC_SCSIMON += $(shell find ./hal -name '*.cpp')
SRC_RASCTL = \
rasctl.cpp\
@ -122,17 +122,16 @@ SRC_RASCTL += $(SRC_PROTOBUF)
SRC_RASDUMP = \
rasdump.cpp \
scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp \
rascsi_version.cpp
SRC_RASDUMP += $(shell find ./hal -name '*.cpp')
SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp')
vpath %.h ./ ./controllers ./devices ./monitor
vpath %.cpp ./ ./controllers ./devices ./monitor ./test
vpath %.h ./ ./controllers ./devices ./monitor ./hal
vpath %.cpp ./ ./controllers ./devices ./monitor ./test ./hal
vpath %.o ./$(OBJDIR)
vpath ./$(BINDIR)

View File

@ -15,7 +15,8 @@
//---------------------------------------------------------------------------
#include "log.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
#include "hal/systimer.h"
#include "rascsi_exceptions.h"
#include "devices/scsi_host_bridge.h"
#include "devices/scsi_daynaport.h"

View File

@ -13,7 +13,8 @@
#include <sys/mman.h>
#include "os.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
#include "hal/systimer.h"
#include "config.h"
#include "log.h"
@ -1452,121 +1453,3 @@ int GPIOBUS::GetCommandByteCount(BYTE opcode) {
}
}
//---------------------------------------------------------------------------
//
// System timer address
//
//---------------------------------------------------------------------------
volatile DWORD* SysTimer::systaddr;
//---------------------------------------------------------------------------
//
// ARM timer address
//
//---------------------------------------------------------------------------
volatile DWORD* SysTimer::armtaddr;
//---------------------------------------------------------------------------
//
// Core frequency
//
//---------------------------------------------------------------------------
volatile DWORD SysTimer::corefreq;
//---------------------------------------------------------------------------
//
// Initialize the system timer
//
//---------------------------------------------------------------------------
void SysTimer::Init(DWORD *syst, DWORD *armt)
{
// RPI Mailbox property interface
// Get max clock rate
// Tag: 0x00030004
//
// Request: Length: 4
// Value: u32: clock id
// Response: Length: 8
// Value: u32: clock id, u32: rate (in Hz)
//
// Clock id
// 0x000000004: CORE
DWORD maxclock[32] = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 };
// Save the base address
systaddr = syst;
armtaddr = armt;
// Change the ARM timer to free run mode
armtaddr[ARMT_CTRL] = 0x00000282;
// Get the core frequency
corefreq = 0;
int fd = open("/dev/vcio", O_RDONLY);
if (fd >= 0) {
ioctl(fd, _IOWR(100, 0, char *), maxclock);
corefreq = maxclock[6] / 1000000;
}
close(fd);
}
//---------------------------------------------------------------------------
//
// Get system timer low byte
//
//---------------------------------------------------------------------------
DWORD SysTimer::GetTimerLow() {
return systaddr[SYST_CLO];
}
//---------------------------------------------------------------------------
//
// Get system timer high byte
//
//---------------------------------------------------------------------------
DWORD SysTimer::GetTimerHigh() {
return systaddr[SYST_CHI];
}
//---------------------------------------------------------------------------
//
// Sleep in nanoseconds
//
//---------------------------------------------------------------------------
void SysTimer::SleepNsec(DWORD nsec)
{
// If time is 0, don't do anything
if (nsec == 0) {
return;
}
// Calculate the timer difference
DWORD diff = corefreq * nsec / 1000;
// Return if the difference in time is too small
if (diff == 0) {
return;
}
// Start
DWORD start = armtaddr[ARMT_FREERUN];
// Loop until timer has elapsed
while ((armtaddr[ARMT_FREERUN] - start) < diff);
}
//---------------------------------------------------------------------------
//
// Sleep in microseconds
//
//---------------------------------------------------------------------------
void SysTimer::SleepUsec(DWORD usec)
{
// If time is 0, don't do anything
if (usec == 0) {
return;
}
DWORD now = GetTimerLow();
while ((GetTimerLow() - now) < usec);
}

View File

@ -9,8 +9,7 @@
//
//---------------------------------------------------------------------------
#if !defined(gpiobus_h)
#define gpiobus_h
#pragma once
#include "config.h"
#include "scsi.h"
@ -25,6 +24,18 @@
//#define CONNECT_TYPE_AIBOM // AIBOM version (positive logic, unique pin assignment)
//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com version (standard logic, unique pin assignment)
#if defined CONNECT_TYPE_STANDARD
#include "hal/gpiobus_standard.h"
#elif defined CONNECT_TYPE_FULLSPEC
#include "hal/gpiobus_fullspec.h"
#elif defined CONNECT_TYPE_AIBOM
#include "hal/gpiobus_aibom.h"
#elif defined CONNECT_TYPE_GAMERNIUM
#include "hal/gpiobus_gamernium.h"
#else
#error Invalid connection type or none specified
#endif
//---------------------------------------------------------------------------
//
// Signal control logic and pin assignment customization
@ -99,185 +110,6 @@
//
//---------------------------------------------------------------------------
#ifdef CONNECT_TYPE_STANDARD
//
// RaSCSI standard (SCSI logic, standard pin assignment)
//
#define CONNECT_DESC "STANDARD" // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 5; // ENABLE
const static int PIN_IND = -1; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
const static int PIN_DTD = -1; // DATA DIRECTION
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI signal pin assignment
const static int PIN_DT0 = 10; // Data 0
const static int PIN_DT1 = 11; // Data 1
const static int PIN_DT2 = 12; // Data 2
const static int PIN_DT3 = 13; // Data 3
const static int PIN_DT4 = 14; // Data 4
const static int PIN_DT5 = 15; // Data 5
const static int PIN_DT6 = 16; // Data 6
const static int PIN_DT7 = 17; // Data 7
const static int PIN_DP = 18; // Data parity
const static int PIN_ATN = 19; // ATN
const static int PIN_RST = 20; // RST
const static int PIN_ACK = 21; // ACK
const static int PIN_REQ = 22; // REQ
const static int PIN_MSG = 23; // MSG
const static int PIN_CD = 24; // CD
const static int PIN_IO = 25; // IO
const static int PIN_BSY = 26; // BSY
const static int PIN_SEL = 27; // SEL
#endif
#ifdef CONNECT_TYPE_FULLSPEC
//
// RaSCSI standard (SCSI logic, standard pin assignment)
//
#define CONNECT_DESC "FULLSPEC" // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 5; // ENABLE
const static int PIN_IND = 6; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = 7; // TARGET CTRL DIRECTION
const static int PIN_DTD = 8; // DATA DIRECTION
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI signal pin assignment
const static int PIN_DT0 = 10; // Data 0
const static int PIN_DT1 = 11; // Data 1
const static int PIN_DT2 = 12; // Data 2
const static int PIN_DT3 = 13; // Data 3
const static int PIN_DT4 = 14; // Data 4
const static int PIN_DT5 = 15; // Data 5
const static int PIN_DT6 = 16; // Data 6
const static int PIN_DT7 = 17; // Data 7
const static int PIN_DP = 18; // Data parity
const static int PIN_ATN = 19; // ATN
const static int PIN_RST = 20; // RST
const static int PIN_ACK = 21; // ACK
const static int PIN_REQ = 22; // REQ
const static int PIN_MSG = 23; // MSG
const static int PIN_CD = 24; // CD
const static int PIN_IO = 25; // IO
const static int PIN_BSY = 26; // BSY
const static int PIN_SEL = 27; // SEL
#endif
#ifdef CONNECT_TYPE_AIBOM
//
// RaSCSI Adapter Aibom version
//
#define CONNECT_DESC "AIBOM PRODUCTS version" // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN FALSE // DATA SIGNAL INPUT
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 17; // ENABLE
const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
const static int PIN_DTD = 18; // DATA DIRECTION
// SCSI signal pin assignment
const static int PIN_DT0 = 6; // Data 0
const static int PIN_DT1 = 12; // Data 1
const static int PIN_DT2 = 13; // Data 2
const static int PIN_DT3 = 16; // Data 3
const static int PIN_DT4 = 19; // Data 4
const static int PIN_DT5 = 20; // Data 5
const static int PIN_DT6 = 26; // Data 6
const static int PIN_DT7 = 21; // Data 7
const static int PIN_DP = 5; // Data parity
const static int PIN_ATN = 22; // ATN
const static int PIN_RST = 25; // RST
const static int PIN_ACK = 10; // ACK
const static int PIN_REQ = 7; // REQ
const static int PIN_MSG = 9; // MSG
const static int PIN_CD = 11; // CD
const static int PIN_IO = 23; // IO
const static int PIN_BSY = 24; // BSY
const static int PIN_SEL = 8; // SEL
#endif
// TODO Is this type stil relevant?
#ifdef CONNECT_TYPE_GAMERNIUM
//
// RaSCSI Adapter GAMERnium.com version
//
#define CONNECT_DESC "GAMERnium.com version"// Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 14; // ACTIVE
const static int PIN_ENB = 6; // ENABLE
const static int PIN_IND = 7; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = 8; // TARGET CTRL DIRECTION
const static int PIN_DTD = 5; // DATA DIRECTION
// SCSI signal pin assignment
const static int PIN_DT0 = 21; // Data 0
const static int PIN_DT1 = 26; // Data 1
const static int PIN_DT2 = 20; // Data 2
const static int PIN_DT3 = 19; // Data 3
const static int PIN_DT4 = 16; // Data 4
const static int PIN_DT5 = 13; // Data 5
const static int PIN_DT6 = 12; // Data 6
const static int PIN_DT7 = 11; // Data 7
const static int PIN_DP = 25; // Data parity
const static int PIN_ATN = 10; // ATN
const static int PIN_RST = 22; // RST
const static int PIN_ACK = 24; // ACK
const static int PIN_REQ = 15; // REQ
const static int PIN_MSG = 17; // MSG
const static int PIN_CD = 18; // CD
const static int PIN_IO = 4; // IO
const static int PIN_BSY = 27; // BSY
const static int PIN_SEL = 23; // SEL
#endif
#define ALL_SCSI_PINS \
((1<<PIN_DT0)|\
(1<<PIN_DT1)|\
@ -667,32 +499,3 @@ private:
static const int SignalTable[19]; // signal table
};
//===========================================================================
//
// System timer
//
//===========================================================================
class SysTimer
{
public:
static void Init(DWORD *syst, DWORD *armt);
// Initialization
static DWORD GetTimerLow();
// Get system timer low byte
static DWORD GetTimerHigh();
// Get system timer high byte
static void SleepNsec(DWORD nsec);
// Sleep for N nanoseconds
static void SleepUsec(DWORD usec);
// Sleep for N microseconds
private:
static volatile DWORD *systaddr;
// System timer address
static volatile DWORD *armtaddr;
// ARM timer address
static volatile DWORD corefreq;
// Core frequency
};
#endif // gpiobus_h

View File

@ -0,0 +1,55 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// [ GPIO-SCSI bus ]
//
//---------------------------------------------------------------------------
#pragma once
//
// RaSCSI Adapter Aibom version
//
#define CONNECT_DESC "AIBOM PRODUCTS version" // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN FALSE // DATA SIGNAL INPUT
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 17; // ENABLE
const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
const static int PIN_DTD = 18; // DATA DIRECTION
// SCSI signal pin assignment
const static int PIN_DT0 = 6; // Data 0
const static int PIN_DT1 = 12; // Data 1
const static int PIN_DT2 = 13; // Data 2
const static int PIN_DT3 = 16; // Data 3
const static int PIN_DT4 = 19; // Data 4
const static int PIN_DT5 = 20; // Data 5
const static int PIN_DT6 = 26; // Data 6
const static int PIN_DT7 = 21; // Data 7
const static int PIN_DP = 5; // Data parity
const static int PIN_ATN = 22; // ATN
const static int PIN_RST = 25; // RST
const static int PIN_ACK = 10; // ACK
const static int PIN_REQ = 7; // REQ
const static int PIN_MSG = 9; // MSG
const static int PIN_CD = 11; // CD
const static int PIN_IO = 23; // IO
const static int PIN_BSY = 24; // BSY
const static int PIN_SEL = 8; // SEL

View File

@ -0,0 +1,53 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// [ GPIO-SCSI bus ]
//
//---------------------------------------------------------------------------
#pragma once
//
// RaSCSI standard (SCSI logic, standard pin assignment)
//
#define CONNECT_DESC "FULLSPEC" // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 5; // ENABLE
const static int PIN_IND = 6; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = 7; // TARGET CTRL DIRECTION
const static int PIN_DTD = 8; // DATA DIRECTION
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI signal pin assignment
const static int PIN_DT0 = 10; // Data 0
const static int PIN_DT1 = 11; // Data 1
const static int PIN_DT2 = 12; // Data 2
const static int PIN_DT3 = 13; // Data 3
const static int PIN_DT4 = 14; // Data 4
const static int PIN_DT5 = 15; // Data 5
const static int PIN_DT6 = 16; // Data 6
const static int PIN_DT7 = 17; // Data 7
const static int PIN_DP = 18; // Data parity
const static int PIN_ATN = 19; // ATN
const static int PIN_RST = 20; // RST
const static int PIN_ACK = 21; // ACK
const static int PIN_REQ = 22; // REQ
const static int PIN_MSG = 23; // MSG
const static int PIN_CD = 24; // CD
const static int PIN_IO = 25; // IO
const static int PIN_BSY = 26; // BSY
const static int PIN_SEL = 27; // SEL

View File

@ -0,0 +1,56 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// [ GPIO-SCSI bus ]
//
//---------------------------------------------------------------------------
#pragma once
//
// RaSCSI Adapter GAMERnium.com version
//
#define CONNECT_DESC "GAMERnium.com version"// Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 14; // ACTIVE
const static int PIN_ENB = 6; // ENABLE
const static int PIN_IND = 7; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = 8; // TARGET CTRL DIRECTION
const static int PIN_DTD = 5; // DATA DIRECTION
// SCSI signal pin assignment
const static int PIN_DT0 = 21; // Data 0
const static int PIN_DT1 = 26; // Data 1
const static int PIN_DT2 = 20; // Data 2
const static int PIN_DT3 = 19; // Data 3
const static int PIN_DT4 = 16; // Data 4
const static int PIN_DT5 = 13; // Data 5
const static int PIN_DT6 = 12; // Data 6
const static int PIN_DT7 = 11; // Data 7
const static int PIN_DP = 25; // Data parity
const static int PIN_ATN = 10; // ATN
const static int PIN_RST = 22; // RST
const static int PIN_ACK = 24; // ACK
const static int PIN_REQ = 15; // REQ
const static int PIN_MSG = 17; // MSG
const static int PIN_CD = 18; // CD
const static int PIN_IO = 4; // IO
const static int PIN_BSY = 27; // BSY
const static int PIN_SEL = 23; // SEL

View File

@ -0,0 +1,54 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// [ GPIO-SCSI bus ]
//
//---------------------------------------------------------------------------
#pragma once
//
// RaSCSI standard (SCSI logic, standard pin assignment)
//
#define CONNECT_DESC "STANDARD" // Startup message
// Select signal control mode
const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification
// Control signal pin assignment (-1 means no control)
const static int PIN_ACT = 4; // ACTIVE
const static int PIN_ENB = 5; // ENABLE
const static int PIN_IND = -1; // INITIATOR CTRL DIRECTION
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
const static int PIN_DTD = -1; // DATA DIRECTION
// Control signal output logic
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI signal pin assignment
const static int PIN_DT0 = 10; // Data 0
const static int PIN_DT1 = 11; // Data 1
const static int PIN_DT2 = 12; // Data 2
const static int PIN_DT3 = 13; // Data 3
const static int PIN_DT4 = 14; // Data 4
const static int PIN_DT5 = 15; // Data 5
const static int PIN_DT6 = 16; // Data 6
const static int PIN_DT7 = 17; // Data 7
const static int PIN_DP = 18; // Data parity
const static int PIN_ATN = 19; // ATN
const static int PIN_RST = 20; // RST
const static int PIN_ACK = 21; // ACK
const static int PIN_REQ = 22; // REQ
const static int PIN_MSG = 23; // MSG
const static int PIN_CD = 24; // CD
const static int PIN_IO = 25; // IO
const static int PIN_BSY = 26; // BSY
const static int PIN_SEL = 27; // SEL

View File

@ -0,0 +1,140 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// Copyright (C) 2022 akuker
//
// [ High resolution timer ]
//
//---------------------------------------------------------------------------
#include "hal/systimer.h"
#include <sys/mman.h>
#include "os.h"
#include "hal/gpiobus.h"
#include "config.h"
#include "log.h"
//---------------------------------------------------------------------------
//
// System timer address
//
//---------------------------------------------------------------------------
volatile DWORD* SysTimer::systaddr;
//---------------------------------------------------------------------------
//
// ARM timer address
//
//---------------------------------------------------------------------------
volatile DWORD* SysTimer::armtaddr;
//---------------------------------------------------------------------------
//
// Core frequency
//
//---------------------------------------------------------------------------
volatile DWORD SysTimer::corefreq;
//---------------------------------------------------------------------------
//
// Initialize the system timer
//
//---------------------------------------------------------------------------
void SysTimer::Init(DWORD *syst, DWORD *armt)
{
// RPI Mailbox property interface
// Get max clock rate
// Tag: 0x00030004
//
// Request: Length: 4
// Value: u32: clock id
// Response: Length: 8
// Value: u32: clock id, u32: rate (in Hz)
//
// Clock id
// 0x000000004: CORE
DWORD maxclock[32] = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 };
// Save the base address
systaddr = syst;
armtaddr = armt;
// Change the ARM timer to free run mode
armtaddr[ARMT_CTRL] = 0x00000282;
// Get the core frequency
corefreq = 0;
int fd = open("/dev/vcio", O_RDONLY);
if (fd >= 0) {
ioctl(fd, _IOWR(100, 0, char *), maxclock);
corefreq = maxclock[6] / 1000000;
}
close(fd);
}
//---------------------------------------------------------------------------
//
// Get system timer low byte
//
//---------------------------------------------------------------------------
DWORD SysTimer::GetTimerLow() {
return systaddr[SYST_CLO];
}
//---------------------------------------------------------------------------
//
// Get system timer high byte
//
//---------------------------------------------------------------------------
DWORD SysTimer::GetTimerHigh() {
return systaddr[SYST_CHI];
}
//---------------------------------------------------------------------------
//
// Sleep in nanoseconds
//
//---------------------------------------------------------------------------
void SysTimer::SleepNsec(DWORD nsec)
{
// If time is 0, don't do anything
if (nsec == 0) {
return;
}
// Calculate the timer difference
DWORD diff = corefreq * nsec / 1000;
// Return if the difference in time is too small
if (diff == 0) {
return;
}
// Start
DWORD start = armtaddr[ARMT_FREERUN];
// Loop until timer has elapsed
while ((armtaddr[ARMT_FREERUN] - start) < diff);
}
//---------------------------------------------------------------------------
//
// Sleep in microseconds
//
//---------------------------------------------------------------------------
void SysTimer::SleepUsec(DWORD usec)
{
// If time is 0, don't do anything
if (usec == 0) {
return;
}
DWORD now = GetTimerLow();
while ((GetTimerLow() - now) < usec);
}

View File

@ -0,0 +1,47 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// Copyright (C) 2022 akuker
//
// [ High resolution timer ]
//
//---------------------------------------------------------------------------
#pragma once
#include <stdint.h>
#include "config.h"
#include "scsi.h"
//===========================================================================
//
// System timer
//
//===========================================================================
class SysTimer
{
public:
static void Init(uint32_t *syst, uint32_t *armt);
// Initialization
static uint32_t GetTimerLow();
// Get system timer low byte
static uint32_t GetTimerHigh();
// Get system timer high byte
static void SleepNsec(uint32_t nsec);
// Sleep for N nanoseconds
static void SleepUsec(uint32_t usec);
// Sleep for N microseconds
private:
static volatile uint32_t *systaddr;
// System timer address
static volatile uint32_t *armtaddr;
// ARM timer address
static volatile uint32_t corefreq;
// Core frequency
};

View File

@ -12,7 +12,7 @@
#pragma once
#include "scsi.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
using data_capture_t = struct data_capture
{

View File

@ -17,7 +17,7 @@
#include <fstream>
#include "data_sample.h"
#include "sm_reports.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
using namespace std;

View File

@ -17,7 +17,8 @@
#include "devices/device.h"
#include "devices/disk.h"
#include "devices/file_support.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
#include "hal/systimer.h"
#include "rascsi_exceptions.h"
#include "protobuf_util.h"
#include "rascsi_version.h"

View File

@ -13,7 +13,8 @@
#include "os.h"
#include "fileio.h"
#include "filepath.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
#include "hal/systimer.h"
#include "rascsi_version.h"
//---------------------------------------------------------------------------

View File

@ -10,7 +10,7 @@
#include "os.h"
#include "log.h"
#include "gpiobus.h"
#include "hal/gpiobus.h"
#include "rascsi_version.h"
#include "spdlog/spdlog.h"
#include <sys/time.h>