i2c: command list format, get boot down to linker errors

This commit is contained in:
Michael Scire
2020-10-31 22:52:43 -07:00
committed by SciresM
parent 42caa4ffd1
commit 258cfb62a2
13 changed files with 233 additions and 50 deletions

View File

@@ -14,22 +14,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "i2c/driver/i2c_api.hpp"
namespace ams::boot {
class BatteryDriver {
private:
i2c::driver::Session i2c_session;
i2c::driver::I2cSession i2c_session;
public:
BatteryDriver() {
i2c::driver::Initialize();
i2c::driver::OpenSession(&this->i2c_session, I2cDevice_Max17050);
i2c::driver::OpenSession(std::addressof(this->i2c_session), i2c::DeviceCode_Max17050);
}
~BatteryDriver() {
i2c::driver::CloseSession(this->i2c_session);
i2c::driver::Finalize();
}
private:
Result Read(u8 addr, u16 *out_data);

View File

@@ -23,11 +23,10 @@ namespace ams::boot {
private:
static constexpr u32 GpioPadName_Bq24193Charger = 0xA;
private:
i2c::driver::Session i2c_session;
i2c::driver::I2cSession i2c_session;
public:
ChargerDriver() {
i2c::driver::Initialize();
i2c::driver::OpenSession(&this->i2c_session, I2cDevice_Bq24193);
i2c::driver::OpenSession(std::addressof(this->i2c_session), i2c::DeviceCode_Bq24193);
//boot::gpio::Configure(GpioPadName_Bq24193Charger);
//boot::gpio::SetDirection(GpioPadName_Bq24193Charger, GpioDirection_Output);
@@ -35,7 +34,6 @@ namespace ams::boot {
~ChargerDriver() {
i2c::driver::CloseSession(this->i2c_session);
i2c::driver::Finalize();
}
private:
Result Read(u8 addr, u8 *out_data);

View File

@@ -196,11 +196,8 @@ namespace ams::boot {
/* Turn on DSI/voltage rail. */
{
i2c::driver::Session i2c_session;
i2c::driver::Initialize();
ON_SCOPE_EXIT { i2c::driver::Finalize(); };
i2c::driver::OpenSession(&i2c_session, I2cDevice_Max77620Pmic);
i2c::driver::I2cSession i2c_session;
i2c::driver::OpenSession(std::addressof(i2c_session), i2c::DeviceCode_Max77620Pmic);
if (g_soc_type == spl::SocType_Mariko) {
WriteI2cRegister(i2c_session, 0x18, 0x3A);

View File

@@ -46,7 +46,7 @@ namespace ams::boot {
/* TODO: pwm::driver::board::Initialize(); */
/* Initialize the pwm driver library. */
/* TODO: pwm::driver::Initialize();
/* TODO: pwm::driver::Initialize(); */
}
}

View File

@@ -22,54 +22,51 @@ namespace ams::boot {
template<typename F>
constexpr Result RetryUntilSuccess(F f) {
constexpr u64 timeout = 10'000'000'000ul;
constexpr u64 retry_interval = 20'000'000ul;
constexpr auto Timeout = TimeSpan::FromSeconds(10);
constexpr auto RetryInterval = TimeSpan::FromMilliSeconds(20);
u64 cur_time = 0;
TimeSpan cur_time = TimeSpan(0);
while (true) {
const auto retry_result = f();
R_SUCCEED_IF(R_SUCCEEDED(retry_result));
cur_time += retry_interval;
if (cur_time < timeout) {
svcSleepThread(retry_interval);
continue;
}
cur_time += RetryInterval;
R_UNLESS(cur_time < Timeout, retry_result);
return retry_result;
os::SleepThread(RetryInterval);
}
}
}
Result ReadI2cRegister(i2c::driver::Session &session, u8 *dst, size_t dst_size, const u8 *cmd, size_t cmd_size) {
Result ReadI2cRegister(i2c::driver::I2cSession &session, u8 *dst, size_t dst_size, const u8 *cmd, size_t cmd_size) {
AMS_ABORT_UNLESS(dst != nullptr && dst_size > 0);
AMS_ABORT_UNLESS(cmd != nullptr && cmd_size > 0);
u8 cmd_list[i2c::CommandListFormatter::MaxCommandListSize];
u8 cmd_list[i2c::CommandListLengthMax];
i2c::CommandListFormatter formatter(cmd_list, sizeof(cmd_list));
R_ABORT_UNLESS(formatter.EnqueueSendCommand(I2cTransactionOption_Start, cmd, cmd_size));
R_ABORT_UNLESS(formatter.EnqueueReceiveCommand(static_cast<I2cTransactionOption>(I2cTransactionOption_Start | I2cTransactionOption_Stop), dst_size));
return RetryUntilSuccess([&]() { return i2c::driver::ExecuteCommandList(session, dst, dst_size, cmd_list, formatter.GetCurrentSize()); });
R_ABORT_UNLESS(formatter.EnqueueSendCommand(i2c::TransactionOption_StartCondition, cmd, cmd_size));
R_ABORT_UNLESS(formatter.EnqueueReceiveCommand(static_cast<i2c::TransactionOption>(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition), dst_size));
return RetryUntilSuccess([&]() { return i2c::driver::ExecuteCommandList(dst, dst_size, session, cmd_list, formatter.GetCurrentLength()); });
}
Result WriteI2cRegister(i2c::driver::Session &session, const u8 *src, size_t src_size, const u8 *cmd, size_t cmd_size) {
Result WriteI2cRegister(i2c::driver::I2cSession &session, const u8 *src, size_t src_size, const u8 *cmd, size_t cmd_size) {
AMS_ABORT_UNLESS(src != nullptr && src_size > 0);
AMS_ABORT_UNLESS(cmd != nullptr && cmd_size > 0);
u8 cmd_list[0x20];
/* N doesn't use a CommandListFormatter here... */
std::memcpy(&cmd_list[0], cmd, cmd_size);
std::memcpy(&cmd_list[cmd_size], src, src_size);
std::memcpy(cmd_list + 0, cmd, cmd_size);
std::memcpy(cmd_list + cmd_size, src, src_size);
return RetryUntilSuccess([&]() { return i2c::driver::Send(session, cmd_list, src_size + cmd_size, static_cast<I2cTransactionOption>(I2cTransactionOption_Start | I2cTransactionOption_Stop)); });
return RetryUntilSuccess([&]() { return i2c::driver::Send(session, cmd_list, src_size + cmd_size, static_cast<i2c::TransactionOption>(i2c::TransactionOption_StartCondition | i2c::TransactionOption_StopCondition)); });
}
Result WriteI2cRegister(i2c::driver::Session &session, const u8 address, const u8 value) {
return WriteI2cRegister(session, &value, sizeof(value), &address, sizeof(address));
Result WriteI2cRegister(i2c::driver::I2cSession &session, const u8 address, const u8 value) {
return WriteI2cRegister(session, std::addressof(value), sizeof(value), &address, sizeof(address));
}
}

View File

@@ -16,13 +16,11 @@
#pragma once
#include <stratosphere.hpp>
#include "i2c/driver/i2c_api.hpp"
namespace ams::boot {
/* I2C Utilities. */
Result ReadI2cRegister(i2c::driver::Session &session, u8 *dst, size_t dst_size, const u8 *cmd, size_t cmd_size);
Result WriteI2cRegister(i2c::driver::Session &session, const u8 *src, size_t src_size, const u8 *cmd, size_t cmd_size);
Result WriteI2cRegister(i2c::driver::Session &session, const u8 address, const u8 value);
Result ReadI2cRegister(i2c::driver::I2cSession &session, u8 *dst, size_t dst_size, const u8 *cmd, size_t cmd_size);
Result WriteI2cRegister(i2c::driver::I2cSession &session, const u8 *src, size_t src_size, const u8 *cmd, size_t cmd_size);
Result WriteI2cRegister(i2c::driver::I2cSession &session, const u8 address, const u8 value);
}

View File

@@ -21,16 +21,14 @@ namespace ams::boot {
/* Driver object. */
class PmicDriver {
private:
i2c::driver::Session i2c_session;
i2c::driver::I2cSession i2c_session;
public:
PmicDriver() {
i2c::driver::Initialize();
i2c::driver::OpenSession(&this->i2c_session, I2cDevice_Max77620Pmic);
i2c::driver::OpenSession(std::addressof(this->i2c_session), i2c::DeviceCode_Max77620Pmic);
}
~PmicDriver() {
i2c::driver::CloseSession(this->i2c_session);
i2c::driver::Finalize();
}
private:
Result GetPowerStatus(u8 *out);

View File

@@ -20,16 +20,14 @@ namespace ams::boot {
class RtcDriver {
private:
i2c::driver::Session i2c_session;
i2c::driver::I2cSession i2c_session;
public:
RtcDriver() {
i2c::driver::Initialize();
i2c::driver::OpenSession(&this->i2c_session, I2cDevice_Max77620Rtc);
R_ABORT_UNLESS(i2c::driver::OpenSession(std::addressof(this->i2c_session), i2c::DeviceCode_Max77620Rtc));
}
~RtcDriver() {
i2c::driver::CloseSession(this->i2c_session);
i2c::driver::Finalize();
}
private:
Result ReadRtcRegister(u8 *out, u8 address);