mp_uint_t sdcard_read_blocks(uint8_t *buff, uint32_t sector, uint32_t count) { HAL_SD_ErrorTypedef err; // If buffer is unaligned or located in CCM don't use DMA. if (CCM_BUFFER(buff) || UNALIGNED_BUFFER(buff)) { if (UNALIGNED_BUFFER(buff)) { printf("unaligned read buf:%p count%lu \n", buff, count); } // This transfer has to be done in an atomic section. mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); err = HAL_SD_ReadBlocks(&SDHandle, (uint32_t*)buff, sector * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, count); MICROPY_END_ATOMIC_SECTION(atomic_state); } else { // Disable USB IRQ to prevent FatFS/MSC contention HAL_NVIC_DisableIRQ(OTG_FS_IRQn); __DSB(); __ISB(); dma_init(SDIO_TXRX_STREAM, SDIO_TXRX_CHANNEL, DMA_PERIPH_TO_MEMORY); err = HAL_SD_ReadBlocks_DMA(&SDHandle, (uint32_t*)buff, sector * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, count); if (err == SD_OK) { err = HAL_SD_CheckReadOperation(&SDHandle, SDIO_TIMEOUT); } if (err != SD_OK) { printf("read buf:%p addr:%lu count%lu error:%d\n", buff, sector, count, err); } dma_deinit(); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); } return (err != SD_OK); }
mp_uint_t sdcard_write_blocks(const uint8_t *buff, uint32_t sector, uint32_t count) { HAL_SD_ErrorTypedef err; mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); err = HAL_SD_WriteBlocks(&SDHandle, (uint32_t*)buff, sector * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, count); MICROPY_END_ATOMIC_SECTION(atomic_state); return (err != SD_OK); }
mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { // check that src pointer is aligned on a 4-byte boundary if (((uint32_t)src & 3) != 0) { return SD_ERROR; } // check that SD card is initialised if (sd_handle.Instance == NULL) { return SD_ERROR; } // We must disable IRQs because the SDIO peripheral has a small FIFO // buffer and we can't let it drain to empty in the middle of a write. // This will not be needed when SD uses DMA for transfer. mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); HAL_SD_ErrorTypedef err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks); MICROPY_END_ATOMIC_SECTION(atomic_state); return err; }
mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in) { mp_int_t size = mp_obj_get_int(size_in); void *buf = NULL; if (size > 0) { buf = m_malloc(size); } int old_size = mp_emergency_exception_buf_size; void *old_buf = mp_emergency_exception_buf; // Update the 2 variables atomically so that an interrupt can't occur // between the assignments. mp_uint_t irq_state = MICROPY_BEGIN_ATOMIC_SECTION(); mp_emergency_exception_buf_size = size; mp_emergency_exception_buf = buf; MICROPY_END_ATOMIC_SECTION(irq_state); if (old_buf != NULL) { m_free(old_buf, old_size); } return mp_const_none; }
STATIC void wiz_cris_enter(void) { wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION(); }
// Support functions for memory protection. lwIP has its own memory management // routines for its internal structures, and since they might be called in // interrupt handlers, they need some protection. sys_prot_t sys_arch_protect() { return (sys_prot_t)MICROPY_BEGIN_ATOMIC_SECTION(); }
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; }