os: implement waitable management.
This implements waitable management for Events (and implements Events). It also refactors PM to use new Event/Waitable semantics, and also adds STS_ASSERT as a macro for asserting a boolean expression. The rest of stratosphere has been refactored to use STS_ASSERT whenever possible.
This commit is contained in:
@@ -75,26 +75,16 @@ namespace sts::boot {
|
||||
/* Get values from PMIC. */
|
||||
{
|
||||
PmicDriver pmic_driver;
|
||||
if (R_FAILED(pmic_driver.GetPowerIntr(&power_intr))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pmic_driver.GetNvErc(&nv_erc))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pmic_driver.GetAcOk(&ac_ok))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pmic_driver.GetPowerIntr(&power_intr));
|
||||
R_ASSERT(pmic_driver.GetNvErc(&nv_erc));
|
||||
R_ASSERT(pmic_driver.GetAcOk(&ac_ok));
|
||||
}
|
||||
|
||||
/* Get values from RTC. */
|
||||
{
|
||||
RtcDriver rtc_driver;
|
||||
if (R_FAILED(rtc_driver.GetRtcIntr(&rtc_intr))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(rtc_driver.GetRtcIntrM(&rtc_intr_m))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(rtc_driver.GetRtcIntr(&rtc_intr));
|
||||
R_ASSERT(rtc_driver.GetRtcIntrM(&rtc_intr_m));
|
||||
}
|
||||
|
||||
/* Set global derived boot reason. */
|
||||
@@ -107,19 +97,14 @@ namespace sts::boot {
|
||||
boot_reason_value.rtc_intr = rtc_intr & ~rtc_intr_m;
|
||||
boot_reason_value.nv_erc = nv_erc;
|
||||
boot_reason_value.boot_reason = g_boot_reason;
|
||||
if (R_FAILED(splSetBootReason(boot_reason_value.value))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(splSetBootReason(boot_reason_value.value));
|
||||
}
|
||||
|
||||
g_detected_boot_reason = true;
|
||||
}
|
||||
|
||||
u32 GetBootReason() {
|
||||
if (!g_detected_boot_reason) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
STS_ASSERT(g_detected_boot_reason);
|
||||
return g_boot_reason;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace sts::boot::bq24193 {
|
||||
constexpr u32 ChargeVoltageLimitMax = 4208;
|
||||
|
||||
inline u8 EncodeChargeVoltageLimit(u32 voltage) {
|
||||
if (voltage < ChargeVoltageLimitMin || voltage > ChargeVoltageLimitMax) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(voltage >= ChargeVoltageLimitMin);
|
||||
STS_ASSERT(voltage <= ChargeVoltageLimitMax);
|
||||
|
||||
voltage -= ChargeVoltageLimitMin;
|
||||
voltage >>= 4;
|
||||
return static_cast<u8>(voltage << 2);
|
||||
@@ -54,9 +54,9 @@ namespace sts::boot::bq24193 {
|
||||
constexpr u32 FastChargeCurrentLimitMax = 4544;
|
||||
|
||||
inline u8 EncodeFastChargeCurrentLimit(u32 current) {
|
||||
if (current < FastChargeCurrentLimitMin || current > FastChargeCurrentLimitMax) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(current >= FastChargeCurrentLimitMin);
|
||||
STS_ASSERT(current <= FastChargeCurrentLimitMax);
|
||||
|
||||
current -= FastChargeCurrentLimitMin;
|
||||
current >>= 6;
|
||||
return static_cast<u8>(current << 2);
|
||||
@@ -81,9 +81,9 @@ namespace sts::boot::bq24193 {
|
||||
constexpr u32 PreChargeCurrentLimitMax = 2048;
|
||||
|
||||
inline u8 EncodePreChargeCurrentLimit(u32 current) {
|
||||
if (current < PreChargeCurrentLimitMin || current > PreChargeCurrentLimitMax) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(current >= PreChargeCurrentLimitMin);
|
||||
STS_ASSERT(current <= PreChargeCurrentLimitMax);
|
||||
|
||||
current -= PreChargeCurrentLimitMin;
|
||||
current >>= 7;
|
||||
return static_cast<u8>(current << 4);
|
||||
@@ -97,9 +97,9 @@ namespace sts::boot::bq24193 {
|
||||
constexpr u32 TerminationCurrentLimitMax = 2048;
|
||||
|
||||
inline u8 EncodeTerminationCurrentLimit(u32 current) {
|
||||
if (current < TerminationCurrentLimitMin || current > TerminationCurrentLimitMax) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(current >= TerminationCurrentLimitMin);
|
||||
STS_ASSERT(current <= TerminationCurrentLimitMax);
|
||||
|
||||
current -= TerminationCurrentLimitMin;
|
||||
current >>= 7;
|
||||
return static_cast<u8>(current);
|
||||
@@ -113,9 +113,9 @@ namespace sts::boot::bq24193 {
|
||||
constexpr u32 MinimumSystemVoltageLimitMax = 3700;
|
||||
|
||||
inline u8 EncodeMinimumSystemVoltageLimit(u32 voltage) {
|
||||
if (voltage < MinimumSystemVoltageLimitMin || voltage > MinimumSystemVoltageLimitMax) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(voltage >= MinimumSystemVoltageLimitMin);
|
||||
STS_ASSERT(voltage <= MinimumSystemVoltageLimitMax);
|
||||
|
||||
voltage -= MinimumSystemVoltageLimitMin;
|
||||
voltage /= 100;
|
||||
return static_cast<u8>(voltage << 1);
|
||||
|
||||
@@ -38,9 +38,7 @@ namespace sts::boot {
|
||||
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
|
||||
};
|
||||
|
||||
if (data == nullptr) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(data != nullptr);
|
||||
|
||||
u16 crc16 = 0x55AA;
|
||||
const u8 *data_u8 = reinterpret_cast<const u8 *>(data);
|
||||
|
||||
@@ -103,12 +103,15 @@ namespace sts::boot {
|
||||
|
||||
inline void DoDsiSleepOrRegisterWrites(const DsiSleepOrRegisterWrite *reg_writes, size_t num_writes) {
|
||||
for (size_t i = 0; i < num_writes; i++) {
|
||||
if (reg_writes[i].kind == DsiSleepOrRegisterWriteKind_Write) {
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * reg_writes[i].offset, reg_writes[i].value);
|
||||
} else if (reg_writes[i].kind == DsiSleepOrRegisterWriteKind_Sleep) {
|
||||
svcSleepThread(1'000'000ul * u64(reg_writes[i].offset));
|
||||
} else {
|
||||
std::abort();
|
||||
switch (reg_writes[i].kind) {
|
||||
case DsiSleepOrRegisterWriteKind_Write:
|
||||
reg::Write(g_dsi_regs + sizeof(u32) * reg_writes[i].offset, reg_writes[i].value);
|
||||
break;
|
||||
case DsiSleepOrRegisterWriteKind_Sleep:
|
||||
svcSleepThread(1'000'000ul * u64(reg_writes[i].offset));
|
||||
break;
|
||||
default:
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,18 +133,12 @@ namespace sts::boot {
|
||||
constexpr u64 DeviceName_DC = 2;
|
||||
|
||||
/* Create Address Space. */
|
||||
if (R_FAILED(svcCreateDeviceAddressSpace(&g_dc_das_hnd, 0, (1ul << 32)))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(svcCreateDeviceAddressSpace(&g_dc_das_hnd, 0, (1ul << 32)));
|
||||
/* Attach it to the DC. */
|
||||
if (R_FAILED(svcAttachDeviceAddressSpace(DeviceName_DC, g_dc_das_hnd))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(svcAttachDeviceAddressSpace(DeviceName_DC, g_dc_das_hnd));
|
||||
|
||||
/* Map the framebuffer for the DC as read-only. */
|
||||
if (R_FAILED(svcMapDeviceAddressSpaceAligned(g_dc_das_hnd, CUR_PROCESS_HANDLE, frame_buffer_aligned, FrameBufferSize, FrameBufferPaddr, 1))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(svcMapDeviceAddressSpaceAligned(g_dc_das_hnd, CUR_PROCESS_HANDLE, frame_buffer_aligned, FrameBufferSize, FrameBufferPaddr, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,17 +148,11 @@ namespace sts::boot {
|
||||
constexpr u64 DeviceName_DC = 2;
|
||||
|
||||
/* Unmap the framebuffer from the DC. */
|
||||
if (R_FAILED(svcUnmapDeviceAddressSpace(g_dc_das_hnd, CUR_PROCESS_HANDLE, frame_buffer_aligned, FrameBufferSize, FrameBufferPaddr))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(svcUnmapDeviceAddressSpace(g_dc_das_hnd, CUR_PROCESS_HANDLE, frame_buffer_aligned, FrameBufferSize, FrameBufferPaddr));
|
||||
/* Detach address space from the DC. */
|
||||
if (R_FAILED(svcDetachDeviceAddressSpace(DeviceName_DC, g_dc_das_hnd))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(svcDetachDeviceAddressSpace(DeviceName_DC, g_dc_das_hnd));
|
||||
/* Close the address space. */
|
||||
if (R_FAILED(svcCloseHandle(g_dc_das_hnd))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(svcCloseHandle(g_dc_das_hnd));
|
||||
g_dc_das_hnd = INVALID_HANDLE;
|
||||
g_frame_buffer = nullptr;
|
||||
}
|
||||
@@ -300,8 +291,8 @@ namespace sts::boot {
|
||||
for (size_t i = 0; i < util::size(host_response); i++) {
|
||||
host_response[i] = reg::Read(g_dsi_regs + sizeof(u32) * DSI_RD_DATA);
|
||||
}
|
||||
|
||||
/* The last word from host response is:
|
||||
|
||||
/* The last word from host response is:
|
||||
Bits 0-7: FAB
|
||||
Bits 8-15: REV
|
||||
Bits 16-23: Minor REV
|
||||
|
||||
@@ -41,9 +41,8 @@ namespace sts::boot {
|
||||
}
|
||||
|
||||
Result ReadI2cRegister(i2c::driver::Session &session, u8 *dst, size_t dst_size, const u8 *cmd, size_t cmd_size) {
|
||||
if (dst == nullptr || dst_size == 0 || cmd == nullptr || cmd_size == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(dst != nullptr && dst_size > 0);
|
||||
STS_ASSERT(cmd != nullptr && cmd_size > 0);
|
||||
|
||||
u8 cmd_list[i2c::CommandListFormatter::MaxCommandListSize];
|
||||
|
||||
@@ -55,9 +54,8 @@ namespace sts::boot {
|
||||
}
|
||||
|
||||
Result WriteI2cRegister(i2c::driver::Session &session, const u8 *src, size_t src_size, const u8 *cmd, size_t cmd_size) {
|
||||
if (src == nullptr || src_size == 0 || cmd == nullptr || cmd_size == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(src != nullptr && src_size > 0);
|
||||
STS_ASSERT(cmd != nullptr && cmd_size > 0);
|
||||
|
||||
u8 cmd_list[0x20];
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ namespace sts::boot {
|
||||
args.X[2] = mask;
|
||||
args.X[3] = value;
|
||||
R_ASSERT(svcCallSecureMonitor(&args));
|
||||
if (args.X[0] != 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(args.X[0] == 0);
|
||||
|
||||
return static_cast<u32>(args.X[1]);
|
||||
}
|
||||
@@ -49,18 +47,12 @@ namespace sts::boot {
|
||||
}
|
||||
|
||||
u32 ReadPmcRegister(u32 phys_addr) {
|
||||
if (!IsValidPmcAddress(phys_addr)) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
STS_ASSERT(IsValidPmcAddress(phys_addr));
|
||||
return SmcAtmosphereReadWriteRegister(phys_addr, 0, 0);
|
||||
}
|
||||
|
||||
void WritePmcRegister(u32 phys_addr, u32 value, u32 mask) {
|
||||
if (!IsValidPmcAddress(phys_addr)) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
STS_ASSERT(IsValidPmcAddress(phys_addr));
|
||||
SmcAtmosphereReadWriteRegister(phys_addr, value, mask);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,9 +80,7 @@ namespace sts::gpio {
|
||||
}
|
||||
|
||||
/* Ensure we found an appropriate config. */
|
||||
if (configs == nullptr) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(configs != nullptr);
|
||||
|
||||
for (size_t i = 0; i < num_configs; i++) {
|
||||
/* Configure the GPIO. */
|
||||
|
||||
@@ -33,10 +33,7 @@ namespace sts::gpio {
|
||||
|
||||
/* Helpers. */
|
||||
inline u32 GetPadDescriptor(u32 gpio_pad_name) {
|
||||
if (gpio_pad_name >= PadNameMax) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
STS_ASSERT(gpio_pad_name < PadNameMax);
|
||||
return Map[gpio_pad_name];
|
||||
}
|
||||
|
||||
|
||||
@@ -88,9 +88,7 @@ namespace sts::i2c::driver {
|
||||
}
|
||||
|
||||
inline void CheckInitialized() {
|
||||
if (!GetResourceManager().IsInitialized()) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(GetResourceManager().IsInitialized());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -107,9 +105,7 @@ namespace sts::i2c::driver {
|
||||
/* Session management. */
|
||||
void OpenSession(Session *out_session, I2cDevice device) {
|
||||
CheckInitialized();
|
||||
if (!impl::IsDeviceSupported(device)) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(impl::IsDeviceSupported(device));
|
||||
|
||||
const auto bus = impl::GetDeviceBus(device);
|
||||
const auto slave_address = impl::GetDeviceSlaveAddress(device);
|
||||
@@ -128,9 +124,8 @@ namespace sts::i2c::driver {
|
||||
/* Communication. */
|
||||
Result Send(Session &session, const void *src, size_t size, I2cTransactionOption option) {
|
||||
CheckInitialized();
|
||||
if (src == nullptr || size == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(src != nullptr);
|
||||
STS_ASSERT(size > 0);
|
||||
|
||||
std::scoped_lock<os::Mutex &> lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
|
||||
return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(nullptr, src, size, option, impl::Command::Send);
|
||||
@@ -138,9 +133,8 @@ namespace sts::i2c::driver {
|
||||
|
||||
Result Receive(Session &session, void *dst, size_t size, I2cTransactionOption option) {
|
||||
CheckInitialized();
|
||||
if (dst == nullptr || size == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(dst != nullptr);
|
||||
STS_ASSERT(size > 0);
|
||||
|
||||
std::scoped_lock<os::Mutex &> lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
|
||||
return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(dst, nullptr, size, option, impl::Command::Receive);
|
||||
@@ -148,9 +142,8 @@ namespace sts::i2c::driver {
|
||||
|
||||
Result ExecuteCommandList(Session &session, void *dst, size_t size, const void *cmd_list, size_t cmd_list_size) {
|
||||
CheckInitialized();
|
||||
if (dst == nullptr || size == 0 || cmd_list == nullptr || cmd_list_size == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(dst != nullptr && size > 0);
|
||||
STS_ASSERT(cmd_list != nullptr && cmd_list_size > 0);
|
||||
|
||||
u8 *cur_dst = static_cast<u8 *>(dst);
|
||||
const u8 *cur_cmd = static_cast<const u8 *>(cmd_list);
|
||||
@@ -158,9 +151,7 @@ namespace sts::i2c::driver {
|
||||
|
||||
while (cur_cmd < cmd_list_end) {
|
||||
Command cmd = static_cast<Command>((*cur_cmd) & 3);
|
||||
if (cmd >= Command::Count) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(cmd < Command::Count);
|
||||
|
||||
R_TRY(g_cmd_handlers[static_cast<size_t>(cmd)](&cur_cmd, &cur_dst, session));
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ namespace sts::i2c::driver::impl {
|
||||
|
||||
/* Ensure we're good if this isn't our first session. */
|
||||
if (this->open_sessions > 1) {
|
||||
if (this->speed_mode != speed_mode) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->speed_mode == speed_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,7 +56,7 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
|
||||
/* Close interrupt event. */
|
||||
eventClose(&this->interrupt_event);
|
||||
this->interrupt_event.Finalize();
|
||||
|
||||
/* Close PCV. */
|
||||
pcv::Finalize();
|
||||
@@ -158,10 +156,10 @@ namespace sts::i2c::driver::impl {
|
||||
break;
|
||||
}
|
||||
|
||||
eventClear(&this->interrupt_event);
|
||||
if (R_FAILED(eventWait(&this->interrupt_event, InterruptTimeout))) {
|
||||
this->interrupt_event.Reset();
|
||||
if (!this->interrupt_event.TimedWait(InterruptTimeout)) {
|
||||
this->HandleTransactionResult(ResultI2cBusBusy);
|
||||
eventClear(&this->interrupt_event);
|
||||
this->interrupt_event.Reset();
|
||||
return ResultI2cTimedOut;
|
||||
}
|
||||
|
||||
@@ -181,10 +179,10 @@ namespace sts::i2c::driver::impl {
|
||||
break;
|
||||
}
|
||||
|
||||
eventClear(&this->interrupt_event);
|
||||
if (R_FAILED(eventWait(&this->interrupt_event, InterruptTimeout))) {
|
||||
this->interrupt_event.Reset();
|
||||
if (!this->interrupt_event.TimedWait(InterruptTimeout)) {
|
||||
this->HandleTransactionResult(ResultI2cBusBusy);
|
||||
eventClear(&this->interrupt_event);
|
||||
this->interrupt_event.Reset();
|
||||
return ResultI2cTimedOut;
|
||||
}
|
||||
}
|
||||
@@ -206,11 +204,11 @@ namespace sts::i2c::driver::impl {
|
||||
|
||||
/* Receive bytes. */
|
||||
while (remaining > 0) {
|
||||
eventClear(&this->interrupt_event);
|
||||
if (R_FAILED(eventWait(&this->interrupt_event, InterruptTimeout))) {
|
||||
this->interrupt_event.Reset();
|
||||
if (!this->interrupt_event.TimedWait(InterruptTimeout)) {
|
||||
this->HandleTransactionResult(ResultI2cBusBusy);
|
||||
this->ClearInterruptMask();
|
||||
eventClear(&this->interrupt_event);
|
||||
this->interrupt_event.Reset();
|
||||
return ResultI2cTimedOut;
|
||||
}
|
||||
|
||||
@@ -245,16 +243,9 @@ namespace sts::i2c::driver::impl {
|
||||
static constexpr u64 s_interrupts[] = {
|
||||
0x46, 0x74, 0x7C, 0x98, 0x55, 0x5F
|
||||
};
|
||||
if (ConvertToIndex(bus) >= util::size(s_interrupts)) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
Handle evt_h;
|
||||
if (R_FAILED(svcCreateInterruptEvent(&evt_h, s_interrupts[ConvertToIndex(bus)], 1))) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
eventLoadRemote(&this->interrupt_event, evt_h, false);
|
||||
const auto index = ConvertToIndex(bus);
|
||||
STS_ASSERT(index < util::size(s_interrupts));
|
||||
R_ASSERT(this->interrupt_event.Initialize(s_interrupts[index], false));
|
||||
}
|
||||
|
||||
void BusAccessor::SetClock(SpeedMode speed_mode) {
|
||||
@@ -307,29 +298,17 @@ namespace sts::i2c::driver::impl {
|
||||
reg::Read(&this->i2c_registers->I2C_I2C_CNFG_0);
|
||||
|
||||
if (this->pcv_module != PcvModule_I2C5) {
|
||||
if (R_FAILED(pcv::SetReset(this->pcv_module, true))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pcv::SetClockRate(this->pcv_module, (408'000'000) / (src_div + 1)))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pcv::SetReset(this->pcv_module, false))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetReset(this->pcv_module, true));
|
||||
R_ASSERT(pcv::SetClockRate(this->pcv_module, (408'000'000) / (src_div + 1)));
|
||||
R_ASSERT(pcv::SetReset(this->pcv_module, false));
|
||||
}
|
||||
}
|
||||
|
||||
void BusAccessor::ResetController() const {
|
||||
if (this->pcv_module != PcvModule_I2C5) {
|
||||
if (R_FAILED(pcv::SetReset(this->pcv_module, true))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pcv::SetClockRate(this->pcv_module, 81'600'000))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pcv::SetReset(this->pcv_module, false))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetReset(this->pcv_module, true));
|
||||
R_ASSERT(pcv::SetClockRate(this->pcv_module, 81'600'000));
|
||||
R_ASSERT(pcv::SetReset(this->pcv_module, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,9 +367,7 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
|
||||
void BusAccessor::DisableClock() {
|
||||
if (R_FAILED(pcv::SetClockEnabled(this->pcv_module, false))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetClockEnabled(this->pcv_module, false));
|
||||
}
|
||||
|
||||
void BusAccessor::SetPacketMode() {
|
||||
@@ -435,24 +412,21 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
|
||||
void BusAccessor::HandleTransactionResult(Result result) {
|
||||
if (R_FAILED(result)) {
|
||||
if (result == ResultI2cNoAck || result == ResultI2cBusBusy) {
|
||||
R_TRY_CATCH(result) {
|
||||
R_CATCH_MANY(ResultI2cNoAck, ResultI2cBusBusy) {
|
||||
this->ResetController();
|
||||
this->SetClock(this->speed_mode);
|
||||
this->SetPacketMode();
|
||||
this->FlushFifos();
|
||||
} else {
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
}
|
||||
|
||||
Result BusAccessor::GetAndHandleTransactionResult() {
|
||||
const Result transaction_res = this->GetTransactionResult();
|
||||
R_TRY_CLEANUP(transaction_res, {
|
||||
this->HandleTransactionResult(transaction_res);
|
||||
R_TRY_CLEANUP(this->GetTransactionResult(), {
|
||||
this->HandleTransactionResult(R_CLEANUP_RESULT);
|
||||
this->ClearInterruptMask();
|
||||
eventClear(&this->interrupt_event);
|
||||
this->interrupt_event.Reset();
|
||||
});
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace sts::i2c::driver::impl {
|
||||
};
|
||||
static constexpr u64 InterruptTimeout = 100'000'000ul;
|
||||
private:
|
||||
Event interrupt_event;
|
||||
os::InterruptEvent interrupt_event;
|
||||
os::Mutex open_mutex;
|
||||
os::Mutex register_mutex;
|
||||
Registers *i2c_registers = nullptr;
|
||||
|
||||
@@ -88,37 +88,37 @@ namespace sts::i2c::driver::impl {
|
||||
|
||||
Bus GetDeviceBus(I2cDevice dev) {
|
||||
const size_t dev_idx = GetDeviceIndex(dev);
|
||||
if (dev_idx == DeviceInvalidIndex) { std::abort(); }
|
||||
STS_ASSERT(dev_idx != DeviceInvalidIndex);
|
||||
return g_device_configs[dev_idx].bus;
|
||||
}
|
||||
|
||||
u32 GetDeviceSlaveAddress(I2cDevice dev) {
|
||||
const size_t dev_idx = GetDeviceIndex(dev);
|
||||
if (dev_idx == DeviceInvalidIndex) { std::abort(); }
|
||||
STS_ASSERT(dev_idx != DeviceInvalidIndex);
|
||||
return g_device_configs[dev_idx].slave_address;
|
||||
}
|
||||
|
||||
AddressingMode GetDeviceAddressingMode(I2cDevice dev) {
|
||||
const size_t dev_idx = GetDeviceIndex(dev);
|
||||
if (dev_idx == DeviceInvalidIndex) { std::abort(); }
|
||||
STS_ASSERT(dev_idx != DeviceInvalidIndex);
|
||||
return g_device_configs[dev_idx].addressing_mode;
|
||||
}
|
||||
|
||||
SpeedMode GetDeviceSpeedMode(I2cDevice dev) {
|
||||
const size_t dev_idx = GetDeviceIndex(dev);
|
||||
if (dev_idx == DeviceInvalidIndex) { std::abort(); }
|
||||
STS_ASSERT(dev_idx != DeviceInvalidIndex);
|
||||
return g_device_configs[dev_idx].speed_mode;
|
||||
}
|
||||
|
||||
u32 GetDeviceMaxRetries(I2cDevice dev) {
|
||||
const size_t dev_idx = GetDeviceIndex(dev);
|
||||
if (dev_idx == DeviceInvalidIndex) { std::abort(); }
|
||||
STS_ASSERT(dev_idx != DeviceInvalidIndex);
|
||||
return g_device_configs[dev_idx].max_retries;
|
||||
}
|
||||
|
||||
u64 GetDeviceRetryWaitTime(I2cDevice dev) {
|
||||
const size_t dev_idx = GetDeviceIndex(dev);
|
||||
if (dev_idx == DeviceInvalidIndex) { std::abort(); }
|
||||
STS_ASSERT(dev_idx != DeviceInvalidIndex);
|
||||
return g_device_configs[dev_idx].retry_wait_time;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,7 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
|
||||
constexpr inline Bus ConvertFromIndex(size_t idx) {
|
||||
if (idx >= static_cast<size_t>(Bus::Count)) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(idx < static_cast<size_t>(Bus::Count));
|
||||
return static_cast<Bus>(idx);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ namespace sts::i2c::driver::impl {
|
||||
|
||||
void ResourceManager::Finalize() {
|
||||
std::scoped_lock lk(this->initialize_mutex);
|
||||
if (this->ref_cnt == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->ref_cnt > 0);
|
||||
this->ref_cnt--;
|
||||
if (this->ref_cnt > 0) {
|
||||
return;
|
||||
@@ -61,14 +59,11 @@ namespace sts::i2c::driver::impl {
|
||||
/* Get, open session. */
|
||||
{
|
||||
std::scoped_lock lk(this->session_open_mutex);
|
||||
if (out_session == nullptr || bus >= Bus::Count) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(out_session != nullptr);
|
||||
STS_ASSERT(bus < Bus::Count);
|
||||
|
||||
session_id = GetFreeSessionId();
|
||||
if (session_id == InvalidSessionId) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(session_id != InvalidSessionId);
|
||||
|
||||
|
||||
if ((bus == Bus::I2C2 || bus == Bus::I2C3) && (this->bus_accessors[ConvertToIndex(Bus::I2C2)].GetOpenSessions() == 0 && this->bus_accessors[ConvertToIndex(Bus::I2C3)].GetOpenSessions() == 0)) {
|
||||
@@ -83,12 +78,8 @@ namespace sts::i2c::driver::impl {
|
||||
this->sessions[session_id].Start();
|
||||
if (need_enable_ldo6) {
|
||||
pcv::Initialize();
|
||||
if (R_FAILED(pcv::SetVoltageValue(10, 2'900'000))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pcv::SetVoltageEnabled(10, true))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetVoltageValue(10, 2'900'000));
|
||||
R_ASSERT(pcv::SetVoltageEnabled(10, true));
|
||||
pcv::Finalize();
|
||||
svcSleepThread(560'000ul);
|
||||
}
|
||||
@@ -99,9 +90,7 @@ namespace sts::i2c::driver::impl {
|
||||
/* Get, open session. */
|
||||
{
|
||||
std::scoped_lock lk(this->session_open_mutex);
|
||||
if (!this->sessions[session.session_id].IsOpen()) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->sessions[session.session_id].IsOpen());
|
||||
|
||||
this->sessions[session.session_id].Close();
|
||||
|
||||
@@ -113,18 +102,14 @@ namespace sts::i2c::driver::impl {
|
||||
|
||||
if (need_disable_ldo6) {
|
||||
pcv::Initialize();
|
||||
if (R_FAILED(pcv::SetVoltageEnabled(10, false))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetVoltageEnabled(10, false));
|
||||
pcv::Finalize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ResourceManager::SuspendBuses() {
|
||||
if (this->ref_cnt == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->ref_cnt > 0);
|
||||
|
||||
if (!this->suspended) {
|
||||
{
|
||||
@@ -137,27 +122,19 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
}
|
||||
pcv::Initialize();
|
||||
if (R_FAILED(pcv::SetVoltageEnabled(10, false))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetVoltageEnabled(10, false));
|
||||
pcv::Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceManager::ResumeBuses() {
|
||||
if (this->ref_cnt == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->ref_cnt > 0);
|
||||
|
||||
if (this->suspended) {
|
||||
if (this->bus_accessors[ConvertToIndex(Bus::I2C2)].GetOpenSessions() > 0 || this->bus_accessors[ConvertToIndex(Bus::I2C3)].GetOpenSessions() > 0) {
|
||||
pcv::Initialize();
|
||||
if (R_FAILED(pcv::SetVoltageValue(10, 2'900'000))) {
|
||||
std::abort();
|
||||
}
|
||||
if (R_FAILED(pcv::SetVoltageEnabled(10, true))) {
|
||||
std::abort();
|
||||
}
|
||||
R_ASSERT(pcv::SetVoltageValue(10, 2'900'000));
|
||||
R_ASSERT(pcv::SetVoltageEnabled(10, true));
|
||||
pcv::Finalize();
|
||||
svcSleepThread(1'560'000ul);
|
||||
}
|
||||
@@ -174,9 +151,7 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
|
||||
void ResourceManager::SuspendPowerBus() {
|
||||
if (this->ref_cnt == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->ref_cnt > 0);
|
||||
std::scoped_lock lk(this->session_open_mutex);
|
||||
|
||||
if (!this->power_bus_suspended) {
|
||||
@@ -188,9 +163,7 @@ namespace sts::i2c::driver::impl {
|
||||
}
|
||||
|
||||
void ResourceManager::ResumePowerBus() {
|
||||
if (this->ref_cnt == 0) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(this->ref_cnt > 0);
|
||||
std::scoped_lock lk(this->session_open_mutex);
|
||||
|
||||
if (this->power_bus_suspended) {
|
||||
|
||||
@@ -43,9 +43,7 @@ namespace sts::i2c {
|
||||
size_t cur_index = 0;
|
||||
public:
|
||||
CommandListFormatter(void *cmd_list, size_t cmd_list_size) : cmd_list(static_cast<u8 *>(cmd_list)), cmd_list_size(cmd_list_size) {
|
||||
if (cmd_list_size > MaxCommandListSize) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(cmd_list_size <= MaxCommandListSize);
|
||||
}
|
||||
~CommandListFormatter() {
|
||||
this->cmd_list = nullptr;
|
||||
|
||||
@@ -66,9 +66,7 @@ namespace sts::pinmux {
|
||||
}
|
||||
|
||||
/* Ensure we found an appropriate config. */
|
||||
if (configs == nullptr) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT(configs != nullptr);
|
||||
|
||||
for (size_t i = 0; i < num_configs; i++) {
|
||||
UpdatePad(configs[i].name, configs[i].val, configs[i].mask);
|
||||
|
||||
@@ -33,19 +33,13 @@ namespace sts::pinmux {
|
||||
|
||||
/* Helpers. */
|
||||
inline const Definition *GetDefinition(u32 pinmux_name) {
|
||||
if (pinmux_name >= PadNameMax) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
STS_ASSERT(pinmux_name < PadNameMax);
|
||||
return &Map[pinmux_name];
|
||||
}
|
||||
|
||||
inline const DrivePadDefinition *GetDrivePadDefinition(u32 pinmux_name) {
|
||||
if (pinmux_name >= DrivePadNameMax) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
return &DrivePadMap[pinmux_name];
|
||||
inline const DrivePadDefinition *GetDrivePadDefinition(u32 drivepad_name) {
|
||||
STS_ASSERT(drivepad_name < DrivePadNameMax);
|
||||
return &DrivePadMap[drivepad_name];
|
||||
}
|
||||
|
||||
uintptr_t GetBaseAddress() {
|
||||
@@ -110,9 +104,7 @@ namespace sts::pinmux {
|
||||
u32 pinmux_val = reg::Read(pinmux_reg);
|
||||
|
||||
/* This PINMUX register is locked */
|
||||
if (pinmux_val & 0x80) {
|
||||
std::abort();
|
||||
}
|
||||
STS_ASSERT((pinmux_val & 0x80) == 0);
|
||||
|
||||
u32 pm_val = (pinmux_config_val & 0x07);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user