Add new PMC3 flashing method
This commit is contained in:
parent
5c4d946a66
commit
f5c87e8f25
@ -76,9 +76,9 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
pmc_sci_queue = 0;
|
pmc_sci_queue = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xDC:
|
case 0xEC:
|
||||||
DEBUG(" scratch rom\n");
|
DEBUG(" scratch rom\n");
|
||||||
pmc_write(pmc, 0x33, PMC_TIMEOUT);
|
pmc_write(pmc, 0x76, PMC_TIMEOUT);
|
||||||
scratch_trampoline();
|
scratch_trampoline();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,83 +10,105 @@ volatile uint8_t __xdata __at(0x103D) ECINDAR2;
|
|||||||
volatile uint8_t __xdata __at(0x103E) ECINDAR3;
|
volatile uint8_t __xdata __at(0x103E) ECINDAR3;
|
||||||
volatile uint8_t __xdata __at(0x103F) ECINDDR;
|
volatile uint8_t __xdata __at(0x103F) ECINDDR;
|
||||||
|
|
||||||
#define FLASH_SPI 0x00000000
|
uint8_t acpi_read(uint8_t addr) {
|
||||||
#define FLASH_EMBEDDED 0x40000000
|
uint8_t data = 0;
|
||||||
|
|
||||||
static int flash_transaction(uint32_t offset, uint8_t * data, int length, bool read) {
|
switch (addr) {
|
||||||
int i;
|
case 4:
|
||||||
for (i = 0; i < length; i++, offset++) {
|
data = ECINDAR0;
|
||||||
ECINDAR3 = (uint8_t)(offset >> 24);
|
break;
|
||||||
ECINDAR2 = (uint8_t)(offset >> 16);
|
case 5:
|
||||||
ECINDAR1 = (uint8_t)(offset >> 8);
|
data = ECINDAR1;
|
||||||
ECINDAR0 = (uint8_t)(offset);
|
break;
|
||||||
if (read) {
|
case 6:
|
||||||
data[i] = ECINDDR;
|
data = ECINDAR2;
|
||||||
} else {
|
break;
|
||||||
ECINDDR = data[i];
|
case 7:
|
||||||
}
|
data = ECINDAR3;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
data = ECINDDR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpi_write(uint8_t addr, uint8_t data) {
|
||||||
|
switch (addr) {
|
||||||
|
case 4:
|
||||||
|
ECINDAR0 = data;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ECINDAR1 = data;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
ECINDAR2 = data;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
ECINDAR3 = data;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
ECINDDR = data;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PmcState {
|
enum PmcState {
|
||||||
PMC_STATE_DEFAULT,
|
PMC_STATE_DEFAULT,
|
||||||
PMC_STATE_WRITE,
|
PMC_STATE_ACPI_READ,
|
||||||
|
PMC_STATE_ACPI_WRITE,
|
||||||
|
PMC_STATE_ACPI_WRITE_ADDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pmc_event(struct Pmc * pmc) {
|
void pmc_event(struct Pmc * pmc) {
|
||||||
static enum PmcState state = PMC_STATE_DEFAULT;
|
static enum PmcState state = PMC_STATE_DEFAULT;
|
||||||
|
static uint8_t state_data[2] = {0, 0};
|
||||||
|
|
||||||
uint8_t sts = pmc_status(pmc);
|
uint8_t sts = pmc_status(pmc);
|
||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
if (sts & PMC_STS_CMD) {
|
if (sts & PMC_STS_CMD) {
|
||||||
printf_tiny("%x\n", data);
|
state = PMC_STATE_DEFAULT;
|
||||||
|
switch (data) {
|
||||||
|
case 0x80:
|
||||||
|
state = PMC_STATE_ACPI_READ;
|
||||||
|
break;
|
||||||
|
case 0x81:
|
||||||
|
state = PMC_STATE_ACPI_WRITE;
|
||||||
|
break;
|
||||||
|
case 0xEC:
|
||||||
|
// Clear processor caches
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
// Exit scratch ROM by going through trampoline
|
||||||
|
__asm__("ljmp 0x1000");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_DEFAULT:
|
case PMC_STATE_ACPI_READ:
|
||||||
switch (data) {
|
state = PMC_STATE_DEFAULT;
|
||||||
case 0x01:
|
uint8_t value = acpi_read(data);
|
||||||
// Enable follow
|
pmc_write(pmc, value);
|
||||||
ECINDAR3 = 0x0F;
|
break;
|
||||||
break;
|
case PMC_STATE_ACPI_WRITE:
|
||||||
case 0x02:
|
state = PMC_STATE_ACPI_WRITE_ADDR;
|
||||||
// Generate high CE#
|
state_data[0] = data;
|
||||||
data = 0;
|
break;
|
||||||
flash_transaction(0x7FFFFE00, &data, 1, false);
|
case PMC_STATE_ACPI_WRITE_ADDR:
|
||||||
// Fall through
|
state = PMC_STATE_DEFAULT;
|
||||||
case 0x03:
|
acpi_write(state_data[0], data);
|
||||||
state = PMC_STATE_WRITE;
|
break;
|
||||||
break;
|
default:
|
||||||
case 0x04:
|
state = PMC_STATE_DEFAULT;
|
||||||
// Read data
|
break;
|
||||||
flash_transaction(0x7FFFFD00, &data, 1, true);
|
|
||||||
pmc_write(pmc, data);
|
|
||||||
printf_tiny("=%x\n", data);
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
// Disable follow
|
|
||||||
ECINDAR3 = 0x00;
|
|
||||||
break;
|
|
||||||
case 0xFC:
|
|
||||||
// Clear processor caches
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
// Exit scratch ROM by going through trampoline
|
|
||||||
__asm__("ljmp 0x1000");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PMC_STATE_WRITE:
|
|
||||||
// Write command or data
|
|
||||||
flash_transaction(0x7FFFFD00, &data, 1, false);
|
|
||||||
state = PMC_STATE_DEFAULT;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +118,6 @@ static void pmc_event(struct Pmc * pmc) {
|
|||||||
void main(void) {
|
void main(void) {
|
||||||
printf_tiny("SCRATCH\n");
|
printf_tiny("SCRATCH\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pmc_event(&PMC_1);
|
pmc_event(&PMC_3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,9 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
pmc_sci_queue = 0;
|
pmc_sci_queue = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xDC:
|
case 0xEC:
|
||||||
DEBUG(" scratch rom\n");
|
DEBUG(" scratch rom\n");
|
||||||
pmc_write(pmc, 0x33, PMC_TIMEOUT);
|
pmc_write(pmc, 0x76, PMC_TIMEOUT);
|
||||||
scratch_trampoline();
|
scratch_trampoline();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,83 +10,105 @@ volatile uint8_t __xdata __at(0x103D) ECINDAR2;
|
|||||||
volatile uint8_t __xdata __at(0x103E) ECINDAR3;
|
volatile uint8_t __xdata __at(0x103E) ECINDAR3;
|
||||||
volatile uint8_t __xdata __at(0x103F) ECINDDR;
|
volatile uint8_t __xdata __at(0x103F) ECINDDR;
|
||||||
|
|
||||||
#define FLASH_SPI 0x00000000
|
uint8_t acpi_read(uint8_t addr) {
|
||||||
#define FLASH_EMBEDDED 0x40000000
|
uint8_t data = 0;
|
||||||
|
|
||||||
static int flash_transaction(uint32_t offset, uint8_t * data, int length, bool read) {
|
switch (addr) {
|
||||||
int i;
|
case 4:
|
||||||
for (i = 0; i < length; i++, offset++) {
|
data = ECINDAR0;
|
||||||
ECINDAR3 = (uint8_t)(offset >> 24);
|
break;
|
||||||
ECINDAR2 = (uint8_t)(offset >> 16);
|
case 5:
|
||||||
ECINDAR1 = (uint8_t)(offset >> 8);
|
data = ECINDAR1;
|
||||||
ECINDAR0 = (uint8_t)(offset);
|
break;
|
||||||
if (read) {
|
case 6:
|
||||||
data[i] = ECINDDR;
|
data = ECINDAR2;
|
||||||
} else {
|
break;
|
||||||
ECINDDR = data[i];
|
case 7:
|
||||||
}
|
data = ECINDAR3;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
data = ECINDDR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpi_write(uint8_t addr, uint8_t data) {
|
||||||
|
switch (addr) {
|
||||||
|
case 4:
|
||||||
|
ECINDAR0 = data;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ECINDAR1 = data;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
ECINDAR2 = data;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
ECINDAR3 = data;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
ECINDDR = data;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PmcState {
|
enum PmcState {
|
||||||
PMC_STATE_DEFAULT,
|
PMC_STATE_DEFAULT,
|
||||||
PMC_STATE_WRITE,
|
PMC_STATE_ACPI_READ,
|
||||||
|
PMC_STATE_ACPI_WRITE,
|
||||||
|
PMC_STATE_ACPI_WRITE_ADDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pmc_event(struct Pmc * pmc) {
|
void pmc_event(struct Pmc * pmc) {
|
||||||
static enum PmcState state = PMC_STATE_DEFAULT;
|
static enum PmcState state = PMC_STATE_DEFAULT;
|
||||||
|
static uint8_t state_data[2] = {0, 0};
|
||||||
|
|
||||||
uint8_t sts = pmc_status(pmc);
|
uint8_t sts = pmc_status(pmc);
|
||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
if (sts & PMC_STS_CMD) {
|
if (sts & PMC_STS_CMD) {
|
||||||
printf_tiny("%x\n", data);
|
state = PMC_STATE_DEFAULT;
|
||||||
|
switch (data) {
|
||||||
|
case 0x80:
|
||||||
|
state = PMC_STATE_ACPI_READ;
|
||||||
|
break;
|
||||||
|
case 0x81:
|
||||||
|
state = PMC_STATE_ACPI_WRITE;
|
||||||
|
break;
|
||||||
|
case 0xEC:
|
||||||
|
// Clear processor caches
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
// Exit scratch ROM by going through trampoline
|
||||||
|
__asm__("ljmp 0x1000");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_DEFAULT:
|
case PMC_STATE_ACPI_READ:
|
||||||
switch (data) {
|
state = PMC_STATE_DEFAULT;
|
||||||
case 0x01:
|
uint8_t value = acpi_read(data);
|
||||||
// Enable follow
|
pmc_write(pmc, value);
|
||||||
ECINDAR3 = 0x0F;
|
break;
|
||||||
break;
|
case PMC_STATE_ACPI_WRITE:
|
||||||
case 0x02:
|
state = PMC_STATE_ACPI_WRITE_ADDR;
|
||||||
// Generate high CE#
|
state_data[0] = data;
|
||||||
data = 0;
|
break;
|
||||||
flash_transaction(0x7FFFFE00, &data, 1, false);
|
case PMC_STATE_ACPI_WRITE_ADDR:
|
||||||
// Fall through
|
state = PMC_STATE_DEFAULT;
|
||||||
case 0x03:
|
acpi_write(state_data[0], data);
|
||||||
state = PMC_STATE_WRITE;
|
break;
|
||||||
break;
|
default:
|
||||||
case 0x04:
|
state = PMC_STATE_DEFAULT;
|
||||||
// Read data
|
break;
|
||||||
flash_transaction(0x7FFFFD00, &data, 1, true);
|
|
||||||
pmc_write(pmc, data);
|
|
||||||
printf_tiny("=%x\n", data);
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
// Disable follow
|
|
||||||
ECINDAR3 = 0x00;
|
|
||||||
break;
|
|
||||||
case 0xFC:
|
|
||||||
// Clear processor caches
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
// Exit scratch ROM by going through trampoline
|
|
||||||
__asm__("ljmp 0x1000");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PMC_STATE_WRITE:
|
|
||||||
// Write command or data
|
|
||||||
flash_transaction(0x7FFFFD00, &data, 1, false);
|
|
||||||
state = PMC_STATE_DEFAULT;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +118,6 @@ static void pmc_event(struct Pmc * pmc) {
|
|||||||
void main(void) {
|
void main(void) {
|
||||||
printf_tiny("SCRATCH\n");
|
printf_tiny("SCRATCH\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pmc_event(&PMC_1);
|
pmc_event(&PMC_3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,9 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
pmc_sci_queue = 0;
|
pmc_sci_queue = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xDC:
|
case 0xEC:
|
||||||
DEBUG(" scratch rom\n");
|
DEBUG(" scratch rom\n");
|
||||||
pmc_write(pmc, 0x33, PMC_TIMEOUT);
|
pmc_write(pmc, 0x76, PMC_TIMEOUT);
|
||||||
scratch_trampoline();
|
scratch_trampoline();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,83 +10,105 @@ volatile uint8_t __xdata __at(0x103D) ECINDAR2;
|
|||||||
volatile uint8_t __xdata __at(0x103E) ECINDAR3;
|
volatile uint8_t __xdata __at(0x103E) ECINDAR3;
|
||||||
volatile uint8_t __xdata __at(0x103F) ECINDDR;
|
volatile uint8_t __xdata __at(0x103F) ECINDDR;
|
||||||
|
|
||||||
#define FLASH_SPI 0x00000000
|
uint8_t acpi_read(uint8_t addr) {
|
||||||
#define FLASH_EMBEDDED 0x40000000
|
uint8_t data = 0;
|
||||||
|
|
||||||
static int flash_transaction(uint32_t offset, uint8_t * data, int length, bool read) {
|
switch (addr) {
|
||||||
int i;
|
case 4:
|
||||||
for (i = 0; i < length; i++, offset++) {
|
data = ECINDAR0;
|
||||||
ECINDAR3 = (uint8_t)(offset >> 24);
|
break;
|
||||||
ECINDAR2 = (uint8_t)(offset >> 16);
|
case 5:
|
||||||
ECINDAR1 = (uint8_t)(offset >> 8);
|
data = ECINDAR1;
|
||||||
ECINDAR0 = (uint8_t)(offset);
|
break;
|
||||||
if (read) {
|
case 6:
|
||||||
data[i] = ECINDDR;
|
data = ECINDAR2;
|
||||||
} else {
|
break;
|
||||||
ECINDDR = data[i];
|
case 7:
|
||||||
}
|
data = ECINDAR3;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
data = ECINDDR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void acpi_write(uint8_t addr, uint8_t data) {
|
||||||
|
switch (addr) {
|
||||||
|
case 4:
|
||||||
|
ECINDAR0 = data;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
ECINDAR1 = data;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
ECINDAR2 = data;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
ECINDAR3 = data;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
ECINDDR = data;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PmcState {
|
enum PmcState {
|
||||||
PMC_STATE_DEFAULT,
|
PMC_STATE_DEFAULT,
|
||||||
PMC_STATE_WRITE,
|
PMC_STATE_ACPI_READ,
|
||||||
|
PMC_STATE_ACPI_WRITE,
|
||||||
|
PMC_STATE_ACPI_WRITE_ADDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pmc_event(struct Pmc * pmc) {
|
void pmc_event(struct Pmc * pmc) {
|
||||||
static enum PmcState state = PMC_STATE_DEFAULT;
|
static enum PmcState state = PMC_STATE_DEFAULT;
|
||||||
|
static uint8_t state_data[2] = {0, 0};
|
||||||
|
|
||||||
uint8_t sts = pmc_status(pmc);
|
uint8_t sts = pmc_status(pmc);
|
||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
if (sts & PMC_STS_CMD) {
|
if (sts & PMC_STS_CMD) {
|
||||||
printf_tiny("%x\n", data);
|
state = PMC_STATE_DEFAULT;
|
||||||
|
switch (data) {
|
||||||
|
case 0x80:
|
||||||
|
state = PMC_STATE_ACPI_READ;
|
||||||
|
break;
|
||||||
|
case 0x81:
|
||||||
|
state = PMC_STATE_ACPI_WRITE;
|
||||||
|
break;
|
||||||
|
case 0xEC:
|
||||||
|
// Clear processor caches
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
__asm__("mov 0xf7, #1");
|
||||||
|
__asm__("nop");
|
||||||
|
// Exit scratch ROM by going through trampoline
|
||||||
|
__asm__("ljmp 0x1000");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_DEFAULT:
|
case PMC_STATE_ACPI_READ:
|
||||||
switch (data) {
|
state = PMC_STATE_DEFAULT;
|
||||||
case 0x01:
|
uint8_t value = acpi_read(data);
|
||||||
// Enable follow
|
pmc_write(pmc, value);
|
||||||
ECINDAR3 = 0x0F;
|
break;
|
||||||
break;
|
case PMC_STATE_ACPI_WRITE:
|
||||||
case 0x02:
|
state = PMC_STATE_ACPI_WRITE_ADDR;
|
||||||
// Generate high CE#
|
state_data[0] = data;
|
||||||
data = 0;
|
break;
|
||||||
flash_transaction(0x7FFFFE00, &data, 1, false);
|
case PMC_STATE_ACPI_WRITE_ADDR:
|
||||||
// Fall through
|
state = PMC_STATE_DEFAULT;
|
||||||
case 0x03:
|
acpi_write(state_data[0], data);
|
||||||
state = PMC_STATE_WRITE;
|
break;
|
||||||
break;
|
default:
|
||||||
case 0x04:
|
state = PMC_STATE_DEFAULT;
|
||||||
// Read data
|
break;
|
||||||
flash_transaction(0x7FFFFD00, &data, 1, true);
|
|
||||||
pmc_write(pmc, data);
|
|
||||||
printf_tiny("=%x\n", data);
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
// Disable follow
|
|
||||||
ECINDAR3 = 0x00;
|
|
||||||
break;
|
|
||||||
case 0xFC:
|
|
||||||
// Clear processor caches
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
__asm__("mov 0xf7, #1");
|
|
||||||
__asm__("nop");
|
|
||||||
// Exit scratch ROM by going through trampoline
|
|
||||||
__asm__("ljmp 0x1000");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PMC_STATE_WRITE:
|
|
||||||
// Write command or data
|
|
||||||
flash_transaction(0x7FFFFD00, &data, 1, false);
|
|
||||||
state = PMC_STATE_DEFAULT;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +118,6 @@ static void pmc_event(struct Pmc * pmc) {
|
|||||||
void main(void) {
|
void main(void) {
|
||||||
printf_tiny("SCRATCH\n");
|
printf_tiny("SCRATCH\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pmc_event(&PMC_1);
|
pmc_event(&PMC_3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user