mirror of
https://github.com/akuker/RASCSI.git
synced 2025-07-25 05:24:17 +00:00
Initial merge of (incomplete) Banana Pi updates (#993)
This commit is contained in:
@@ -12,129 +12,55 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "hal/systimer.h"
|
||||
#include "hal/gpiobus.h"
|
||||
#include "shared/config.h"
|
||||
#include "hal/systimer_allwinner.h"
|
||||
#include "hal/systimer_raspberry.h"
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <array>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// System timer address
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
volatile uint32_t* SysTimer::systaddr;
|
||||
#include "hal/gpiobus.h"
|
||||
#include "hal/sbc_version.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ARM timer address
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
volatile uint32_t* SysTimer::armtaddr;
|
||||
#include "shared/log.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Core frequency
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
volatile uint32_t SysTimer::corefreq;
|
||||
bool SysTimer::initialized = false;
|
||||
bool SysTimer::is_allwinnner = false;
|
||||
bool SysTimer::is_raspberry = false;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Initialize the system timer
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void SysTimer::Init(uint32_t *syst, uint32_t *armt)
|
||||
std::unique_ptr<PlatformSpecificTimer> SysTimer::systimer_ptr;
|
||||
|
||||
void SysTimer::Init()
|
||||
{
|
||||
// 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
|
||||
array<uint32_t, 32> maxclock = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 };
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__)
|
||||
|
||||
// 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);
|
||||
if (!initialized) {
|
||||
if (SBC_Version::IsRaspberryPi()) {
|
||||
systimer_ptr = make_unique<SysTimer_Raspberry>();
|
||||
is_raspberry = true;
|
||||
} else if (SBC_Version::IsBananaPi()) {
|
||||
systimer_ptr = make_unique<SysTimer_AllWinner>();
|
||||
is_allwinnner = true;
|
||||
}
|
||||
systimer_ptr->Init();
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Get system timer low byte
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
uint32_t SysTimer::GetTimerLow() {
|
||||
return systaddr[SYST_CLO];
|
||||
// Get system timer low byte
|
||||
uint32_t SysTimer::GetTimerLow()
|
||||
{
|
||||
return systimer_ptr->GetTimerLow();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Get system timer high byte
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
uint32_t SysTimer::GetTimerHigh() {
|
||||
return systaddr[SYST_CHI];
|
||||
// Get system timer high byte
|
||||
uint32_t SysTimer::GetTimerHigh()
|
||||
{
|
||||
return systimer_ptr->GetTimerHigh();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Sleep in nanoseconds
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
// Sleep for N nanoseconds
|
||||
void SysTimer::SleepNsec(uint32_t nsec)
|
||||
{
|
||||
// If time is 0, don't do anything
|
||||
if (nsec == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the timer difference
|
||||
uint32_t diff = corefreq * nsec / 1000;
|
||||
|
||||
// Return if the difference in time is too small
|
||||
if (diff == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start
|
||||
uint32_t start = armtaddr[ARMT_FREERUN];
|
||||
|
||||
// Loop until timer has elapsed
|
||||
while ((armtaddr[ARMT_FREERUN] - start) < diff);
|
||||
systimer_ptr->SleepNsec(nsec);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Sleep in microseconds
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
// Sleep for N microseconds
|
||||
void SysTimer::SleepUsec(uint32_t usec)
|
||||
{
|
||||
// If time is 0, don't do anything
|
||||
if (usec == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t now = GetTimerLow();
|
||||
while ((GetTimerLow() - now) < usec);
|
||||
systimer_ptr->SleepUsec(usec);
|
||||
}
|
||||
|
Reference in New Issue
Block a user