Compare commits

..

10 Commits

Author SHA1 Message Date
CTCaer
57623acc99 Bump hekate to v5.5.7 and Nyx to v1.0.4 2021-06-08 06:06:26 +03:00
CTCaer
4f8d29d0b7 pkg2: Add HOS 12.0.3 support
In 12.0.3 only FS is the relevant change.

So add support for 12.0.3 emuMMC and NOGC
2021-06-08 06:05:12 +03:00
CTCaer
8eda2d805f nyx: explicitly state if fuses are overburnt 2021-06-08 05:57:39 +03:00
CTCaer
432d4a4ffa Use bit_count for burnt fuses counting 2021-06-08 05:57:00 +03:00
CTCaer
539caf3d83 utils: add bit count and bit count mask 2021-06-08 05:53:58 +03:00
CTCaer
ce6926c36c fuse: remove fuse counting, bit count will be used instead 2021-06-08 05:53:31 +03:00
CTCaer
8058d550ab nyx: reflect 5v regulator changes 2021-06-08 05:51:52 +03:00
CTCaer
9a21ff6976 regulator 5v: don't enable usb one by default 2021-06-08 05:51:21 +03:00
CTCaer
1f4f41b6e6 als: Update ambient light sensor driver to use integers
Additionally separate calibration so later Aula one can be used
2021-06-08 05:49:16 +03:00
CTCaer
a959196c2a Add info about usb3force key in readme
Additionally explain what atmosphere config keys can affect hekate boot configuration externally when the equivalent ones are missing from hekate config.
2021-06-03 03:25:51 +03:00
17 changed files with 190 additions and 115 deletions

View File

@@ -99,6 +99,15 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| icon={SD path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise default will be used. |
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
### Boot entry key/value Exosphère combinations:
| Config option | Description |
@@ -107,15 +116,13 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
| usb3force=1 | Overrides system settings mitm config `usb30_force_enabled`. If that key doesn't exist, `system_settings.ini` will be used. |
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
**Warning**: Never define *fss0 core* kips when using `fss0` and make sure that the folder (when using `/*`), does not include them.
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
**Note2**: `blank_prodinfo_{sys/emu}mmc`, `allow_writing_to_cal_sysmmc` and `usb30_force_enabled` in `exosphere.ini` and `system_settings.ini` respectively, are the only atmosphere config keys that can affect hekate booting configuration externally, **if** the equivalent keys in hekate config are missing.
### Payload storage:

View File

@@ -1,11 +1,11 @@
# IPL Version.
BLVERSION_MAJOR := 5
BLVERSION_MINOR := 5
BLVERSION_HOTFX := 6
BLVERSION_HOTFX := 7
BLVERSION_RSVD := 0
# Nyx Version.
NYXVERSION_MAJOR := 1
NYXVERSION_MINOR := 0
NYXVERSION_HOTFX := 3
NYXVERSION_HOTFX := 4
NYXVERSION_RSVD := 0

View File

@@ -23,79 +23,117 @@
#include <soc/pinmux.h>
#include <utils/util.h>
#define HOS_GAIN BH1730_GAIN_64X
#define HOS_ITIME 38
#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X
#define BH1730_DEFAULT_ICYCLE 38
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime)
#define BH1730_INTERNAL_CLOCK_NS 2800
#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
#define BH1730_DEFAULT_ITIME_MS 100
#define BH1730_LUX_MULTIPLIER 3600
#define BH1730_LUX_MULTIPLIER_AULA 1410
#define BH1730_LUX_MAX 100000
typedef struct _opt_win_cal_t
{
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - itime));
u32 rc;
u32 cv;
u32 ci;
} opt_win_cal_t;
als_val->gain = gain;
als_val->itime = itime;
// Nintendo Switch Icosa/Iowa Optical Window calibration.
const opt_win_cal_t opt_win_cal_default[] = {
{ 500, 5002, 7502 },
{ 754, 2250, 2000 },
{ 1029, 1999, 1667 },
{ 1373, 884, 583 },
{ 1879, 309, 165 }
};
// Nintendo Switch Aula Optical Window calibration.
const opt_win_cal_t opt_win_cal_aula[] = {
{ 231, 9697, 30300 },
{ 993, 3333, 2778 },
{ 1478, 1621, 1053 },
{ 7500, 81, 10 }
};
const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
{
if (gain > BH1730_GAIN_128X)
gain = BH1730_GAIN_128X;
if (!cycle)
cycle = 1;
else if (cycle > 255)
cycle = 255;
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
als_ctxt->gain = gain;
als_ctxt->cycle = cycle;
}
void get_als_lux(als_table_t *als_val)
void get_als_lux(als_ctxt_t *als_ctxt)
{
u32 data[2];
float pre_gain_lux;
float visible_light;
float ir_light;
float light_ratio;
u32 visible_light;
u32 ir_light;
u64 lux = 0;
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
u8 adc_ready = 0;
u8 retries = 100;
const float als_gain_idx_tbl[4] = { 1.0, 2.0, 64.0, 128.0 };
const float als_norm_res = 100.0;
const float als_multiplier = 3.6;
const float als_tint = 2.7;
// Wait for ADC to prepare new data.
while (!(adc_ready & BH1730_CTL_ADC_VALID) && retries)
{
retries--;
adc_ready = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG));
}
// Get visible and ir light raw data.
// Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
als_val->over_limit = data[0] > 65534 || data[1] > 65534;
als_val->vi_light = data[0];
als_val->ir_light = data[1];
visible_light = data[0];
ir_light = data[1];
if (!data[0] || !retries)
als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534;
als_ctxt->vi_light = visible_light;
als_ctxt->ir_light = ir_light;
if (!visible_light)
{
als_val->lux = 0.0;
als_ctxt->lux = 0;
return;
}
visible_light = (float)data[0];
ir_light = (float)data[1];
light_ratio = (float)data[1] / (float)data[0];
// Set calibration parameters.
u32 lux_multiplier = BH1730_LUX_MULTIPLIER;
u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default);
const opt_win_cal_t *opt_win_cal = opt_win_cal_default;
// The following are specific to the light filter Switch uses.
if (light_ratio < 0.5)
pre_gain_lux = visible_light * 5.002 - ir_light * 7.502;
else if (light_ratio < 0.754)
pre_gain_lux = visible_light * 2.250 - ir_light * 2.000;
else if (light_ratio < 1.029)
pre_gain_lux = visible_light * 1.999 - ir_light * 1.667;
else if (light_ratio < 1.373)
pre_gain_lux = visible_light * 0.884 - ir_light * 0.583;
else if (light_ratio < 1.879)
pre_gain_lux = visible_light * 0.309 - ir_light * 0.165;
else pre_gain_lux = 0.0;
// Apply optical window calibration coefficients.
for (u32 i = 0; i < opt_win_cal_count; i++)
{
if (1000 * ir_light / visible_light < opt_win_cal[i].rc)
{
lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
break;
}
}
als_val->lux = (pre_gain_lux / als_gain_idx_tbl[als_val->gain]) * (als_norm_res / ((float)als_val->itime * als_tint)) * als_multiplier;
lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier;
lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us;
lux /= 1000;
if (lux > BH1730_LUX_MAX)
lux = BH1730_LUX_MAX;
als_ctxt->lux = lux;
}
u8 als_init(als_table_t *als_val)
u8 als_power_on(als_ctxt_t *als_ctxt)
{
// Enable power to ALS IC.
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
@@ -109,12 +147,10 @@ u8 als_init(als_table_t *als_val)
// Initialize ALS.
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), HOS_GAIN);
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - HOS_ITIME));
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
als_val->gain = HOS_GAIN;
als_val->itime = HOS_ITIME;
set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE);
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
return id;
}

View File

@@ -48,18 +48,18 @@
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
typedef struct _als_table_t
typedef struct _als_ctxt_t
{
float lux;
u32 lux;
bool over_limit;
u32 vi_light;
u32 ir_light;
u8 gain;
u8 itime;
} als_table_t;
u32 vi_light;
u32 ir_light;
u8 gain;
u8 cycle;
} als_ctxt_t;
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime);
void get_als_lux(als_table_t *als_val);
u8 als_init(als_table_t *als_val);
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle);
void get_als_lux(als_ctxt_t *als_ctxt);
u8 als_power_on(als_ctxt_t *als_ctxt);
#endif /* __ALS_H_ */

View File

@@ -21,25 +21,25 @@
#include <utils/types.h>
static u8 reg_5v_dev = 0;
static bool batt_src = false;
static bool usb_src = false;
void regulator_5v_enable(u8 dev)
{
// The power supply selection from battery or USB is automatic.
if (!reg_5v_dev)
{
// Fan and Rail power from internal 5V regulator (battery).
// Fan and Rail power from battery 5V regulator.
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = 1;
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
batt_src = true;
// Fan and Rail power from USB 5V VDD.
// Fan and Rail power from USB 5V VBUS.
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_LPDR | 1;
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_GPIO);
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_ENABLE);
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
usb_src = false;
// Make sure GPIO power is enabled.
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_GPIO_IO_EN;
@@ -55,18 +55,18 @@ void regulator_5v_disable(u8 dev)
if (!reg_5v_dev)
{
// Rail power from internal 5V regulator (battery).
// Rail power from battery 5V regulator.
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
gpio_output_enable(GPIO_PORT_A, GPIO_PIN_5, GPIO_OUTPUT_DISABLE);
gpio_config(GPIO_PORT_A, GPIO_PIN_5, GPIO_MODE_SPIO);
PINMUX_AUX(PINMUX_AUX_SATA_LED_ACTIVE) = PINMUX_PARKED | PINMUX_INPUT_ENABLE;
batt_src = false;
// Rail power from USB 5V VDD.
// Rail power from USB 5V VBUS.
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
gpio_config(GPIO_PORT_CC, GPIO_PIN_4, GPIO_MODE_SPIO);
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN0) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_PARKED | PINMUX_INPUT_ENABLE;
usb_src = false;
// GPIO AO IO rails.
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_GPIO_IO_EN;
@@ -78,16 +78,16 @@ bool regulator_5v_get_dev_enabled(u8 dev)
return (reg_5v_dev & dev);
}
void regulator_5v_batt_src_enable(bool enable)
void regulator_5v_usb_src_enable(bool enable)
{
if (enable && !batt_src)
if (enable && !usb_src)
{
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_HIGH);
batt_src = true;
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_HIGH);
usb_src = true;
}
else if (!enable && batt_src)
else if (!enable && usb_src)
{
gpio_write(GPIO_PORT_A, GPIO_PIN_5, GPIO_LOW);
batt_src = false;
gpio_write(GPIO_PORT_CC, GPIO_PIN_4, GPIO_LOW);
usb_src = false;
}
}

View File

@@ -30,6 +30,6 @@ enum
void regulator_5v_enable(u8 dev);
void regulator_5v_disable(u8 dev);
bool regulator_5v_get_dev_enabled(u8 dev);
void regulator_5v_batt_src_enable(bool enable);
void regulator_5v_usb_src_enable(bool enable);
#endif

View File

@@ -121,18 +121,6 @@ u32 fuse_read_hw_type()
return FUSE_NX_HW_TYPE_ICOSA;
}
u8 fuse_count_burnt(u32 val)
{
u8 burnt_fuses = 0;
for (u32 i = 0; i < 32; i++)
{
if ((val >> i) & 1)
burnt_fuses++;
}
return burnt_fuses;
}
void fuse_wait_idle()
{
u32 ctrl;

View File

@@ -97,7 +97,6 @@ u32 fuse_read_odm_keygen_rev();
u32 fuse_read_dramid(bool raw_id);
u32 fuse_read_hw_state();
u32 fuse_read_hw_type();
u8 fuse_count_burnt(u32 val);
void fuse_wait_idle();
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);

View File

@@ -30,6 +30,27 @@
extern volatile nyx_storage_t *nyx_str;
u8 bit_count(u32 val)
{
u8 cnt = 0;
for (u32 i = 0; i < 32; i++)
{
if ((val >> i) & 1)
cnt++;
}
return cnt;
}
u32 bit_count_mask(u8 bits)
{
u32 val = 0;
for (u32 i = 0; i < bits; i++)
val |= 1 << i;
return val;
}
u32 get_tmr_s()
{
return RTC(APBDEV_RTC_SECONDS);

View File

@@ -84,6 +84,9 @@ typedef struct _nyx_storage_t
emc_table_t mtc_table[10];
} nyx_storage_t;
u8 bit_count(u32 val);
u32 bit_count_mask(u8 bits);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);

View File

@@ -61,7 +61,7 @@ void print_fuseinfo()
break;
}
gfx_printf("Sdram ID: %d\n", fuse_read_dramid(true));
gfx_printf("Burnt fuses: %d / 64\n", fuse_count_burnt(fuse_read_odm(7)));
gfx_printf("Burnt fuses: %d / 64\n", bit_count(fuse_read_odm(7)));
gfx_printf("Secure key: %08X%08X%08X%08X\n\n\n",
byte_swap_32(FUSE(FUSE_PRIVATE_KEY0)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY1)),
byte_swap_32(FUSE(FUSE_PRIVATE_KEY2)), byte_swap_32(FUSE(FUSE_PRIVATE_KEY3)));

View File

@@ -609,7 +609,7 @@ try_load:
// Try backup bootloader.
if (bootloader_offset != BOOTLOADER_BACKUP_OFFSET)
{
EPRINTF("Trying backup bootloader...");
EPRINTF("\nTrying backup bootloader...");
bootloader_offset = BOOTLOADER_BACKUP_OFFSET;
goto try_load;
}

View File

@@ -32,6 +32,7 @@
#include <soc/t210.h>
#include <storage/nx_sd.h>
#include <utils/aarch64_util.h>
#include <utils/util.h>
extern hekate_config h_cfg;
@@ -355,7 +356,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base)
u32 pa_id;
u32 fuses_max = 32; // Current ODM7 max.
u32 fuses_fw = ctxt->pkg1_id->fuses;
u8 burnt_fuses = fuse_count_burnt(fuse_read_odm(7));
u8 burnt_fuses = bit_count(fuse_read_odm(7));
// Save current warmboot in storage cache (MWS) and check if another one is needed.
if (!ctxt->warmboot)

View File

@@ -684,6 +684,20 @@ static kip1_patchset_t _fs_patches_1200[] =
{ NULL, NULL }
};
static kip1_patch_t _fs_nogc_1203[] =
{
{ KPS(KIP_TEXT) | 0x13EB34, 8, "\xFD\x7B\xBE\xA9\xF4\x4F\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ KPS(KIP_TEXT) | 0x155478, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};
static kip1_patchset_t _fs_patches_1203[] =
{
{ "nogc", _fs_nogc_1203 },
{ "emummc", _fs_emummc },
{ NULL, NULL }
};
// SHA256 hashes.
static kip1_id_t _kip_ids[] =
{
@@ -727,4 +741,6 @@ static kip1_id_t _kip_ids[] =
{ "FS", "\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", _fs_patches_1100 }, // FS 11.0.0 exfat
{ "FS", "\xDC\x2A\x08\x49\x96\xBB\x3C\x01", _fs_patches_1200 }, // FS 12.0.0
{ "FS", "\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", _fs_patches_1200 }, // FS 12.0.0 exfat
{ "FS", "\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", _fs_patches_1203 }, // FS 12.0.3
{ "FS", "\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", _fs_patches_1203 }, // FS 12.0.3 exfat
};

View File

@@ -1514,7 +1514,7 @@ ment_t ment_top[] = {
MDEF_END()
};
menu_t menu_top = { ment_top, "hekate v5.5.6", 0, 0 };
menu_t menu_top = { ment_top, "hekate v5.5.7", 0, 0 };
extern void pivot_stack(u32 stack_top);

View File

@@ -1262,14 +1262,9 @@ static void _update_status_bar(void *params)
else
strcat(label, "#FF3C28 "SYMBOL_BATTERY_EMPTY"#");
// Set charging symbol and regulator 5V source based on USB state.
// Set charging symbol.
if (charge_status)
{
strcat(label, " #FFDD00 "SYMBOL_CHARGE"#");
regulator_5v_batt_src_enable(false);
}
else
regulator_5v_batt_src_enable(true);
lv_label_set_text(status_bar.battery, label);
lv_obj_realign(status_bar.battery);

View File

@@ -686,11 +686,17 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
}
// Count burnt fuses.
u8 burnt_fuses_7 = fuse_count_burnt(fuse_read_odm(7));
u8 burnt_fuses_6 = fuse_count_burnt(fuse_read_odm(6));
u8 burnt_fuses_7 = bit_count(fuse_read_odm(7));
u8 burnt_fuses_6 = bit_count(fuse_read_odm(6));
switch (burnt_fuses_7)
// Check if overburnt.
u8 burnt_fuses_hos = (fuse_read_odm(7) & ~bit_count_mask(burnt_fuses_7)) ? 255 : burnt_fuses_7;
switch (burnt_fuses_hos)
{
case 0:
strcpy(fuses_hos_version, "#96FF00 Golden sample#");
break;
case 1:
strcpy(fuses_hos_version, "1.0.0");
break;
@@ -736,6 +742,9 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
case 15:
strcpy(fuses_hos_version, "12.0.2+");
break;
case 255:
strcpy(fuses_hos_version, "#FFD000 Overburnt#");
break;
default:
strcpy(fuses_hos_version, "#FF8000 Unknown#");
break;
@@ -936,7 +945,7 @@ static lv_res_t _create_window_fuses_info_status(lv_obj_t *btn)
break;
}
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# [%02X] %02X [%02X]",
s_printf(txt_buf + strlen(txt_buf), "\n#FF8000 ID:# #96FF00 %02X# %02X #96FF00 %02X#",
nyx_str->info.disp_id & 0xFF, (nyx_str->info.disp_id >> 8) & 0xFF, (nyx_str->info.disp_id >> 16) & 0xFF);
touch_fw_info_t touch_fw;