Turn on nvm in 3.0.

Its 256b on M0 and 8k on M4 to match flash erase sizes.

Fixes #758
This commit is contained in:
Scott Shawcroft 2018-04-12 18:13:40 -07:00
parent 10eabf6bc2
commit 812fe0c93f
24 changed files with 55 additions and 125 deletions

View File

@ -285,6 +285,8 @@ SRC_COMMON_HAL = \
analogio/__init__.c \
analogio/AnalogIn.c \
analogio/AnalogOut.c \
nvm/__init__.c \
nvm/ByteArray.c \
pulseio/__init__.c \
pulseio/PulseIn.c \
pulseio/PulseOut.c \
@ -293,9 +295,7 @@ SRC_COMMON_HAL = \
usb_hid/Device.c \
audioio/__init__.c \
audioio/AudioOut.c \
# nvm/__init__.c \
audiobusio/PDMIn.c \
nvm/ByteArray.c \
# audiobusio/PDMIn.c \
touchio/__init__.c \
touchio/TouchIn.c \

View File

@ -42,8 +42,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -35,8 +35,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -37,8 +37,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -19,8 +19,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -35,8 +35,8 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
#include "external_flash/devices.h"

View File

@ -19,8 +19,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -36,8 +36,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -22,8 +22,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -49,8 +49,7 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
// #define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -5,8 +5,8 @@
/* Specify the memory areas */
MEMORY
{
/* Leave 16KiB for the bootloader. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 256K - 16K
/* Leave 16KiB for the bootloader. 8K for user data*/
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 256K - 16K - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
@ -76,7 +76,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -5,8 +5,8 @@
/* Specify the memory areas */
MEMORY
{
/* Leave 16KiB for the bootloader. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 512K - 16K
/* Leave 16KiB for the bootloader. 8K for user data*/
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 512K - 16K - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
}
@ -76,7 +76,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -5,8 +5,8 @@
/* Specify the memory areas */
MEMORY
{
/* Leave 16KiB for the bootloader and 256KiB for the internal file system. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 512K - 16K - 256K
/* Leave 16KiB for the bootloader, 256KiB for the internal file system, and 8KiB for user binary data. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 512K - 16K - 256K - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
}
@ -76,7 +76,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -6,7 +6,7 @@
MEMORY
{
/* Leave 16KiB for the bootloader. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 1M - 16K
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 1M - 16K - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
}
@ -76,7 +76,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -5,8 +5,8 @@
/* Specify the memory areas */
MEMORY
{
/* Leave 16KiB for the bootloader and 512k for the filesystem. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 1M - 16K - 512K
/* Leave 16KiB for the bootloader, 512k for the filesystem and 8k for user config data. */
FLASH (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 1M - 16K - 512K - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
}
@ -76,7 +76,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -5,7 +5,7 @@
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
}
@ -74,7 +74,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -5,8 +5,8 @@
/* Specify the memory areas */
MEMORY
{
/* 1024 KiB minus 512KiB for the internal file system. */
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M - 512K
/* 1024 KiB minus 512KiB for the internal file system and 8KiB for the user nvm. */
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1M - 512K - 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
}
@ -75,7 +75,7 @@ SECTIONS
.stack :
{
. = ALIGN(4);
. = . + 2K; /* Reserve a minimum of 2K for the stack. */
. = . + 10K; /* Reserve a minimum of 10K for the stack. nvm will temporarily store 8k on the stack when writing. */
. = ALIGN(4);
} >RAM

View File

@ -44,8 +44,8 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
//#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
#include "external_flash/devices.h"

View File

@ -37,8 +37,8 @@
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code.
//#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
#define CIRCUITPY_INTERNAL_NVM_SIZE 256
#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE)
#include "external_flash/devices.h"

View File

@ -74,10 +74,12 @@ bool gclk_enabled(uint8_t gclk) {
void disable_gclk(uint8_t gclk) {
#ifdef SAMD51
while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {}
GCLK->GENCTRL[gclk].bit.GENEN = false;
while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {}
#endif
#ifdef SAMD21
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk);
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
#endif

View File

@ -85,13 +85,13 @@ const mcu_processor_obj_t common_hal_mcu_processor_obj = {
// NVM is only available on Express boards for now.
#if CIRCUITPY_INTERNAL_NVM_SIZE > 0
// The singleton nvm.ByteArray object.
// const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
// .base = {
// .type = &nvm_bytearray_type,
// },
// .len = NVMCTRL_ROW_SIZE,
// .start_address = (uint8_t*) (FLASH_SIZE - NVMCTRL_ROW_SIZE)
// };
const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
.base = {
.type = &nvm_bytearray_type,
},
.len = CIRCUITPY_INTERNAL_NVM_SIZE,
.start_address = (uint8_t*) (FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE)
};
#endif
// This maps MCU pin names to pin objects.

View File

@ -26,7 +26,7 @@
#include "common-hal/nvm/ByteArray.h"
#include "asf/sam0/drivers/nvm/nvm.h"
#include "hal_flash.h"
#include <stdint.h>
#include <string.h>
@ -36,48 +36,12 @@ uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
}
bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
uint32_t start_index, uint8_t* values, uint32_t len) {
uint32_t total_written = 0;
for (uint32_t i = 0; i < self->len / NVMCTRL_ROW_SIZE; i++) {
uint32_t row_start = NVMCTRL_ROW_SIZE * i;
if (row_start + NVMCTRL_ROW_SIZE < start_index || start_index + len < row_start) {
continue;
}
uint8_t temp_row[NVMCTRL_ROW_SIZE];
memcpy(temp_row,
self->start_address + row_start,
NVMCTRL_ROW_SIZE);
enum status_code error_code;
do {
error_code = nvm_erase_row((uint32_t) self->start_address + row_start);
} while (error_code == STATUS_BUSY);
if (error_code != STATUS_OK) {
return false;
}
uint32_t data_start = 0;
if (start_index > row_start) {
data_start = start_index - row_start;
}
uint32_t data_len = len;
uint32_t data_remaining = data_len - total_written;
uint32_t row_remaining = NVMCTRL_ROW_SIZE - data_start;
if (data_remaining > row_remaining) {
data_len = row_remaining;
}
memcpy(temp_row + data_start,
values + total_written,
data_len);
for (int page = 0; page < NVMCTRL_ROW_SIZE / NVMCTRL_PAGE_SIZE; page++) {
do {
error_code = nvm_write_buffer((uint32_t) self->start_address + row_start + page * NVMCTRL_PAGE_SIZE,
temp_row + page * NVMCTRL_PAGE_SIZE,
NVMCTRL_PAGE_SIZE);
} while (error_code == STATUS_BUSY);
if (error_code != STATUS_OK) {
return false;
}
}
}
uint32_t start_index, uint8_t* values, uint32_t len) {
// We don't use features that use any advanced NVMCTRL features so we can fake the descriptor
// whenever we need it instead of storing it long term.
struct flash_descriptor desc;
desc.dev.hw = NVMCTRL;
flash_write(&desc, (uint32_t) self->start_address + start_index, values, len);
return true;
}

View File

@ -147,35 +147,6 @@ safe_mode_t port_init(void) {
return USER_SAFE_MODE;
}
// #if CIRCUITPY_INTERNAL_NVM_SIZE > 0
// // Upgrade the nvm flash to include one sector for eeprom emulation.
// struct nvm_fusebits fuses;
// if (nvm_get_fuses(&fuses) == STATUS_OK &&
// fuses.eeprom_size == NVM_EEPROM_EMULATOR_SIZE_0) {
// #ifdef INTERNAL_FLASH_FS
// // Shift the internal file system up one row.
// for (uint8_t row = 0; row < TOTAL_INTERNAL_FLASH_SIZE / NVMCTRL_ROW_SIZE; row++) {
// uint32_t new_row_address = INTERNAL_FLASH_MEM_SEG1_START_ADDR + row * NVMCTRL_ROW_SIZE;
// nvm_erase_row(new_row_address);
// nvm_write_buffer(new_row_address,
// (uint8_t*) (new_row_address + CIRCUITPY_INTERNAL_EEPROM_SIZE),
// NVMCTRL_ROW_SIZE);
// }
// #endif
// uint32_t nvm_size = CIRCUITPY_INTERNAL_NVM_SIZE;
// uint8_t enum_value = 6;
// while (nvm_size > 256 && enum_value != 255) {
// nvm_size /= 2;
// enum_value -= 1;
// }
// if (enum_value != 255 && nvm_size == 256) {
// // Mark the last section as eeprom now.
// fuses.eeprom_size = (enum nvm_eeprom_emulator_size) enum_value;
// nvm_set_fuses(&fuses);
// }
// }
// #endif
return NO_SAFE_MODE;
}

View File

@ -36,12 +36,13 @@
//| ================================================================================
//|
//| Non-volatile memory is available as a byte array that persists over reloads
//| and power cycles.
//| and power cycles. Each assignment causes an erase and write cycle so its recommended to assign
//| all values to change at once.
//|
//| Usage::
//|
//| import microcontroller
//| microcontroller.nvm[0] = 0xcc
//| microcontroller.nvm[0:] = b"\xcc\x10\x00"
//|
//| .. class:: ByteArray()