Partially implement proper flash storage.
This commit is contained in:
parent
5ac1b2efbd
commit
995b8aabb1
13
stm/Makefile
13
stm/Makefile
@ -14,7 +14,9 @@ SRC_C = \
|
|||||||
main.c \
|
main.c \
|
||||||
printf.c \
|
printf.c \
|
||||||
system_stm32f4xx.c \
|
system_stm32f4xx.c \
|
||||||
|
led.c \
|
||||||
flash.c \
|
flash.c \
|
||||||
|
storage.c \
|
||||||
string0.c \
|
string0.c \
|
||||||
malloc0.c \
|
malloc0.c \
|
||||||
stm32fxxx_it.c \
|
stm32fxxx_it.c \
|
||||||
@ -84,11 +86,14 @@ OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(PY_O) $(SRC_FATFS:.
|
|||||||
|
|
||||||
all: $(BUILD) $(BUILD)/flash.dfu
|
all: $(BUILD) $(BUILD)/flash.dfu
|
||||||
|
|
||||||
$(BUILD)/flash.dfu: $(BUILD)/flash.bin
|
$(BUILD)/flash.dfu: $(BUILD)/flash0.bin $(BUILD)/flash1.bin
|
||||||
python2 ~/stm/dfu/dfu.py -b 0x08000000:$< $@
|
python2 ~/stm/dfu/dfu.py -b 0x08000000:$(BUILD)/flash0.bin -b 0x08020000:$(BUILD)/flash1.bin $@
|
||||||
|
|
||||||
$(BUILD)/flash.bin: $(BUILD)/flash.elf
|
$(BUILD)/flash0.bin: $(BUILD)/flash.elf
|
||||||
arm-none-eabi-objcopy -O binary -j .isr_vector -j .text -j .data $^ $@
|
arm-none-eabi-objcopy -O binary -j .isr_vector $^ $@
|
||||||
|
|
||||||
|
$(BUILD)/flash1.bin: $(BUILD)/flash.elf
|
||||||
|
arm-none-eabi-objcopy -O binary -j .text -j .data $^ $@
|
||||||
|
|
||||||
$(BUILD)/flash.elf: $(OBJ)
|
$(BUILD)/flash.elf: $(OBJ)
|
||||||
$(LD) $(LDFLAGS) -o $@ $(OBJ)
|
$(LD) $(LDFLAGS) -o $@ $(OBJ)
|
||||||
|
128
stm/flash.c
128
stm/flash.c
@ -1,5 +1,7 @@
|
|||||||
|
#include <stdio.h>
|
||||||
#include <stm32f4xx.h>
|
#include <stm32f4xx.h>
|
||||||
#include <stm32f4xx_flash.h>
|
#include <stm32f4xx_flash.h>
|
||||||
|
#include "flash.h"
|
||||||
|
|
||||||
/* Base address of the Flash sectors */
|
/* Base address of the Flash sectors */
|
||||||
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
|
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
|
||||||
@ -15,7 +17,73 @@
|
|||||||
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
|
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
|
||||||
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
|
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
|
||||||
|
|
||||||
static uint32_t GetSector(uint32_t Address);
|
static const uint32_t flash_info_table[26] = {
|
||||||
|
ADDR_FLASH_SECTOR_0, FLASH_Sector_0,
|
||||||
|
ADDR_FLASH_SECTOR_1, FLASH_Sector_1,
|
||||||
|
ADDR_FLASH_SECTOR_2, FLASH_Sector_2,
|
||||||
|
ADDR_FLASH_SECTOR_3, FLASH_Sector_3,
|
||||||
|
ADDR_FLASH_SECTOR_4, FLASH_Sector_4,
|
||||||
|
ADDR_FLASH_SECTOR_5, FLASH_Sector_5,
|
||||||
|
ADDR_FLASH_SECTOR_6, FLASH_Sector_6,
|
||||||
|
ADDR_FLASH_SECTOR_7, FLASH_Sector_7,
|
||||||
|
ADDR_FLASH_SECTOR_8, FLASH_Sector_8,
|
||||||
|
ADDR_FLASH_SECTOR_9, FLASH_Sector_9,
|
||||||
|
ADDR_FLASH_SECTOR_10, FLASH_Sector_10,
|
||||||
|
ADDR_FLASH_SECTOR_11, FLASH_Sector_11,
|
||||||
|
ADDR_FLASH_SECTOR_11 + 0x20000, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
|
||||||
|
if (addr >= flash_info_table[0]) {
|
||||||
|
for (int i = 0; i < 24; i += 2) {
|
||||||
|
if (addr < flash_info_table[i + 2]) {
|
||||||
|
if (start_addr != NULL) {
|
||||||
|
*start_addr = flash_info_table[i];
|
||||||
|
}
|
||||||
|
if (size != NULL) {
|
||||||
|
*size = flash_info_table[i + 2] - flash_info_table[i];
|
||||||
|
}
|
||||||
|
return flash_info_table[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* @brief Gets the sector of a given address
|
||||||
|
* @param None
|
||||||
|
* @retval The sector of a given address
|
||||||
|
*/
|
||||||
|
uint32_t flash_get_sector(uint32_t addr) {
|
||||||
|
if ((addr < ADDR_FLASH_SECTOR_1) && (addr >= ADDR_FLASH_SECTOR_0)) {
|
||||||
|
return FLASH_Sector_0;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_2) && (addr >= ADDR_FLASH_SECTOR_1)) {
|
||||||
|
return FLASH_Sector_1;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_3) && (addr >= ADDR_FLASH_SECTOR_2)) {
|
||||||
|
return FLASH_Sector_2;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_4) && (addr >= ADDR_FLASH_SECTOR_3)) {
|
||||||
|
return FLASH_Sector_3;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_5) && (addr >= ADDR_FLASH_SECTOR_4)) {
|
||||||
|
return FLASH_Sector_4;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_6) && (addr >= ADDR_FLASH_SECTOR_5)) {
|
||||||
|
return FLASH_Sector_5;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_7) && (addr >= ADDR_FLASH_SECTOR_6)) {
|
||||||
|
return FLASH_Sector_6;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_8) && (addr >= ADDR_FLASH_SECTOR_7)) {
|
||||||
|
return FLASH_Sector_7;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_9) && (addr >= ADDR_FLASH_SECTOR_8)) {
|
||||||
|
return FLASH_Sector_8;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_10) && (addr >= ADDR_FLASH_SECTOR_9)) {
|
||||||
|
return FLASH_Sector_9;
|
||||||
|
} else if ((addr < ADDR_FLASH_SECTOR_11) && (addr >= ADDR_FLASH_SECTOR_10)) {
|
||||||
|
return FLASH_Sector_10;
|
||||||
|
} else {
|
||||||
|
return FLASH_Sector_11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
|
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
|
||||||
// unlock
|
// unlock
|
||||||
@ -26,7 +94,7 @@ void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32)
|
|||||||
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
|
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
|
||||||
|
|
||||||
// Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word
|
// Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word
|
||||||
if (FLASH_EraseSector(GetSector(flash_dest), VoltageRange_3) != FLASH_COMPLETE) {
|
if (FLASH_EraseSector(flash_get_sector_info(flash_dest, NULL, NULL), VoltageRange_3) != FLASH_COMPLETE) {
|
||||||
/* Error occurred while sector erase.
|
/* Error occurred while sector erase.
|
||||||
User can add here some code to deal with this error */
|
User can add here some code to deal with this error */
|
||||||
return;
|
return;
|
||||||
@ -51,59 +119,3 @@ void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32)
|
|||||||
// lock
|
// lock
|
||||||
FLASH_Lock();
|
FLASH_Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the sector of a given address
|
|
||||||
* @param None
|
|
||||||
* @retval The sector of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetSector(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t sector = 0;
|
|
||||||
|
|
||||||
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_0;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_1;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_2;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_3;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_4;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_5;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_6;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_7;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_8;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_9;
|
|
||||||
}
|
|
||||||
else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
|
|
||||||
{
|
|
||||||
sector = FLASH_Sector_10;
|
|
||||||
}
|
|
||||||
return sector;
|
|
||||||
}
|
|
||||||
|
2
stm/flash.h
Normal file
2
stm/flash.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size);
|
||||||
|
void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32);
|
47
stm/led.c
Normal file
47
stm/led.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include <stm32f4xx.h>
|
||||||
|
#include <stm32f4xx_gpio.h>
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
#define PYB_LED_R_PORT (GPIOA)
|
||||||
|
#define PYB_LED_R1_PIN (GPIO_Pin_8)
|
||||||
|
#define PYB_LED_R2_PIN (GPIO_Pin_10)
|
||||||
|
#define PYB_LED_G_PORT (GPIOC)
|
||||||
|
#define PYB_LED_G1_PIN (GPIO_Pin_4)
|
||||||
|
#define PYB_LED_G2_PIN (GPIO_Pin_5)
|
||||||
|
|
||||||
|
void led_init() {
|
||||||
|
// set the output high (so LED is off)
|
||||||
|
PYB_LED_R_PORT->BSRRL = PYB_LED_R1_PIN;
|
||||||
|
PYB_LED_R_PORT->BSRRL = PYB_LED_R2_PIN;
|
||||||
|
PYB_LED_G_PORT->BSRRL = PYB_LED_G1_PIN;
|
||||||
|
PYB_LED_G_PORT->BSRRL = PYB_LED_G2_PIN;
|
||||||
|
// make them open drain outputs
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
GPIO_InitStructure.GPIO_Pin = PYB_LED_R1_PIN | PYB_LED_R2_PIN;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||||
|
GPIO_Init(PYB_LED_R_PORT, &GPIO_InitStructure);
|
||||||
|
GPIO_InitStructure.GPIO_Pin = PYB_LED_G1_PIN | PYB_LED_G2_PIN;
|
||||||
|
GPIO_Init(PYB_LED_G_PORT, &GPIO_InitStructure);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_state(pyb_led_t led, int state) {
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint32_t pin;
|
||||||
|
switch (led) {
|
||||||
|
case PYB_LED_R1: port = PYB_LED_R_PORT; pin = PYB_LED_R1_PIN; break;
|
||||||
|
case PYB_LED_R2: port = PYB_LED_R_PORT; pin = PYB_LED_R2_PIN; break;
|
||||||
|
case PYB_LED_G1: port = PYB_LED_G_PORT; pin = PYB_LED_G1_PIN; break;
|
||||||
|
case PYB_LED_G2: port = PYB_LED_G_PORT; pin = PYB_LED_G2_PIN; break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
if (state == 0) {
|
||||||
|
// LED off, output is high
|
||||||
|
port->BSRRL = pin;
|
||||||
|
} else {
|
||||||
|
// LED on, output is low
|
||||||
|
port->BSRRH = pin;
|
||||||
|
}
|
||||||
|
}
|
9
stm/led.h
Normal file
9
stm/led.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
typedef enum {
|
||||||
|
PYB_LED_R1 = 0,
|
||||||
|
PYB_LED_R2 = 1,
|
||||||
|
PYB_LED_G1 = 2,
|
||||||
|
PYB_LED_G2 = 3,
|
||||||
|
} pyb_led_t;
|
||||||
|
|
||||||
|
void led_init();
|
||||||
|
void led_state(pyb_led_t led, int state);
|
111
stm/main.c
111
stm/main.c
@ -2,6 +2,9 @@
|
|||||||
#include <stm32f4xx_rcc.h>
|
#include <stm32f4xx_rcc.h>
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "led.h"
|
||||||
|
#include "storage.h"
|
||||||
#include "font_petme128_8x8.h"
|
#include "font_petme128_8x8.h"
|
||||||
|
|
||||||
void delay_ms(int ms);
|
void delay_ms(int ms);
|
||||||
@ -32,13 +35,6 @@ void gpio_init() {
|
|||||||
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOAEN;
|
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOAEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PYB_LEDR_PORT (GPIOA)
|
|
||||||
#define PYB_LEDR1_PORT_NUM (8)
|
|
||||||
#define PYB_LEDR2_PORT_NUM (10)
|
|
||||||
#define PYB_LEDG_PORT (GPIOC)
|
|
||||||
#define PYB_LEDG1_PORT_NUM (4)
|
|
||||||
#define PYB_LEDG2_PORT_NUM (5)
|
|
||||||
|
|
||||||
void gpio_pin_init(GPIO_TypeDef *gpio, uint32_t pin, uint32_t moder, uint32_t otyper, uint32_t ospeedr, uint32_t pupdr) {
|
void gpio_pin_init(GPIO_TypeDef *gpio, uint32_t pin, uint32_t moder, uint32_t otyper, uint32_t ospeedr, uint32_t pupdr) {
|
||||||
set_bits(&gpio->MODER, 2 * pin, 3, moder);
|
set_bits(&gpio->MODER, 2 * pin, 3, moder);
|
||||||
set_bits(&gpio->OTYPER, pin, 1, otyper);
|
set_bits(&gpio->OTYPER, pin, 1, otyper);
|
||||||
@ -163,37 +159,6 @@ static void mma_stop() {
|
|||||||
I2C1->CR1 |= I2C_CR1_STOP;
|
I2C1->CR1 |= I2C_CR1_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_init() {
|
|
||||||
// set the output high (so LED is off)
|
|
||||||
PYB_LEDR_PORT->BSRRL = 1 << PYB_LEDR1_PORT_NUM;
|
|
||||||
PYB_LEDR_PORT->BSRRL = 1 << PYB_LEDR2_PORT_NUM;
|
|
||||||
PYB_LEDG_PORT->BSRRL = 1 << PYB_LEDG1_PORT_NUM;
|
|
||||||
PYB_LEDG_PORT->BSRRL = 1 << PYB_LEDG2_PORT_NUM;
|
|
||||||
// make it an open drain output
|
|
||||||
gpio_pin_init(PYB_LEDR_PORT, PYB_LEDR1_PORT_NUM, 1, 1, 0, 0);
|
|
||||||
gpio_pin_init(PYB_LEDR_PORT, PYB_LEDR2_PORT_NUM, 1, 1, 0, 0);
|
|
||||||
gpio_pin_init(PYB_LEDG_PORT, PYB_LEDG1_PORT_NUM, 1, 1, 0, 0);
|
|
||||||
gpio_pin_init(PYB_LEDG_PORT, PYB_LEDG2_PORT_NUM, 1, 1, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void led_state(uint32_t led_port, int s) {
|
|
||||||
if (s == 0) {
|
|
||||||
// LED off, output is high
|
|
||||||
if (led_port == PYB_LEDR1_PORT_NUM || led_port == PYB_LEDR2_PORT_NUM) {
|
|
||||||
PYB_LEDR_PORT->BSRRL = 1 << led_port;
|
|
||||||
} else {
|
|
||||||
PYB_LEDG_PORT->BSRRL = 1 << led_port;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// LED on, output is low
|
|
||||||
if (led_port == PYB_LEDR1_PORT_NUM || led_port == PYB_LEDR2_PORT_NUM) {
|
|
||||||
PYB_LEDR_PORT->BSRRH = 1 << led_port;
|
|
||||||
} else {
|
|
||||||
PYB_LEDG_PORT->BSRRH = 1 << led_port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PYB_USRSW_PORT (GPIOA)
|
#define PYB_USRSW_PORT (GPIOA)
|
||||||
#define PYB_USRSW_PORT_NUM (13)
|
#define PYB_USRSW_PORT_NUM (13)
|
||||||
|
|
||||||
@ -402,11 +367,11 @@ void __fatal_error(const char *msg) {
|
|||||||
lcd_print_strn(msg, strlen(msg));
|
lcd_print_strn(msg, strlen(msg));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 1);
|
led_state(PYB_LED_R1, 1);
|
||||||
led_state(PYB_LEDR2_PORT_NUM, 0);
|
led_state(PYB_LED_R2, 0);
|
||||||
delay_ms(150);
|
delay_ms(150);
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 0);
|
led_state(PYB_LED_R1, 0);
|
||||||
led_state(PYB_LEDR2_PORT_NUM, 1);
|
led_state(PYB_LED_R2, 1);
|
||||||
delay_ms(150);
|
delay_ms(150);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,7 +389,7 @@ py_obj_t pyb_delay(py_obj_t count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
py_obj_t pyb_led(py_obj_t state) {
|
py_obj_t pyb_led(py_obj_t state) {
|
||||||
led_state(PYB_LEDG1_PORT_NUM, rt_is_true(state));
|
led_state(PYB_LED_G1, rt_is_true(state));
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,12 +436,8 @@ void nlr_test() {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int dummy_bss;
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int dummy;
|
// TODO disable JTAG
|
||||||
|
|
||||||
// should disable JTAG
|
|
||||||
|
|
||||||
qstr_init();
|
qstr_init();
|
||||||
rt_init();
|
rt_init();
|
||||||
@ -485,25 +446,26 @@ int main() {
|
|||||||
led_init();
|
led_init();
|
||||||
sw_init();
|
sw_init();
|
||||||
lcd_init();
|
lcd_init();
|
||||||
|
storage_init();
|
||||||
|
|
||||||
// print a message
|
// print a message
|
||||||
printf(" micro py board\n");
|
printf(" micro py board\n");
|
||||||
|
|
||||||
// flash to indicate we are alive!
|
// flash to indicate we are alive!
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 1);
|
led_state(PYB_LED_R1, 1);
|
||||||
led_state(PYB_LEDR2_PORT_NUM, 0);
|
led_state(PYB_LED_R2, 0);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 0);
|
led_state(PYB_LED_R1, 0);
|
||||||
led_state(PYB_LEDR2_PORT_NUM, 1);
|
led_state(PYB_LED_R2, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn LEDs off
|
// turn LEDs off
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 0);
|
led_state(PYB_LED_R1, 0);
|
||||||
led_state(PYB_LEDR2_PORT_NUM, 0);
|
led_state(PYB_LED_R2, 0);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
led_state(PYB_LEDG2_PORT_NUM, 0);
|
led_state(PYB_LED_G2, 0);
|
||||||
|
|
||||||
// get and print clock speeds
|
// get and print clock speeds
|
||||||
// SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
|
// SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
|
||||||
@ -522,10 +484,12 @@ int main() {
|
|||||||
usb_init();
|
usb_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// to print info about memory
|
||||||
for (;;) {
|
for (;;) {
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LED_G1, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
extern void *_sidata;
|
extern void *_sidata;
|
||||||
extern void *_sdata;
|
extern void *_sdata;
|
||||||
extern void *_edata;
|
extern void *_edata;
|
||||||
@ -543,14 +507,11 @@ int main() {
|
|||||||
printf("_estack=%p\n", &_estack);
|
printf("_estack=%p\n", &_estack);
|
||||||
printf("_etext=%p\n", &_etext);
|
printf("_etext=%p\n", &_etext);
|
||||||
printf("_heap_start=%p\n", &_heap_start);
|
printf("_heap_start=%p\n", &_heap_start);
|
||||||
printf("&dummy=%p\n", &dummy);
|
|
||||||
printf("&dummy_bss=%p\n", &dummy_bss);
|
|
||||||
printf("dummy_bss=%x\n", dummy_bss);
|
|
||||||
//printf("sizeof(int)=%d\n", sizeof(int)); // 4
|
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
}
|
}
|
||||||
delay_ms(500);
|
delay_ms(500);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
|
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
|
||||||
//delay_ms(1000);
|
//delay_ms(1000);
|
||||||
@ -662,7 +623,7 @@ int main() {
|
|||||||
printf("pars;al=%u\n", m_get_total_bytes_allocated());
|
printf("pars;al=%u\n", m_get_total_bytes_allocated());
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
//parse_node_show(pn, 0);
|
//parse_node_show(pn, 0);
|
||||||
py_compile(pn);
|
py_compile(pn, false);
|
||||||
printf("comp;al=%u\n", m_get_total_bytes_allocated());
|
printf("comp;al=%u\n", m_get_total_bytes_allocated());
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
|
|
||||||
@ -677,9 +638,9 @@ int main() {
|
|||||||
py_obj_t module_fun = rt_make_function_from_id(1);
|
py_obj_t module_fun = rt_make_function_from_id(1);
|
||||||
|
|
||||||
// flash once
|
// flash once
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LED_G1, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
|
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
@ -696,9 +657,9 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// flash once
|
// flash once
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LED_G1, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
|
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
printf("nalloc=%u\n", m_get_total_bytes_allocated());
|
printf("nalloc=%u\n", m_get_total_bytes_allocated());
|
||||||
@ -710,13 +671,13 @@ int main() {
|
|||||||
|
|
||||||
// benchmark C version of impl02.py
|
// benchmark C version of impl02.py
|
||||||
if (0) {
|
if (0) {
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LED_G1, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
impl02_c_version();
|
impl02_c_version();
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LED_G1, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MMA testing
|
// MMA testing
|
||||||
@ -834,8 +795,8 @@ int main() {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
delay_ms(10);
|
delay_ms(10);
|
||||||
if (sw_get()) {
|
if (sw_get()) {
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 1);
|
led_state(PYB_LED_R1, 1);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
i = 1 - i;
|
i = 1 - i;
|
||||||
if (i) {
|
if (i) {
|
||||||
printf(" angel %05x.\n", n);
|
printf(" angel %05x.\n", n);
|
||||||
@ -846,8 +807,8 @@ int main() {
|
|||||||
}
|
}
|
||||||
n += 1;
|
n += 1;
|
||||||
} else {
|
} else {
|
||||||
led_state(PYB_LEDR1_PORT_NUM, 0);
|
led_state(PYB_LED_R1, 0);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LED_G1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ static uint32_t mem = 0;
|
|||||||
void *malloc(size_t n) {
|
void *malloc(size_t n) {
|
||||||
if (mem == 0) {
|
if (mem == 0) {
|
||||||
extern uint32_t _heap_start;
|
extern uint32_t _heap_start;
|
||||||
mem = &_heap_start; // need to use big ram block so we can execute code from it (is it true that we can't execute from CCM?)
|
mem = (uint32_t)&_heap_start; // need to use big ram block so we can execute code from it (is it true that we can't execute from CCM?)
|
||||||
}
|
}
|
||||||
void *ptr = (void*)mem;
|
void *ptr = (void*)mem;
|
||||||
mem = (mem + n + 3) & (~3);
|
mem = (mem + n + 3) & (~3);
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
/* Specify the memory areas */
|
/* Specify the memory areas */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* 1 MiB */
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
|
||||||
|
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */
|
||||||
|
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x020000 /* sector 5, 128 KiB */
|
||||||
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
|
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
|
||||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
|
||||||
}
|
}
|
||||||
@ -27,7 +29,7 @@ SECTIONS
|
|||||||
KEEP(*(.isr_vector)) /* Startup code */
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >FLASH
|
} >FLASH_ISR
|
||||||
|
|
||||||
/* The program code and other data goes into FLASH */
|
/* The program code and other data goes into FLASH */
|
||||||
.text :
|
.text :
|
||||||
@ -43,7 +45,7 @@ SECTIONS
|
|||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_etext = .; /* define a global symbol at end of code */
|
_etext = .; /* define a global symbol at end of code */
|
||||||
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
|
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
|
||||||
} >FLASH
|
} >FLASH_TEXT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
.ARM.extab :
|
.ARM.extab :
|
||||||
|
142
stm/storage.c
Normal file
142
stm/storage.c
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "std.h"
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "led.h"
|
||||||
|
#include "flash.h"
|
||||||
|
#include "storage.h"
|
||||||
|
|
||||||
|
#define BLOCK_SIZE (512)
|
||||||
|
#define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
|
||||||
|
#define FLASH_PART1_START_BLOCK (0x100)
|
||||||
|
#define FLASH_PART1_NUM_BLOCKS (224) // 16k+16k+16k+64k=112k
|
||||||
|
#define FLASH_MEM_START_ADDR (0x08004000) // sector 1, 16k
|
||||||
|
|
||||||
|
static bool is_initialised = false;
|
||||||
|
static uint32_t cache_flash_sector_id;
|
||||||
|
static uint32_t cache_flash_sector_start;
|
||||||
|
static uint32_t cache_flash_sector_size;
|
||||||
|
static bool cache_dirty;
|
||||||
|
|
||||||
|
static void cache_flush() {
|
||||||
|
if (cache_dirty) {
|
||||||
|
// sync the cache RAM buffer by writing it to the flash page
|
||||||
|
flash_write(cache_flash_sector_start, (const uint32_t*)CACHE_MEM_START_ADDR, cache_flash_sector_size / 4);
|
||||||
|
cache_dirty = false;
|
||||||
|
// indicate a clean cache with LED off
|
||||||
|
led_state(PYB_LED_R1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *cache_get_addr_for_write(uint32_t flash_addr) {
|
||||||
|
uint32_t flash_sector_start;
|
||||||
|
uint32_t flash_sector_size;
|
||||||
|
uint32_t flash_sector_id = flash_get_sector_info(flash_addr, &flash_sector_start, &flash_sector_size);
|
||||||
|
if (cache_flash_sector_id != flash_sector_id) {
|
||||||
|
cache_flush();
|
||||||
|
memcpy((void*)CACHE_MEM_START_ADDR, (const void*)flash_sector_start, flash_sector_size);
|
||||||
|
cache_flash_sector_id = flash_sector_id;
|
||||||
|
cache_flash_sector_start = flash_sector_start;
|
||||||
|
cache_flash_sector_size = flash_sector_size;
|
||||||
|
}
|
||||||
|
cache_dirty = true;
|
||||||
|
// indicate a dirty cache with LED on
|
||||||
|
led_state(PYB_LED_R1, 1);
|
||||||
|
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void storage_init() {
|
||||||
|
cache_flash_sector_id = 0;
|
||||||
|
cache_dirty = false;
|
||||||
|
is_initialised = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void storage_flush() {
|
||||||
|
cache_flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) {
|
||||||
|
buf[0] = boot;
|
||||||
|
|
||||||
|
if (num_blocks == 0) {
|
||||||
|
buf[1] = 0;
|
||||||
|
buf[2] = 0;
|
||||||
|
buf[3] = 0;
|
||||||
|
} else {
|
||||||
|
buf[1] = 0xff;
|
||||||
|
buf[2] = 0xff;
|
||||||
|
buf[3] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[4] = type;
|
||||||
|
|
||||||
|
if (num_blocks == 0) {
|
||||||
|
buf[5] = 0;
|
||||||
|
buf[6] = 0;
|
||||||
|
buf[7] = 0;
|
||||||
|
} else {
|
||||||
|
buf[5] = 0xff;
|
||||||
|
buf[6] = 0xff;
|
||||||
|
buf[7] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[8] = start_block;
|
||||||
|
buf[9] = start_block >> 8;
|
||||||
|
buf[10] = start_block >> 16;
|
||||||
|
buf[11] = start_block >> 24;
|
||||||
|
|
||||||
|
buf[12] = num_blocks;
|
||||||
|
buf[13] = num_blocks >> 8;
|
||||||
|
buf[14] = num_blocks >> 16;
|
||||||
|
buf[15] = num_blocks >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool storage_read_block(uint8_t *dest, uint32_t block) {
|
||||||
|
//printf("RD %u\n", block);
|
||||||
|
if (block == 0) {
|
||||||
|
// fake the MBR so we can decide on our own partition table
|
||||||
|
|
||||||
|
for (int i = 0; i < 446; i++) {
|
||||||
|
dest[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
build_partition(dest + 446, 0, 0x01 /* FAT12 */, FLASH_PART1_START_BLOCK, FLASH_PART1_NUM_BLOCKS);
|
||||||
|
build_partition(dest + 462, 0, 0, 0, 0);
|
||||||
|
build_partition(dest + 478, 0, 0, 0, 0);
|
||||||
|
build_partition(dest + 494, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
dest[510] = 0x55;
|
||||||
|
dest[511] = 0xaa;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
|
||||||
|
// non-MBR block, just copy straight from flash
|
||||||
|
uint8_t *src = (uint8_t*)FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * BLOCK_SIZE;
|
||||||
|
memcpy(dest, src, BLOCK_SIZE);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// bad block number
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool storage_write_block(const uint8_t *src, uint32_t block) {
|
||||||
|
//printf("WR %u\n", block);
|
||||||
|
if (block == 0) {
|
||||||
|
// can't write MBR, but pretend we did
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
|
||||||
|
// non-MBR block, copy to cache
|
||||||
|
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * BLOCK_SIZE;
|
||||||
|
uint8_t *dest = cache_get_addr_for_write(flash_addr);
|
||||||
|
memcpy(dest, src, BLOCK_SIZE);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// bad block number
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
4
stm/storage.h
Normal file
4
stm/storage.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
void storage_init();
|
||||||
|
void storage_flush();
|
||||||
|
bool storage_read_block(uint8_t *dest, uint32_t block);
|
||||||
|
bool storage_write_block(const uint8_t *src, uint32_t block);
|
Loading…
Reference in New Issue
Block a user