mirror of
https://github.com/d0k3/GodMode9.git
synced 2026-05-31 06:46:56 +00:00
Add support for reading and writing to I2C devices from lua (#934)
* Add i2c read support to lua * Add i2c write support to lua With memory permissions before write * Adjust i2c write * Fix inverted id check, better permissions * Change write to not return anything on success * Add some documentation for lua i2c * Change write length from 1024 to 64 * Add whitelist for i2c writing * Move i2c module into preload * Add registers and bitmasks for mcu Add documentation to lua-doc * Fix missing column divider in lua-doc * Add ~= 0 then to lua example * Add some more registers
This commit is contained in:
parent
468a91b414
commit
584b68b7b1
147
arm9/source/lua/gm9internali2c.c
Normal file
147
arm9/source/lua/gm9internali2c.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#ifndef NO_LUA
|
||||||
|
#include "gm9internali2c.h"
|
||||||
|
#include "fsperm.h"
|
||||||
|
#include "system/i2c.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t dev_id;
|
||||||
|
uint8_t reg_addr_start;
|
||||||
|
uint8_t reg_addr_end;
|
||||||
|
} WhiteListPair;
|
||||||
|
|
||||||
|
static const WhiteListPair WriteWhitelist[] = {
|
||||||
|
// Device_id, Register_address, Register_address_end
|
||||||
|
{ I2C_DEV_MCU, 0x15, 0x17 },
|
||||||
|
{ I2C_DEV_MCU, 0x1c, 0x1f },
|
||||||
|
{ I2C_DEV_MCU, 0x28, 0x29 },
|
||||||
|
{ I2C_DEV_MCU, 0x2a, 0x2d },
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool IsWriteAllowed(uint8_t dev_id, uint8_t reg_addr)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < sizeof(WriteWhitelist)/sizeof(WriteWhitelist[0]); i++) {
|
||||||
|
if (WriteWhitelist[i].dev_id == dev_id &&
|
||||||
|
reg_addr >= WriteWhitelist[i].reg_addr_start &&
|
||||||
|
reg_addr <= WriteWhitelist[i].reg_addr_end)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int i2c_read(lua_State *L) {
|
||||||
|
int dev_id = luaL_checkinteger(L, 1);
|
||||||
|
int reg_addr = luaL_checkinteger(L, 2);
|
||||||
|
int length = luaL_checkinteger(L, 3);
|
||||||
|
|
||||||
|
if (dev_id < 0 || dev_id > 17) {
|
||||||
|
return luaL_error(L, "Invalid device ID: %d (must be 0-17)", dev_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length <= 0 || length > 64) {
|
||||||
|
return luaL_error(L, "Invalid length: %d (must be 1-64)", length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg_addr < 0 || reg_addr > 255) {
|
||||||
|
return luaL_error(L, "Invalid register address: %d (must be 0-255)", reg_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a buffer for the read data
|
||||||
|
u8 *buffer = malloc(length);
|
||||||
|
if (!buffer) {
|
||||||
|
return luaL_error(L, "Memory allocation failed");
|
||||||
|
}
|
||||||
|
bool success = I2C_readRegBuf((I2cDevice)dev_id, (u8)reg_addr, buffer, (u32)length);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
// Create a Lua table to hold the byte values
|
||||||
|
lua_createtable(L, length, 0);
|
||||||
|
|
||||||
|
// Fill the table with byte values as integers
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
lua_pushinteger(L, buffer[i]); // Push byte value as integer
|
||||||
|
lua_rawseti(L, -2, i + 1); // Set table[i+1] = byte
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
free(buffer);
|
||||||
|
return luaL_error(L, "I2C read failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int i2c_write(lua_State *L) {
|
||||||
|
SetWritePermissionsLuaError(L, PERM_MEMORY);
|
||||||
|
|
||||||
|
int dev_id = luaL_checkinteger(L, 1);
|
||||||
|
int reg_addr = luaL_checkinteger(L, 2);
|
||||||
|
|
||||||
|
if (!lua_istable(L, 3)) {
|
||||||
|
return luaL_error(L, "Third parameter must be a table of byte values");
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = lua_rawlen(L, 3);
|
||||||
|
|
||||||
|
if (dev_id < 0 || dev_id > 17) {
|
||||||
|
return luaL_error(L, "Invalid device ID: %d (must be 0-17)", dev_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length <= 0 || length > 64) {
|
||||||
|
return luaL_error(L, "Invalid data length: %d (must be 1-64)", length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg_addr < 0 || reg_addr > 255) {
|
||||||
|
return luaL_error(L, "Invalid register address: %d (must be 0-255)", reg_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsWriteAllowed(dev_id, reg_addr)) {
|
||||||
|
return luaL_error(L, "Write to device %d, register %d is not allowed", dev_id, reg_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a buffer for the write data
|
||||||
|
u8 *buffer = malloc(length);
|
||||||
|
if (!buffer) {
|
||||||
|
return luaL_error(L, "Memory allocation failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract byte values from Lua table
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
lua_rawgeti(L, 3, i + 1); // Get table[i+1]
|
||||||
|
|
||||||
|
if (!lua_isinteger(L, -1)) {
|
||||||
|
free(buffer);
|
||||||
|
return luaL_error(L, "Table element %d is not an integer", i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = lua_tointeger(L, -1);
|
||||||
|
if (value < 0 || value > 255) {
|
||||||
|
free(buffer);
|
||||||
|
return luaL_error(L, "Table element %d is out of range: %d (must be 0-255)", i + 1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = (u8)value;
|
||||||
|
lua_pop(L, 1); // Remove the value from stack
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = I2C_writeRegBuf((I2cDevice)dev_id, (u8)reg_addr, buffer, (u32)length);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return luaL_error(L, "I2C write failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg i2c[] = {
|
||||||
|
{"read", i2c_read},
|
||||||
|
{"write", i2c_write},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int gm9lua_open_internali2c(lua_State* L) {
|
||||||
|
luaL_newlib(L, i2c);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
6
arm9/source/lua/gm9internali2c.h
Normal file
6
arm9/source/lua/gm9internali2c.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "gm9lua.h"
|
||||||
|
|
||||||
|
#define GM9LUA_I2CLIBNAME "_i2c"
|
||||||
|
|
||||||
|
int gm9lua_open_internali2c(lua_State* L);
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include "gm9os.h"
|
#include "gm9os.h"
|
||||||
#include "gm9ui.h"
|
#include "gm9ui.h"
|
||||||
#include "gm9title.h"
|
#include "gm9title.h"
|
||||||
|
#include "gm9internali2c.h"
|
||||||
#include "gm9internalfs.h"
|
#include "gm9internalfs.h"
|
||||||
#include "gm9internalsys.h"
|
#include "gm9internalsys.h"
|
||||||
|
|
||||||
@ -90,6 +91,12 @@ void CheckWritePermissionsLuaError(lua_State* L, const char* path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetWritePermissionsLuaError(lua_State* L, u32 perm) {
|
||||||
|
if (!SetWritePermissions(perm, true)) {
|
||||||
|
luaL_error(L, "failed to set write permissions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const luaL_Reg gm9lualibs[] = {
|
static const luaL_Reg gm9lualibs[] = {
|
||||||
// built-ins
|
// built-ins
|
||||||
{LUA_GNAME, luaopen_base},
|
{LUA_GNAME, luaopen_base},
|
||||||
@ -109,6 +116,7 @@ static const luaL_Reg gm9lualibs[] = {
|
|||||||
// gm9 custom internals (usually wrapped by a pure lua module)
|
// gm9 custom internals (usually wrapped by a pure lua module)
|
||||||
{GM9LUA_INTERNALFSLIBNAME, gm9lua_open_internalfs},
|
{GM9LUA_INTERNALFSLIBNAME, gm9lua_open_internalfs},
|
||||||
{GM9LUA_INTERNALSYSLIBNAME, gm9lua_open_internalsys},
|
{GM9LUA_INTERNALSYSLIBNAME, gm9lua_open_internalsys},
|
||||||
|
{GM9LUA_I2CLIBNAME, gm9lua_open_internali2c},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -45,5 +45,6 @@ static inline bool CheckLuaArgCountPlusExtra(lua_State* L, int argcount, const c
|
|||||||
int LoadLuaFile(lua_State* L, const char* filename);
|
int LoadLuaFile(lua_State* L, const char* filename);
|
||||||
u32 GetFlagsFromTable(lua_State* L, int pos, u32 flags_ext_starter, u32 allowed_flags);
|
u32 GetFlagsFromTable(lua_State* L, int pos, u32 flags_ext_starter, u32 allowed_flags);
|
||||||
void CheckWritePermissionsLuaError(lua_State* L, const char* path);
|
void CheckWritePermissionsLuaError(lua_State* L, const char* path);
|
||||||
|
void SetWritePermissionsLuaError(lua_State* L, u32 perm);
|
||||||
#endif
|
#endif
|
||||||
bool ExecuteLuaScript(const char* path_script);
|
bool ExecuteLuaScript(const char* path_script);
|
||||||
|
|||||||
240
data/luapackages/i2c.lua
Normal file
240
data/luapackages/i2c.lua
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
local i2c = {}
|
||||||
|
|
||||||
|
i2c.read = _i2c.read
|
||||||
|
i2c.write = _i2c.write
|
||||||
|
|
||||||
|
-- List of devices on the I2C bus
|
||||||
|
i2c.dev = {
|
||||||
|
POWER = 0, -- Unconfirmed
|
||||||
|
CAMERA = 1, -- Unconfirmed
|
||||||
|
CAMERA2 = 2, -- Unconfirmed
|
||||||
|
MCU = 3,
|
||||||
|
CAMERA3 = 4,
|
||||||
|
LCD1 = 5,
|
||||||
|
LCD2 = 6,
|
||||||
|
GYRO3 = 9,
|
||||||
|
GYRO = 10,
|
||||||
|
GYRO2 = 11,
|
||||||
|
DEBUG_PAD = 12,
|
||||||
|
IR = 13,
|
||||||
|
EEPROM = 14, -- Unconfirmed
|
||||||
|
NFC = 15,
|
||||||
|
QTM = 16,
|
||||||
|
N3DS_HID = 17
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Sub-tables for specific devices, containing register addresses and some bitmasks
|
||||||
|
i2c.mcu = {
|
||||||
|
-- Bitmasks for the 4-byte interupt registers.
|
||||||
|
interrupt_1 = {
|
||||||
|
POWER_BUTTON_HELD = 1 << 1, -- The power button was held.
|
||||||
|
HOME_BUTTON_PRESS = 1 << 2, -- The HOME button was pressed.
|
||||||
|
HOME_BUTTON_RELEASE = 1 << 3, -- The HOME button was released.
|
||||||
|
WLAN_SWITCH_TRIGGER = 1 << 4, -- The WiFi switch was triggered.
|
||||||
|
SHELL_CLOSE = 1 << 5, -- The shell was closed (or sleep switch turned off).
|
||||||
|
SHELL_OPEN = 1 << 6, -- The shell was opened (or sleep switch turned on).
|
||||||
|
FATAL_HW_ERROR = 1 << 7, -- MCU watchdog reset occurred.
|
||||||
|
},
|
||||||
|
|
||||||
|
interrupt_2 = {
|
||||||
|
AC_ADAPTER_REMOVED = 1 << 0, -- The AC adapter was disconnected.
|
||||||
|
AC_ADAPTER_PLUGGED_IN = 1 << 1, -- The AC adapter was connected.
|
||||||
|
RTC_ALARM = 1 << 2, -- The RTC alarm time has been reached.
|
||||||
|
ACCELEROMETER_I2C_MANUAL_IO = 1 << 3, -- The manual accelerometer I²C read/write operation has completed.
|
||||||
|
ACCELEROMETER_NEW_SAMPLE = 1 << 4, -- A new accelerometer sample is available.
|
||||||
|
CRITICAL_BATTERY = 1 << 5, -- The battery is critically low.
|
||||||
|
CHARGING_STOP = 1 << 6, -- The battery stopped charging.
|
||||||
|
CHARGING_START = 1 << 7, -- The battery started charging.
|
||||||
|
},
|
||||||
|
|
||||||
|
interrupt_3 = {
|
||||||
|
VOL_SLIDER = 1 << 6, -- The position of the volume slider changed.
|
||||||
|
},
|
||||||
|
|
||||||
|
interrupt_4 = {
|
||||||
|
LCD_OFF = 1 << 0, -- The LCDs turned off.
|
||||||
|
LCD_ON = 1 << 1, -- The LCDs turned on.
|
||||||
|
BOT_BACKLIGHT_OFF = 1 << 2, -- The bottom screen backlight turned off.
|
||||||
|
BOT_BACKLIGHT_ON = 1 << 3, -- The bottom screen backlight turned on.
|
||||||
|
TOP_BACKLIGHT_OFF = 1 << 4, -- The top screen backlight turned off.
|
||||||
|
TOP_BACKLIGHT_ON = 1 << 5, -- The top screen backlight turned on.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Register addresses
|
||||||
|
reg = {
|
||||||
|
VERSION_HIGH = 0x0, -- Major version of the MCU firmware.
|
||||||
|
VERSION_LOW = 0x1, -- Minor version of the MCU firmware.
|
||||||
|
|
||||||
|
RESET_EVENTS = 0x2, -- @ref mcu.reset_event_flags
|
||||||
|
|
||||||
|
VCOM_TOP = 0x3, -- Flicker/VCOM value for the top screen.
|
||||||
|
VCOM_BOTTOM = 0x4, -- Flicker/VCOM value for the bottom screen.
|
||||||
|
|
||||||
|
FIRMWARE_UPLOAD_0 = 0x5, -- Firmware upload register.
|
||||||
|
FIRMWARE_UPLOAD_1 = 0x6, -- Firmware upload register.
|
||||||
|
FIRMWARE_UPLOAD_2 = 0x7, -- Firmware upload register.
|
||||||
|
|
||||||
|
RAW_3D_SLIDER_POSITION = 0x8, -- Position of the 3D slider.
|
||||||
|
VOLUME_SLIDER_POSITION = 0x9, -- Position of the volume slider.
|
||||||
|
|
||||||
|
BATTERY_PCB_TEMPERATURE = 0xA, -- Temperature of the battery, measured on a sensor on the PCB.
|
||||||
|
BATTERY_PERCENTAGE_INT = 0xB, -- Integer part of the battery percentage.
|
||||||
|
BATTERY_PERCENTAGE_FRAC = 0xC, -- Fractional part of the battery percentage.
|
||||||
|
BATTERY_VOLTAGE = 0xD, -- Voltage of the battery, in units of 20 mV.
|
||||||
|
|
||||||
|
HW_STATUS = 0xE, -- Hardware status bits
|
||||||
|
POWER_STATUS = 0xF, -- @ref mcu.power_status_flags
|
||||||
|
|
||||||
|
LEGACY_VERSION_HIGH = 0xF, -- (Old MCU_FIRM only) Major firmware version.
|
||||||
|
LEGACY_VERSION_LOW = 0x10, -- (Old MCU_FIRM only) Minor firmware version.
|
||||||
|
LEGACY_FIRM_UPLOAD = 0x3B, -- (Old MCU_FIRM only) Firmware upload register.
|
||||||
|
|
||||||
|
RECEIVED_IRQS_1 = 0x10, -- Bitmask of received IRQs. @ref mcu.interrupt_1
|
||||||
|
RECEIVED_IRQS_2 = 0x11, -- Bitmask of received IRQs. @ref mcu.interrupt_2
|
||||||
|
RECEIVED_IRQS_3 = 0x12, -- Bitmask of received IRQs. @ref mcu.interrupt_3
|
||||||
|
RECEIVED_IRQS_4 = 0x13, -- Bitmask of received IRQs. @ref mcu.interrupt_4
|
||||||
|
UNUSED_RO_14 = 0x14, -- Unused read-only register.
|
||||||
|
USERDATA_RAM_15 = 0x15, -- Unused register, supports writing
|
||||||
|
USERDATA_RAM_16 = 0x16, -- Unused register, supports writing
|
||||||
|
USERDATA_RAM_17 = 0x17, -- Unused register, supports writing
|
||||||
|
IRQ_MASK_1 = 0x18, -- Bitmask of enabled IRQs. @ref mcu.interrupt_1
|
||||||
|
IRQ_MASK_2 = 0x19, -- Bitmask of enabled IRQs. @ref mcu.interrupt_2
|
||||||
|
IRQ_MASK_3 = 0x1A, -- Bitmask of enabled IRQs. @ref mcu.interrupt_3
|
||||||
|
IRQ_MASK_4 = 0x1B, -- Bitmask of enabled IRQs. @ref mcu.interrupt_4
|
||||||
|
USERDATA_RAM_1C = 0x1C, -- Unused register, supports writing
|
||||||
|
USERDATA_RAM_1D = 0x1D, -- Unused register, supports writing
|
||||||
|
USERDATA_RAM_1E = 0x1E, -- Unused register, supports writing
|
||||||
|
USERDATA_RAM_1F = 0x1F, -- Unused register, supports writing
|
||||||
|
|
||||||
|
PWR_CTL = 0x20, -- @ref mcu.power_trigger
|
||||||
|
LCD_PWR_CTL = 0x22, -- LCD Power control.
|
||||||
|
MCU_RESET_CTL = 0x23, -- Writing 'r' to this register resets the MCU. Stubbed on retail.
|
||||||
|
FORCE_SHUTDOWN_DELAY = 0x24, -- The amount of time, in units of 0.125s, for which the power button needs to be held to trigger a hard shutdown.
|
||||||
|
|
||||||
|
VOLUME_UNK_25 = 0x25, -- Unknown register. Used in mcu::SND
|
||||||
|
UNK_26 = 0x26, -- Unknown register. Used in mcu::CDC
|
||||||
|
|
||||||
|
VOLUME_SLIDER_RAW = 0x27, -- Raw value of the volume slider, in the range of 0-255
|
||||||
|
LED_BRIGHTNESS_STATE = 0x28, -- Brightness of the status LEDs.
|
||||||
|
POWER_LED_STATE = 0x29, -- @ref mcu.power_led_state
|
||||||
|
WLAN_LED_STATE = 0x2A, -- Controls the WiFi LED.
|
||||||
|
CAMERA_LED_STATE = 0x2B, -- Controls the camera LED (on models that have one).
|
||||||
|
LED_3D_STATE = 0x2C, -- Controls the 3D LED (on models that have one).
|
||||||
|
NOTIFICATION_LED_STATE = 0x2D, -- Controls the info (notification) LED.
|
||||||
|
NOTIFICATION_LED_CYCLE_STATE = 0x2E, -- Bit 0 is set if the info (notification) LED has started a new cycle of its pattern.
|
||||||
|
|
||||||
|
RTC_TIME_SECOND = 0x30, -- RTC second.
|
||||||
|
RTC_TIME_MINUTE = 0x31, -- RTC minute.
|
||||||
|
RTC_TIME_HOUR = 0x32, -- RTC hour.
|
||||||
|
RTC_TIME_WEEKDAY = 0x33, -- RTC day of the week.
|
||||||
|
RTC_TIME_DAY = 0x34, -- RTC day of the month.
|
||||||
|
RTC_TIME_MONTH = 0x35, -- RTC month.
|
||||||
|
RTC_TIME_YEAR = 0x36, -- RTC year.
|
||||||
|
RTC_TIME_CORRECTION = 0x37, -- RTC subsecond (RSUBC) correction value.
|
||||||
|
|
||||||
|
RTC_ALARM_MINUTE = 0x38, -- RTC alarm minute.
|
||||||
|
RTC_ALARM_HOUR = 0x39, -- RTC alarm hour.
|
||||||
|
RTC_ALARM_DAY = 0x3A, -- RTC alarm day.
|
||||||
|
RTC_ALARM_MONTH = 0x3B, -- RTC alarm month.
|
||||||
|
RTC_ALARM_YEAR = 0x3C, -- RTC alarm year.
|
||||||
|
|
||||||
|
TICK_COUNTER_LSB = 0x3D, -- MCU tick counter value (low byte).
|
||||||
|
TICK_COUNTER_MSB = 0x3E, -- MCU tick counter value (high byte).
|
||||||
|
|
||||||
|
UNK_3F = 0x3F, -- Unknown register
|
||||||
|
|
||||||
|
SENSOR_CONFIG = 0x40, -- @ref mcu.sensor_config
|
||||||
|
|
||||||
|
ACCELEROMETER_MANUAL_REGID_R = 0x41, -- Hardware register ID for use in manual accelerometer I²C reads.
|
||||||
|
ACCELEROMETER_MANUAL_REGID_W = 0x43, -- Hardware reigster ID for use in manual accelerometer I²C writes.
|
||||||
|
ACCELEROMETER_MANUAL_IO = 0x44, -- Data register for manual accelerometer reads/writes.
|
||||||
|
ACCELEROMETER_OUTPUT_X_LSB = 0x45, -- Accelerometer X coordinate (low byte).
|
||||||
|
ACCELEROMETER_OUTPUT_X_MSB = 0x46, -- Accelerometer X coordinate (high byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Y_LSB = 0x47, -- Accelerometer Y coordinate (low byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Y_MSB = 0x48, -- Accelerometer Y coordinate (high byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Z_LSB = 0x49, -- Accelerometer Z coordinate (low byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Z_MSB = 0x4A, -- Accelerometer Z coordinate (high byte).
|
||||||
|
|
||||||
|
PEDOMETER_STEPS_LOWBYTE = 0x4B, -- Pedometer step count (low byte).
|
||||||
|
PEDOMETER_STEPS_MIDDLEBYTE = 0x4C, -- Pedometer step count (middle byte).
|
||||||
|
PEDOMETER_STEPS_HIGHBYTE = 0x4D, -- Pedometer step count (high byte).
|
||||||
|
PEDOMETER_CNT = 0x4E, -- @ref mcu.pedometer_control
|
||||||
|
PEDOMETER_STEP_DATA = 0x4F, -- Step history and time of last update.
|
||||||
|
PEDOMETER_WRAP_MINUTE = 0x50, -- The minute within each RTC hour at which the step history should roll into the next hour.
|
||||||
|
PEDOMETER_WRAP_SECOND = 0x51, -- The second within each RTC hour at which the step history should roll into the next hour.
|
||||||
|
|
||||||
|
VOLUME_CALIBRATION_MIN = 0x58, -- Lower bound of sound volume.
|
||||||
|
VOLUME_CALIBRATION_MAX = 0x59, -- Upper bound of sound volume.
|
||||||
|
|
||||||
|
STORAGE_AREA_OFFSET = 0x60, -- Offset within the storage area to read/write to.
|
||||||
|
STORAGE_AREA = 0x61, -- Input/output byte for write/read operations in the storage area.
|
||||||
|
|
||||||
|
INFO = 0x7F, -- System information register.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Bitmasks for the reset event flags
|
||||||
|
reset_event_flags = {
|
||||||
|
RTC_TIME_LOST = 1 << 0, -- RTC time was lost (as is the case when the battery is removed).
|
||||||
|
WATCHDOG_RESET = 1 << 1, -- MCU Watchdog reset occurred.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Bitmasks for the power status
|
||||||
|
power_status_flags = {
|
||||||
|
SHELL_OPEN = 1 << 1, -- Set if the shell is open.
|
||||||
|
ADAPTER_CONNECTED = 1 << 3, -- Set if the AC adapter is connected.
|
||||||
|
CHARGING = 1 << 4, -- Set if the battery is charging.
|
||||||
|
BOTTOM_BL_ON = 1 << 5, -- Set if the bottom backlight is on.
|
||||||
|
TOP_BL_ON = 1 << 6, -- Set if the top backlight is on.
|
||||||
|
LCD_ON = 1 << 7 -- Set if the LCDs are on.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Bitmasks for the pedometer control
|
||||||
|
pedometer_control = {
|
||||||
|
CLEAR = 1 << 0, -- Clear the step history.
|
||||||
|
STEPS_FULL = 1 << 4 -- Set when the step history is full.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Bitmasks for the power signal triggers
|
||||||
|
power_trigger = {
|
||||||
|
SHUTDOWN = 1 << 0, -- Turn off the system.
|
||||||
|
RESET = 1 << 1, -- Reset the MCU.
|
||||||
|
REBOOT = 1 << 2, -- Reboot the system.
|
||||||
|
LGY_SHUTDOWN = 1 << 3, -- Turn off the system. (Used by LgyBg)
|
||||||
|
SLEEP = 1 << 4, -- Signal to enter sleep mode.
|
||||||
|
OLDMCU_BL_OFF = 1 << 4, -- (Old MCU_FIRM only) turn the backlights off.
|
||||||
|
OLDMCU_BL_ON = 1 << 5, -- (Old MCU_FIRM only) turn the backlights on.
|
||||||
|
OLDMCU_LCD_OFF = 1 << 6, -- (Old MCU_FIRM only) turn the LCDs off.
|
||||||
|
OLDMCU_LCD_ON = 1 << 7, -- (Old MCU_FIRM only) turn the LCDs on.
|
||||||
|
},
|
||||||
|
|
||||||
|
power_led_state = {
|
||||||
|
NORMAL = 0, -- Fade power LED to blue, while checking for battery percentage.
|
||||||
|
FADE_BLUE = 1, -- Fade power LED to blue.
|
||||||
|
SLEEP_MODE = 2, -- The power LED pulses blue slowly, as it does in sleep mode.
|
||||||
|
OFF = 3, -- Power LED fades off.
|
||||||
|
RED = 4, -- Power LED instantaneously turns red.
|
||||||
|
BLUE = 5, -- Power LED instantaneously turns blue.
|
||||||
|
BLINK_RED = 6, -- Power LED and info (notification) LED blink red, as they do when the battery is critically low.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- WiFi mode register values
|
||||||
|
wifi_mode = {
|
||||||
|
CTR = 0, -- 3DS WiFi mode.
|
||||||
|
MP = 1, -- DS[i] WiFi mode ("MP").
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Sensor configuration register values
|
||||||
|
sensor_config = {
|
||||||
|
ACCELEROMETER_ENABLE = 1 << 0, -- If set, the accelerometer is enabled.
|
||||||
|
PEDOMETER_ENABLE = 1 << 1, -- If set, the pedometer is enabled.
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Accelerometer scale settings
|
||||||
|
accelerometer_scale = {
|
||||||
|
SCALE_2G = 0x0, -- -2G to 2G
|
||||||
|
SCALE_4G = 0x1, -- -4G to 4G
|
||||||
|
SCALE_8G = 0x3, -- -8G to 8G
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i2c
|
||||||
@ -6,3 +6,4 @@ fs = require('fs')
|
|||||||
util = require('util')
|
util = require('util')
|
||||||
io = require('io')
|
io = require('io')
|
||||||
sys = require('sys')
|
sys = require('sys')
|
||||||
|
i2c = require('i2c')
|
||||||
|
|||||||
@ -1127,3 +1127,315 @@ Determines if the currently executing script was directly run, or was imported b
|
|||||||
> This is not well tested.
|
> This is not well tested.
|
||||||
|
|
||||||
* **Returns:** `true` if the current script was imported as a module
|
* **Returns:** `true` if the current script was imported as a module
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `i2c` module
|
||||||
|
|
||||||
|
#### i2c.dev ####
|
||||||
|
A list of devices for use with `i2c.read` and `i2c.write`
|
||||||
|
|
||||||
|
Lua | Value
|
||||||
|
-- | --
|
||||||
|
POWER | 0
|
||||||
|
POWER | 1
|
||||||
|
CAMERA2 | 2
|
||||||
|
MCU | 3
|
||||||
|
CAMERA3 | 4
|
||||||
|
LCD1 | 5
|
||||||
|
LCD2 | 6
|
||||||
|
GYRO3 | 9
|
||||||
|
GYRO | 10
|
||||||
|
GYRO2 | 11
|
||||||
|
DEBUG_PAD | 12
|
||||||
|
IR | 13
|
||||||
|
EEPROM | 14
|
||||||
|
NFC | 15
|
||||||
|
QTM | 16
|
||||||
|
N3DS_HID | 17
|
||||||
|
|
||||||
|
#### i2c.mcu ####
|
||||||
|
|
||||||
|
`i2c.mcu` contains registers and bitmasks for registers
|
||||||
|
|
||||||
|
##### i2c.mcu.reg #####
|
||||||
|
Contains some registers in the MCU
|
||||||
|
|
||||||
|
Lua | Value | Notes
|
||||||
|
-- | -- | --
|
||||||
|
VERSION_HIGH | 0x0 | Major version of the MCU firmware.
|
||||||
|
VERSION_LOW | 0x1 | Minor version of the MCU firmware.
|
||||||
|
RESET_EVENTS | 0x2 | @ref mcu.reset_event_flags
|
||||||
|
VCOM_TOP | 0x3 | Flicker/VCOM value for the top screen.
|
||||||
|
VCOM_BOTTOM | 0x4 | Flicker/VCOM value for the bottom screen.
|
||||||
|
FIRMWARE_UPLOAD_0 | 0x5 | Firmware upload register.
|
||||||
|
FIRMWARE_UPLOAD_1 | 0x6 | Firmware upload register.
|
||||||
|
FIRMWARE_UPLOAD_2 | 0x7 | Firmware upload register.
|
||||||
|
RAW_3D_SLIDER_POSITION | 0x8 | Position of the 3D slider.
|
||||||
|
VOLUME_SLIDER_POSITION | 0x9 | Position of the volume slider.
|
||||||
|
BATTERY_PCB_TEMPERATURE | 0xA | Temperature of the battery, measured on a sensor on the PCB.
|
||||||
|
BATTERY_PERCENTAGE_INT | 0xB | Integer part of the battery percentage.
|
||||||
|
BATTERY_PERCENTAGE_FRAC | 0xC | Fractional part of the battery percentage.
|
||||||
|
BATTERY_VOLTAGE | 0xD | Voltage of the battery, in units of 20 mV.
|
||||||
|
HW_STATUS | 0xE | Hardware status bits
|
||||||
|
POWER_STATUS | 0xF | @ref mcu.power_status_flags
|
||||||
|
LEGACY_VERSION_HIGH | 0xF | (Old MCU_FIRM only) Major firmware version.
|
||||||
|
LEGACY_VERSION_LOW | 0x10 | (Old MCU_FIRM only) Minor firmware version.
|
||||||
|
LEGACY_FIRM_UPLOAD | 0x3B | (Old MCU_FIRM only) Firmware upload register.
|
||||||
|
RECEIVED_IRQS_1 | 0x10 | Bitmask of received IRQs. @ref mcu.interrupt_1
|
||||||
|
RECEIVED_IRQS_2 | 0x11 | Bitmask of received IRQs. @ref mcu.interrupt_2
|
||||||
|
RECEIVED_IRQS_3 | 0x12 | Bitmask of received IRQs. @ref mcu.interrupt_3
|
||||||
|
RECEIVED_IRQS_4 | 0x13 | Bitmask of received IRQs. @ref mcu.interrupt_4
|
||||||
|
UNUSED_RO_14 | 0x14 | Unused read-only register.
|
||||||
|
USERDATA_RAM_15 | 0x15 | Unused register, supports writing
|
||||||
|
USERDATA_RAM_16 | 0x16 | Unused register, supports writing
|
||||||
|
USERDATA_RAM_17 | 0x17 | Unused register, supports writing
|
||||||
|
IRQ_MASK_1 | 0x18 | Bitmask of enabled IRQs. @ref mcu.interrupt_1
|
||||||
|
IRQ_MASK_2 | 0x19 | Bitmask of enabled IRQs. @ref mcu.interrupt_2
|
||||||
|
IRQ_MASK_3 | 0x1A | Bitmask of enabled IRQs. @ref mcu.interrupt_3
|
||||||
|
IRQ_MASK_4 | 0x1B | Bitmask of enabled IRQs. @ref mcu.interrupt_4
|
||||||
|
USERDATA_RAM_1C | 0x1C | Unused register, supports writing
|
||||||
|
USERDATA_RAM_1D | 0x1D | Unused register, supports writing
|
||||||
|
USERDATA_RAM_1E | 0x1E | Unused register, supports writing
|
||||||
|
USERDATA_RAM_1F | 0x1F | Unused register, supports writing
|
||||||
|
PWR_CTL | 0x20 | @ref mcu.power_trigger
|
||||||
|
LCD_PWR_CTL | 0x22 | LCD Power control
|
||||||
|
MCU_RESET_CTL | 0x23 | Writing 'r' to this register resets the MCU. Stubbed on retail.
|
||||||
|
FORCE_SHUTDOWN_DELAY | 0x24 | The amount of time, in units of 0.125s, for which the power button needs to be held to trigger a hard shutdown.
|
||||||
|
VOLUME_UNK_25 | 0x25 | Unknown register. Used in mcu::SND
|
||||||
|
UNK_26 | 0x26 | Unknown register. Used in mcu::CDC
|
||||||
|
VOLUME_SLIDER_RAW | 0x27 | Raw value of the volume slider, in the range of 0-255
|
||||||
|
LED_BRIGHTNESS_STATE | 0x28 | Brightness of the status LEDs.
|
||||||
|
POWER_LED_STATE | 0x29 | @ref mcu.power_led_state
|
||||||
|
WLAN_LED_STATE | 0x2A | Controls the WiFi LED.
|
||||||
|
CAMERA_LED_STATE | 0x2B | Controls the camera LED (on models that have one).
|
||||||
|
LED_3D_STATE | 0x2C | Controls the 3D LED (on models that have one).
|
||||||
|
NOTIFICATION_LED_STATE | 0x2D | Controls the info (notification) LED.
|
||||||
|
NOTIFICATION_LED_CYCLE_STATE | 0x2E | Bit 0 is set if the info (notification) LED has started a new cycle of its pattern.
|
||||||
|
RTC_TIME_SECOND | 0x30 | RTC second.
|
||||||
|
RTC_TIME_MINUTE | 0x31 | RTC minute.
|
||||||
|
RTC_TIME_HOUR | 0x32 | RTC hour.
|
||||||
|
RTC_TIME_WEEKDAY | 0x33 | RTC day of the week.
|
||||||
|
RTC_TIME_DAY | 0x34 | RTC day of the month.
|
||||||
|
RTC_TIME_MONTH | 0x35 | RTC month.
|
||||||
|
RTC_TIME_YEAR | 0x36 | RTC year.
|
||||||
|
RTC_TIME_CORRECTION | 0x37 | RTC subsecond (RSUBC) correction value.
|
||||||
|
RTC_ALARM_MINUTE | 0x38 | RTC alarm minute.
|
||||||
|
RTC_ALARM_HOUR | 0x39 | RTC alarm hour.
|
||||||
|
RTC_ALARM_DAY | 0x3A | RTC alarm day.
|
||||||
|
RTC_ALARM_MONTH | 0x3B | RTC alarm month.
|
||||||
|
RTC_ALARM_YEAR | 0x3C | RTC alarm year.
|
||||||
|
TICK_COUNTER_LSB | 0x3D | MCU tick counter value (low byte).
|
||||||
|
TICK_COUNTER_MSB | 0x3E | MCU tick counter value (high byte).
|
||||||
|
UNK_3F | 0x3F | Unknown register
|
||||||
|
SENSOR_CONFIG | 0x40 | @ref mcu.sensor_config
|
||||||
|
ACCELEROMETER_MANUAL_REGID_R | 0x41 | Hardware register ID for use in manual accelerometer I²C reads.
|
||||||
|
ACCELEROMETER_MANUAL_REGID_W | 0x43 | Hardware reigster ID for use in manual accelerometer I²C writes.
|
||||||
|
ACCELEROMETER_MANUAL_IO | 0x44 | Data register for manual accelerometer reads/writes.
|
||||||
|
ACCELEROMETER_OUTPUT_X_LSB | 0x45 | Accelerometer X coordinate (low byte).
|
||||||
|
ACCELEROMETER_OUTPUT_X_MSB | 0x46 | Accelerometer X coordinate (high byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Y_LSB | 0x47 | Accelerometer Y coordinate (low byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Y_MSB | 0x48 | Accelerometer Y coordinate (high byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Z_LSB | 0x49 | Accelerometer Z coordinate (low byte).
|
||||||
|
ACCELEROMETER_OUTPUT_Z_MSB | 0x4A | Accelerometer Z coordinate (high byte).
|
||||||
|
PEDOMETER_STEPS_LOWBYTE | 0x4B | Pedometer step count (low byte).
|
||||||
|
PEDOMETER_STEPS_MIDDLEBYTE | 0x4C | Pedometer step count (middle byte).
|
||||||
|
PEDOMETER_STEPS_HIGHBYTE | 0x4D | Pedometer step count (high byte).
|
||||||
|
PEDOMETER_CNT | 0x4E | @ref mcu.pedometer_control
|
||||||
|
PEDOMETER_STEP_DATA | 0x4F | Step history and time of last update.
|
||||||
|
PEDOMETER_WRAP_MINUTE | 0x50 | The minute within each RTC hour at which the step history should roll into the next hour.
|
||||||
|
PEDOMETER_WRAP_SECOND | 0x51 | The second within each RTC hour at which the step history should roll into the next hour.
|
||||||
|
VOLUME_CALIBRATION_MIN | 0x58 | Lower bound of sound volume.
|
||||||
|
VOLUME_CALIBRATION_MAX | 0x59 | Upper bound of sound volume.
|
||||||
|
STORAGE_AREA_OFFSET | 0x60 | Offset within the storage area to read/write to.
|
||||||
|
STORAGE_AREA | 0x61 | Input/output byte for write/read operations in the storage area.
|
||||||
|
INFO | 0x7F | System information register.
|
||||||
|
|
||||||
|
##### i2c.mcu.interrupt_1 #####
|
||||||
|
Bitmask for interrupts (1)
|
||||||
|
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
POWER_BUTTON_PRESS | 0 | The power button was pressed
|
||||||
|
POWER_BUTTON_HELD | 1 | The power button was held
|
||||||
|
HOME_BUTTON_PRESS | 2 | The HOME button was pressed
|
||||||
|
HOME_BUTTON_RELEASE | 3 | The HOME button was released
|
||||||
|
WLAN_SWITCH_TRIGGER | 4 | The WiFi switch was triggered
|
||||||
|
SHELL_CLOSE | 5 | The shell was closed (or sleep switch turned off)
|
||||||
|
SHELL_OPEN | 6 | The shell was opened (or sleep switch turned on)
|
||||||
|
FATAL_HW_ERROR | 7 | MCU watchdog reset occurred
|
||||||
|
|
||||||
|
##### i2c.mcu.interrupt_2 #####
|
||||||
|
Bitmask for interrupts (2)
|
||||||
|
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
AC_ADAPTER_REMOVED | 0 | The AC adapter was disconnected
|
||||||
|
AC_ADAPTER_PLUGGED_IN | 1 | The AC adapter was connected
|
||||||
|
RTC_ALARM | 2 | The RTC alarm time has been reached
|
||||||
|
ACCELEROMETER_I2C_MANUAL_IO | 3 | The manual accelerometer I²C read/write operation has completed
|
||||||
|
ACCELEROMETER_NEW_SAMPLE | 4 | A new accelerometer sample is available
|
||||||
|
CRITICAL_BATTERY | 5 | The battery is critically low
|
||||||
|
CHARGING_STOP | 6 | The battery stopped charging
|
||||||
|
CHARGING_START | 7 | The battery started charging
|
||||||
|
|
||||||
|
|
||||||
|
##### i2c.mcu.interrupt_3 #####
|
||||||
|
Bitmask for interrupts (3)
|
||||||
|
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
VOL_SLIDER | 6 | The position of the volume slider changed
|
||||||
|
|
||||||
|
|
||||||
|
##### i2c.mcu.interrupt_4 #####
|
||||||
|
Bitmask for interrupts (4)
|
||||||
|
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
LCD_OFF | 0 | The LCDs turned off.
|
||||||
|
LCD_ON | 1 | The LCDs turned on.
|
||||||
|
BOT_BACKLIGHT_OFF | 2 | The bottom screen backlight turned off.
|
||||||
|
BOT_BACKLIGHT_ON | 3 | The bottom screen backlight turned on.
|
||||||
|
TOP_BACKLIGHT_OFF | 4 | The top screen backlight turned off.
|
||||||
|
TOP_BACKLIGHT_ON | 5 | The top screen backlight turned on.
|
||||||
|
|
||||||
|
##### i2c.mcu.reset_event_flags #####
|
||||||
|
Bitmasks for the reset event flags
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
RTC_TIME_LOST | 0 | RTC time was lost (as is the case when the battery is removed).
|
||||||
|
WATCHDOG_RESET | 1 | MCU Watchdog reset occurred.
|
||||||
|
|
||||||
|
##### i2c.mcu.power_status_flags #####
|
||||||
|
Bitmasks for the power status
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
SHELL_OPEN | 1 | Set if the shell is open.
|
||||||
|
ADAPTER_CONNECTED | 3 | Set if the AC adapter is connected.
|
||||||
|
CHARGING | 4 | Set if the battery is charging.
|
||||||
|
BOTTOM_BL_ON | 5 | Set if the bottom backlight is on.
|
||||||
|
TOP_BL_ON | 6 | Set if the top backlight is on.
|
||||||
|
LCD_ON | 7 | Set if the LCDs are on.
|
||||||
|
|
||||||
|
##### i2c.mcu.pedometer_control #####
|
||||||
|
Bitmasks for the pedometer control
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
CLEAR | 0 | Clear the step history.
|
||||||
|
STEPS_FULL | 4 | Set when the step history is full.
|
||||||
|
|
||||||
|
##### i2c.mcu.power_trigger #####
|
||||||
|
Bitmasks for the power signal triggers
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
SHUTDOWN | 0 | Turn off the system.
|
||||||
|
RESET | 1 | Reset the MCU.
|
||||||
|
REBOOT | 2 | Reboot the system.
|
||||||
|
LGY_SHUTDOWN | 3 | Turn off the system. (Used by LgyBg)
|
||||||
|
SLEEP | 4 | Signal to enter sleep mode.
|
||||||
|
OLDMCU_BL_OFF | 4 | (Old MCU_FIRM only) turn the backlights off.
|
||||||
|
OLDMCU_BL_ON | 5 | (Old MCU_FIRM only) turn the backlights on.
|
||||||
|
OLDMCU_LCD_OFF | 6 | (Old MCU_FIRM only) turn the LCDs off.
|
||||||
|
OLDMCU_LCD_ON | 7 | (Old MCU_FIRM only) turn the LCDs on.
|
||||||
|
|
||||||
|
##### i2c.mcu.power_led_state #####
|
||||||
|
Lua | Value | Notes
|
||||||
|
-- | -- | --
|
||||||
|
NORMAL | 0 | Fade power LED to blue, while checking for battery percentage.
|
||||||
|
FADE_BLUE | 1 | Fade power LED to blue.
|
||||||
|
SLEEP_MODE | 2 | The power LED pulses blue slowly, as it does in sleep mode.
|
||||||
|
OFF | 3 | Power LED fades off.
|
||||||
|
RED | 4 | Power LED instantaneously turns red.
|
||||||
|
BLUE | 5 | Power LED instantaneously turns blue.
|
||||||
|
BLINK_RED | 6 | Power LED and info (notification) LED blink red, as they do when the battery is critically low.
|
||||||
|
|
||||||
|
##### i2c.mcu.wifi_mode #####
|
||||||
|
WiFi mode register values
|
||||||
|
Lua | Value | Notes
|
||||||
|
-- | -- | --
|
||||||
|
CTR | 0 | 3DS WiFi mode.
|
||||||
|
MP | 1 | DS[i] WiFi mode ("MP").
|
||||||
|
|
||||||
|
##### i2c.mcu.sensor_config #####
|
||||||
|
Sensor configuration register values
|
||||||
|
Lua | Bit | Notes
|
||||||
|
-- | -- | --
|
||||||
|
ACCELEROMETER_ENABLE | 0 | If set, the accelerometer is enabled.
|
||||||
|
PEDOMETER_ENABLE | 1 | If set, the pedometer is enabled.
|
||||||
|
|
||||||
|
##### i2c.mcu.accelerometer_scale #####
|
||||||
|
Accelerometer scale settings
|
||||||
|
Lua | Value | Notes
|
||||||
|
-- | -- | --
|
||||||
|
SCALE_2G | 0x0 | -2G to 2G
|
||||||
|
SCALE_4G | 0x1 | -4G to 4G
|
||||||
|
SCALE_8G | 0x3 | -8G to 8G
|
||||||
|
|
||||||
|
|
||||||
|
#### i2c.read
|
||||||
|
|
||||||
|
* `table i2c.read(int device_id, int register_address, int length)`
|
||||||
|
|
||||||
|
Read data from an I²C device register. Returns the data as a table of integers (0-255) for direct math operations.
|
||||||
|
|
||||||
|
* **Arguments**
|
||||||
|
* `device_id` - I²C device ID (0-17).
|
||||||
|
* `register_address` - Register address to read from (0-255)
|
||||||
|
* `length` - Number of bytes to read (1-64)
|
||||||
|
* **Returns:** Table of byte values as integers
|
||||||
|
* **Throws**
|
||||||
|
* `"Invalid device ID: ## (must be 0-17)"` - device ID is outside valid range
|
||||||
|
* `"Invalid register address: ## (must be 0-255)"` - register address is outside valid range
|
||||||
|
* `"Invalid length: ## (must be 1-64)"` - length is outside valid range
|
||||||
|
* `"I2C read failed"` - hardware I²C operation failed
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```lua
|
||||||
|
-- Read voltage from MCU device
|
||||||
|
local voltage_raw = i2c.read(i2c.dev.MCU, i2c.mcu.reg.BATTERY_VOLTAGE, 1)
|
||||||
|
local voltage = voltage_raw[1] * 5 / 256.0
|
||||||
|
print("System voltage:", voltage, "V")
|
||||||
|
|
||||||
|
-- Read Power status
|
||||||
|
local power_state = i2c.read(i2c.dev.MCU, i2c.mcu.reg.POWER_STATUS, 1)
|
||||||
|
if power_state[1] & i2c.mcu.power_status_flags.SHELL_OPEN ~= 0 then
|
||||||
|
print("Shell is open")
|
||||||
|
end
|
||||||
|
if power_state[1] & i2c.mcu.power_status_flags.CHARGING ~= 0 then
|
||||||
|
print("Charging")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### i2c.write
|
||||||
|
|
||||||
|
* `void i2c.write(int device_id, int register_address, table data)`
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Writing data to random registers can lead to bricking!.
|
||||||
|
|
||||||
|
Write data to an I²C device register. Requires memory write permissions.
|
||||||
|
Not all registers are supported for writing.
|
||||||
|
|
||||||
|
* **Allowed registers (MCU)**
|
||||||
|
* `mcu.reg.USERDATA_RAM_` - Registers 0x15-0x17 and 0x1C-0x1F
|
||||||
|
* `mcu.reg.LED_BRIGHTNESS_STATE` - Brightness of the status LEDs.
|
||||||
|
* `mcu.reg.POWER_LED_STATE` - Sets the state of the power LED
|
||||||
|
* `mcu.reg.WLAN_LED_STATE` - Sets the state of the wifi LED
|
||||||
|
* `mcu.reg.CAMERA_LED_STATE` - Sets the state of the camera LED
|
||||||
|
* `mcu.reg.LED_3D_STATE` - Sets the state of the 3D LED
|
||||||
|
* `mcu.reg.NOTIFICATION_LED_STATE` - Sets the state of the info (notification) LED
|
||||||
|
* **Arguments**
|
||||||
|
* `device_id` - I²C device ID (0-17).
|
||||||
|
* `register_address` - Register address to write to (0-255)
|
||||||
|
* `data` - Table of byte values to write (each value must be 0-255)
|
||||||
|
* **Throws**
|
||||||
|
* `"Invalid device ID: ## (must be 0-17)"` - device ID is outside valid range
|
||||||
|
* `"Invalid register address: ## (must be 0-255)"` - register address is outside valid range
|
||||||
|
* `"Write to device ##, register ## is not allowed"` - The device/register is not on the allowed write list
|
||||||
|
* `"Third parameter must be a table of byte values"` - data parameter is not a table
|
||||||
|
* `"Invalid data length: ## (must be 1-64)"` - data table length is outside valid range
|
||||||
|
* `"Table element ## is not an integer"` - data table contains non-integer values
|
||||||
|
* `"Table element ## is out of range: ## (must be 0-255)"` - data table contains values outside byte range
|
||||||
|
* `"I2C write failed"` - hardware I²C operation failed
|
||||||
|
* Permission errors if memory write access is denied
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user