Skip to content

Commit

Permalink
add option that will update user row to enable smarteeprom
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandre d'Alton <alex@alexdalton.org>
  • Loading branch information
daltona committed Jan 4, 2020
1 parent caa03ed commit 7bbec3c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
74 changes: 74 additions & 0 deletions mdloader_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,65 @@ int test_mcu(char silent)
return 1;
}

#define DSU 0x41002000
#define DSU_STATUSB (DSU + 2)

#define NVMCTRL 0x41004000
#define NVMCTRL_CTRLA (NVMCTRL)
#define NVMCTRL_CTRLB (NVMCTRL + 4)
#define NVMCTRL_ADDR (NVMCTRL + 0x14)

#define NVMCTRL_CTRLB_CMDEX_KEY 0xA500
#define NVMCTRL_CTRLB_CMD_WQW 0x4
#define NVMCTRL_CTRLB_CMD_PBC 0x15
#define NVMCTRL_CTRLB_CMD_EP 0x0

#define NVMCTRL_USER 0x00804000

int write_user_row(uint32_t *data)
{
uint16_t status = read_half_word(DSU_STATUSB);
printf("dsu statusb: %08x\n", status);
write_half_word(DSU_STATUSB, status);

uint32_t cfg = read_word(NVMCTRL_CTRLA); /* clear nvm interrupt status bits */
printf("nvm config: %08x\n", cfg);
cfg &= ~(0xf0);
write_word(NVMCTRL_CTRLA, cfg);

write_word(NVMCTRL_ADDR, NVMCTRL_USER); /* set user row address */
write_half_word(NVMCTRL_CTRLB, (NVMCTRL_CTRLB_CMDEX_KEY|NVMCTRL_CTRLB_CMD_EP)); /* erase page */
slp(100);
write_half_word(NVMCTRL_CTRLB, (NVMCTRL_CTRLB_CMDEX_KEY|NVMCTRL_CTRLB_CMD_PBC)); /* erase write buffer */
slp(100);
for(int i = 0; i < 4; i++) {
write_word(NVMCTRL_USER + i * 4, data[i]); /* write in the write buffer */
}
write_word(NVMCTRL_ADDR, NVMCTRL_USER); /* set user row address */
write_half_word(NVMCTRL_CTRLB, (NVMCTRL_CTRLB_CMDEX_KEY|NVMCTRL_CTRLB_CMD_WQW)); /* program quad word (128bits) */
slp(100);
return 0;
}

int read_user_row(void)
{
uint32_t user_row[4];
printf("user row: ");
for (int i = 0; i < 4; i++) {
user_row[i] = read_word(0x804000 + i * 4);
printf("0x%08x ", user_row[i]);
}
printf("\n");
if ((user_row[1] & 0x7f) != 0x12) {
printf("SmartEEPROM not configured, proceed\n");
user_row[1] |= (0x12);
write_user_row(user_row);
} else {
printf("SmartEEPROM already configured\n");
}
return 0;
}

//Upper case any lower case characters in a string
void strlower(char *str)
{
Expand Down Expand Up @@ -465,6 +524,7 @@ void display_help(void)
printf(" -s --size size Read firmware size of <size>\n");
printf(" -D --download file Write firmware from <file> into device\n");
printf(" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n");
printf(" --smarteep Enable Smart EEPROM MCU feature\n");
printf(" --cols count Hex listing column count <count> [%i]\n", COLS);
printf(" --colw width Hex listing column width <width> [%i]\n", COLW);
printf(" --restart Restart device after successful programming\n");
Expand All @@ -473,6 +533,7 @@ void display_help(void)

#define SW_COLS 1000
#define SW_COLW 1001
#define SW_SMARTEEP 1002

//Program command line options
struct option long_options[] = {
Expand All @@ -490,6 +551,7 @@ struct option long_options[] = {
{ "addr", required_argument, 0, 'a' },
{ "size", required_argument, 0, 's' },
{ "test", no_argument, 0, 't' },
{ "smarteep", no_argument, 0, SW_SMARTEEP },
{ "cols", required_argument, 0, SW_COLS },
{ "colw", required_argument, 0, SW_COLW },
{ 0, 0, 0, 0 }
Expand Down Expand Up @@ -603,6 +665,10 @@ int main(int argc, char *argv[])
testmode = 1;
break;

case SW_SMARTEEP:
command = CMD_READ_USER_ROW;
break;

case SW_COLS:
hex_cols = atoi(optarg);
if (hex_cols < 1)
Expand Down Expand Up @@ -726,6 +792,14 @@ int main(int argc, char *argv[])
print_bootloader_version();
if (verbose) printf("Device ID: %08X\n", mcu->cidr);

if (command == CMD_READ_USER_ROW)
{
read_user_row();
goto exitProgram;
}



//Load applet
FILE *fIn;
char appletfname[128] = "";
Expand Down
4 changes: 3 additions & 1 deletion mdloader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ enum command {
CMD_DOWNLOAD,
CMD_UPLOAD,
CMD_TEST,
CMD_ABORT
CMD_ABORT,
CMD_READ_USER_ROW
};

extern struct option long_options[];
Expand Down Expand Up @@ -181,6 +182,7 @@ int write_data(int addr, int writesize, int data);
void list_devices(char *first);
void strupper(char *str);
void strlower(char *str);
int read_user_row(void);

#endif //_MDLOADER_COMMON_H

1 comment on commit 7bbec3c

@larsks
Copy link

@larsks larsks commented on 7bbec3c Apr 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi there; I found my way here from qmk/qmk_firmware#6068. Is it possible to make --restart operate in conjunction with --smarteep? Or alternately make the combination emit an error rather than silently ignoring --restart, because the current situation results in a brief scare when running mdloader --restart --smarteep and the keyboard doesn't reboot :).

Please sign in to comment.