int spi_read_status(int chip) { struct sfreg_t *sfreg = reg_sf; unsigned long temp, timeout = 0x30000000; int rc; do { //REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; if (chip == 0) temp = sfreg->SPI_MEM_0_SR_ACC; else temp = sfreg->SPI_MEM_1_SR_ACC; /* please SPI flash data sheet */ if ((temp & 0x1) == 0x0) break; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) { /*printk(KERN_ERR "flash error rc = 0x%x\n", rc);*/ sfreg->SPI_ERROR_STATUS = 0x3F; /* write 1 to clear status*/ goto sf_err1; } timeout--; } while (timeout); if (timeout == 0) return ERR_TIMOUT; return 0; sf_err1: return rc; }
void __fatal_error(const char *msg) { #if MICROPY_HW_HAS_LCD lcd_print_strn("\nFATAL ERROR:\n", 14); lcd_print_strn(msg, strlen(msg)); #endif for (;;) { flash_error(1); } }
void fatality(void) { led_state(PYB_LED_R1, 1); led_state(PYB_LED_G1, 1); led_state(PYB_LED_R2, 1); led_state(PYB_LED_G2, 1); for (;;) { flash_error(1); } }
int spi_flash_write_status(int chip, int value) { unsigned long rl_data ; unsigned long temp; int start_time, end_time; int rc ; /* SPI flash write enable control register: write enable on chip sel 0 */ //tmp1 = get_timer_masked(); wmt_read_ostc(&start_time); end_time = start_time + 1; if (chip == 0) { sfreg->SPI_WR_EN_CTR = SF_CS0_WR_EN; sfreg->SPI_MEM_0_SR_ACC = value; /* poll status reg of chip 0 for chip erase */ do { temp = sfreg->SPI_MEM_0_SR_ACC; temp = sfreg->SPI_MEM_0_SR_ACC; /* please SPI flash data sheet */ if ((temp & 0x1) == 0x0) break ; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) return rc ; wmt_read_ostc(&end_time); } while ((end_time - start_time) < CFG_FLASH_ERASE_TOUT); if ((end_time - start_time) >= CFG_FLASH_ERASE_TOUT) { rl_data = BIT_TIMEOUT; rc = flash_error(rl_data); return rc; } sfreg->SPI_WR_EN_CTR = SF_CS0_WR_DIS ; return ERR_OK ; } else { sfreg->SPI_WR_EN_CTR = SF_CS1_WR_EN; sfreg->SPI_MEM_1_SR_ACC = value; /* poll status reg of chip 0 for chip erase */ do { temp = sfreg->SPI_MEM_1_SR_ACC ; /* please SPI flash data sheet */ if ((temp & 0x1) == 0x0) break ; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) return rc ; } while ((end_time - start_time) < CFG_FLASH_ERASE_TOUT); if ((end_time - start_time) >= CFG_FLASH_ERASE_TOUT) { rl_data = BIT_TIMEOUT ; rc = flash_error(rl_data) ; return rc; } sfreg->SPI_WR_EN_CTR = SF_CS1_WR_DIS ; return ERR_OK ; } }
int main(void) { // TODO disable JTAG // update the SystemCoreClock variable SystemCoreClockUpdate(); // set interrupt priority config to use all 4 bits for pre-empting NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // enable the CCM RAM and the GPIO's RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN; #if MICROPY_HW_HAS_SDCARD { // configure SDIO pins to be high to start with (apparently makes it more robust) // FIXME this is not making them high, it just makes them outputs... GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); // Configure PD.02 CMD line GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); } #endif #if defined(NETDUINO_PLUS_2) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; #if MICROPY_HW_HAS_SDCARD // Turn on the power enable for the sdcard (PB1) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET); #endif // Turn on the power for the 5V on the expansion header (PB2) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET); } #endif // basic sub-system init sys_tick_init(); pendsv_init(); led_init(); #if MICROPY_HW_ENABLE_RTC rtc_init(); #endif // turn on LED to indicate bootup led_state(PYB_LED_G1, 1); // more sub-system init #if MICROPY_HW_HAS_SDCARD sdcard_init(); #endif storage_init(); // uncomment these 2 lines if you want REPL on USART_6 (or another usart) as well as on USB VCP //pyb_usart_global_debug = PYB_USART_YA; //usart_init(pyb_usart_global_debug, 115200); int first_soft_reset = true; soft_reset: // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init qstr_init(); mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); exti_init(); #if MICROPY_HW_HAS_SWITCH switch_init(); #endif #if MICROPY_HW_HAS_LCD // LCD init (just creates class, init hardware by calling LCD()) lcd_init(); #endif #if MICROPY_HW_ENABLE_SERVO // servo servo_init(); #endif #if MICROPY_HW_ENABLE_TIMER // timer timer_init(); #endif #if MICROPY_HW_ENABLE_RNG // RNG RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); RNG_Cmd(ENABLE); #endif pin_map_init(); // add some functions to the builtin Python namespace mp_store_name(MP_QSTR_help, mp_make_function_n(0, pyb_help)); mp_store_name(MP_QSTR_open, mp_make_function_n(2, pyb_io_open)); // load the pyb module mp_module_register(MP_QSTR_pyb, (mp_obj_t)&pyb_module); // check if user switch held (initiates reset of filesystem) bool reset_filesystem = false; #if MICROPY_HW_HAS_SWITCH if (switch_get()) { reset_filesystem = true; for (int i = 0; i < 50; i++) { if (!switch_get()) { reset_filesystem = false; break; } sys_tick_delay_ms(10); } } #endif // local filesystem init { // try to mount the flash FRESULT res = f_mount(&fatfs0, "0:", 1); if (!reset_filesystem && res == FR_OK) { // mount sucessful } else if (reset_filesystem || res == FR_NO_FILESYSTEM) { // no filesystem, so create a fresh one // TODO doesn't seem to work correctly when reset_filesystem is true... // LED on to indicate creation of LFS led_state(PYB_LED_R2, 1); uint32_t stc = sys_tick_counter; res = f_mkfs("0:", 0, 0); if (res == FR_OK) { // success creating fresh LFS } else { __fatal_error("could not create LFS"); } // create src directory res = f_mkdir("0:/src"); // ignore result from mkdir // create empty main.py FIL fp; f_open(&fp, "0:/src/main.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(stc, 200); led_state(PYB_LED_R2, 0); } else { __fatal_error("could not access LFS"); } } // make sure we have a /boot.py { FILINFO fno; FRESULT res = f_stat("0:/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { // exists as a directory // TODO handle this case // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation } else { // exists as a file, good! } } else { // doesn't exist, create fresh file // LED on to indicate creation of boot.py led_state(PYB_LED_R2, 1); uint32_t stc = sys_tick_counter; FIL fp; f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(stc, 200); led_state(PYB_LED_R2, 0); } } // run /boot.py if (!pyexec_file("0:/boot.py")) { flash_error(4); } if (first_soft_reset) { #if MICROPY_HW_HAS_MMA7660 // MMA accel: init and reset address to zero accel_init(); #endif } // turn boot-up LED off led_state(PYB_LED_G1, 0); #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on 1:/ if (sdcard_is_present()) { FRESULT res = f_mount(&fatfs1, "1:", 1); if (res != FR_OK) { printf("[SD] could not mount SD card\n"); } else { if (first_soft_reset) { // use SD card as medium for the USB MSD usbd_storage_select_medium(USBD_STORAGE_MEDIUM_SDCARD); } } } #endif #ifdef USE_HOST_MODE // USB host pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC); #endif // run main script { vstr_t *vstr = vstr_new(); vstr_add_str(vstr, "0:/"); if (pyb_config_source_dir == MP_OBJ_NULL) { vstr_add_str(vstr, "src"); } else { vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_source_dir)); } vstr_add_char(vstr, '/'); if (pyb_config_main == MP_OBJ_NULL) { vstr_add_str(vstr, "main.py"); } else { vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_main)); } if (!pyexec_file(vstr_str(vstr))) { flash_error(3); } vstr_free(vstr); } #if MICROPY_HW_HAS_MMA7660 // HID example if (0) { uint8_t data[4]; data[0] = 0; data[1] = 1; data[2] = -2; data[3] = 0; for (;;) { #if MICROPY_HW_HAS_SWITCH if (switch_get()) { data[0] = 0x01; // 0x04 is middle, 0x02 is right } else { data[0] = 0x00; } #else data[0] = 0x00; #endif accel_start(0x4c /* ACCEL_ADDR */, 1); accel_send_byte(0); accel_restart(0x4c /* ACCEL_ADDR */, 0); for (int i = 0; i <= 1; i++) { int v = accel_read_ack() & 0x3f; if (v & 0x20) { v |= ~0x1f; } data[1 + i] = v; } accel_read_nack(); usb_hid_send_report(data); sys_tick_delay_ms(15); } } #endif #if MICROPY_HW_HAS_WLAN // wifi pyb_wlan_init(); pyb_wlan_start(); #endif pyexec_repl(); printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); first_soft_reset = false; goto soft_reset; }
int spi_flash_sector_write(struct sfreg_t *sfreg, unsigned char *sf_base_addr, loff_t to, size_t len, u_char *buf) { unsigned long temp; unsigned int i = 0; int rc ; unsigned long timeout = 0x30000000; size_t retlen; REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; udelay(1); //printk("wr sf check"); if ((to + MTDSF_PHY_ADDR) >= g_sf_info[0].phy) { rc = spi_read_status(0); if (rc) printk("wr c0 wait status ret=%d\n", rc); } else { rc = spi_read_status(1); if (rc) printk("wr c1 wait status ret=%d\n", rc); } //printk("end\n"); sfreg->SPI_WR_EN_CTR = 0x03; while (len >= 8) { memcpy_toio(((u_char *)(sf_base_addr+to+i)), buf+i, 4); i += 4; memcpy_toio(((u_char *)(sf_base_addr+to+i)), (buf+i), 4); i += 4; len -= 8; timeout = 0x30000000; do { temp = sfreg->SPI_MEM_0_SR_ACC ; /* please see SPI flash data sheet */ if ((temp & 0x1) == 0x0) break ; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) { sfreg->SPI_ERROR_STATUS = 0x3F ; /* write 1 to clear status */ goto sf_wr_err; } timeout--; } while (timeout); if (timeout == 0) { printk(KERN_ERR "time out \n"); goto err_timeout; } } while (len >= 4) { memcpy_toio(((u_char *)(sf_base_addr+to+i)), (u_char*)(buf+i), 4); i += 4; len -= 4; if (len) { memcpy_toio(((u_char *)(sf_base_addr+to+i)), (u_char*)(buf+i), 1); i++; len--; } timeout = 0x30000000; do { temp = sfreg->SPI_MEM_0_SR_ACC ; /* please see SPI flash data sheet */ if ((temp & 0x1) == 0x0) break; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) { sfreg->SPI_ERROR_STATUS = 0x3F ; /* write 1 to clear status */ goto sf_wr_err; } timeout--; } while (timeout); if (timeout == 0) { printk(KERN_ERR "time out \n"); goto err_timeout; } } while (len) { memcpy_toio(((u_char *)(sf_base_addr+to+i)), (buf+i), 1); i++; len--; if (len) { memcpy_toio(((u_char *)(sf_base_addr+to+i)), (buf+i), 1); i++; len--; } timeout = 0x30000000; do { temp = sfreg->SPI_MEM_0_SR_ACC ; /* please see SPI flash data sheet */ if ((temp & 0x1) == 0x0) break; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) { sfreg->SPI_ERROR_STATUS = 0x3F ; /* write 1 to clear status */ goto sf_wr_err; } timeout--; } while (timeout); if (timeout == 0) { printk(KERN_ERR "time out \n"); goto err_timeout; } } retlen = i; sfreg->SPI_WR_EN_CTR = 0x00; REG32_VAL(PMCEU_ADDR) &= ~(SF_CLOCK_EN); return retlen; err_timeout: return ERR_TIMOUT; sf_wr_err: return rc; }
int spi_flash_sector_erase(unsigned long addr, struct sfreg_t *sfreg) { unsigned long timeout = 0x30000000; unsigned long temp ; int rc ; REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; /* SPI module chip erase SPI flash write enable control register: write enable on chip sel 0 */ if ((addr + MTDSF_PHY_ADDR) >= g_sf_info[0].phy) { sfreg->SPI_WR_EN_CTR = SF_CS0_WR_EN ; /* printk("sfreg->SPI_ER_START_ADDR = %x \n",sfreg->SPI_ER_START_ADDR);*/ /*printk("!!!! Erase chip 0\n"); */ /* select sector to erase */ addr &= 0xFFFF0000; sfreg->SPI_ER_START_ADDR = (addr+MTDSF_PHY_ADDR); /* SPI flash erase control register: start chip erase Auto clear when transmit finishes. */ sfreg->SPI_ER_CTR = SF_SEC_ER_EN; /*printk("sfreg->SPI_ER_START_ADDR = %x \n",sfreg->SPI_ER_START_ADDR);*/ /* poll status reg of chip 0 for chip erase */ do { //printk("0s"); msleep(60); REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; //printk(" 0e\n"); udelay(1); temp = sfreg->SPI_MEM_0_SR_ACC; /* please SPI flash data sheet */ if ((temp & 0x1) == 0x0) break; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) { /*printk(KERN_ERR "flash error rc = 0x%x\n", rc);*/ sfreg->SPI_ERROR_STATUS = 0x3F; /* write 1 to clear status*/ goto sf_err; } timeout--; } while (timeout); if (timeout == 0) goto er_err_timout; sfreg->SPI_WR_EN_CTR = SF_CS0_WR_DIS; goto sf_OK; } else { sfreg->SPI_WR_EN_CTR = SF_CS1_WR_EN; /* select sector to erase */ addr &= 0xFFFF0000; sfreg->SPI_ER_START_ADDR = (addr+MTDSF_PHY_ADDR); /* SPI flash erase control register: start chip erase Auto clear when transmit finishes. */ sfreg->SPI_ER_CTR = SF_SEC_ER_EN; /* poll status reg of chip 0 for chip erase */ do { //printk("1s"); msleep(60); REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN; //printk(" 1e\n"); udelay(1); temp = sfreg->SPI_MEM_1_SR_ACC; /* please SPI flash data sheet */ if ((temp & 0x1) == 0x0) break; rc = flash_error(sfreg->SPI_ERROR_STATUS); if (rc != ERR_OK) { sfreg->SPI_ERROR_STATUS = 0x3F ; /* write 1 to clear status*/ goto sf_err; } timeout--; } while (timeout); if (timeout == 0) goto er_err_timout; sfreg->SPI_WR_EN_CTR = SF_CS1_WR_DIS ; goto sf_OK; } sf_OK: return ERR_OK; sf_err: return rc; er_err_timout: return ERR_TIMOUT; }
int main(void) { // Stack limit should be less than real stack size, so we // had chance to recover from limit hit. mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024); /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); // basic sub-system init pendsv_init(); timer_tim3_init(); led_init(); soft_reset: // check if user switch held to select the reset mode led_state(LED_RED, 1); led_state(LED_GREEN, 1); led_state(LED_BLUE, 1); #if MICROPY_HW_ENABLE_RTC rtc_init(); #endif // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); readline_init0(); pin_init0(); extint_init0(); timer_init0(); rng_init0(); i2c_init0(); spi_init0(); uart_init0(); pyb_usb_init0(); usbdbg_init(); if (sensor_init() != 0) { __fatal_error("Failed to init sensor"); } /* Export functions to the global python namespace */ mp_store_global(qstr_from_str("randint"), (mp_obj_t)&py_randint_obj); mp_store_global(qstr_from_str("cpu_freq"), (mp_obj_t)&py_cpu_freq_obj); mp_store_global(qstr_from_str("Image"), (mp_obj_t)&py_image_load_image_obj); mp_store_global(qstr_from_str("HaarCascade"), (mp_obj_t)&py_image_load_cascade_obj); mp_store_global(qstr_from_str("FreakDesc"), (mp_obj_t)&py_image_load_descriptor_obj); mp_store_global(qstr_from_str("FreakDescSave"), (mp_obj_t)&py_image_save_descriptor_obj); mp_store_global(qstr_from_str("LBPDesc"), (mp_obj_t)&py_image_load_lbp_obj); mp_store_global(qstr_from_str("vcp_is_connected"), (mp_obj_t)&py_vcp_is_connected_obj); if (sdcard_is_present()) { sdcard_init(); FRESULT res = f_mount(&fatfs, "1:", 1); if (res != FR_OK) { __fatal_error("could not mount SD\n"); } // Set CWD and USB medium to SD f_chdrive("1:"); pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD; } else { storage_init(); // try to mount the flash FRESULT res = f_mount(&fatfs, "0:", 1); if (res == FR_NO_FILESYSTEM) { // create a fresh fs make_flash_fs(); } else if (res != FR_OK) { __fatal_error("could not access LFS\n"); } // Set CWD and USB medium to flash f_chdrive("0:"); pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_FLASH; } // turn boot-up LEDs off led_state(LED_RED, 0); led_state(LED_GREEN, 0); led_state(LED_BLUE, 0); // init USB device to default setting if it was not already configured if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) { pyb_usb_dev_init(USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, NULL); } // Run the main script from the current directory. FRESULT res = f_stat("main.py", NULL); if (res == FR_OK) { if (!pyexec_file("main.py")) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { flash_error(3); nlr_pop(); } } } // Enter REPL nlr_buf_t nlr; for (;;) { if (nlr_push(&nlr) == 0) { while (usbdbg_script_ready()) { nlr_buf_t nlr; vstr_t *script_buf = usbdbg_get_script(); // clear script flag usbdbg_clr_script(); // execute the script if (nlr_push(&nlr) == 0) { pyexec_push_scope(); // parse and compile script mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(script_buf), vstr_len(script_buf), 0); mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_obj_t script = mp_compile(pn, lex->source_name, MP_EMIT_OPT_NONE, false); // execute the script mp_call_function_0(script); nlr_pop(); } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } pyexec_pop_scope(); } // clear script flag usbdbg_clr_script(); // no script run REPL pyexec_friendly_repl(); nlr_pop(); } } printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); goto soft_reset; }
int main(void) { FRESULT f_res; int sensor_init_ret; // Stack limit should be less than real stack size, so we // had chance to recover from limit hit. mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024); /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); // basic sub-system init pendsv_init(); timer_tim3_init(); led_init(); soft_reset: // check if user switch held to select the reset mode led_state(LED_RED, 1); led_state(LED_GREEN, 1); led_state(LED_BLUE, 1); #if MICROPY_HW_ENABLE_RTC rtc_init(); #endif // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); readline_init0(); pin_init0(); extint_init0(); timer_init0(); rng_init0(); i2c_init0(); spi_init0(); uart_init0(); pyb_usb_init0(); usbdbg_init(); sensor_init_ret = sensor_init(); /* Export functions to the global python namespace */ mp_store_global(qstr_from_str("randint"), (mp_obj_t)&py_randint_obj); mp_store_global(qstr_from_str("cpu_freq"), (mp_obj_t)&py_cpu_freq_obj); mp_store_global(qstr_from_str("vcp_is_connected"), (mp_obj_t)&py_vcp_is_connected_obj); if (sdcard_is_present()) { sdcard_init(); FRESULT res = f_mount(&fatfs, "1:", 1); if (res != FR_OK) { __fatal_error("could not mount SD\n"); } // Set CWD and USB medium to SD f_chdrive("1:"); pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD; } else { storage_init(); // try to mount the flash FRESULT res = f_mount(&fatfs, "0:", 1); if (res == FR_NO_FILESYSTEM) { // create a fresh fs make_flash_fs(); } else if (res != FR_OK) { __fatal_error("could not access LFS\n"); } // Set CWD and USB medium to flash f_chdrive("0:"); pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_FLASH; } // turn boot-up LEDs off led_state(LED_RED, 0); led_state(LED_GREEN, 0); led_state(LED_BLUE, 0); // init USB device to default setting if it was not already configured if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) { pyb_usb_dev_init(USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, NULL); } // check sensor init result if (sensor_init_ret != 0) { char buf[512]; snprintf(buf, sizeof(buf), "Failed to init sensor, error:%d", sensor_init_ret); __fatal_error(buf); } // Run self tests the first time only f_res = f_stat("selftest.py", NULL); if (f_res == FR_OK) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { // Parse, compile and execute the self-tests script. pyexec_file("selftest.py"); nlr_pop(); } else { // Get the exception message. TODO: might be a hack. mp_obj_str_t *str = mp_obj_exception_get_value((mp_obj_t)nlr.ret_val); // If any of the self-tests fail log the exception message // and loop forever. Note: IDE exceptions will not be caught. __fatal_error((const char*) str->data); } // Success: remove self tests script and flush cache f_unlink("selftest.py"); storage_flush(); } // Run the main script from the current directory. f_res = f_stat("main.py", NULL); if (f_res == FR_OK) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { // Parse, compile and execute the main script. pyexec_file("main.py"); nlr_pop(); } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); if (nlr_push(&nlr) == 0) { flash_error(3); nlr_pop(); }// if this gets interrupted again ignore it. } } // Enter REPL nlr_buf_t nlr; for (;;) { if (nlr_push(&nlr) == 0) { while (usbdbg_script_ready()) { nlr_buf_t nlr; vstr_t *script_buf = usbdbg_get_script(); // clear debugging flags usbdbg_clear_flags(); // re-init MP mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); mp_init(); MICROPY_END_ATOMIC_SECTION(atomic_state); // execute the script if (nlr_push(&nlr) == 0) { // parse, compile and execute script pyexec_str(script_buf); nlr_pop(); } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } } // clear debugging flags usbdbg_clear_flags(); // re-init MP mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); mp_init(); MICROPY_END_ATOMIC_SECTION(atomic_state); // no script run REPL pyexec_friendly_repl(); nlr_pop(); } } printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); goto soft_reset; }
int main(void) { // TODO disable JTAG /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); // set the system clock to be HSE SystemClock_Config(); // enable GPIO clocks __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOD_CLK_ENABLE(); // enable the CCM RAM __CCMDATARAMEN_CLK_ENABLE(); #if 0 #if defined(NETDUINO_PLUS_2) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; #if MICROPY_HW_HAS_SDCARD // Turn on the power enable for the sdcard (PB1) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET); #endif // Turn on the power for the 5V on the expansion header (PB2) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET); } #endif #endif // basic sub-system init pendsv_init(); timer_tim3_init(); led_init(); switch_init0(); int first_soft_reset = true; soft_reset: // check if user switch held to select the reset mode led_state(1, 0); led_state(2, 1); led_state(3, 0); led_state(4, 0); uint reset_mode = 1; #if MICROPY_HW_HAS_SWITCH if (switch_get()) { for (uint i = 0; i < 3000; i++) { if (!switch_get()) { break; } HAL_Delay(20); if (i % 30 == 29) { if (++reset_mode > 3) { reset_mode = 1; } led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); } } // flash the selected reset mode for (uint i = 0; i < 6; i++) { led_state(2, 0); led_state(3, 0); led_state(4, 0); HAL_Delay(50); led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); HAL_Delay(50); } HAL_Delay(400); } #endif #if MICROPY_HW_ENABLE_RTC if (first_soft_reset) { rtc_init(); } #endif // more sub-system init #if MICROPY_HW_HAS_SDCARD if (first_soft_reset) { sdcard_init(); } #endif if (first_soft_reset) { storage_init(); } // GC init gc_init(&_heap_start, &_heap_end); // Change #if 0 to #if 1 if you want REPL on USART_6 (or another usart) // as well as on USB VCP #if 0 pyb_usart_global_debug = pyb_Usart(MP_OBJ_NEW_SMALL_INT(PYB_USART_YA), MP_OBJ_NEW_SMALL_INT(115200)); #else pyb_usart_global_debug = NULL; #endif // Micro Python init qstr_init(); mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); readline_init(); exti_init(); #if MICROPY_HW_HAS_SWITCH // must come after exti_init switch_init(); #endif #if MICROPY_HW_HAS_LCD // LCD init (just creates class, init hardware by calling LCD()) lcd_init(); #endif pin_map_init(); // local filesystem init { // try to mount the flash FRESULT res = f_mount(&fatfs0, "0:", 1); if (reset_mode == 3 || res == FR_NO_FILESYSTEM) { // no filesystem, or asked to reset it, so create a fresh one // LED on to indicate creation of LFS led_state(PYB_LED_R2, 1); uint32_t start_tick = HAL_GetTick(); res = f_mkfs("0:", 0, 0); if (res == FR_OK) { // success creating fresh LFS } else { __fatal_error("could not create LFS"); } // create empty main.py FIL fp; f_open(&fp, "0:/main.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // create .inf driver file f_open(&fp, "0:/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS); f_write(&fp, fresh_pybcdc_inf, sizeof(fresh_pybcdc_inf) - 1 /* don't count null terminator */, &n); f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(start_tick, 200); led_state(PYB_LED_R2, 0); } else if (res == FR_OK) { // mount sucessful } else { __fatal_error("could not access LFS"); } } // make sure we have a 0:/boot.py { FILINFO fno; #if _USE_LFN fno.lfname = NULL; fno.lfsize = 0; #endif FRESULT res = f_stat("0:/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { // exists as a directory // TODO handle this case // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation } else { // exists as a file, good! } } else { // doesn't exist, create fresh file // LED on to indicate creation of boot.py led_state(PYB_LED_R2, 1); uint32_t start_tick = HAL_GetTick(); FIL fp; f_open(&fp, "0:/boot.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(start_tick, 200); led_state(PYB_LED_R2, 0); } } // root device defaults to internal flash filesystem uint root_device = 0; #if defined(USE_DEVICE_MODE) usb_storage_medium_t usb_medium = USB_STORAGE_MEDIUM_FLASH; #endif #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on 1:/ if (reset_mode == 1 && sdcard_is_present()) { FRESULT res = f_mount(&fatfs1, "1:", 1); if (res != FR_OK) { printf("[SD] could not mount SD card\n"); } else { // use SD card as root device root_device = 1; if (first_soft_reset) { // use SD card as medium for the USB MSD #if defined(USE_DEVICE_MODE) usb_medium = USB_STORAGE_MEDIUM_SDCARD; #endif } } } #else // Get rid of compiler warning if no SDCARD is configured. (void)first_soft_reset; #endif // run <root>:/boot.py, if it exists if (reset_mode == 1) { const char *boot_file; if (root_device == 0) { boot_file = "0:/boot.py"; } else { boot_file = "1:/boot.py"; } FRESULT res = f_stat(boot_file, NULL); if (res == FR_OK) { if (!pyexec_file(boot_file)) { flash_error(4); } } } // turn boot-up LEDs off led_state(2, 0); led_state(3, 0); led_state(4, 0); #if defined(USE_HOST_MODE) // USB host pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device if (reset_mode == 1) { usb_device_mode_t usb_mode = USB_DEVICE_MODE_CDC_MSC; if (pyb_config_usb_mode != MP_OBJ_NULL) { if (strcmp(mp_obj_str_get_str(pyb_config_usb_mode), "CDC+HID") == 0) { usb_mode = USB_DEVICE_MODE_CDC_HID; } } pyb_usb_dev_init(usb_mode, usb_medium); } else { pyb_usb_dev_init(USB_DEVICE_MODE_CDC_MSC, usb_medium); } #endif #if MICROPY_HW_ENABLE_RNG // RNG rng_init(); #endif #if MICROPY_HW_ENABLE_TIMER // timer //timer_init(); #endif // I2C i2c_init(); #if MICROPY_HW_HAS_MMA7660 // MMA accel: init and reset accel_init(); #endif #if MICROPY_HW_ENABLE_SERVO // servo servo_init(); #endif #if MICROPY_HW_ENABLE_DAC // DAC dac_init(); #endif // now that everything is initialised, run main script if (reset_mode == 1 && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { vstr_t *vstr = vstr_new(); vstr_printf(vstr, "%d:/", root_device); if (pyb_config_main == MP_OBJ_NULL) { vstr_add_str(vstr, "main.py"); } else { vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_main)); } FRESULT res = f_stat(vstr_str(vstr), NULL); if (res == FR_OK) { if (!pyexec_file(vstr_str(vstr))) { flash_error(3); } } vstr_free(vstr); } #if 0 #if MICROPY_HW_HAS_WLAN // wifi pyb_wlan_init(); pyb_wlan_start(); #endif #endif // enter REPL // REPL mode can change, or it can request a soft reset for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { break; } } else { if (pyexec_friendly_repl() != 0) { break; } } } printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); first_soft_reset = false; goto soft_reset; }
int main(void) { // TODO disable JTAG // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024); /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); // set the system clock to be HSE SystemClock_Config(); // enable GPIO clocks __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOD_CLK_ENABLE(); // enable the CCM RAM __CCMDATARAMEN_CLK_ENABLE(); #if 0 #if defined(NETDUINO_PLUS_2) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; #if MICROPY_HW_HAS_SDCARD // Turn on the power enable for the sdcard (PB1) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET); #endif // Turn on the power for the 5V on the expansion header (PB2) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET); } #endif #endif // basic sub-system init pendsv_init(); timer_tim3_init(); led_init(); #if MICROPY_HW_HAS_SWITCH switch_init0(); #endif int first_soft_reset = true; soft_reset: // check if user switch held to select the reset mode led_state(1, 0); led_state(2, 1); led_state(3, 0); led_state(4, 0); uint reset_mode = 1; #if MICROPY_HW_HAS_SWITCH if (switch_get()) { for (uint i = 0; i < 3000; i++) { if (!switch_get()) { break; } HAL_Delay(20); if (i % 30 == 29) { if (++reset_mode > 3) { reset_mode = 1; } led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); } } // flash the selected reset mode for (uint i = 0; i < 6; i++) { led_state(2, 0); led_state(3, 0); led_state(4, 0); HAL_Delay(50); led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); led_state(4, reset_mode & 4); HAL_Delay(50); } HAL_Delay(400); } #endif #if MICROPY_HW_ENABLE_RTC if (first_soft_reset) { rtc_init(); } #endif // more sub-system init #if MICROPY_HW_HAS_SDCARD if (first_soft_reset) { sdcard_init(); } #endif if (first_soft_reset) { storage_init(); } // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script) mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib)); mp_obj_list_init(mp_sys_argv, 0); // Change #if 0 to #if 1 if you want REPL on UART_6 (or another uart) // as well as on USB VCP #if 0 { mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(PYB_UART_6), MP_OBJ_NEW_SMALL_INT(115200), }; pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); } #else pyb_stdio_uart = NULL; #endif // Initialise low-level sub-systems. Here we need to very basic things like // zeroing out memory and resetting any of the sub-systems. Following this // we can run Python scripts (eg boot.py), but anything that is configurable // by boot.py must be set after boot.py is run. readline_init0(); pin_init0(); extint_init0(); timer_init0(); uart_init0(); #if MICROPY_HW_ENABLE_RNG rng_init0(); #endif i2c_init0(); spi_init0(); pyb_usb_init0(); // Initialise the local flash filesystem. // Create it if needed, and mount in on /flash. { // try to mount the flash FRESULT res = f_mount(&fatfs0, "/flash", 1); if (reset_mode == 3 || res == FR_NO_FILESYSTEM) { // no filesystem, or asked to reset it, so create a fresh one // LED on to indicate creation of LFS led_state(PYB_LED_R2, 1); uint32_t start_tick = HAL_GetTick(); res = f_mkfs("/flash", 0, 0); if (res == FR_OK) { // success creating fresh LFS } else { __fatal_error("could not create LFS"); } // set label f_setlabel("/flash/pybflash"); // create empty main.py FIL fp; f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // create .inf driver file f_open(&fp, "/flash/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS); f_write(&fp, fresh_pybcdc_inf, sizeof(fresh_pybcdc_inf) - 1 /* don't count null terminator */, &n); f_close(&fp); // create readme file f_open(&fp, "/flash/README.txt", FA_WRITE | FA_CREATE_ALWAYS); f_write(&fp, fresh_readme_txt, sizeof(fresh_readme_txt) - 1 /* don't count null terminator */, &n); f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(start_tick, 200); led_state(PYB_LED_R2, 0); } else if (res == FR_OK) { // mount sucessful } else { __fatal_error("could not access LFS"); } } // The current directory is used as the boot up directory. // It is set to the internal flash filesystem by default. f_chdrive("/flash"); // Make sure we have a /flash/boot.py. Create it if needed. { FILINFO fno; #if _USE_LFN fno.lfname = NULL; fno.lfsize = 0; #endif FRESULT res = f_stat("/flash/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { // exists as a directory // TODO handle this case // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation } else { // exists as a file, good! } } else { // doesn't exist, create fresh file // LED on to indicate creation of boot.py led_state(PYB_LED_R2, 1); uint32_t start_tick = HAL_GetTick(); FIL fp; f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); // keep LED on for at least 200ms sys_tick_wait_at_least(start_tick, 200); led_state(PYB_LED_R2, 0); } } #if defined(USE_DEVICE_MODE) usb_storage_medium_t usb_medium = USB_STORAGE_MEDIUM_FLASH; #endif #if MICROPY_HW_HAS_SDCARD // if an SD card is present then mount it on /sd/ if (sdcard_is_present()) { FRESULT res = f_mount(&fatfs1, "/sd", 1); if (res != FR_OK) { printf("[SD] could not mount SD card\n"); } else { // use SD card as current directory f_chdrive("/sd"); // TODO these should go before the /flash entries in the path mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib)); if (first_soft_reset) { // use SD card as medium for the USB MSD #if defined(USE_DEVICE_MODE) usb_medium = USB_STORAGE_MEDIUM_SDCARD; #endif } } } #endif // reset config variables; they should be set by boot.py pyb_config_main = MP_OBJ_NULL; pyb_config_usb_mode = MP_OBJ_NULL; // run boot.py, if it exists // TODO perhaps have pyb.reboot([bootpy]) function to soft-reboot and execute custom boot.py if (reset_mode == 1) { const char *boot_py = "boot.py"; FRESULT res = f_stat(boot_py, NULL); if (res == FR_OK) { int ret = pyexec_file(boot_py); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { flash_error(4); } } } // turn boot-up LEDs off led_state(2, 0); led_state(3, 0); led_state(4, 0); // Now we initialise sub-systems that need configuration from boot.py, // or whose initialisation can be safely deferred until after running // boot.py. #if defined(USE_HOST_MODE) // USB host pyb_usb_host_init(); #elif defined(USE_DEVICE_MODE) // USB device usb_device_mode_t usb_mode = USB_DEVICE_MODE_CDC_MSC; // if we are not in reset_mode==1, this config variable will always be NULL if (pyb_config_usb_mode != MP_OBJ_NULL) { if (strcmp(mp_obj_str_get_str(pyb_config_usb_mode), "CDC+HID") == 0) { usb_mode = USB_DEVICE_MODE_CDC_HID; } } pyb_usb_dev_init(usb_mode, usb_medium); #endif #if MICROPY_HW_HAS_MMA7660 // MMA accel: init and reset accel_init(); #endif #if MICROPY_HW_ENABLE_SERVO // servo servo_init(); #endif #if MICROPY_HW_ENABLE_DAC // DAC dac_init(); #endif mod_network_init(); // At this point everything is fully configured and initialised. // Run the main script from the current directory. if (reset_mode == 1 && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { const char *main_py; if (pyb_config_main == MP_OBJ_NULL) { main_py = "main.py"; } else { main_py = mp_obj_str_get_str(pyb_config_main); } FRESULT res = f_stat(main_py, NULL); if (res == FR_OK) { int ret = pyexec_file(main_py); if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } if (!ret) { flash_error(3); } } } // Main script is finished, so now go into REPL mode. // The REPL mode can change, or it can request a soft reset. for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { if (pyexec_raw_repl() != 0) { break; } } else { if (pyexec_friendly_repl() != 0) { break; } } } soft_reset_exit: // soft reset printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); timer_deinit(); uart_deinit(); first_soft_reset = false; goto soft_reset; }
uint8_t genMenu() { uint8_t *p; uint16_t filecount = 0; // shut off TI cart bug disableBus(); // open SD card rc = pf_mount(&sd_fs); if (rc) flash_error(1); rc = pf_opendir(&sd_dp, ""); if (rc) flash_error(2); // add menu and browser code writeMenuCode(); while (images_written < MAX_ENTRIES) { // get next item in directory rc = pf_readdir(&sd_dp, &sd_fno); if (rc) flash_error(3); if (sd_fno.fname[0] == 0) // end of dir break; ++filecount; if (sd_fno.fattrib & AM_DIR) continue; // skip directories // check if file ends in ".BIN" p = (uint8_t *)sd_fno.fname; while (*++p); if (p - (uint8_t *)sd_fno.fname < 5 || *--p != 'N' || *--p != 'I' || *--p != 'B' || *--p != '.') continue; --p; // p at last char of filename w/o extension // check image size if (sd_fno.fsize > 32768) continue; #ifdef MULTI_FILE // check for multi-file image // - if file ends in C -> check how many banks // - if file ends in D, E, F -> check if C exists, then ignore uint8_t c; if (sd_fno.fsize == 8192 && *p == 'C') { for (c = 'D'; c <= 'F'; ++c) { *p = c; rc = pf_open(sd_fno.fname); if (rc) break; } *p = 'C'; } else if (sd_fno.fsize == 8192 && (*p == 'D' || *p == 'E' || *p == 'F')) { c = *p; *p = 'C'; rc = pf_open(sd_fno.fname); if (!rc) continue; // current file covered by C file *p = c; // actually not a multi-file image } #endif // create entry if (addEntries(sd_fno.fname)) ++files_written; } // if only one image found, load file directly if (files_written == 1) return 1; // close menu and browser items closeEntries(); // bring cartridge online enableBus(); return 0; }
void loadImage() { uint8_t files_read = 0; UINT bytes_read; // lock RAM for cart disableBus(); ram_addr = 0; rc = pf_mount(&sd_fs); if (rc) flash_error(1); // sender data in buf_entry: F I L E N A M E \0 uint8_t *q = buf_entry; while (*++q); uint8_t *p = q--; // q at last name char == bank indicator *p++ = '.'; *p++ = 'B'; *p++ = 'I'; *p++ = 'N'; *p++ = 0; // load BIN files #ifdef MULTI_FILE while (1) { #else while (files_read == 0) { #endif rc = pf_open((char *)buf_entry); if (rc) break; while (1) { rc = pf_read((void *)buffer, sizeof(buffer), &bytes_read); if (bytes_read == 0) break; p = buffer; while (bytes_read-- > 0) writeMem(*p++); } if (*q - files_read != 'C') break; // single-file ++files_read; ++(*q); // load next BIN } // release cartridge enableBus(); } /* * write single byte to SRAM at current address w/auto increment */ static void writeMem(uint8_t byte) { setRAM(ram_addr, byte); // mirror byte into unused banks if (ram_addr < 0x4000) setRAM(ram_addr + 0x4000, byte); if (ram_addr < 0x2000) { setRAM(ram_addr + 0x2000, byte); setRAM(ram_addr + 0x6000, byte); } ++ram_addr; }