nRF52 update with internal file system support
This commit is contained in:
parent
36ec29d4e8
commit
60a23f0fb6
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -40,3 +40,6 @@
|
||||
[submodule "tools/usb_descriptor"]
|
||||
path = tools/usb_descriptor
|
||||
url = https://github.com/adafruit/usb_descriptor.git
|
||||
[submodule "lib/nrfutil"]
|
||||
path = lib/nrfutil
|
||||
url = https://github.com/adafruit/nRF52_nrfutil
|
||||
|
1
lib/nrfutil
Submodule
1
lib/nrfutil
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 07b43832ee53a4a248c30f5a3014e2632d8aeb88
|
@ -1,6 +1,6 @@
|
||||
# Select the board to build for: if not given on the command line,
|
||||
# then default to pca10040.
|
||||
BOARD ?= pca10040
|
||||
# then default to feather52.
|
||||
BOARD ?= feather52
|
||||
ifeq ($(wildcard boards/$(BOARD)/.),)
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
@ -11,33 +11,38 @@ SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# TODO: Verify that it is a valid target.
|
||||
|
||||
|
||||
ifeq ($(SD), )
|
||||
# If the build directory is not given, make it reflect the board name.
|
||||
BUILD ?= build-$(BOARD)
|
||||
include ../../py/mkenv.mk
|
||||
include boards/$(BOARD)/mpconfigboard.mk
|
||||
-include mpconfigport.mk
|
||||
|
||||
INC += -Idrivers/bluetooth/s132_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/s132_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include
|
||||
INC += -Idrivers/bluetooth/s132_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/s132_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT)
|
||||
|
||||
else
|
||||
# If the build directory is not given, make it reflect the board name.
|
||||
BUILD ?= build-$(BOARD)-$(SD_LOWER)
|
||||
include ../../py/mkenv.mk
|
||||
include boards/$(BOARD)/mpconfigboard_$(SD_LOWER).mk
|
||||
-include mpconfigport.mk
|
||||
|
||||
include drivers/bluetooth/bluetooth_common.mk
|
||||
endif
|
||||
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
FROZEN_MPY_DIR = freeze
|
||||
|
||||
# include py core make definitions
|
||||
include ../../py/py.mk
|
||||
|
||||
include $(TOP)/supervisor/supervisor.mk
|
||||
|
||||
FATFS_DIR = lib/oofatfs
|
||||
MPY_CROSS = ../../mpy-cross/mpy-cross
|
||||
MPY_TOOL = ../../tools/mpy-tool.py
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
@ -105,22 +110,12 @@ LIBS += -L $(dir $(LIBC_FILE_NAME)) -lc
|
||||
LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
|
||||
endif
|
||||
|
||||
SRC_LIB = $(addprefix lib/,\
|
||||
libc/string0.c \
|
||||
mp-readline/readline.c \
|
||||
utils/pyexec.c \
|
||||
timeutils/timeutils.c \
|
||||
oofatfs/ff.c \
|
||||
oofatfs/option/unicode.c \
|
||||
)
|
||||
|
||||
SRC_HAL = $(addprefix hal/,\
|
||||
hal_uart.c \
|
||||
hal_uarte.c \
|
||||
hal_spi.c \
|
||||
hal_spie.c \
|
||||
hal_time.c \
|
||||
hal_rtc.c \
|
||||
hal_timer.c \
|
||||
hal_twi.c \
|
||||
hal_adc.c \
|
||||
@ -136,17 +131,31 @@ SRC_HAL += $(addprefix hal/,\
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
SRC_C += \
|
||||
main.c \
|
||||
mphalport.c \
|
||||
help.c \
|
||||
gccollect.c \
|
||||
pin_named_pins.c \
|
||||
fatfs_port.c \
|
||||
fifo.c \
|
||||
drivers/softpwm.c \
|
||||
drivers/ticker.c \
|
||||
drivers/bluetooth/ble_drv.c \
|
||||
drivers/bluetooth/ble_uart.c \
|
||||
boards/$(BOARD)/board.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
device/$(MCU_VARIANT)/system_$(MCU_SUB_VARIANT).c \
|
||||
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
internal_flash.c \
|
||||
|
||||
|
||||
DRIVERS_SRC_C += $(addprefix modules/,\
|
||||
machine/modmachine.c \
|
||||
@ -156,11 +165,9 @@ DRIVERS_SRC_C += $(addprefix modules/,\
|
||||
machine/adc.c \
|
||||
machine/pin.c \
|
||||
machine/timer.c \
|
||||
machine/rtc.c \
|
||||
machine/pwm.c \
|
||||
machine/led.c \
|
||||
machine/temp.c \
|
||||
uos/moduos.c \
|
||||
utime/modutime.c \
|
||||
pyb/modpyb.c \
|
||||
ubluepy/modubluepy.c \
|
||||
@ -179,18 +186,72 @@ DRIVERS_SRC_C += $(addprefix modules/,\
|
||||
random/modrandom.c \
|
||||
)
|
||||
|
||||
SRC_C += \
|
||||
device/$(MCU_VARIANT)/system_$(MCU_SUB_VARIANT).c \
|
||||
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
|
||||
|
||||
SRC_COMMON_HAL += \
|
||||
board/__init__.c \
|
||||
digitalio/__init__.c \
|
||||
digitalio/DigitalInOut.c \
|
||||
microcontroller/__init__.c \
|
||||
microcontroller/Pin.c \
|
||||
microcontroller/Processor.c \
|
||||
os/__init__.c \
|
||||
time/__init__.c \
|
||||
analogio/__init__.c \
|
||||
analogio/AnalogIn.c \
|
||||
analogio/AnalogOut.c \
|
||||
busio/__init__.c\
|
||||
busio/I2C.c \
|
||||
busio/SPI.c \
|
||||
pulseio/__init__.c \
|
||||
pulseio/PulseIn.c \
|
||||
pulseio/PulseOut.c \
|
||||
pulseio/PWMOut.c \
|
||||
storage/__init__.c \
|
||||
|
||||
# These don't have corresponding files in each port but are still located in
|
||||
# shared-bindings to make it clear what the contents of the modules are.
|
||||
SRC_BINDINGS_ENUMS = \
|
||||
digitalio/Direction.c \
|
||||
digitalio/DriveMode.c \
|
||||
digitalio/Pull.c \
|
||||
help.c \
|
||||
math/__init__.c \
|
||||
supervisor/__init__.c \
|
||||
util.c
|
||||
|
||||
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
|
||||
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
|
||||
$(addprefix common-hal/, $(SRC_COMMON_HAL))
|
||||
|
||||
SRC_SHARED_MODULE = \
|
||||
os/__init__.c \
|
||||
random/__init__.c \
|
||||
storage/__init__.c \
|
||||
|
||||
# bitbangio/__init__.c \
|
||||
bitbangio/I2C.c \
|
||||
bitbangio/OneWire.c \
|
||||
bitbangio/SPI.c \
|
||||
busio/OneWire.c \
|
||||
gamepad/__init__.c \
|
||||
gamepad/GamePad.c \
|
||||
struct/__init__.c \
|
||||
uheap/__init__.c \
|
||||
ustack/__init__.c
|
||||
|
||||
#SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
|
||||
$(addprefix shared-module/, $(SRC_SHARED_MODULE))
|
||||
|
||||
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-module/, $(SRC_SHARED_MODULE))
|
||||
|
||||
FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
|
||||
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
|
||||
|
||||
OBJ += $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
|
||||
OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
|
||||
OBJ += $(BUILD)/pins_gen.o
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
|
||||
$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
|
||||
$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
|
||||
@ -241,11 +302,11 @@ endif
|
||||
|
||||
$(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ)
|
||||
$(ECHO) "LINK $@"
|
||||
$(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
|
||||
$(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) -Wl,--start-group $(LIBS) -Wl,--end-group
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
# List of sources for qstr extraction
|
||||
SRC_QSTR += $(SRC_C) $(SRC_MOD) $(SRC_LIB) $(DRIVERS_SRC_C)
|
||||
SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(DRIVERS_SRC_C) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)
|
||||
|
||||
# Append any auto-generated sources that are needed by sources listed in
|
||||
# SRC_QSTR
|
||||
@ -256,16 +317,16 @@ SRC_QSTR_AUTO_DEPS +=
|
||||
# any of the objects. The normal dependency generation will deal with the
|
||||
# case when pins.h is modified. But when it doesn't exist, we don't know
|
||||
# which source files might need it.
|
||||
$(OBJ): | $(HEADER_BUILD)/pins.h
|
||||
#$(OBJ): | $(HEADER_BUILD)/pins.h
|
||||
|
||||
# Use a pattern rule here so that make will only call make-pins.py once to make
|
||||
# both pins_$(BOARD).c and pins.h
|
||||
$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC)
|
||||
#$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
|
||||
# $(ECHO) "Create $@"
|
||||
# $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC)
|
||||
|
||||
$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
|
||||
$(call compile_c)
|
||||
#$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
|
||||
# $(call compile_c)
|
||||
|
||||
MAKE_PINS = boards/make-pins.py
|
||||
BOARD_PINS = boards/$(BOARD)/pins.csv
|
||||
@ -290,4 +351,4 @@ CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
|
||||
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
|
||||
endif
|
||||
|
||||
include ../../py/mkrules.mk
|
||||
include $(TOP)/py/mkrules.mk
|
||||
|
47
ports/nrf/boards/board.h
Normal file
47
ports/nrf/boards/board.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file defines board specific functions.
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_BOARDS_BOARD_H
|
||||
#define MICROPY_INCLUDED_NRF_BOARDS_BOARD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern volatile uint32_t ticks_ms;
|
||||
|
||||
// Initializes board related state once on start up.
|
||||
void board_init(void);
|
||||
|
||||
// Returns true if the user initiates safe mode in a board specific way.
|
||||
// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific
|
||||
// way.
|
||||
bool board_requests_safe_mode(void);
|
||||
|
||||
// Reset the state of off MCU components such as neopixels.
|
||||
void reset_board(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_BOARDS_BOARD_H
|
@ -1,3 +1,7 @@
|
||||
/* Flash region for File System */
|
||||
__fatfs_flash_start_addr = ORIGIN(FLASH_FATFS);
|
||||
__fatfs_flash_length = LENGTH(FLASH_FATFS);
|
||||
|
||||
/* define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
@ -75,8 +79,8 @@ SECTIONS
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
_heap_start = .; /* define a global symbol at heap start */
|
||||
. = . + _minimum_heap_size;
|
||||
} >RAM
|
||||
@ -101,3 +105,4 @@ SECTIONS
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
# Setup
|
||||
|
||||
Before you can build, you will need to run the following commands once:
|
||||
## Installing CircuitPython submodules
|
||||
|
||||
Before you can build, you will need to run the following commands once, which
|
||||
will install the submodules that are part of the CircuitPython ecosystem, and
|
||||
build the `mpy-cross` tool:
|
||||
|
||||
```
|
||||
$ cd circuitpython
|
||||
@ -8,7 +12,7 @@ $ git submodule update --init
|
||||
$ make -C mpy-cross
|
||||
```
|
||||
|
||||
You then need to download the SD and Nordic SDK files:
|
||||
You then need to download the SD and Nordic SDK files via:
|
||||
|
||||
> This script relies on `wget`, which must be available from the command line.
|
||||
|
||||
@ -17,47 +21,50 @@ $ cd ports/nrf
|
||||
$ ./drivers/bluetooth/download_ble_stack.sh
|
||||
```
|
||||
|
||||
## Installing `nrfutil`
|
||||
|
||||
The Adafruit Bluefruit nRF52 Feather ships with a serial and OTA BLE bootloader
|
||||
that can be used to flash firmware images over a simple serial connection,
|
||||
using the on-board USB serial converter.
|
||||
|
||||
If you haven't installed this command-line tool yet, go to the `/libs/nrfutil`
|
||||
folder (where nrfutil 0.5.2 is installed as a sub-module) and run the following
|
||||
commands:
|
||||
|
||||
> If you get a 'sudo: pip: command not found' error running 'sudo pip install',
|
||||
you can install pip via 'sudo easy_install pip'
|
||||
|
||||
```
|
||||
$ cd ../../libs/nrfutil
|
||||
$ sudo pip install -r requirements.txt
|
||||
$ sudo python setup.py install
|
||||
```
|
||||
|
||||
# Building and flashing firmware images
|
||||
|
||||
## Building CircuitPython
|
||||
## Building CircuitPython binaries
|
||||
|
||||
#### REPL over UART (default settings)
|
||||
|
||||
To build a CircuitPython binary with default settings for the
|
||||
`feather52` target enter:
|
||||
|
||||
> **NOTE:** `BOARD=feather52` is the default option and isn't stricly required.
|
||||
|
||||
```
|
||||
$ make BOARD=feather52 V=1
|
||||
```
|
||||
|
||||
#### REPL over BLE UART (AKA `NUS`)
|
||||
#### REPL over BLE support
|
||||
|
||||
To build a CircuitPython binary with REPL over BLE UART, edit
|
||||
`bluetooth_conf.h` with the following values (under
|
||||
`#elif (BLUETOOTH_SD == 132)`):
|
||||
|
||||
```
|
||||
#define MICROPY_PY_BLE (1)
|
||||
#define MICROPY_PY_BLE_NUS (1)
|
||||
#define BLUETOOTH_WEBBLUETOOTH_REPL (1)
|
||||
```
|
||||
|
||||
Then build the CircuitPython binary, including `SD=s132`
|
||||
to enable BLE support in the build process:
|
||||
To build a CircuitPython binary with BLE support (S132) include `SD=s132`
|
||||
as part of the build process:
|
||||
|
||||
```
|
||||
$ make BOARD=feather52 V=1 SD=s132
|
||||
```
|
||||
|
||||
## Flashing with `nrfutil`
|
||||
|
||||
The Adafruit Bluefruit nRF52 Feather ships with a serial and OTA BLE bootloader
|
||||
that can be used to flash firmware images over a simple serial connection,
|
||||
using the on-board USB serial converter.
|
||||
|
||||
These commands assume that you have already installed `nrfutil`, as described
|
||||
in the [learning guide](https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/arduino-bsp-setup)
|
||||
for the Arduino variant of the board.
|
||||
## Flashing binaries with `nrfutil`
|
||||
|
||||
### 1. **Update bootloader** to single-bank version
|
||||
|
||||
@ -88,7 +95,7 @@ To enable BLE5 support and the latest S132 release, flash the v5.0.0 bootloader
|
||||
$ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART SOFTDEV_VERSION=5.0.0 boot-flash
|
||||
```
|
||||
|
||||
### 2. Generate a CircuitPython DFU .zip package and flash it over serial
|
||||
### 2. Generate and flash a CircuitPython DFU .zip package over serial
|
||||
|
||||
The following command will package and flash the CircuitPython binary using the
|
||||
appropriate bootloader mentionned above.
|
||||
@ -102,9 +109,76 @@ image, as described earlier in this readme.
|
||||
$ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART dfu-gen dfu-flash
|
||||
```
|
||||
|
||||
If you built your CircuitPython binary with **BLE UART** support you will
|
||||
need to add the `SD=s132` flag as shown below:
|
||||
If you built your CircuitPython binary with **BLE** support you will need to
|
||||
add the `SD=s132` flag as shown below:
|
||||
|
||||
```
|
||||
$ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 dfu-gen dfu-flash
|
||||
```
|
||||
|
||||
## Working with CircuitPython
|
||||
|
||||
### Running local files with `ampy`
|
||||
|
||||
[ampy](https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy)
|
||||
is a command-line tool that can be used with the nRF52 Feather to transfer
|
||||
local python files to the nRF52 for execution, rather than having to enter
|
||||
the REPL manually, enter paste mode, and paste the code yourself.
|
||||
|
||||
> **IMPORTANT**: You must have `ampy` version **1.0.3** or higher to use `ampy`
|
||||
with the nRF52. The bootloader on the nRF52 requires a delay between the
|
||||
HW reset, and the moment when the command sequance is sent to enter raw
|
||||
mode. This required `-d/--delay` flag was added in release 1.0.3.
|
||||
|
||||
|
||||
Save the following file as `test.py`:
|
||||
|
||||
```
|
||||
import board
|
||||
import digitalio
|
||||
import time
|
||||
|
||||
led = digitalio.DigitalInOut(board.LED2)
|
||||
led.direction = digitalio.Direction.OUTPUT
|
||||
|
||||
while True:
|
||||
led.value = True
|
||||
time.sleep(0.5)
|
||||
led.value = False
|
||||
time.sleep(0.5)
|
||||
```
|
||||
|
||||
Then run the saved file via ampy, updating the serial port as required:
|
||||
|
||||
```
|
||||
$ ampy -p /dev/tty.SLAB_USBtoUART -d 1.5 run test.py
|
||||
```
|
||||
|
||||
This should give you blinky at 1 Hz on LED2 (the blue LED on the nRF52 Feather).
|
||||
|
||||
### Uploading files and libraries with `ampy`
|
||||
|
||||
To upload Python files or pre-compiled CircuitPython libraries to the `lib` folder,
|
||||
run the following commands:
|
||||
|
||||
> In this example **i2c_device.py** is used, which is part of
|
||||
[Adafruit_CircuitPython_BusDevice](https://github.com/adafruit/Adafruit_CircuitPython_BusDevice)
|
||||
|
||||
```
|
||||
$ ampy -p /dev/tty.SLAB_USBtoUART -d 1.5 put i2c_device.py lib/i2c_device.py
|
||||
```
|
||||
|
||||
To verify that the file was uploaded correctly, you can check the contents of
|
||||
the `lib` folder with:
|
||||
|
||||
```
|
||||
$ ampy -p /dev/tty.SLAB_USBtoUART -d 1.5 ls /lib
|
||||
i2c_device.py
|
||||
```
|
||||
|
||||
### Suggested libraries
|
||||
|
||||
The following libraries should be installed as a minimum on most new boards:
|
||||
|
||||
- [Adafruit_CircuitPython_BusDevice](https://github.com/adafruit/Adafruit_CircuitPython_BusDevice)
|
||||
- [Adafruit_CircuitPython_Register](https://github.com/adafruit/Adafruit_CircuitPython_Register/tree/master)
|
||||
|
122
ports/nrf/boards/feather52/board.c
Normal file
122
ports/nrf/boards/feather52/board.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "nrf.h"
|
||||
|
||||
#include "boards/board.h"
|
||||
|
||||
#if 0
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "hal/include/hal_gpio.h"
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-bindings/neopixel_write/__init__.h"
|
||||
#endif
|
||||
|
||||
// Must match temp register in bootloader
|
||||
#define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0]
|
||||
uint32_t bootloaderVersion = 0;
|
||||
|
||||
volatile uint32_t ticks_ms = 0;
|
||||
|
||||
#define HAL_LFCLK_FREQ (32768UL)
|
||||
#define HAL_RTC_FREQ (1024UL)
|
||||
#define HAL_RTC_COUNTER_PRESCALER ((HAL_LFCLK_FREQ/HAL_RTC_FREQ)-1)
|
||||
|
||||
/* Maximum RTC ticks */
|
||||
#define portNRF_RTC_MAXTICKS ((1U<<24)-1U)
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
// Retrieve bootloader version
|
||||
bootloaderVersion = BOOTLOADER_VERSION_REGISTER;
|
||||
|
||||
// 32Khz XTAL
|
||||
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
|
||||
|
||||
// Set up RTC1 as tick timer
|
||||
NVIC_DisableIRQ(RTC1_IRQn);
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
|
||||
NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
|
||||
NRF_RTC1->TASKS_STOP = 1;
|
||||
NRF_RTC1->TASKS_CLEAR = 1;
|
||||
|
||||
ticks_ms = 0;
|
||||
|
||||
NRF_RTC1->PRESCALER = HAL_RTC_COUNTER_PRESCALER;
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk;
|
||||
NRF_RTC1->TASKS_START = 1;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTEN_OVRFLW_Msk;
|
||||
NVIC_SetPriority(RTC1_IRQn, 0xf); // lowest priority
|
||||
NVIC_EnableIRQ(RTC1_IRQn);
|
||||
}
|
||||
|
||||
void RTC1_IRQHandler(void)
|
||||
{
|
||||
// Clear event
|
||||
NRF_RTC1->EVENTS_TICK = 0;
|
||||
volatile uint32_t dummy = NRF_RTC1->EVENTS_TICK;
|
||||
(void) dummy;
|
||||
|
||||
// Tick correction
|
||||
uint32_t systick_counter = NRF_RTC1->COUNTER;
|
||||
uint32_t diff = (systick_counter - ticks_ms) & portNRF_RTC_MAXTICKS;
|
||||
ticks_ms += diff;
|
||||
}
|
||||
|
||||
// Check the status of the two buttons on CircuitPlayground Express. If both are
|
||||
// pressed, then boot into user safe mode.
|
||||
bool board_requests_safe_mode(void) {
|
||||
// gpio_set_pin_function(PIN_PA14, GPIO_PIN_FUNCTION_OFF);
|
||||
// gpio_set_pin_direction(PIN_PA14, GPIO_DIRECTION_IN);
|
||||
// gpio_set_pin_pull_mode(PIN_PA14, GPIO_PULL_DOWN);
|
||||
//
|
||||
// gpio_set_pin_function(PIN_PA28, GPIO_PIN_FUNCTION_OFF);
|
||||
// gpio_set_pin_direction(PIN_PA28, GPIO_DIRECTION_IN);
|
||||
// gpio_set_pin_pull_mode(PIN_PA28, GPIO_PULL_DOWN);
|
||||
// bool safe_mode = gpio_get_pin_level(PIN_PA14) &&
|
||||
// gpio_get_pin_level(PIN_PA28);
|
||||
// reset_pin(PIN_PA14);
|
||||
// reset_pin(PIN_PA28);
|
||||
// return safe_mode;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void reset_board(void) {
|
||||
// uint8_t empty[30];
|
||||
// memset(empty, 0, 30);
|
||||
// digitalio_digitalinout_obj_t neopixel_pin;
|
||||
// common_hal_digitalio_digitalinout_construct(&neopixel_pin, &pin_PB23);
|
||||
// common_hal_digitalio_digitalinout_switch_to_output(&neopixel_pin, false,
|
||||
// DRIVE_MODE_PUSH_PULL);
|
||||
// common_hal_neopixel_write(&neopixel_pin, empty, 30);
|
||||
// common_hal_digitalio_digitalinout_deinit(&neopixel_pin);
|
||||
}
|
||||
|
9
ports/nrf/boards/feather52/bootloader/README.md
Normal file
9
ports/nrf/boards/feather52/bootloader/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Adafruit nRF52 Feather Single-Bank Bootloader
|
||||
|
||||
These files contain an implementation of a single-bank bootloader,
|
||||
which doubles the amount of flash memory available to applications
|
||||
at the expense of safe over the air updates.
|
||||
|
||||
Two versions are present, based on release **2.0.1** and **5.0.0**
|
||||
of the Nordic S132 SoftDevice. The SoftDevice is included as poart
|
||||
of the bootloader binary.
|
@ -5,10 +5,15 @@
|
||||
------------------------------------------------------------------------
|
||||
START ADDR END ADDR SIZE DESCRIPTION
|
||||
---------- ---------- ------- -----------------------------------------
|
||||
0x00074000..0x00080000 ( 48KB) Serial + OTA Bootloader
|
||||
0x0006D000..0x00073FFF ( 28KB) Private Config Data (Bonding, Keys, etc.)
|
||||
0x00055000..0x0006CFFF ( 96KB) User Filesystem
|
||||
0x0001C000..0x00054FFF (228KB) Application Code
|
||||
0x0007F000..0x0007FFFF ( 4KB) Bootloader Settings
|
||||
0x0007E000..0x0007EFFF ( 4KB) Master Boot Record Params
|
||||
0x00074000..0x0007DFFF ( 40KB) Serial + OTA Bootloader
|
||||
|
||||
0x00073000..0x00073FFF ( 4KB ) Private Config Data (Bonding, Keys, etc.)
|
||||
0x00072000..0x00072FFF ( 4KB ) User NVM data
|
||||
0x00059000..0x00071FFF (100KB) User Filesystem
|
||||
|
||||
0x0001C000..0x00058FFF (244KB) Application Code
|
||||
0x00001000..0x0001BFFF (108KB) SoftDevice
|
||||
0x00000000..0x00000FFF (4KB) Master Boot Record
|
||||
*/
|
||||
@ -16,15 +21,16 @@
|
||||
/* Specify the memory areas (S132 2.0.1) */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */
|
||||
FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x038000 /* APP - ISR, 224 KiB */
|
||||
RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */
|
||||
FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x03C000 /* APP - ISR, 240 KiB */
|
||||
FLASH_FATFS (r) : ORIGIN = 0x00059000, LENGTH = 0x019000 /* File system 100KB KB */
|
||||
RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */
|
||||
}
|
||||
|
||||
/* produce a link error if there is not this amount of RAM for these sections */
|
||||
_minimum_stack_size = 2K;
|
||||
_minimum_heap_size = 16K;
|
||||
_minimum_heap_size = 0 /*16K Circuit Python use static variable for HEAP */;
|
||||
|
||||
/* top end of the stack */
|
||||
|
||||
|
@ -5,10 +5,15 @@
|
||||
------------------------------------------------------------------------
|
||||
START ADDR END ADDR SIZE DESCRIPTION
|
||||
---------- ---------- ------- -----------------------------------------
|
||||
0x00074000..0x00080000 ( 48KB) Serial + OTA Bootloader
|
||||
0x0006D000..0x00073FFF ( 28KB) Private Config Data (Bonding, Keys, etc.)
|
||||
0x00055000..0x0006CFFF ( 96KB) User Filesystem
|
||||
0x00023000..0x00054FFF (200KB) Application Code
|
||||
0x0007F000..0x0007FFFF ( 4KB) Bootloader Settings
|
||||
0x0007E000..0x0007EFFF ( 4KB) Master Boot Record Params
|
||||
0x00074000..0x0007DFFF ( 40KB) Serial + OTA Bootloader
|
||||
|
||||
0x00073000..0x00073FFF ( 4KB ) Private Config Data (Bonding, Keys, etc.)
|
||||
0x00072000..0x00072FFF ( 4KB ) User NVM data
|
||||
0x00059000..0x00071FFF ( 100KB) User Filesystem
|
||||
|
||||
0x00023000..0x00058FFF (216KB) Application Code
|
||||
0x00001000..0x00022FFF (136KB) SoftDevice
|
||||
0x00000000..0x00000FFF (4KB) Master Boot Record
|
||||
*/
|
||||
@ -18,13 +23,14 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */
|
||||
FLASH_ISR (rx) : ORIGIN = 0x00023000, LENGTH = 0x001000 /* sector 0, 4 KiB */
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x00024000, LENGTH = 0x030FFF /* APP - ISR, 200 KiB */
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x00024000, LENGTH = 0x036000 /* APP - ISR, 216 KiB */
|
||||
FLASH_FATFS (r) : ORIGIN = 0x00059000, LENGTH = 0x019000 /* File system 100KB KB */
|
||||
RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */
|
||||
}
|
||||
|
||||
/* produce a link error if there is not this amount of RAM for these sections */
|
||||
_minimum_stack_size = 2K;
|
||||
_minimum_heap_size = 16K;
|
||||
_minimum_heap_size = 0 /*16K Circuit Python use static variable for HEAP */;
|
||||
|
||||
/* top end of the stack */
|
||||
|
||||
|
12
ports/nrf/boards/feather52/examples/blinky.py
Normal file
12
ports/nrf/boards/feather52/examples/blinky.py
Normal file
@ -0,0 +1,12 @@
|
||||
import board
|
||||
import digitalio
|
||||
import time
|
||||
|
||||
led = digitalio.DigitalInOut(board.LED2)
|
||||
led.direction = digitalio.Direction.OUTPUT
|
||||
|
||||
while True:
|
||||
led.value = True
|
||||
time.sleep(0.5)
|
||||
led.value = False
|
||||
time.sleep(0.5)
|
20
ports/nrf/boards/feather52/examples/i2c_scan.py
Normal file
20
ports/nrf/boards/feather52/examples/i2c_scan.py
Normal file
@ -0,0 +1,20 @@
|
||||
import board
|
||||
import busio
|
||||
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
count = 0
|
||||
|
||||
# Wait for I2C lock
|
||||
while not i2c.try_lock():
|
||||
pass
|
||||
|
||||
# Scan for devices on the I2C bus
|
||||
print("Scanning I2C bus")
|
||||
for x in i2c.scan():
|
||||
print(hex(x))
|
||||
count += 1
|
||||
|
||||
print("%d device(s) found on I2C bus" % count)
|
||||
|
||||
# Release the I2C bus
|
||||
i2c.unlock()
|
25
ports/nrf/boards/feather52/examples/pulseio.py
Normal file
25
ports/nrf/boards/feather52/examples/pulseio.py
Normal file
@ -0,0 +1,25 @@
|
||||
import time
|
||||
from board import *
|
||||
from pulseio import *
|
||||
|
||||
# Setup BLUE and RED LEDs as PWM output (default frequency is 500 Hz)
|
||||
ledb = PWMOut(LED2)
|
||||
ledr = PWMOut(LED1)
|
||||
|
||||
# Set the BLUE LED to have a duty cycle of 5000 (out of 65535, so ~7.5%)
|
||||
ledb.duty_cycle = 5000
|
||||
|
||||
# Setup pin A0 as a standard PWM out @ 50% to test on the oscilloscope.
|
||||
# You should see a 50% duty cycle waveform at ~500Hz on the scope when you
|
||||
# connect a probe to pin A0
|
||||
a0 = PWMOut(A0)
|
||||
a0.duty_cycle = int(65535/2)
|
||||
|
||||
# Constantly pulse the RED LED
|
||||
while True:
|
||||
for i in range(100):
|
||||
ledr.duty_cycle = int(i / 100 * 65535)
|
||||
time.sleep(0.01)
|
||||
for i in range(100, -1, -1):
|
||||
ledr.duty_cycle = int(i / 100 * 65535)
|
||||
time.sleep(0.01)
|
@ -24,8 +24,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define PCA10040
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "Bluefruit nRF52 Feather"
|
||||
#define MICROPY_HW_MCU_NAME "NRF52832"
|
||||
#define MICROPY_PY_SYS_PLATFORM "nrf52"
|
||||
@ -33,7 +31,7 @@
|
||||
#define MICROPY_PY_MACHINE_HW_PWM (1)
|
||||
#define MICROPY_PY_MACHINE_HW_SPI (1)
|
||||
#define MICROPY_PY_MACHINE_TIMER (1)
|
||||
#define MICROPY_PY_MACHINE_RTC (1)
|
||||
#define MICROPY_PY_MACHINE_RTC (0)
|
||||
#define MICROPY_PY_MACHINE_I2C (1)
|
||||
#define MICROPY_PY_MACHINE_ADC (1)
|
||||
#define MICROPY_PY_MACHINE_TEMP (1)
|
||||
@ -59,18 +57,23 @@
|
||||
#define MICROPY_HW_LED2 (19) // LED2
|
||||
|
||||
// UART config
|
||||
#define MICROPY_HW_UART1_RX (pin_A8)
|
||||
#define MICROPY_HW_UART1_TX (pin_A6)
|
||||
#define MICROPY_HW_UART1_RX (pin_PA08)
|
||||
#define MICROPY_HW_UART1_TX (pin_PA06)
|
||||
#define MICROPY_HW_UART1_HWFC (0)
|
||||
|
||||
// SPI0 config
|
||||
#define MICROPY_HW_SPI0_NAME "SPI0"
|
||||
#define MICROPY_HW_SPI0_SCK (pin_A12) // (Arduino D13)
|
||||
#define MICROPY_HW_SPI0_MOSI (pin_A13) // (Arduino D11)
|
||||
#define MICROPY_HW_SPI0_MISO (pin_A14) // (Arduino D12)
|
||||
#define MICROPY_HW_SPI0_SCK (pin_PA12) // (Arduino D13)
|
||||
#define MICROPY_HW_SPI0_MOSI (pin_PA13) // (Arduino D11)
|
||||
#define MICROPY_HW_SPI0_MISO (pin_PA14) // (Arduino D12)
|
||||
|
||||
#define MICROPY_HW_PWM0_NAME "PWM0"
|
||||
#define MICROPY_HW_PWM1_NAME "PWM1"
|
||||
#define MICROPY_HW_PWM2_NAME "PWM2"
|
||||
|
||||
#define HELP_TEXT_BOARD_LED "1,2"
|
||||
|
||||
|
||||
|
||||
#define PORT_HEAP_SIZE (32*1024)
|
||||
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
|
||||
|
@ -8,7 +8,7 @@ BOOTLOADER_PKG = boards/feather52/bootloader/feather52_bootloader_$(SOFTDEV_VERS
|
||||
|
||||
NRF_DEFINES += -DNRF52832_XXAA
|
||||
|
||||
|
||||
CFLAGS += -DADAFRUIT_FEATHER52
|
||||
|
||||
check_defined = \
|
||||
$(strip $(foreach 1,$1, \
|
||||
|
124
ports/nrf/boards/feather52/pins.c
Normal file
124
ports/nrf/boards/feather52/pins.c
Normal file
@ -0,0 +1,124 @@
|
||||
// This file was automatically generated by make-pins.py
|
||||
//
|
||||
// --af nrf52_af.csv
|
||||
// --board boards/feather52/pins.csv
|
||||
// --prefix boards/nrf52_prefix.c
|
||||
|
||||
// nrf52_prefix.c becomes the initial portion of the generated pins file.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "pin.h"
|
||||
|
||||
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
|
||||
{ \
|
||||
{ &pin_af_type }, \
|
||||
.name = MP_QSTR_AF ## af_idx ## _ ## af_fn ## af_unit, \
|
||||
.idx = (af_idx), \
|
||||
.fn = AF_FN_ ## af_fn, \
|
||||
.unit = (af_unit), \
|
||||
.type = AF_PIN_TYPE_ ## af_fn ## _ ## af_type, \
|
||||
.af_fn = (af_ptr) \
|
||||
}
|
||||
|
||||
#define PIN(p_port, p_pin, p_af, p_adc_channel) \
|
||||
{ \
|
||||
{ &mcu_pin_type }, \
|
||||
.name = MP_QSTR_ ## p_port ## p_pin, \
|
||||
.port = PORT_ ## p_port, \
|
||||
.pin = (p_pin), \
|
||||
.num_af = (sizeof(p_af) / sizeof(pin_af_obj_t)), \
|
||||
/*.pin_mask = (1 << p_pin), */\
|
||||
.af = p_af, \
|
||||
.adc_channel = p_adc_channel,\
|
||||
}
|
||||
|
||||
#define NO_ADC 0
|
||||
|
||||
const pin_obj_t pin_PA02 = PIN(A, 2, NULL, SAADC_CH_PSELP_PSELP_AnalogInput0);
|
||||
const pin_obj_t pin_PA03 = PIN(A, 3, NULL, SAADC_CH_PSELP_PSELP_AnalogInput1);
|
||||
const pin_obj_t pin_PA04 = PIN(A, 4, NULL, SAADC_CH_PSELP_PSELP_AnalogInput2);
|
||||
const pin_obj_t pin_PA05 = PIN(A, 5, NULL, SAADC_CH_PSELP_PSELP_AnalogInput3);
|
||||
const pin_obj_t pin_PA06 = PIN(A, 6, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA07 = PIN(A, 7, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA08 = PIN(A, 8, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA09 = PIN(A, 9, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA10 = PIN(A, 10, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA11 = PIN(A, 11, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA12 = PIN(A, 12, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA13 = PIN(A, 13, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA14 = PIN(A, 14, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA15 = PIN(A, 15, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA16 = PIN(A, 16, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA17 = PIN(A, 17, NULL, NO_ADC);
|
||||
|
||||
const pin_obj_t pin_PA19 = PIN(A, 19, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA20 = PIN(A, 20, NULL, NO_ADC);
|
||||
|
||||
const pin_obj_t pin_PA25 = PIN(A, 25, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA26 = PIN(A, 26, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA27 = PIN(A, 27, NULL, NO_ADC);
|
||||
const pin_obj_t pin_PA28 = PIN(A, 28, NULL, SAADC_CH_PSELP_PSELP_AnalogInput4);
|
||||
const pin_obj_t pin_PA29 = PIN(A, 29, NULL, SAADC_CH_PSELP_PSELP_AnalogInput5);
|
||||
const pin_obj_t pin_PA30 = PIN(A, 30, NULL, SAADC_CH_PSELP_PSELP_AnalogInput6);
|
||||
const pin_obj_t pin_PA31 = PIN(A, 31, NULL, SAADC_CH_PSELP_PSELP_AnalogInput7);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA16), MP_ROM_PTR(&pin_PA16) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA17), MP_ROM_PTR(&pin_PA17) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA19), MP_ROM_PTR(&pin_PA19) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA20), MP_ROM_PTR(&pin_PA20) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA25), MP_ROM_PTR(&pin_PA25) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA26), MP_ROM_PTR(&pin_PA26) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA27), MP_ROM_PTR(&pin_PA27) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA28), MP_ROM_PTR(&pin_PA28) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA29), MP_ROM_PTR(&pin_PA29) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA30), MP_ROM_PTR(&pin_PA30) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PA31), MP_ROM_PTR(&pin_PA31) },
|
||||
};
|
||||
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table);
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_A0 ), MP_ROM_PTR(&pin_PA02) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A1 ), MP_ROM_PTR(&pin_PA03) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A2 ), MP_ROM_PTR(&pin_PA04) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A3 ), MP_ROM_PTR(&pin_PA05) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TX ), MP_ROM_PTR(&pin_PA06) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A7 ), MP_ROM_PTR(&pin_PA07) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_RX ), MP_ROM_PTR(&pin_PA08) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_NFC1 ), MP_ROM_PTR(&pin_PA09) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_NFC2 ), MP_ROM_PTR(&pin_PA10) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D11 ), MP_ROM_PTR(&pin_PA11) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SCK ), MP_ROM_PTR(&pin_PA12) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MOSI ), MP_ROM_PTR(&pin_PA13) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MISO ), MP_ROM_PTR(&pin_PA14) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D15 ), MP_ROM_PTR(&pin_PA15) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D16 ), MP_ROM_PTR(&pin_PA16) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_LED1 ), MP_ROM_PTR(&pin_PA17) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_LED2 ), MP_ROM_PTR(&pin_PA19) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DFU ), MP_ROM_PTR(&pin_PA20) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SDA ), MP_ROM_PTR(&pin_PA25) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SCL ), MP_ROM_PTR(&pin_PA26) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D27 ), MP_ROM_PTR(&pin_PA27) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A4 ), MP_ROM_PTR(&pin_PA28) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A5 ), MP_ROM_PTR(&pin_PA29) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A6 ), MP_ROM_PTR(&pin_PA30) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A7 ), MP_ROM_PTR(&pin_PA31) },
|
||||
};
|
||||
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
@ -1,25 +1,25 @@
|
||||
PA2,PA2,ADC0_IN0
|
||||
PA3,PA3,ADC0_IN1
|
||||
PA4,PA4,ADC0_IN2
|
||||
PA5,PA5,ADC0_IN3
|
||||
UART_TX,PA6
|
||||
A0,PA2,ADC0_IN0
|
||||
A1,PA3,ADC0_IN1
|
||||
A2,PA4,ADC0_IN2
|
||||
A3,PA5,ADC0_IN3
|
||||
TX,PA6
|
||||
PA7,PA7
|
||||
UART_RX,PA8
|
||||
RX,PA8
|
||||
NFC1,PA9
|
||||
NFC2,PA10
|
||||
PA11,PA11
|
||||
SPI_SCK,PA12
|
||||
SPI_MOSI,PA13
|
||||
SPI_MISO,PA14
|
||||
PA15,PA15
|
||||
PA16,PA16
|
||||
D11,PA11
|
||||
SCK,PA12
|
||||
MOSI,PA13
|
||||
MISO,PA14
|
||||
D15,PA15
|
||||
D16,PA16
|
||||
LED1,PA17
|
||||
LED2,PA19
|
||||
PA20,PA20
|
||||
I2C_SDA,PA25
|
||||
I2C_SCL,PA26
|
||||
PA27,PA27
|
||||
PA28,PA28,ADC0_IN4
|
||||
PA29,PA29,ADC0_IN5
|
||||
PA30,PA30,ADC0_IN6
|
||||
PA31,PA31,ADC0_IN7
|
||||
DFU,PA20
|
||||
SDA,PA25
|
||||
SCL,PA26
|
||||
D27,PA27
|
||||
A4,PA28,ADC0_IN4
|
||||
A5,PA29,ADC0_IN5
|
||||
A6,PA30,ADC0_IN6
|
||||
A7,PA31,ADC0_IN7
|
||||
|
|
28
ports/nrf/boards/feather52/pins.h
Normal file
28
ports/nrf/boards/feather52/pins.h
Normal file
@ -0,0 +1,28 @@
|
||||
extern const pin_obj_t pin_PA02;
|
||||
extern const pin_obj_t pin_PA03;
|
||||
extern const pin_obj_t pin_PA04;
|
||||
extern const pin_obj_t pin_PA05;
|
||||
extern const pin_obj_t pin_PA06;
|
||||
extern const pin_obj_t pin_PA07;
|
||||
extern const pin_obj_t pin_PA08;
|
||||
extern const pin_obj_t pin_PA09;
|
||||
extern const pin_obj_t pin_PA10;
|
||||
extern const pin_obj_t pin_PA11;
|
||||
extern const pin_obj_t pin_PA12;
|
||||
extern const pin_obj_t pin_PA13;
|
||||
extern const pin_obj_t pin_PA14;
|
||||
extern const pin_obj_t pin_PA15;
|
||||
extern const pin_obj_t pin_PA16;
|
||||
extern const pin_obj_t pin_PA17;
|
||||
extern const pin_obj_t pin_PA19;
|
||||
extern const pin_obj_t pin_PA20;
|
||||
extern const pin_obj_t pin_PA25;
|
||||
extern const pin_obj_t pin_PA26;
|
||||
extern const pin_obj_t pin_PA27;
|
||||
extern const pin_obj_t pin_PA28;
|
||||
extern const pin_obj_t pin_PA29;
|
||||
extern const pin_obj_t pin_PA30;
|
||||
extern const pin_obj_t pin_PA31;
|
||||
extern const pin_obj_t * const pin_PAdc1[];
|
||||
extern const pin_obj_t * const pin_PAdc2[];
|
||||
extern const pin_obj_t * const pin_PAdc3[];
|
@ -233,22 +233,22 @@ class Pins(object):
|
||||
self.board_pins.append(NamedPin(row[0], pin))
|
||||
|
||||
def print_named(self, label, named_pins):
|
||||
print('STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
|
||||
print('STATIC const mp_rom_map_elem_t {:s}_table[] = {{'.format(label))
|
||||
for named_pin in named_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},'.format(named_pin.name(), pin.cpu_pin_name()))
|
||||
print('};')
|
||||
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
|
||||
print('MP_DEFINE_CONST_DICT({:s}, {:s}_table);'.format(label, label));
|
||||
|
||||
def print(self):
|
||||
for named_pin in self.cpu_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
pin.print()
|
||||
self.print_named('cpu', self.cpu_pins)
|
||||
self.print_named('mcu_pin_globals', self.cpu_pins)
|
||||
print('')
|
||||
self.print_named('board', self.board_pins)
|
||||
self.print_named('board_module_globals', self.board_pins)
|
||||
|
||||
def print_adc(self, adc_num):
|
||||
print('');
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define MICROPY_PY_MACHINE_HW_SPI (1)
|
||||
#define MICROPY_PY_MACHINE_TIMER (1)
|
||||
#define MICROPY_PY_MACHINE_RTC (1)
|
||||
#define MICROPY_PY_MACHINE_I2C (1)
|
||||
#define MICROPY_PY_MACHINE_I2C (0)
|
||||
#define MICROPY_PY_MACHINE_ADC (1)
|
||||
#define MICROPY_PY_MACHINE_TEMP (1)
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#define PIN(p_port, p_pin, p_af, p_adc_num, p_adc_channel) \
|
||||
{ \
|
||||
{ &pin_type }, \
|
||||
{ &mcu_pin_type }, \
|
||||
.name = MP_QSTR_ ## p_port ## p_pin, \
|
||||
.port = PORT_ ## p_port, \
|
||||
.pin = (p_pin), \
|
||||
|
118
ports/nrf/common-hal/analogio/AnalogIn.c
Normal file
118
ports/nrf/common-hal/analogio/AnalogIn.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/analogio/AnalogIn.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/mphal.h"
|
||||
#include "shared-bindings/analogio/AnalogIn.h"
|
||||
#include "nrf.h"
|
||||
|
||||
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, const mcu_pin_obj_t *pin) {
|
||||
if (!pin->adc_channel) {
|
||||
// No ADC function on that pin
|
||||
mp_raise_ValueError("Pin does not have ADC capabilities");
|
||||
}
|
||||
|
||||
hal_gpio_cfg_pin(pin->port, pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
self->pin = pin;
|
||||
}
|
||||
|
||||
bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) {
|
||||
return self->pin == mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) {
|
||||
if (common_hal_analogio_analogin_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
reset_pin(self->pin->pin);
|
||||
self->pin = mp_const_none;
|
||||
}
|
||||
|
||||
void analogin_reset() {
|
||||
}
|
||||
|
||||
uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
|
||||
// Something else might have used the ADC in a different way,
|
||||
// so we completely re-initialize it.
|
||||
|
||||
int16_t value;
|
||||
|
||||
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit;
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
NRF_SAADC->CH[i].PSELN = SAADC_CH_PSELP_PSELP_NC;
|
||||
NRF_SAADC->CH[i].PSELP = SAADC_CH_PSELP_PSELP_NC;
|
||||
}
|
||||
|
||||
NRF_SAADC->CH[0].CONFIG = ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk)
|
||||
| ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk)
|
||||
| ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk)
|
||||
| ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk)
|
||||
| ((SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk)
|
||||
| ((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk);
|
||||
NRF_SAADC->CH[0].PSELN = self->pin->adc_channel;
|
||||
NRF_SAADC->CH[0].PSELP = self->pin->adc_channel;
|
||||
|
||||
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&value;
|
||||
NRF_SAADC->RESULT.MAXCNT = 1;
|
||||
|
||||
NRF_SAADC->TASKS_START = 0x01UL;
|
||||
|
||||
while (!NRF_SAADC->EVENTS_STARTED);
|
||||
NRF_SAADC->EVENTS_STARTED = 0x00UL;
|
||||
|
||||
NRF_SAADC->TASKS_SAMPLE = 0x01UL;
|
||||
|
||||
while (!NRF_SAADC->EVENTS_END);
|
||||
NRF_SAADC->EVENTS_END = 0x00UL;
|
||||
|
||||
NRF_SAADC->TASKS_STOP = 0x01UL;
|
||||
|
||||
while (!NRF_SAADC->EVENTS_STOPPED);
|
||||
NRF_SAADC->EVENTS_STOPPED = 0x00UL;
|
||||
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
|
||||
// Map value to from 14 to 16 bits
|
||||
return (value << 2);
|
||||
}
|
||||
|
||||
float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) {
|
||||
return 3.3f;
|
||||
}
|
41
ports/nrf/common-hal/analogio/AnalogIn.h
Normal file
41
ports/nrf/common-hal/analogio/AnalogIn.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGIN_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGIN_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const mcu_pin_obj_t * pin;
|
||||
} analogio_analogin_obj_t;
|
||||
|
||||
void analogin_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGIN_H
|
76
ports/nrf/common-hal/analogio/AnalogOut.c
Normal file
76
ports/nrf/common-hal/analogio/AnalogOut.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/analogio/AnalogOut.h"
|
||||
|
||||
|
||||
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin) {
|
||||
// if (pin->pin != PIN_PA02) {
|
||||
// mp_raise_ValueError("AnalogOut not supported on given pin");
|
||||
// return;
|
||||
// }
|
||||
// struct dac_config config_dac;
|
||||
// dac_get_config_defaults(&config_dac);
|
||||
// config_dac.reference = DAC_REFERENCE_AVCC;
|
||||
// enum status_code status = dac_init(&self->dac_instance, DAC, &config_dac);
|
||||
// if (status != STATUS_OK) {
|
||||
// mp_raise_OSError(MP_EIO);
|
||||
// return;
|
||||
// }
|
||||
// claim_pin(pin);
|
||||
//
|
||||
// struct dac_chan_config config_analogout_chan;
|
||||
// dac_chan_get_config_defaults(&config_analogout_chan);
|
||||
// dac_chan_set_config(&self->dac_instance, DAC_CHANNEL_0, &config_analogout_chan);
|
||||
// dac_chan_enable(&self->dac_instance, DAC_CHANNEL_0);
|
||||
//
|
||||
// dac_enable(&self->dac_instance);
|
||||
}
|
||||
|
||||
bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) {
|
||||
return self->deinited;
|
||||
}
|
||||
|
||||
void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) {
|
||||
// if (common_hal_analogio_analogout_deinited(self)) {
|
||||
// return;
|
||||
// }
|
||||
// dac_disable(&self->dac_instance);
|
||||
// dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0);
|
||||
// reset_pin(PIN_PA02);
|
||||
// self->deinited = true;
|
||||
}
|
||||
|
||||
void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value) {
|
||||
// Input is 16 bit but we only support 10 bit so we shift the input.
|
||||
// dac_chan_write(&self->dac_instance, DAC_CHANNEL_0, value >> 6);
|
||||
}
|
42
ports/nrf/common-hal/analogio/AnalogOut.h
Normal file
42
ports/nrf/common-hal/analogio/AnalogOut.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGOUT_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
//#include "asf/sam0/drivers/dac/dac.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
// struct dac_module dac_instance;
|
||||
bool deinited;
|
||||
} analogio_analogout_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ANALOGIO_ANALOGOUT_H
|
1
ports/nrf/common-hal/analogio/__init__.c
Normal file
1
ports/nrf/common-hal/analogio/__init__.c
Normal file
@ -0,0 +1 @@
|
||||
// No analogio module functions.
|
34
ports/nrf/common-hal/board/__init__.c
Normal file
34
ports/nrf/common-hal/board/__init__.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
// Pins aren't actually defined here. They are in the board specific directory
|
||||
// such as boards/arduino_zero/pins.c.
|
207
ports/nrf/common-hal/busio/I2C.c
Normal file
207
ports/nrf/common-hal/busio/I2C.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
* Copyright (c) 2017 hathach
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "shared-bindings/busio/I2C.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "pins.h"
|
||||
#include "nrf.h"
|
||||
|
||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency) {
|
||||
if (scl->pin == sda->pin) {
|
||||
mp_raise_ValueError("Invalid pins");
|
||||
}
|
||||
|
||||
NRF_GPIO->PIN_CNF[scl->pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
|
||||
|
||||
NRF_GPIO->PIN_CNF[sda->pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
|
||||
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
|
||||
|
||||
// 1 for I2C, 0 for SPI
|
||||
self->twi = NRF_TWIM1;
|
||||
|
||||
if ( frequency < 100000 ) {
|
||||
self->twi->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100;
|
||||
}else if ( frequency < 250000 ) {
|
||||
self->twi->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K250;
|
||||
}else {
|
||||
self->twi->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400;
|
||||
}
|
||||
|
||||
self->twi->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos);
|
||||
|
||||
self->twi->PSEL.SCL = scl->pin;
|
||||
self->twi->PSEL.SDA = sda->pin;
|
||||
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
||||
return self->twi->ENABLE == 0;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t scl_pin = self->twi->PSEL.SCL;
|
||||
uint8_t sda_pin = self->twi->PSEL.SDA;
|
||||
|
||||
self->twi->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
|
||||
self->twi->PSEL.SCL = (TWIM_PSEL_SCL_CONNECT_Disconnected << TWIM_PSEL_SCL_CONNECT_Pos);
|
||||
self->twi->PSEL.SDA = (TWIM_PSEL_SDA_CONNECT_Disconnected << TWIM_PSEL_SDA_CONNECT_Pos);
|
||||
|
||||
reset_pin(scl_pin);
|
||||
reset_pin(sda_pin);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
// Write no data when just probing
|
||||
return 0 == common_hal_busio_i2c_write(self, addr, NULL, 0, true);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
|
||||
bool grabbed_lock = false;
|
||||
// CRITICAL_SECTION_ENTER()
|
||||
if (!self->has_lock) {
|
||||
grabbed_lock = true;
|
||||
self->has_lock = true;
|
||||
}
|
||||
// CRITICAL_SECTION_LEAVE();
|
||||
return grabbed_lock;
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) {
|
||||
return self->has_lock;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
|
||||
self->has_lock = false;
|
||||
}
|
||||
|
||||
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) {
|
||||
NRF_TWIM_Type* twi = self->twi;
|
||||
|
||||
twi->ADDRESS = addr;
|
||||
twi->TASKS_RESUME = 1;
|
||||
|
||||
twi->TXD.PTR = (uint32_t) data;
|
||||
twi->TXD.MAXCNT = len;
|
||||
|
||||
twi->TASKS_STARTTX = 1;
|
||||
|
||||
// Wait for TX started
|
||||
while(!twi->EVENTS_TXSTARTED && !twi->EVENTS_ERROR) {}
|
||||
twi->EVENTS_TXSTARTED = 0;
|
||||
|
||||
// Wait for TX complete
|
||||
if ( len )
|
||||
{
|
||||
while(!twi->EVENTS_LASTTX && !twi->EVENTS_ERROR) {}
|
||||
twi->EVENTS_LASTTX = 0x0UL;
|
||||
}
|
||||
|
||||
if (stopBit || twi->EVENTS_ERROR)
|
||||
{
|
||||
twi->TASKS_STOP = 0x1UL;
|
||||
while(!twi->EVENTS_STOPPED);
|
||||
twi->EVENTS_STOPPED = 0x0UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
twi->TASKS_SUSPEND = 0x1UL;
|
||||
while(!twi->EVENTS_SUSPENDED);
|
||||
twi->EVENTS_SUSPENDED = 0x0UL;
|
||||
}
|
||||
|
||||
if (twi->EVENTS_ERROR)
|
||||
{
|
||||
twi->EVENTS_ERROR = 0x0UL;
|
||||
uint32_t error = twi->ERRORSRC;
|
||||
twi->ERRORSRC = error;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) {
|
||||
NRF_TWIM_Type* twi = self->twi;
|
||||
|
||||
if(len == 0) return 0;
|
||||
bool stopBit = true; // should be a parameter
|
||||
|
||||
twi->ADDRESS = addr;
|
||||
twi->TASKS_RESUME = 0x1UL;
|
||||
|
||||
twi->RXD.PTR = (uint32_t) data;
|
||||
twi->RXD.MAXCNT = len;
|
||||
|
||||
twi->TASKS_STARTRX = 0x1UL;
|
||||
|
||||
while(!twi->EVENTS_RXSTARTED && !twi->EVENTS_ERROR);
|
||||
twi->EVENTS_RXSTARTED = 0x0UL;
|
||||
|
||||
while(!twi->EVENTS_LASTRX && !twi->EVENTS_ERROR);
|
||||
twi->EVENTS_LASTRX = 0x0UL;
|
||||
|
||||
if (stopBit || twi->EVENTS_ERROR)
|
||||
{
|
||||
twi->TASKS_STOP = 0x1UL;
|
||||
while(!twi->EVENTS_STOPPED);
|
||||
twi->EVENTS_STOPPED = 0x0UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
twi->TASKS_SUSPEND = 0x1UL;
|
||||
while(!twi->EVENTS_SUSPENDED);
|
||||
twi->EVENTS_SUSPENDED = 0x0UL;
|
||||
}
|
||||
|
||||
if (twi->EVENTS_ERROR)
|
||||
{
|
||||
twi->EVENTS_ERROR = 0x0UL;
|
||||
uint32_t error = twi->ERRORSRC;
|
||||
twi->ERRORSRC = error;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
// number of byte read
|
||||
// (void) _p_twim->RXD.AMOUNT;
|
||||
|
||||
return 0;
|
||||
}
|
42
ports/nrf/common-hal/busio/I2C.h
Normal file
42
ports/nrf/common-hal/busio/I2C.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_I2C_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_I2C_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
//#include "hal/include/hal_i2c_m_sync.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
volatile bool has_lock;
|
||||
NRF_TWIM_Type* twi;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_I2C_H
|
162
ports/nrf/common-hal/busio/SPI.c
Normal file
162
ports/nrf/common-hal/busio/SPI.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* SPI Master library for nRF5x.
|
||||
* Copyright (c) 2015 Arduino LLC
|
||||
* Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
* Copyright (c) 2017 hathach
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "shared-bindings/busio/SPI.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "nrf.h"
|
||||
#include "pins.h"
|
||||
|
||||
// Convert frequency to clock-speed-dependent value. Return 0 if out of range.
|
||||
static uint32_t baudrate_to_reg(const uint32_t baudrate) {
|
||||
uint32_t value;
|
||||
|
||||
if (baudrate <= 125000) {
|
||||
value = SPI_FREQUENCY_FREQUENCY_K125;
|
||||
} else if (baudrate <= 250000) {
|
||||
value = SPI_FREQUENCY_FREQUENCY_K250;
|
||||
} else if (baudrate <= 500000) {
|
||||
value = SPI_FREQUENCY_FREQUENCY_K500;
|
||||
} else if (baudrate <= 1000000) {
|
||||
value = SPI_FREQUENCY_FREQUENCY_M1;
|
||||
} else if (baudrate <= 2000000) {
|
||||
value = SPI_FREQUENCY_FREQUENCY_M2;
|
||||
} else if (baudrate <= 4000000) {
|
||||
value = SPI_FREQUENCY_FREQUENCY_M4;
|
||||
} else {
|
||||
value = SPI_FREQUENCY_FREQUENCY_M8;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) {
|
||||
|
||||
// 1 for I2C, 0 for SPI
|
||||
self->spi = NRF_SPI0;
|
||||
|
||||
self->spi->PSELSCK = clock->pin;
|
||||
self->spi->PSELMOSI = mosi->pin;
|
||||
self->spi->PSELMISO = miso->pin;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
|
||||
return self->spi == NULL;
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
|
||||
if (common_hal_busio_spi_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self->spi->PSELSCK = SPI_PSEL_SCK_PSELSCK_Disconnected;
|
||||
self->spi->PSELMOSI = SPI_PSEL_MOSI_PSELMOSI_Disconnected;
|
||||
self->spi->PSELMISO = SPI_PSEL_MISO_PSELMISO_Disconnected;
|
||||
|
||||
// reset_pin(self->clock_pin);
|
||||
// reset_pin(self->MOSI_pin);
|
||||
// reset_pin(self->MISO_pin);
|
||||
|
||||
self->spi = NULL;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) {
|
||||
// nrf52 does not support 16 bit
|
||||
if ( bits != 8 ) return false;
|
||||
|
||||
self->spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
|
||||
uint32_t config = (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos);
|
||||
|
||||
config |= ((polarity ? SPI_CONFIG_CPOL_ActiveLow : SPI_CONFIG_CPOL_ActiveHigh) << SPI_CONFIG_CPOL_Pos);
|
||||
config |= ((phase ? SPI_CONFIG_CPHA_Trailing : SPI_CONFIG_CPHA_Leading ) << SPI_CONFIG_CPHA_Pos);
|
||||
|
||||
self->spi->CONFIG = config;
|
||||
self->spi->FREQUENCY = baudrate_to_reg(baudrate);
|
||||
|
||||
self->spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) {
|
||||
bool grabbed_lock = false;
|
||||
// CRITICAL_SECTION_ENTER()
|
||||
// if (!self->has_lock) {
|
||||
grabbed_lock = true;
|
||||
self->has_lock = true;
|
||||
// }
|
||||
// CRITICAL_SECTION_LEAVE();
|
||||
return grabbed_lock;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) {
|
||||
return self->has_lock;
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_unlock(busio_spi_obj_t *self) {
|
||||
self->has_lock = false;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) {
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
self->spi->TXD = *data;
|
||||
|
||||
while(!self->spi->EVENTS_READY);
|
||||
|
||||
(void) self->spi->RXD;
|
||||
data++;
|
||||
len--;
|
||||
|
||||
self->spi->EVENTS_READY = 0x0UL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) {
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
self->spi->TXD = write_value;
|
||||
|
||||
while(!self->spi->EVENTS_READY);
|
||||
|
||||
*data = self->spi->RXD;
|
||||
|
||||
data++;
|
||||
len--;
|
||||
|
||||
self->spi->EVENTS_READY = 0x0UL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
42
ports/nrf/common-hal/busio/SPI.h
Normal file
42
ports/nrf/common-hal/busio/SPI.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_SPI_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_SPI_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
//#include "hal/include/hal_spi_m_sync.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
NRF_SPI_Type *spi;
|
||||
bool has_lock;
|
||||
} busio_spi_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_SPI_H
|
1
ports/nrf/common-hal/busio/__init__.c
Normal file
1
ports/nrf/common-hal/busio/__init__.c
Normal file
@ -0,0 +1 @@
|
||||
// No busio module functions.
|
169
ports/nrf/common-hal/digitalio/DigitalInOut.c
Normal file
169
ports/nrf/common-hal/digitalio/DigitalInOut.c
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "hal/hal_gpio.h"
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
|
||||
digitalinout_result_t common_hal_digitalio_digitalinout_construct(
|
||||
digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) {
|
||||
self->pin = pin;
|
||||
hal_gpio_cfg_pin(pin->port, pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
return DIGITALINOUT_OK;
|
||||
}
|
||||
|
||||
bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) {
|
||||
return self->pin == mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) {
|
||||
if (common_hal_digitalio_digitalinout_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
reset_pin(self->pin->pin);
|
||||
self->pin = mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_switch_to_input(
|
||||
digitalio_digitalinout_obj_t* self, enum digitalio_pull_t pull) {
|
||||
self->output = false;
|
||||
|
||||
hal_gpio_cfg_pin(self->pin->port, self->pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
common_hal_digitalio_digitalinout_set_pull(self, pull);
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_switch_to_output(
|
||||
digitalio_digitalinout_obj_t* self, bool value,
|
||||
enum digitalio_drive_mode_t drive_mode) {
|
||||
const uint8_t pin = self->pin->pin;
|
||||
|
||||
self->output = true;
|
||||
self->open_drain = (drive_mode == DRIVE_MODE_OPEN_DRAIN);
|
||||
|
||||
hal_gpio_cfg_pin(self->pin->port, pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED);
|
||||
common_hal_digitalio_digitalinout_set_value(self, value);
|
||||
}
|
||||
|
||||
enum digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
return self->output? DIRECTION_OUTPUT : DIRECTION_INPUT;
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_set_value(
|
||||
digitalio_digitalinout_obj_t* self, bool value) {
|
||||
if (value) {
|
||||
if (self->open_drain) {
|
||||
hal_gpio_dir_set(self->pin->port, self->pin->pin, HAL_GPIO_MODE_INPUT);
|
||||
} else {
|
||||
hal_gpio_pin_set(self->pin->port, self->pin->pin);
|
||||
hal_gpio_dir_set(self->pin->port, self->pin->pin, HAL_GPIO_MODE_OUTPUT);
|
||||
}
|
||||
} else {
|
||||
hal_gpio_pin_clear(self->pin->port, self->pin->pin);
|
||||
hal_gpio_dir_set(self->pin->port, self->pin->pin, HAL_GPIO_MODE_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
bool common_hal_digitalio_digitalinout_get_value(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
const uint8_t pin = self->pin->pin;
|
||||
if (!self->output) {
|
||||
return hal_gpio_pin_read(self->pin);
|
||||
} else {
|
||||
if (self->open_drain && hal_gpio_dir_get(self->pin->port, self->pin->pin) == HAL_GPIO_MODE_INPUT) {
|
||||
return true;
|
||||
} else {
|
||||
return (GPIO_BASE(self->pin->port)->OUT >> pin) & 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_set_drive_mode(
|
||||
digitalio_digitalinout_obj_t* self,
|
||||
enum digitalio_drive_mode_t drive_mode) {
|
||||
bool value = common_hal_digitalio_digitalinout_get_value(self);
|
||||
self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN;
|
||||
// True is implemented differently between modes so reset the value to make
|
||||
// sure its correct for the new mode.
|
||||
if (value) {
|
||||
common_hal_digitalio_digitalinout_set_value(self, value);
|
||||
}
|
||||
}
|
||||
|
||||
enum digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
if (self->open_drain) {
|
||||
return DRIVE_MODE_OPEN_DRAIN;
|
||||
} else {
|
||||
return DRIVE_MODE_PUSH_PULL;
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_set_pull(
|
||||
digitalio_digitalinout_obj_t* self, enum digitalio_pull_t pull) {
|
||||
hal_gpio_pull_t asf_pull = HAL_GPIO_PULL_DISABLED;
|
||||
switch (pull) {
|
||||
case PULL_UP:
|
||||
asf_pull = HAL_GPIO_PULL_UP;
|
||||
break;
|
||||
case PULL_DOWN:
|
||||
asf_pull = HAL_GPIO_PULL_DOWN;
|
||||
break;
|
||||
case PULL_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hal_gpio_pull_set(self->pin->port, self->pin->pin, asf_pull);
|
||||
}
|
||||
|
||||
enum digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
uint32_t pin = self->pin->pin;
|
||||
if (self->output) {
|
||||
mp_raise_AttributeError("Cannot get pull while in output mode");
|
||||
return PULL_NONE;
|
||||
} else {
|
||||
hal_gpio_pull_t pull = hal_gpio_pull_get(self->pin->port, pin);
|
||||
|
||||
switch(pull)
|
||||
{
|
||||
case HAL_GPIO_PULL_UP:
|
||||
return PULL_UP;
|
||||
|
||||
case HAL_GPIO_PULL_DOWN:
|
||||
return PULL_DOWN;
|
||||
|
||||
default: return PULL_NONE;
|
||||
}
|
||||
}
|
||||
}
|
40
ports/nrf/common-hal/digitalio/DigitalInOut.h
Normal file
40
ports/nrf/common-hal/digitalio/DigitalInOut.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const mcu_pin_obj_t * pin;
|
||||
bool output;
|
||||
bool open_drain;
|
||||
} digitalio_digitalinout_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
|
1
ports/nrf/common-hal/digitalio/__init__.c
Normal file
1
ports/nrf/common-hal/digitalio/__init__.c
Normal file
@ -0,0 +1 @@
|
||||
// No digitalio module functions.
|
75
ports/nrf/common-hal/microcontroller/Pin.c
Normal file
75
ports/nrf/common-hal/microcontroller/Pin.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
#include "py/mphal.h"
|
||||
|
||||
#if 0
|
||||
|
||||
extern volatile bool adc_in_use;
|
||||
|
||||
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
|
||||
if (pin == &pin_TOUT) {
|
||||
return !adc_in_use;
|
||||
}
|
||||
if (pin->gpio_number == NO_GPIO || pin->gpio_number == SPECIAL_CASE) {
|
||||
return false;
|
||||
}
|
||||
return (READ_PERI_REG(pin->peripheral) &
|
||||
(PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S)) == 0 &&
|
||||
(GPIO_REG_READ(GPIO_ENABLE_ADDRESS) & (1 << pin->gpio_number)) == 0 &&
|
||||
(READ_PERI_REG(pin->peripheral) & PERIPHS_IO_MUX_PULLUP) == 0;
|
||||
}
|
||||
|
||||
void reset_pins(void) {
|
||||
for (int i = 0; i < 17; i++) {
|
||||
// 5 is RXD, 6 is TXD
|
||||
if ((i > 4 && i < 13) || i == 12) {
|
||||
continue;
|
||||
}
|
||||
uint32_t peripheral = PERIPHS_IO_MUX + i * 4;
|
||||
PIN_FUNC_SELECT(peripheral, 0);
|
||||
PIN_PULLUP_DIS(peripheral);
|
||||
// Disable the pin.
|
||||
gpio_output_set(0x0, 0x0, 0x0, 1 << i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset_all_pins(void) {
|
||||
}
|
||||
|
||||
void reset_pin(uint8_t pin) {
|
||||
|
||||
}
|
||||
|
||||
|
40
ports/nrf/common-hal/microcontroller/Pin.h
Normal file
40
ports/nrf/common-hal/microcontroller/Pin.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
|
||||
#include "py/mphal.h"
|
||||
#include "modules/machine/pin.h"
|
||||
|
||||
//typedef pin_obj_t mcu_pin_obj_t;
|
||||
#define mcu_pin_obj_t pin_obj_t
|
||||
void reset_all_pins(void);
|
||||
void reset_pin(uint8_t pin);
|
||||
//void claim_pin(const mcu_pin_obj_t* pin);
|
||||
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PIN_H
|
37
ports/nrf/common-hal/microcontroller/Processor.c
Normal file
37
ports/nrf/common-hal/microcontroller/Processor.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/microcontroller/Processor.h"
|
||||
|
||||
// TODO port common_hal_mcu_processor
|
||||
float common_hal_mcu_processor_get_temperature(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t common_hal_mcu_processor_get_frequency(void) {
|
||||
return 64000000ul;
|
||||
}
|
||||
|
37
ports/nrf/common-hal/microcontroller/Processor.h
Normal file
37
ports/nrf/common-hal/microcontroller/Processor.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
|
||||
#define MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
// Stores no state currently.
|
||||
} mcu_processor_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
|
51
ports/nrf/common-hal/microcontroller/__init__.c
Normal file
51
ports/nrf/common-hal/microcontroller/__init__.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/microcontroller/Processor.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/Processor.h"
|
||||
|
||||
// TODO porting common_hal_mcu
|
||||
void common_hal_mcu_delay_us(uint32_t delay) {
|
||||
// os_delay_us(delay);
|
||||
}
|
||||
|
||||
void common_hal_mcu_disable_interrupts() {
|
||||
}
|
||||
|
||||
void common_hal_mcu_enable_interrupts() {
|
||||
}
|
||||
|
||||
// The singleton microcontroller.Processor object, returned by microcontroller.cpu
|
||||
// It currently only has properties, and no state.
|
||||
mcu_processor_obj_t common_hal_mcu_processor_obj = {
|
||||
.base = {
|
||||
.type = &mcu_processor_type,
|
||||
},
|
||||
};
|
||||
|
88
ports/nrf/common-hal/os/__init__.c
Normal file
88
ports/nrf/common-hal/os/__init__.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/qstr.h"
|
||||
|
||||
#include "nrf_sdm.h"
|
||||
#include "nrf_soc.h"
|
||||
|
||||
STATIC const qstr os_uname_info_fields[] = {
|
||||
MP_QSTR_sysname, MP_QSTR_nodename,
|
||||
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
||||
};
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "nrf52");
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "nrf52");
|
||||
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||
|
||||
|
||||
STATIC MP_DEFINE_ATTRTUPLE(
|
||||
os_uname_info_obj,
|
||||
os_uname_info_fields,
|
||||
5,
|
||||
(mp_obj_t)&os_uname_info_sysname_obj,
|
||||
(mp_obj_t)&os_uname_info_nodename_obj,
|
||||
(mp_obj_t)&os_uname_info_release_obj,
|
||||
(mp_obj_t)&os_uname_info_version_obj,
|
||||
(mp_obj_t)&os_uname_info_machine_obj
|
||||
);
|
||||
|
||||
mp_obj_t common_hal_os_uname(void) {
|
||||
return (mp_obj_t)&os_uname_info_obj;
|
||||
}
|
||||
|
||||
bool common_hal_os_urandom(uint8_t* buffer, uint32_t length) {
|
||||
uint8_t sd_en = 0;
|
||||
(void) sd_softdevice_is_enabled(&sd_en);
|
||||
|
||||
if ( sd_en )
|
||||
{
|
||||
return NRF_SUCCESS == sd_rand_application_vector_get(buffer,length);
|
||||
}else
|
||||
{
|
||||
// SoftDevice is not enabled.
|
||||
NRF_RNG->EVENTS_VALRDY = 0;
|
||||
NRF_RNG->TASKS_START = 1;
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
while (NRF_RNG->EVENTS_VALRDY == 0) {
|
||||
;
|
||||
}
|
||||
NRF_RNG->EVENTS_VALRDY = 0;
|
||||
buffer[i] = (uint8_t) NRF_RNG->VALUE;
|
||||
}
|
||||
|
||||
NRF_RNG->TASKS_STOP = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
240
ports/nrf/common-hal/pulseio/PWMOut.c
Normal file
240
ports/nrf/common-hal/pulseio/PWMOut.c
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
* Copyright (c) 2016 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "common-hal/pulseio/PWMOut.h"
|
||||
#include "shared-bindings/pulseio/PWMOut.h"
|
||||
|
||||
#define PWM_MAX_MODULE 3
|
||||
#define PWM_MAX_CHANNEL 4
|
||||
|
||||
#define PWM_MAX_FREQ (16000000)
|
||||
|
||||
NRF_PWM_Type* const pwm_arr[PWM_MAX_MODULE] = { NRF_PWM0, NRF_PWM1, NRF_PWM2 };
|
||||
|
||||
uint16_t _seq0[PWM_MAX_MODULE][PWM_MAX_CHANNEL];
|
||||
|
||||
|
||||
static int pin2channel(NRF_PWM_Type* pwm, uint8_t pin)
|
||||
{
|
||||
for(int i=0; i < PWM_MAX_CHANNEL; i++)
|
||||
{
|
||||
if ( pwm->PSEL.OUT[i] == ((uint32_t)pin) ) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_free_channel(NRF_PWM_Type* pwm)
|
||||
{
|
||||
for(int i=0; i < PWM_MAX_CHANNEL; i++)
|
||||
{
|
||||
if (pwm->PSEL.OUT[i] == 0xFFFFFFFFUL)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool pwm_is_unused(NRF_PWM_Type* pwm)
|
||||
{
|
||||
for(int i=0; i < PWM_MAX_CHANNEL; i++)
|
||||
{
|
||||
if (pwm->PSEL.OUT[i] != 0xFFFFFFFFUL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void find_new_pwm(pulseio_pwmout_obj_t* self)
|
||||
{
|
||||
// First find unused PWM module
|
||||
for(int i=0; i<PWM_MAX_MODULE; i++)
|
||||
{
|
||||
if ( pwm_is_unused(pwm_arr[i]) )
|
||||
{
|
||||
self->pwm = pwm_arr[i];
|
||||
self->channel = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find available channel in a using PWM
|
||||
for(int i=0; i<PWM_MAX_MODULE; i++)
|
||||
{
|
||||
int ch = find_free_channel(pwm_arr[i]);
|
||||
if ( ch >= 0 )
|
||||
{
|
||||
self->pwm = pwm_arr[i];
|
||||
self->channel = (uint8_t) ch;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pwmout_reset(void)
|
||||
{
|
||||
for(int i=0; i<PWM_MAX_MODULE; i++)
|
||||
{
|
||||
NRF_PWM_Type* pwm = pwm_arr[i];
|
||||
|
||||
pwm->MODE = PWM_MODE_UPDOWN_Up;
|
||||
pwm->DECODER = PWM_DECODER_LOAD_Individual;
|
||||
pwm->LOOP = 0;
|
||||
pwm->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_1; // default is 500 hz
|
||||
pwm->COUNTERTOP = (PWM_MAX_FREQ/500); // default is 500 hz
|
||||
|
||||
pwm->SEQ[0].PTR = (uint32_t) _seq0[i];
|
||||
pwm->SEQ[0].CNT = PWM_MAX_CHANNEL; // default mode is Individual --> count must be 4
|
||||
pwm->SEQ[0].REFRESH = 0;
|
||||
pwm->SEQ[0].ENDDELAY = 0;
|
||||
|
||||
pwm->SEQ[1].PTR = 0;
|
||||
pwm->SEQ[1].CNT = 0;
|
||||
pwm->SEQ[1].REFRESH = 0;
|
||||
pwm->SEQ[1].ENDDELAY = 0;
|
||||
|
||||
for(int ch =0; ch < PWM_MAX_CHANNEL; ch++)
|
||||
{
|
||||
_seq0[i][ch] = (1UL << 15); // polarity = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
|
||||
const mcu_pin_obj_t* pin,
|
||||
uint16_t duty,
|
||||
uint32_t frequency,
|
||||
bool variable_frequency) {
|
||||
self->pwm = NULL;
|
||||
self->pin = pin;
|
||||
|
||||
// check if mapped to PWM channel already
|
||||
for(int i=0; i<PWM_MAX_MODULE; i++)
|
||||
{
|
||||
int ch = pin2channel(pwm_arr[i], pin->pin);
|
||||
if ( ch >= 0 )
|
||||
{
|
||||
self->pwm = pwm_arr[i];
|
||||
self->channel = (uint8_t) ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Haven't mapped before
|
||||
if ( !self->pwm )
|
||||
{
|
||||
find_new_pwm(self);
|
||||
}
|
||||
|
||||
if (self->pwm)
|
||||
{
|
||||
hal_gpio_cfg_pin(pin->port, pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED);
|
||||
|
||||
// disable before mapping pin channel
|
||||
self->pwm->ENABLE = 0;
|
||||
|
||||
self->pwm->PSEL.OUT[self->channel] = pin->pin;
|
||||
|
||||
self->pwm->COUNTERTOP = (PWM_MAX_FREQ/frequency);
|
||||
self->freq = frequency;
|
||||
self->variable_freq = variable_frequency;
|
||||
|
||||
self->pwm->ENABLE = 1;
|
||||
|
||||
common_hal_pulseio_pwmout_set_duty_cycle(self, duty);
|
||||
}
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) {
|
||||
return self->pwm == NULL;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
|
||||
if (common_hal_pulseio_pwmout_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self->pwm->ENABLE = 0;
|
||||
|
||||
self->pwm->PSEL.OUT[self->channel] = 0xFFFFFFFFUL;
|
||||
|
||||
// re-enable PWM module if there is other active channel
|
||||
for(int i=0; i < PWM_MAX_CHANNEL; i++)
|
||||
{
|
||||
if (self->pwm->PSEL.OUT[i] != 0xFFFFFFFFUL)
|
||||
{
|
||||
self->pwm->ENABLE = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hal_gpio_cfg_pin(self->pin->port, self->pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
|
||||
self->pwm = NULL;
|
||||
self->pin = mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) {
|
||||
self->duty = duty;
|
||||
|
||||
uint16_t* p_value = ((uint16_t*)self->pwm->SEQ[0].PTR) + self->channel;
|
||||
*p_value = ((duty * self->pwm->COUNTERTOP) / 0xFFFF) | (1 << 15);
|
||||
|
||||
self->pwm->TASKS_SEQSTART[0] = 1;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
|
||||
return self->duty;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
|
||||
if (frequency == 0 || frequency > 16000000) {
|
||||
mp_raise_ValueError("Invalid PWM frequency");
|
||||
}
|
||||
|
||||
self->freq = frequency;
|
||||
self->pwm->COUNTERTOP = (PWM_MAX_FREQ/frequency);
|
||||
self->pwm->TASKS_SEQSTART[0] = 1;
|
||||
}
|
||||
|
||||
uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
|
||||
return self->freq;
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) {
|
||||
return self->variable_freq;
|
||||
}
|
||||
|
47
ports/nrf/common-hal/pulseio/PWMOut.h
Normal file
47
ports/nrf/common-hal/pulseio/PWMOut.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const mcu_pin_obj_t *pin;
|
||||
NRF_PWM_Type* pwm;
|
||||
|
||||
uint8_t channel;
|
||||
bool variable_freq;
|
||||
uint16_t duty;
|
||||
uint32_t freq;
|
||||
} pulseio_pwmout_obj_t;
|
||||
|
||||
void pwmout_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H
|
295
ports/nrf/common-hal/pulseio/PulseIn.c
Normal file
295
ports/nrf/common-hal/pulseio/PulseIn.c
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/pulseio/PulseIn.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//#include "asf/common2/services/delay/delay.h"
|
||||
//#include "asf/sam0/drivers/extint/extint.h"
|
||||
//#include "asf/sam0/drivers/extint/extint_callback.h"
|
||||
//#include "asf/sam0/drivers/port/port.h"
|
||||
|
||||
#include "mpconfigport.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
//#include "samd21_pins.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/pulseio/PulseIn.h"
|
||||
|
||||
//#include "tick.h"
|
||||
|
||||
void pulsein_reset(void) {
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
|
||||
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) {
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
|
||||
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
|
||||
return 0xadaf;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
|
||||
return 0xadaf;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) {
|
||||
return 0xadaf;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
static pulseio_pulsein_obj_t *active_pulseins[EIC_NUMBER_OF_INTERRUPTS];
|
||||
static uint64_t last_ms[EIC_NUMBER_OF_INTERRUPTS];
|
||||
static uint16_t last_us[EIC_NUMBER_OF_INTERRUPTS];
|
||||
|
||||
void pulsein_reset(void) {
|
||||
for (int i = 0; i < EIC_NUMBER_OF_INTERRUPTS; i++) {
|
||||
if (active_pulseins[i] != NULL) {
|
||||
extint_chan_disable_callback(i, EXTINT_CALLBACK_TYPE_DETECT);
|
||||
}
|
||||
active_pulseins[i] = NULL;
|
||||
last_ms[i] = 0;
|
||||
last_us[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void pulsein_set_config(pulseio_pulsein_obj_t* self, bool first_edge) {
|
||||
struct extint_chan_conf config;
|
||||
extint_chan_get_config_defaults(&config);
|
||||
config.gpio_pin = self->pin;
|
||||
config.gpio_pin_pull = EXTINT_PULL_NONE;
|
||||
config.filter_input_signal = true;
|
||||
|
||||
if (!first_edge) {
|
||||
config.detection_criteria = EXTINT_DETECT_BOTH;
|
||||
} else if (self->idle_state) {
|
||||
config.detection_criteria = EXTINT_DETECT_FALLING;
|
||||
} else {
|
||||
config.detection_criteria = EXTINT_DETECT_RISING;
|
||||
}
|
||||
extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT);
|
||||
extint_chan_set_config(self->channel, &config);
|
||||
// Clear any interrupts that may have triggered without notifying the CPU.
|
||||
EIC->INTFLAG.reg |= (1UL << self->channel);
|
||||
extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT);
|
||||
}
|
||||
|
||||
static void pulsein_callback(void) {
|
||||
// Grab the current time first.
|
||||
uint16_t current_us = tc_get_count_value(&ms_timer);
|
||||
// Add the overflow flag to account for tick interrupts that are blocked by
|
||||
// this interrupt.
|
||||
uint64_t current_ms = ticks_ms + TC5->COUNT16.INTFLAG.bit.OVF;
|
||||
pulseio_pulsein_obj_t* self = active_pulseins[extint_get_current_channel()];
|
||||
current_us = current_us * 1000 / self->ticks_per_ms;
|
||||
if (self->first_edge) {
|
||||
self->first_edge = false;
|
||||
pulsein_set_config(self, false);
|
||||
} else {
|
||||
uint32_t ms_diff = current_ms - last_ms[self->channel];
|
||||
uint16_t us_diff = current_us - last_us[self->channel];
|
||||
uint32_t total_diff = us_diff;
|
||||
if (last_us[self->channel] > current_us) {
|
||||
total_diff = 1000 + current_us - last_us[self->channel];
|
||||
if (ms_diff > 1) {
|
||||
total_diff += (ms_diff - 1) * 1000;
|
||||
}
|
||||
} else {
|
||||
total_diff += ms_diff * 1000;
|
||||
}
|
||||
uint16_t duration = 0xffff;
|
||||
if (total_diff < duration) {
|
||||
duration = total_diff;
|
||||
}
|
||||
|
||||
uint16_t i = (self->start + self->len) % self->maxlen;
|
||||
self->buffer[i] = duration;
|
||||
if (self->len < self->maxlen) {
|
||||
self->len++;
|
||||
} else {
|
||||
self->start++;
|
||||
}
|
||||
}
|
||||
last_ms[self->channel] = current_ms;
|
||||
last_us[self->channel] = current_us;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
|
||||
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
|
||||
if (!pin->has_extint) {
|
||||
mp_raise_RuntimeError("No hardware support on pin");
|
||||
}
|
||||
// TODO(tannewt): Switch to checking actual extint peripheral state when other
|
||||
// classes use extints.
|
||||
if (active_pulseins[pin->extint_channel] != NULL) {
|
||||
mp_raise_RuntimeError("EXTINT channel already in use");
|
||||
}
|
||||
|
||||
self->buffer = (uint16_t *) gc_alloc(maxlen * sizeof(uint16_t), false);
|
||||
if (self->buffer == NULL) {
|
||||
mp_raise_msg_varg(&mp_type_MemoryError, "Failed to allocate RX buffer of %d bytes", maxlen * sizeof(uint16_t));
|
||||
}
|
||||
self->channel = pin->extint_channel;
|
||||
self->pin = pin->pin;
|
||||
self->maxlen = maxlen;
|
||||
self->idle_state = idle_state;
|
||||
self->start = 0;
|
||||
self->len = 0;
|
||||
self->first_edge = true;
|
||||
self->ticks_per_ms = (system_cpu_clock_get_hz() / 1000 - 1);
|
||||
|
||||
active_pulseins[pin->extint_channel] = self;
|
||||
|
||||
pulsein_set_config(self, true);
|
||||
extint_register_callback(
|
||||
pulsein_callback,
|
||||
self->channel,
|
||||
EXTINT_CALLBACK_TYPE_DETECT);
|
||||
extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT);
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
|
||||
return self->pin == NO_PIN;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
||||
if (common_hal_pulseio_pulsein_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT);
|
||||
active_pulseins[self->channel] = NULL;
|
||||
reset_pin(self->pin);
|
||||
self->pin = NO_PIN;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
|
||||
extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self,
|
||||
uint16_t trigger_duration) {
|
||||
// Send the trigger pulse.
|
||||
if (trigger_duration > 0) {
|
||||
struct port_config pin_conf;
|
||||
port_get_config_defaults(&pin_conf);
|
||||
|
||||
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
|
||||
pin_conf.input_pull = PORT_PIN_PULL_NONE;
|
||||
port_pin_set_config(self->pin, &pin_conf);
|
||||
|
||||
// TODO(tannewt): delay_us isn't exactly correct so we adjust the value
|
||||
// here before calling it. Find out why its not exact and fix it instead
|
||||
// of hacking around it here.
|
||||
uint32_t adjusted_duration = trigger_duration;
|
||||
adjusted_duration *= 4;
|
||||
adjusted_duration /= 5;
|
||||
|
||||
common_hal_mcu_disable_interrupts();
|
||||
port_pin_set_output_level(self->pin, !self->idle_state);
|
||||
common_hal_mcu_delay_us(adjusted_duration);
|
||||
port_pin_set_output_level(self->pin, self->idle_state);
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
// Reconfigure the pin and make sure its set to detect the first edge.
|
||||
last_ms[self->channel] = 0;
|
||||
last_us[self->channel] = 0;
|
||||
self->first_edge = true;
|
||||
pulsein_set_config(self, true);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
self->start = 0;
|
||||
self->len = 0;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
|
||||
if (self->len == 0) {
|
||||
mp_raise_IndexError("pop from an empty PulseIn");
|
||||
}
|
||||
common_hal_mcu_disable_interrupts();
|
||||
uint16_t value = self->buffer[self->start];
|
||||
self->start = (self->start + 1) % self->maxlen;
|
||||
self->len--;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
|
||||
return self->maxlen;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
|
||||
return self->len;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self,
|
||||
int16_t index) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
if (index < 0) {
|
||||
index += self->len;
|
||||
}
|
||||
if (index < 0 || index >= self->len) {
|
||||
common_hal_mcu_enable_interrupts();
|
||||
mp_raise_IndexError("index out of range");
|
||||
}
|
||||
uint16_t value = self->buffer[(self->start + index) % self->maxlen];
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif
|
49
ports/nrf/common-hal/pulseio/PulseIn.h
Normal file
49
ports/nrf/common-hal/pulseio/PulseIn.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint8_t channel;
|
||||
uint8_t pin;
|
||||
uint16_t* buffer;
|
||||
uint16_t maxlen;
|
||||
bool idle_state;
|
||||
volatile uint16_t start;
|
||||
volatile uint16_t len;
|
||||
volatile bool first_edge;
|
||||
uint16_t ticks_per_ms;
|
||||
} pulseio_pulsein_obj_t;
|
||||
|
||||
void pulsein_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H
|
206
ports/nrf/common-hal/pulseio/PulseOut.c
Normal file
206
ports/nrf/common-hal/pulseio/PulseOut.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/pulseio/PulseOut.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//#include "asf/sam0/drivers/tc/tc_interrupt.h"
|
||||
//#include "asf/sam0/drivers/port/port.h"
|
||||
|
||||
#include "mpconfigport.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
//#include "samd21_pins.h"
|
||||
#include "shared-bindings/pulseio/PulseOut.h"
|
||||
|
||||
//void pulse_finish(struct tc_module *const module) {
|
||||
//
|
||||
//}
|
||||
|
||||
void pulseout_reset() {
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier) {
|
||||
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
|
||||
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This timer is shared amongst all PulseOut objects under the assumption that
|
||||
// the code is single threaded. Its stored in MICROPY_PORT_ROOT_POINTERS so it
|
||||
// doesn't get garbage collected.
|
||||
static uint8_t refcount = 0;
|
||||
|
||||
static __IO PORT_PINCFG_Type *active_pincfg = NULL;
|
||||
static uint16_t *pulse_buffer = NULL;
|
||||
static volatile uint16_t pulse_index = 0;
|
||||
static uint16_t pulse_length;
|
||||
static volatile uint32_t current_compare = 0;
|
||||
|
||||
static void turn_on(__IO PORT_PINCFG_Type * pincfg) {
|
||||
pincfg->reg = PORT_PINCFG_PMUXEN;
|
||||
}
|
||||
|
||||
static void turn_off(__IO PORT_PINCFG_Type * pincfg) {
|
||||
pincfg->reg = PORT_PINCFG_RESETVALUE;
|
||||
}
|
||||
|
||||
void pulse_finish(struct tc_module *const module) {
|
||||
pulse_index++;
|
||||
|
||||
if (active_pincfg == NULL) {
|
||||
return;
|
||||
}
|
||||
// Always turn it off.
|
||||
turn_off(active_pincfg);
|
||||
if (pulse_index >= pulse_length) {
|
||||
return;
|
||||
}
|
||||
current_compare = (current_compare + pulse_buffer[pulse_index] * 3 / 4) & 0xffff;
|
||||
tc_set_compare_value(MP_STATE_VM(pulseout_tc_instance), TC_COMPARE_CAPTURE_CHANNEL_0, current_compare);
|
||||
if (pulse_index % 2 == 0) {
|
||||
turn_on(active_pincfg);
|
||||
}
|
||||
}
|
||||
|
||||
void pulseout_reset() {
|
||||
refcount = 0;
|
||||
MP_STATE_VM(pulseout_tc_instance) = NULL;
|
||||
active_pincfg = NULL;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
if (refcount == 0) {
|
||||
// Find a spare timer.
|
||||
Tc *t = NULL;
|
||||
Tc *tcs[TC_INST_NUM] = TC_INSTS;
|
||||
for (uint8_t i = TC_INST_NUM; i > 0; i--) {
|
||||
if (tcs[i - 1]->COUNT16.CTRLA.bit.ENABLE == 0) {
|
||||
t = tcs[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == NULL) {
|
||||
mp_raise_RuntimeError("All timers in use");
|
||||
}
|
||||
MP_STATE_VM(pulseout_tc_instance) = gc_alloc(sizeof(struct tc_module), false);
|
||||
if (t == NULL) {
|
||||
mp_raise_msg(&mp_type_MemoryError, "");
|
||||
}
|
||||
|
||||
struct tc_config config_tc;
|
||||
tc_get_config_defaults(&config_tc);
|
||||
|
||||
config_tc.counter_size = TC_COUNTER_SIZE_16BIT;
|
||||
config_tc.clock_prescaler = TC_CTRLA_PRESCALER_DIV64;
|
||||
config_tc.wave_generation = TC_WAVE_GENERATION_NORMAL_FREQ;
|
||||
|
||||
tc_init(MP_STATE_VM(pulseout_tc_instance), t, &config_tc);
|
||||
tc_register_callback(MP_STATE_VM(pulseout_tc_instance), pulse_finish, TC_CALLBACK_CC_CHANNEL0);
|
||||
tc_enable(MP_STATE_VM(pulseout_tc_instance));
|
||||
tc_stop_counter(MP_STATE_VM(pulseout_tc_instance));
|
||||
}
|
||||
refcount++;
|
||||
|
||||
self->pin = carrier->pin->pin;
|
||||
|
||||
PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin);
|
||||
self->pincfg = &port_base->PINCFG[self->pin % 32];
|
||||
|
||||
// Set the port to output a zero.
|
||||
port_base->OUTCLR.reg = 1 << (self->pin % 32);
|
||||
port_base->DIRSET.reg = 1 << (self->pin % 32);
|
||||
|
||||
// Turn off the pinmux which should connect the port output.
|
||||
turn_off(self->pincfg);
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
|
||||
return self->pin == NO_PIN;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
|
||||
if (common_hal_pulseio_pulseout_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin);
|
||||
port_base->DIRCLR.reg = 1 << (self->pin % 32);
|
||||
|
||||
turn_on(self->pincfg);
|
||||
|
||||
refcount--;
|
||||
if (refcount == 0) {
|
||||
tc_reset(MP_STATE_VM(pulseout_tc_instance));
|
||||
gc_free(MP_STATE_VM(pulseout_tc_instance));
|
||||
MP_STATE_VM(pulseout_tc_instance) = NULL;
|
||||
}
|
||||
self->pin = NO_PIN;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
|
||||
if (active_pincfg != NULL) {
|
||||
mp_raise_RuntimeError("Another send is already active");
|
||||
}
|
||||
active_pincfg = self->pincfg;
|
||||
pulse_buffer = pulses;
|
||||
pulse_index = 0;
|
||||
pulse_length = length;
|
||||
|
||||
current_compare = pulses[0] * 3 / 4;
|
||||
tc_set_compare_value(MP_STATE_VM(pulseout_tc_instance), TC_COMPARE_CAPTURE_CHANNEL_0, current_compare);
|
||||
|
||||
tc_enable_callback(MP_STATE_VM(pulseout_tc_instance), TC_CALLBACK_CC_CHANNEL0);
|
||||
turn_on(active_pincfg);
|
||||
tc_start_counter(MP_STATE_VM(pulseout_tc_instance));
|
||||
|
||||
while(pulse_index < length) {
|
||||
// Do other things while we wait. The interrupts will handle sending the
|
||||
// signal.
|
||||
#ifdef MICROPY_VM_HOOK_LOOP
|
||||
MICROPY_VM_HOOK_LOOP
|
||||
#endif
|
||||
}
|
||||
|
||||
tc_stop_counter(MP_STATE_VM(pulseout_tc_instance));
|
||||
tc_disable_callback(MP_STATE_VM(pulseout_tc_instance), TC_CALLBACK_CC_CHANNEL0);
|
||||
active_pincfg = NULL;
|
||||
}
|
||||
#endif
|
||||
|
42
ports/nrf/common-hal/pulseio/PulseOut.h
Normal file
42
ports/nrf/common-hal/pulseio/PulseOut.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
// __IO PORT_PINCFG_Type *pincfg;
|
||||
uint8_t pin;
|
||||
} pulseio_pulseout_obj_t;
|
||||
|
||||
void pulseout_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H
|
1
ports/nrf/common-hal/pulseio/__init__.c
Normal file
1
ports/nrf/common-hal/pulseio/__init__.c
Normal file
@ -0,0 +1 @@
|
||||
// No pulseio module functions.
|
39
ports/nrf/common-hal/storage/__init__.c
Normal file
39
ports/nrf/common-hal/storage/__init__.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/storage/__init__.h"
|
||||
|
||||
extern volatile bool mp_msc_enabled;
|
||||
|
||||
void common_hal_storage_remount(const char* mount_path, bool readonly) {
|
||||
if (strcmp(mount_path, "/") != 0) {
|
||||
mp_raise_OSError(MP_EINVAL);
|
||||
}
|
||||
}
|
38
ports/nrf/common-hal/time/__init__.c
Normal file
38
ports/nrf/common-hal/time/__init__.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
#include "boards/board.h"
|
||||
|
||||
inline uint64_t common_hal_time_monotonic() {
|
||||
return ticks_ms;
|
||||
}
|
||||
|
||||
void common_hal_time_delay_ms(uint32_t delay) {
|
||||
mp_hal_delay_ms(delay);
|
||||
}
|
@ -35,6 +35,8 @@ extern uint32_t _ebss;
|
||||
|
||||
typedef void (*func)(void);
|
||||
|
||||
#define _start main
|
||||
|
||||
extern void _start(void) __attribute__((noreturn));
|
||||
extern void SystemInit(void);
|
||||
|
||||
|
@ -35,6 +35,8 @@ extern uint32_t _ebss;
|
||||
|
||||
typedef void (*func)(void);
|
||||
|
||||
#define _start main
|
||||
|
||||
extern void _start(void) __attribute__((noreturn));
|
||||
extern void SystemInit(void);
|
||||
|
||||
|
@ -52,6 +52,23 @@ function download_s132_nrf52_3_0_0
|
||||
cd -
|
||||
}
|
||||
|
||||
function download_s132_nrf52_5_0_0
|
||||
{
|
||||
echo ""
|
||||
echo "####################################"
|
||||
echo "### Downloading s132_nrf52_5.0.0 ###"
|
||||
echo "####################################"
|
||||
echo ""
|
||||
|
||||
mkdir -p $1/s132_nrf52_5.0.0
|
||||
cd $1/s132_nrf52_5.0.0
|
||||
|
||||
wget http://www.nordicsemi.com/eng/nordic/download_resource/58987/11/7198220/116068
|
||||
mv 116068 temp.zip
|
||||
unzip -u temp.zip
|
||||
rm temp.zip
|
||||
cd -
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
@ -60,6 +77,7 @@ if [ $# -eq 0 ]; then
|
||||
download_s110_nrf51_8_0_0 ${SCRIPT_DIR}
|
||||
download_s132_nrf52_2_0_1 ${SCRIPT_DIR}
|
||||
download_s132_nrf52_3_0_0 ${SCRIPT_DIR}
|
||||
download_s132_nrf52_5_0_0 ${SCRIPT_DIR}
|
||||
else
|
||||
case $1 in
|
||||
"s110_nrf51" )
|
||||
@ -68,6 +86,8 @@ else
|
||||
download_s132_nrf52_2_0_1 ${SCRIPT_DIR} ;;
|
||||
"s132_nrf52_3_0_0" )
|
||||
download_s132_nrf52_3_0_0 ${SCRIPT_DIR} ;;
|
||||
"s132_nrf52_5_0_0" )
|
||||
download_s132_nrf52_5_0_0 ${SCRIPT_DIR} ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
267
ports/nrf/fifo.c
Normal file
267
ports/nrf/fifo.c
Normal file
@ -0,0 +1,267 @@
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@file fifo.c
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Light-weight FIFO buffer with basic mutex support
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2012, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "fifo.h"
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
*------------------------------------------------------------------*/
|
||||
#if CFG_FIFO_MUTEX
|
||||
|
||||
#define mutex_lock_if_needed(_ff) if (_ff->mutex) fifo_mutex_lock(_ff->mutex)
|
||||
#define mutex_unlock_if_needed(_ff) if (_ff->mutex) fifo_mutex_unlock(_ff->mutex)
|
||||
|
||||
#else
|
||||
|
||||
#define mutex_lock_if_needed(_ff)
|
||||
#define mutex_unlock_if_needed(_ff)
|
||||
|
||||
#endif
|
||||
|
||||
static inline uint16_t min16_of(uint16_t x, uint16_t y)
|
||||
{
|
||||
return (x < y) ? x : y;
|
||||
}
|
||||
|
||||
static inline bool fifo_initalized(fifo_t* f)
|
||||
{
|
||||
return (f->buffer != NULL) && (f->depth > 0) && (f->item_size > 0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@brief Read one byte out of the RX buffer.
|
||||
|
||||
This function will return the byte located at the array index of the
|
||||
read pointer, and then increment the read pointer index. If the read
|
||||
pointer exceeds the maximum buffer size, it will roll over to zero.
|
||||
|
||||
@param[in] f
|
||||
Pointer to the FIFO buffer to manipulate
|
||||
@param[in] p_buffer
|
||||
Pointer to the place holder for data read from the buffer
|
||||
|
||||
@returns TRUE if the queue is not empty
|
||||
*/
|
||||
/******************************************************************************/
|
||||
bool fifo_read(fifo_t* f, void * p_buffer)
|
||||
{
|
||||
if( !fifo_initalized(f) ) return false;
|
||||
if( fifo_empty(f) ) return false;
|
||||
|
||||
mutex_lock_if_needed(f);
|
||||
|
||||
memcpy(p_buffer,
|
||||
f->buffer + (f->rd_idx * f->item_size),
|
||||
f->item_size);
|
||||
f->rd_idx = (f->rd_idx + 1) % f->depth;
|
||||
f->count--;
|
||||
|
||||
mutex_unlock_if_needed(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@brief This function will read n elements into the array index specified by
|
||||
the write pointer and increment the write index. If the write index
|
||||
exceeds the max buffer size, then it will roll over to zero.
|
||||
|
||||
@param[in] f
|
||||
Pointer to the FIFO buffer to manipulate
|
||||
@param[in] p_data
|
||||
The pointer to data location
|
||||
@param[in] count
|
||||
Number of element that buffer can afford
|
||||
|
||||
@returns number of bytes read from the FIFO
|
||||
*/
|
||||
/******************************************************************************/
|
||||
uint16_t fifo_read_n (fifo_t* f, void * p_buffer, uint16_t count)
|
||||
{
|
||||
if( !fifo_initalized(f) ) return false;
|
||||
if( fifo_empty(f) ) return false;
|
||||
|
||||
/* Limit up to fifo's count */
|
||||
count = min16_of(count, f->count);
|
||||
if( count == 0 ) return 0;
|
||||
|
||||
mutex_lock_if_needed(f);
|
||||
|
||||
/* Could copy up to 2 portions marked as 'x' if queue is wrapped around
|
||||
* case 1: ....RxxxxW.......
|
||||
* case 2: xxxxxW....Rxxxxxx
|
||||
*/
|
||||
// uint16_t index2upper = min16_of(count, f->count-f->rd_idx);
|
||||
|
||||
uint8_t* p_buf = (uint8_t*) p_buffer;
|
||||
uint16_t len = 0;
|
||||
while( (len < count) && fifo_read(f, p_buf) )
|
||||
{
|
||||
len++;
|
||||
p_buf += f->item_size;
|
||||
}
|
||||
|
||||
mutex_unlock_if_needed(f);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@brief Reads one item without removing it from the FIFO
|
||||
|
||||
@param[in] f
|
||||
Pointer to the FIFO buffer to manipulate
|
||||
@param[in] position
|
||||
Position to read from in the FIFO buffer
|
||||
@param[in] p_buffer
|
||||
Pointer to the place holder for data read from the buffer
|
||||
|
||||
@returns TRUE if the queue is not empty
|
||||
*/
|
||||
/******************************************************************************/
|
||||
bool fifo_peek_at(fifo_t* f, uint16_t position, void * p_buffer)
|
||||
{
|
||||
if ( !fifo_initalized(f) ) return false;
|
||||
if ( position >= f->count ) return false;
|
||||
|
||||
// rd_idx is position=0
|
||||
uint16_t index = (f->rd_idx + position) % f->depth;
|
||||
memcpy(p_buffer,
|
||||
f->buffer + (index * f->item_size),
|
||||
f->item_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@brief Write one element into the RX buffer.
|
||||
|
||||
This function will write one element into the array index specified by
|
||||
the write pointer and increment the write index. If the write index
|
||||
exceeds the max buffer size, then it will roll over to zero.
|
||||
|
||||
@param[in] f
|
||||
Pointer to the FIFO buffer to manipulate
|
||||
@param[in] p_data
|
||||
The byte to add to the FIFO
|
||||
|
||||
@returns TRUE if the data was written to the FIFO (overwrittable
|
||||
FIFO will always return TRUE)
|
||||
*/
|
||||
/******************************************************************************/
|
||||
bool fifo_write(fifo_t* f, void const * p_data)
|
||||
{
|
||||
if ( !fifo_initalized(f) ) return false;
|
||||
if ( fifo_full(f) && !f->overwritable ) return false;
|
||||
|
||||
mutex_lock_if_needed(f);
|
||||
|
||||
memcpy( f->buffer + (f->wr_idx * f->item_size),
|
||||
p_data,
|
||||
f->item_size);
|
||||
|
||||
f->wr_idx = (f->wr_idx + 1) % f->depth;
|
||||
|
||||
if (fifo_full(f))
|
||||
{
|
||||
f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size)
|
||||
}
|
||||
else
|
||||
{
|
||||
f->count++;
|
||||
}
|
||||
|
||||
mutex_unlock_if_needed(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@brief This function will write n elements into the array index specified by
|
||||
the write pointer and increment the write index. If the write index
|
||||
exceeds the max buffer size, then it will roll over to zero.
|
||||
|
||||
@param[in] f
|
||||
Pointer to the FIFO buffer to manipulate
|
||||
@param[in] p_data
|
||||
The pointer to data to add to the FIFO
|
||||
@param[in] count
|
||||
Number of element
|
||||
@return Number of written elements
|
||||
*/
|
||||
/******************************************************************************/
|
||||
uint16_t fifo_write_n(fifo_t* f, void const * p_data, uint16_t count)
|
||||
{
|
||||
if ( count == 0 ) return 0;
|
||||
|
||||
uint8_t* p_buf = (uint8_t*) p_data;
|
||||
|
||||
uint16_t len = 0;
|
||||
while( (len < count) && fifo_write(f, p_buf) )
|
||||
{
|
||||
len++;
|
||||
p_buf += f->item_size;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@brief Clear the fifo read and write pointers and set length to zero
|
||||
|
||||
@param[in] f
|
||||
Pointer to the FIFO buffer to manipulate
|
||||
*/
|
||||
/******************************************************************************/
|
||||
void fifo_clear(fifo_t *f)
|
||||
{
|
||||
mutex_lock_if_needed(f);
|
||||
|
||||
f->rd_idx = f->wr_idx = f->count = 0;
|
||||
|
||||
mutex_unlock_if_needed(f);
|
||||
}
|
148
ports/nrf/fifo.h
Normal file
148
ports/nrf/fifo.h
Normal file
@ -0,0 +1,148 @@
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
@file fifo.h
|
||||
@author hathach (tinyusb.org)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2012, K. Townsend (microBuilder.eu)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/******************************************************************************/
|
||||
#ifndef __FIFO_H__
|
||||
#define __FIFO_H__
|
||||
|
||||
#define CFG_FIFO_MUTEX 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CFG_FIFO_MUTEX
|
||||
|
||||
#include "nrf52.h"
|
||||
|
||||
#define fifo_mutex_t IRQn_Type
|
||||
|
||||
#define fifo_mutex_lock(m) NVIC_DisableIRQ(m)
|
||||
#define fifo_mutex_unlock(m) NVIC_EnableIRQ(m)
|
||||
|
||||
/* Internal use only */
|
||||
#define _mutex_declare(m) .mutex = m
|
||||
|
||||
#else
|
||||
|
||||
#define _mutex_declare(m)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct _fifo_t
|
||||
{
|
||||
uint8_t* const buffer ; ///< buffer pointer
|
||||
uint16_t const depth ; ///< max items
|
||||
uint16_t const item_size ; ///< size of each item
|
||||
volatile uint16_t count ; ///< number of items in queue
|
||||
volatile uint16_t wr_idx ; ///< write pointer
|
||||
volatile uint16_t rd_idx ; ///< read pointer
|
||||
bool const overwritable;
|
||||
|
||||
#if CFG_FIFO_MUTEX
|
||||
fifo_mutex_t const mutex;
|
||||
#endif
|
||||
|
||||
} fifo_t;
|
||||
|
||||
/**
|
||||
* Macro to declare a fifo
|
||||
* @param name : name of the fifo
|
||||
* @param depth : max number of items
|
||||
* @param type : data type of item
|
||||
* @param overwritable : whether fifo should be overwrite when full
|
||||
* @param mutex : mutex object
|
||||
*/
|
||||
#define FIFO_DEF(_name, _depth, _type, _overwritable, _mutex)\
|
||||
_type _name##_buffer[_depth];\
|
||||
fifo_t _name##_fifo = {\
|
||||
.buffer = (uint8_t*) _name##_buffer,\
|
||||
.depth = _depth,\
|
||||
.item_size = sizeof(_type),\
|
||||
.overwritable = _overwritable,\
|
||||
_mutex_declare(_mutex)\
|
||||
};\
|
||||
fifo_t* _name = &_name##_fifo
|
||||
|
||||
|
||||
void fifo_clear (fifo_t *f);
|
||||
|
||||
bool fifo_write (fifo_t* f, void const * p_data);
|
||||
uint16_t fifo_write_n (fifo_t* f, void const * p_data, uint16_t count);
|
||||
|
||||
bool fifo_read (fifo_t* f, void * p_buffer);
|
||||
uint16_t fifo_read_n (fifo_t* f, void * p_buffer, uint16_t count);
|
||||
|
||||
bool fifo_peek_at (fifo_t* f, uint16_t position, void * p_buffer);
|
||||
static inline bool fifo_peek(fifo_t* f, void * p_buffer)
|
||||
{
|
||||
return fifo_peek_at(f, 0, p_buffer);
|
||||
}
|
||||
|
||||
|
||||
static inline bool fifo_empty(fifo_t* f)
|
||||
{
|
||||
return (f->count == 0);
|
||||
}
|
||||
|
||||
static inline bool fifo_full(fifo_t* f)
|
||||
{
|
||||
return (f->count == f->depth);
|
||||
}
|
||||
|
||||
static inline uint16_t fifo_count(fifo_t* f)
|
||||
{
|
||||
return f->count;
|
||||
}
|
||||
|
||||
static inline uint16_t fifo_remaining(fifo_t* f)
|
||||
{
|
||||
return f->depth - f->count;
|
||||
}
|
||||
|
||||
static inline uint16_t fifo_depth(fifo_t* f)
|
||||
{
|
||||
return f->depth;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -45,8 +45,8 @@
|
||||
|
||||
#define GPIO_BASE(x) ((NRF_GPIO_Type *)POINTERS[x])
|
||||
|
||||
#define hal_gpio_pin_high(p) (((NRF_GPIO_Type *)(GPIO_BASE((p)->port)))->OUTSET = (p)->pin_mask)
|
||||
#define hal_gpio_pin_low(p) (((NRF_GPIO_Type *)(GPIO_BASE((p)->port)))->OUTCLR = (p)->pin_mask)
|
||||
#define hal_gpio_pin_high(p) (((NRF_GPIO_Type *)(GPIO_BASE((p)->port)))->OUTSET = (1 << (p)->pin) )
|
||||
#define hal_gpio_pin_low(p) (((NRF_GPIO_Type *)(GPIO_BASE((p)->port)))->OUTCLR = (1 << (p)->pin) )
|
||||
#define hal_gpio_pin_read(p) (((NRF_GPIO_Type *)(GPIO_BASE((p)->port)))->IN >> ((p)->pin) & 1)
|
||||
|
||||
typedef enum {
|
||||
@ -74,6 +74,28 @@ static inline void hal_gpio_cfg_pin(uint8_t port, uint32_t pin_number, hal_gpio_
|
||||
| mode;
|
||||
}
|
||||
|
||||
static inline void hal_gpio_dir_set(uint8_t port, uint32_t pin, hal_gpio_mode_t mode)
|
||||
{
|
||||
GPIO_BASE(port)->PIN_CNF[pin] &= ~GPIO_PIN_CNF_DIR_Msk;
|
||||
GPIO_BASE(port)->PIN_CNF[pin] |= mode;
|
||||
}
|
||||
|
||||
static inline hal_gpio_mode_t hal_gpio_dir_get(uint8_t port, uint32_t pin)
|
||||
{
|
||||
return GPIO_BASE(port)->PIN_CNF[pin] & GPIO_PIN_CNF_DIR_Msk;
|
||||
}
|
||||
|
||||
static inline void hal_gpio_pull_set(uint8_t port, uint32_t pin, hal_gpio_pull_t pull)
|
||||
{
|
||||
GPIO_BASE(port)->PIN_CNF[pin] &= ~GPIO_PIN_CNF_PULL_Msk;
|
||||
GPIO_BASE(port)->PIN_CNF[pin] |= pull;
|
||||
}
|
||||
|
||||
static inline hal_gpio_pull_t hal_gpio_pull_get(uint8_t port, uint32_t pin)
|
||||
{
|
||||
return GPIO_BASE(port)->PIN_CNF[pin] & GPIO_PIN_CNF_PULL_Msk;
|
||||
}
|
||||
|
||||
static inline void hal_gpio_out_set(uint8_t port, uint32_t pin_mask) {
|
||||
GPIO_BASE(port)->OUTSET = pin_mask;
|
||||
}
|
||||
@ -90,6 +112,14 @@ static inline void hal_gpio_pin_clear(uint8_t port, uint32_t pin) {
|
||||
GPIO_BASE(port)->OUTCLR = (1 << pin);
|
||||
}
|
||||
|
||||
static inline void hal_gpio_pin_set_value(uint8_t port, uint32_t pin, uint8_t value) {
|
||||
if (value) {
|
||||
hal_gpio_pin_set(port, pin);
|
||||
}else {
|
||||
hal_gpio_pin_clear(port, pin);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hal_gpio_pin_toggle(uint8_t port, uint32_t pin) {
|
||||
uint32_t pin_mask = (1 << pin);
|
||||
uint32_t pins_state = NRF_GPIO->OUT;
|
||||
|
@ -30,9 +30,12 @@
|
||||
#include "nrf.h"
|
||||
#include "mphalport.h"
|
||||
#include "hal_uart.h"
|
||||
#include "fifo.h"
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
|
||||
FIFO_DEF(_ff_uart, 128, uint8_t, true, UARTE0_UART0_IRQn);
|
||||
|
||||
uint32_t hal_uart_baudrate_lookup[] = {
|
||||
UART_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud.
|
||||
UART_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud.
|
||||
@ -66,15 +69,21 @@ hal_uart_error_t hal_uart_char_write(NRF_UART_Type * p_instance, uint8_t ch) {
|
||||
}
|
||||
|
||||
hal_uart_error_t hal_uart_char_read(NRF_UART_Type * p_instance, uint8_t * ch) {
|
||||
p_instance->ERRORSRC = 0;
|
||||
while (p_instance->EVENTS_RXDRDY != 1) {
|
||||
// Wait for RXD data.
|
||||
}
|
||||
// p_instance->ERRORSRC = 0;
|
||||
// while (p_instance->EVENTS_RXDRDY != 1) {
|
||||
// // Wait for RXD data.
|
||||
// }
|
||||
//
|
||||
// p_instance->EVENTS_RXDRDY = 0;
|
||||
// *ch = p_instance->RXD;
|
||||
//
|
||||
// return p_instance->ERRORSRC;
|
||||
|
||||
p_instance->EVENTS_RXDRDY = 0;
|
||||
*ch = p_instance->RXD;
|
||||
while ( !fifo_read(_ff_uart, ch) ) {
|
||||
// wait for fifo data
|
||||
}
|
||||
|
||||
return p_instance->ERRORSRC;
|
||||
return HAL_UART_ERROR_NONE;
|
||||
}
|
||||
|
||||
hal_uart_error_t hal_uart_buffer_write(NRF_UART_Type * p_instance, uint8_t * p_buffer, uint32_t num_of_bytes, uart_complete_cb cb) {
|
||||
@ -106,6 +115,11 @@ hal_uart_error_t hal_uart_buffer_read(NRF_UART_Type * p_instance, uint8_t * p_bu
|
||||
return err;
|
||||
}
|
||||
|
||||
int hal_uart_available(NRF_UART_Type * p_instance)
|
||||
{
|
||||
return fifo_count(_ff_uart);
|
||||
}
|
||||
|
||||
void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_init) {
|
||||
hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->tx_pin->pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_PULL_DISABLED);
|
||||
hal_gpio_cfg_pin(p_uart_init->tx_pin->port, p_uart_init->rx_pin->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED);
|
||||
@ -141,6 +155,27 @@ void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_in
|
||||
p_instance->EVENTS_RXDRDY = 0;
|
||||
p_instance->TASKS_STARTTX = 1;
|
||||
p_instance->TASKS_STARTRX = 1;
|
||||
|
||||
// Adafruit IRQ + fifo
|
||||
fifo_clear(_ff_uart);
|
||||
p_instance->INTENSET = UART_INTENSET_RXDRDY_Msk;
|
||||
NVIC_ClearPendingIRQ(p_uart_init->irq_num);
|
||||
NVIC_SetPriority(p_uart_init->irq_num, p_uart_init->irq_priority);
|
||||
NVIC_EnableIRQ(p_uart_init->irq_num);
|
||||
}
|
||||
|
||||
|
||||
void UARTE0_UART0_IRQHandler(void)
|
||||
{
|
||||
NRF_UART_Type * p_instance = NRF_UART0;
|
||||
|
||||
if (p_instance->EVENTS_RXDRDY)
|
||||
{
|
||||
uint8_t ch = (uint8_t) p_instance->RXD;
|
||||
fifo_write(_ff_uart, &ch);
|
||||
|
||||
p_instance->EVENTS_RXDRDY = 0x0UL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAL_UART_MODULE_ENABLED
|
||||
|
@ -121,5 +121,6 @@ void hal_uart_init(NRF_UART_Type * p_instance, hal_uart_init_t const * p_uart_in
|
||||
hal_uart_error_t hal_uart_char_write(NRF_UART_Type * p_instance, uint8_t ch);
|
||||
|
||||
hal_uart_error_t hal_uart_char_read(NRF_UART_Type * p_instance, uint8_t * ch);
|
||||
int hal_uart_available(NRF_UART_Type * p_instance);
|
||||
|
||||
#endif // HAL_UART_H__
|
||||
|
208
ports/nrf/internal_flash.c
Normal file
208
ports/nrf/internal_flash.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "internal_flash.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "supervisor/shared/rgb_led_status.h"
|
||||
|
||||
#include "nrf.h"
|
||||
#include "nrf_soc.h"
|
||||
|
||||
// defined in linker
|
||||
extern uint32_t __fatfs_flash_start_addr[];
|
||||
extern uint32_t __fatfs_flash_length[];
|
||||
|
||||
void internal_flash_init(void) {
|
||||
// Activity LED for flash writes.
|
||||
#ifdef MICROPY_HW_LED_MSC
|
||||
struct port_config pin_conf;
|
||||
port_get_config_defaults(&pin_conf);
|
||||
|
||||
pin_conf.direction = PORT_PIN_DIR_OUTPUT;
|
||||
port_pin_set_config(MICROPY_HW_LED_MSC, &pin_conf);
|
||||
port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
hri_mclk_set_AHBMASK_NVMCTRL_bit(MCLK);
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
_pm_enable_bus_clock(PM_BUS_APBB, NVMCTRL);
|
||||
#endif
|
||||
// flash_init(&internal_flash_desc, NVMCTRL);
|
||||
}
|
||||
|
||||
uint32_t internal_flash_get_block_size(void) {
|
||||
return FILESYSTEM_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
uint32_t internal_flash_get_block_count(void) {
|
||||
return ((uint32_t) __fatfs_flash_length) / FILESYSTEM_BLOCK_SIZE ;
|
||||
}
|
||||
|
||||
void internal_flash_flush(void) {
|
||||
}
|
||||
|
||||
void flash_flush(void) {
|
||||
internal_flash_flush();
|
||||
}
|
||||
|
||||
static uint32_t convert_block_to_flash_addr(uint32_t block) {
|
||||
return ((uint32_t)__fatfs_flash_start_addr) + block * FILESYSTEM_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
bool internal_flash_write_block(const uint8_t *src, uint32_t block) {
|
||||
#ifdef MICROPY_HW_LED_MSC
|
||||
port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
|
||||
#endif
|
||||
temp_status_color(ACTIVE_WRITE);
|
||||
// non-MBR block, copy to cache
|
||||
|
||||
uint32_t dest = convert_block_to_flash_addr(block);
|
||||
|
||||
uint32_t pagenum = dest / FLASH_PAGE_SIZE;
|
||||
uint8_t* flash_align = (uint8_t*) (pagenum*FLASH_PAGE_SIZE);
|
||||
|
||||
// Read back current page to update only 512 portion
|
||||
__ALIGN(4) uint8_t buf[FLASH_PAGE_SIZE];
|
||||
memcpy(buf, flash_align, FLASH_PAGE_SIZE);
|
||||
memcpy(buf + (dest%FLASH_PAGE_SIZE), src, FILESYSTEM_BLOCK_SIZE);
|
||||
|
||||
if (NRF_SUCCESS != sd_flash_page_erase(pagenum)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NRF_SUCCESS != sd_flash_write((uint32_t*) flash_align, (uint32_t*) buf, FLASH_PAGE_SIZE/4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clear_temp_status();
|
||||
#ifdef MICROPY_HW_LED_MSC
|
||||
port_pin_set_output_level(MICROPY_HW_LED_MSC, false);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
|
||||
uint32_t src = convert_block_to_flash_addr(block);
|
||||
memcpy(dest, (uint8_t*) src, FILESYSTEM_BLOCK_SIZE*num_blocks);
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
|
||||
for (size_t i = 0; i < num_blocks; i++) {
|
||||
if (!internal_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block_num + i)) {
|
||||
return 1; // error
|
||||
}
|
||||
}
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings
|
||||
//
|
||||
// Expose the flash as an object with the block protocol.
|
||||
|
||||
// there is a singleton Flash object
|
||||
STATIC const mp_obj_base_t internal_flash_obj = {&internal_flash_type};
|
||||
|
||||
STATIC mp_obj_t internal_flash_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return singleton object
|
||||
return (mp_obj_t)&internal_flash_obj;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t internal_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||
mp_uint_t ret = internal_flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_readblocks_obj, internal_flash_obj_readblocks);
|
||||
|
||||
STATIC mp_obj_t internal_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||
mp_uint_t ret = internal_flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
|
||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_writeblocks_obj, internal_flash_obj_writeblocks);
|
||||
|
||||
STATIC mp_obj_t internal_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||
switch (cmd) {
|
||||
case BP_IOCTL_INIT: internal_flash_init(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case BP_IOCTL_DEINIT: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0); // TODO properly
|
||||
case BP_IOCTL_SYNC: internal_flash_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_count());
|
||||
case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(internal_flash_get_block_size());
|
||||
default: return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(internal_flash_obj_ioctl_obj, internal_flash_obj_ioctl);
|
||||
|
||||
STATIC const mp_rom_map_elem_t internal_flash_obj_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&internal_flash_obj_readblocks_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&internal_flash_obj_writeblocks_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&internal_flash_obj_ioctl_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(internal_flash_obj_locals_dict, internal_flash_obj_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t internal_flash_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_InternalFlash,
|
||||
.make_new = internal_flash_obj_make_new,
|
||||
.locals_dict = (mp_obj_t)&internal_flash_obj_locals_dict,
|
||||
};
|
||||
|
||||
void flash_init_vfs(fs_user_mount_t *vfs) {
|
||||
vfs->base.type = &mp_fat_vfs_type;
|
||||
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
|
||||
vfs->fatfs.drv = vfs;
|
||||
|
||||
// vfs->fatfs.part = 1; // flash filesystem lives on first partition
|
||||
vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj;
|
||||
vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj;
|
||||
vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version
|
||||
|
||||
vfs->writeblocks[0] = (mp_obj_t)&internal_flash_obj_writeblocks_obj;
|
||||
vfs->writeblocks[1] = (mp_obj_t)&internal_flash_obj;
|
||||
vfs->writeblocks[2] = (mp_obj_t)internal_flash_write_blocks; // native version
|
||||
|
||||
vfs->u.ioctl[0] = (mp_obj_t)&internal_flash_obj_ioctl_obj;
|
||||
vfs->u.ioctl[1] = (mp_obj_t)&internal_flash_obj;
|
||||
}
|
61
ports/nrf/internal_flash.h
Normal file
61
ports/nrf/internal_flash.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
#define FLASH_ROOT_POINTERS
|
||||
|
||||
#define FLASH_PAGE_SIZE 0x1000
|
||||
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
|
||||
|
||||
#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms
|
||||
#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2)
|
||||
|
||||
void internal_flash_init(void);
|
||||
uint32_t internal_flash_get_block_size(void);
|
||||
uint32_t internal_flash_get_block_count(void);
|
||||
void internal_flash_irq_handler(void);
|
||||
void internal_flash_flush(void);
|
||||
bool internal_flash_read_block(uint8_t *dest, uint32_t block);
|
||||
bool internal_flash_write_block(const uint8_t *src, uint32_t block);
|
||||
|
||||
// these return 0 on success, non-zero on error
|
||||
mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
|
||||
mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
|
||||
|
||||
extern const struct _mp_obj_type_t internal_flash_type;
|
||||
|
||||
struct _fs_user_mount_t;
|
||||
|
||||
void flash_init_vfs(struct _fs_user_mount_t *vfs);
|
||||
void flash_flush(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_INTERNAL_FLASH_H
|
265
ports/nrf/main.c
265
ports/nrf/main.c
@ -1,265 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Glenn Ruben Bakke
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/lexer.h"
|
||||
#include "py/parse.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/compile.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
#include "readline.h"
|
||||
#include "gccollect.h"
|
||||
#include "modmachine.h"
|
||||
#include "modmusic.h"
|
||||
#include "led.h"
|
||||
#include "uart.h"
|
||||
#include "nrf.h"
|
||||
#include "pin.h"
|
||||
#include "spi.h"
|
||||
#include "i2c.h"
|
||||
#include "rtc.h"
|
||||
#if MICROPY_PY_MACHINE_HW_PWM
|
||||
#include "pwm.h"
|
||||
#endif
|
||||
#include "timer.h"
|
||||
|
||||
#if (MICROPY_PY_BLE_NUS)
|
||||
#include "ble_uart.h"
|
||||
#endif
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
printf("MemoryError: lexer could not allocate memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t pn = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&pn, source_name, MP_EMIT_OPT_NONE, true);
|
||||
mp_call_function_0(module_fun);
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _heap_end;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
soft_reset:
|
||||
mp_stack_set_top(&_ram_end);
|
||||
|
||||
// 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 - 400);
|
||||
|
||||
machine_init();
|
||||
|
||||
gc_init(&_heap_start, &_heap_end);
|
||||
|
||||
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_init(mp_sys_argv, 0);
|
||||
|
||||
pyb_set_repl_info(MP_OBJ_NEW_SMALL_INT(0));
|
||||
|
||||
readline_init0();
|
||||
|
||||
#if MICROPY_PY_MACHINE_HW_SPI
|
||||
spi_init0();
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_MACHINE_I2C
|
||||
i2c_init0();
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_MACHINE_HW_PWM
|
||||
pwm_init0();
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_MACHINE_RTC
|
||||
rtc_init0();
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_MACHINE_TIMER
|
||||
timer_init0();
|
||||
#endif
|
||||
|
||||
uart_init0();
|
||||
|
||||
#if (MICROPY_PY_BLE_NUS == 0)
|
||||
{
|
||||
mp_obj_t args[2] = {
|
||||
MP_OBJ_NEW_SMALL_INT(0),
|
||||
MP_OBJ_NEW_SMALL_INT(115200),
|
||||
};
|
||||
MP_STATE_PORT(pyb_stdio_uart) = machine_hard_uart_type.make_new((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
pin_init0();
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// if an SD card is present then mount it on /sd/
|
||||
if (sdcard_is_present()) {
|
||||
// create vfs object
|
||||
fs_user_mount_t *vfs = m_new_obj_maybe(fs_user_mount_t);
|
||||
if (vfs == NULL) {
|
||||
goto no_mem_for_sd;
|
||||
}
|
||||
vfs->str = "/sd";
|
||||
vfs->len = 3;
|
||||
vfs->flags = FSUSER_FREE_OBJ;
|
||||
sdcard_init_vfs(vfs);
|
||||
|
||||
// put the sd device in slot 1 (it will be unused at this point)
|
||||
MP_STATE_PORT(fs_user_mount)[1] = vfs;
|
||||
|
||||
FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
|
||||
if (res != FR_OK) {
|
||||
printf("PYB: can't mount SD card\n");
|
||||
MP_STATE_PORT(fs_user_mount)[1] = NULL;
|
||||
m_del_obj(fs_user_mount_t, vfs);
|
||||
} else {
|
||||
// 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));
|
||||
|
||||
// use SD card as current directory
|
||||
f_chdrive("/sd");
|
||||
}
|
||||
no_mem_for_sd:;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (MICROPY_HW_HAS_LED)
|
||||
led_init();
|
||||
|
||||
do_str("import pyb\r\n" \
|
||||
"pyb.LED(1).on()",
|
||||
MP_PARSE_FILE_INPUT);
|
||||
#endif
|
||||
|
||||
// Main script is finished, so now go into REPL mode.
|
||||
// The REPL mode can change, or it can request a soft reset.
|
||||
int ret_code = 0;
|
||||
|
||||
#if MICROPY_PY_BLE_NUS
|
||||
ble_uart_init0();
|
||||
while (!ble_uart_enabled()) {
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
if (pyexec_raw_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret_code = pyexec_friendly_repl();
|
||||
if (ret_code != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_deinit();
|
||||
|
||||
if (ret_code == PYEXEC_FORCED_EXIT) {
|
||||
NVIC_SystemReset();
|
||||
} else {
|
||||
goto soft_reset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !MICROPY_VFS
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
mp_raise_OSError(MP_EPERM);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
#endif
|
||||
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
#if NRF52
|
||||
static volatile uint32_t reg;
|
||||
static volatile uint32_t reg2;
|
||||
static volatile uint32_t bfar;
|
||||
reg = SCB->HFSR;
|
||||
reg2 = SCB->CFSR;
|
||||
bfar = SCB->BFAR;
|
||||
for (int i = 0; i < 0; i++)
|
||||
{
|
||||
(void)reg;
|
||||
(void)reg2;
|
||||
(void)bfar;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
printf("FATAL: uncaught exception %p\n", val);
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)val);
|
||||
__fatal_error("");
|
||||
}
|
||||
|
||||
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||
__fatal_error("Assertion failed");
|
||||
}
|
||||
|
||||
void _start(void) {main(0, NULL);}
|
@ -194,7 +194,7 @@ STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
||||
mp_printf(print, "Pin(Pin.cpu.%q, mode=Pin.", self->name);
|
||||
mp_printf(print, "port=0x%x, ", self->port);
|
||||
mp_printf(print, "pin=0x%x, ", self->pin);
|
||||
mp_printf(print, "pin_mask=0x%x,", self->pin_mask);
|
||||
// mp_printf(print, "pin_mask=0x%x,", self->pin_mask);
|
||||
/*
|
||||
uint32_t mode = pin_get_mode(self);
|
||||
|
||||
@ -567,7 +567,7 @@ STATIC const mp_rom_map_elem_t pin_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_AF_OD), MP_ROM_INT(GPIO_MODE_AF_OD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(GPIO_NOPULL) },
|
||||
*/
|
||||
#include "genhdr/pins_af_const.h"
|
||||
//#include "genhdr/pins_af_const.h"
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);
|
||||
|
@ -51,17 +51,21 @@ typedef struct {
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
qstr name;
|
||||
uint32_t port : 4;
|
||||
uint32_t pin : 5; // Some ARM processors use 32 bits/PORT
|
||||
uint32_t num_af : 4;
|
||||
uint32_t adc_channel : 5; // Some ARM processors use 32 bits/PORT
|
||||
uint32_t adc_num : 3; // 1 bit per ADC
|
||||
uint32_t pin_mask;
|
||||
|
||||
uint32_t port : 1;
|
||||
uint32_t pin : 5; // Some ARM processors use 32 bits/PORT
|
||||
uint32_t num_af : 4;
|
||||
uint32_t adc_channel : 4; // 0 is no ADC, ADC channel from 1 to 8
|
||||
|
||||
// uint32_t pin_mask;
|
||||
pin_gpio_t *gpio;
|
||||
const pin_af_obj_t *af;
|
||||
uint32_t pull;
|
||||
} pin_obj_t;
|
||||
|
||||
// Adafruit
|
||||
extern const mp_obj_type_t mcu_pin_type;
|
||||
|
||||
extern const mp_obj_type_t pin_type;
|
||||
extern const mp_obj_type_t pin_af_type;
|
||||
|
||||
@ -84,8 +88,16 @@ typedef struct {
|
||||
extern const mp_obj_type_t pin_board_pins_obj_type;
|
||||
extern const mp_obj_type_t pin_cpu_pins_obj_type;
|
||||
|
||||
extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
|
||||
extern const mp_obj_dict_t pin_board_pins_locals_dict;
|
||||
//extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
|
||||
//extern const mp_obj_dict_t pin_board_pins_locals_dict;
|
||||
|
||||
// Adafruit modification for CircuitPython board module
|
||||
extern const mp_obj_dict_t mcu_pin_globals;
|
||||
extern const mp_obj_dict_t board_module_globals;
|
||||
|
||||
#define pin_cpu_pins_locals_dict mcu_pin_globals
|
||||
#define pin_board_pins_locals_dict board_module_globals
|
||||
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(pin_init_obj);
|
||||
|
||||
|
@ -34,7 +34,8 @@
|
||||
#if MICROPY_PY_MACHINE_HW_PWM
|
||||
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
//#include "genhdr/pins.h"
|
||||
#include "pins.h"
|
||||
#include "pwm.h"
|
||||
|
||||
#if NRF52
|
||||
|
@ -33,7 +33,8 @@
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
//#include "genhdr/pins.h"
|
||||
#include "pins.h"
|
||||
#include "spi.h"
|
||||
#include "hal_spi.h"
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
//#include "genhdr/pins.h"
|
||||
#include "pins.h"
|
||||
|
||||
#include "uart.h"
|
||||
#include "mpconfigboard.h"
|
||||
@ -65,6 +66,8 @@ void uart_init0(void) {
|
||||
// reset the UART handles
|
||||
memset(&UARTHandle0, 0, sizeof(UART_HandleTypeDef));
|
||||
UARTHandle0.p_instance = UART_BASE(0);
|
||||
UARTHandle0.init.irq_num = UARTE0_UART0_IRQn;
|
||||
|
||||
#if NRF52840_XXAA
|
||||
memset(&UARTHandle1, 0, sizeof(UART_HandleTypeDef));
|
||||
UARTHandle0.p_instance = UART_BASE(1);
|
||||
@ -82,13 +85,13 @@ STATIC int uart_find(mp_obj_t id) {
|
||||
"UART(%d) does not exist", uart_id));
|
||||
}
|
||||
|
||||
void uart_irq_handler(mp_uint_t uart_id) {
|
||||
|
||||
}
|
||||
//void uart_irq_handler(mp_uint_t uart_id) {
|
||||
//
|
||||
//}
|
||||
|
||||
bool uart_rx_any(machine_hard_uart_obj_t *uart_obj) {
|
||||
// TODO: uart will block for now.
|
||||
return true;
|
||||
return hal_uart_available(uart_obj->uart->p_instance) > 0;
|
||||
}
|
||||
|
||||
int uart_rx_char(machine_hard_uart_obj_t * self) {
|
||||
|
@ -1,174 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
//#include "timeutils.h"
|
||||
//#include "rng.h"
|
||||
#include "uart.h"
|
||||
//#include "portmodules.h"
|
||||
|
||||
/// \module os - basic "operating system" services
|
||||
///
|
||||
/// The `os` module contains functions for filesystem access and `urandom`.
|
||||
///
|
||||
/// The filesystem has `/` as the root directory, and the available physical
|
||||
/// drives are accessible from here. They are currently:
|
||||
///
|
||||
/// /flash -- the internal flash filesystem
|
||||
/// /sd -- the SD card (if it exists)
|
||||
///
|
||||
/// On boot up, the current directory is `/flash` if no SD card is inserted,
|
||||
/// otherwise it is `/sd`.
|
||||
|
||||
STATIC const qstr os_uname_info_fields[] = {
|
||||
MP_QSTR_sysname, MP_QSTR_nodename,
|
||||
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
||||
};
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "pyboard");
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "pyboard");
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||
STATIC MP_DEFINE_ATTRTUPLE(
|
||||
os_uname_info_obj,
|
||||
os_uname_info_fields,
|
||||
5,
|
||||
(mp_obj_t)&os_uname_info_sysname_obj,
|
||||
(mp_obj_t)&os_uname_info_nodename_obj,
|
||||
(mp_obj_t)&os_uname_info_release_obj,
|
||||
(mp_obj_t)&os_uname_info_version_obj,
|
||||
(mp_obj_t)&os_uname_info_machine_obj
|
||||
);
|
||||
|
||||
STATIC mp_obj_t os_uname(void) {
|
||||
return (mp_obj_t)&os_uname_info_obj;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
||||
|
||||
#if MICROPY_VFS
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
|
||||
// this assumes that vfs->obj is fs_user_mount_t with block device functions
|
||||
disk_ioctl(MP_OBJ_TO_PTR(vfs->obj), CTRL_SYNC, NULL);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(mod_os_sync_obj, os_sync);
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
/// Return a bytes object with n random bytes, generated by the hardware
|
||||
/// random number generator.
|
||||
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
mp_int_t n = mp_obj_get_int(num);
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
vstr.buf[i] = rng_get();
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
#endif
|
||||
|
||||
// Get or set the UART object that the REPL is repeated on.
|
||||
// TODO should accept any object with read/write methods.
|
||||
STATIC mp_obj_t os_dupterm(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
if (MP_STATE_PORT(pyb_stdio_uart) == NULL) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
return MP_STATE_PORT(pyb_stdio_uart);
|
||||
}
|
||||
} else {
|
||||
if (args[0] == mp_const_none) {
|
||||
MP_STATE_PORT(pyb_stdio_uart) = NULL;
|
||||
} else if (mp_obj_get_type(args[0]) == &machine_hard_uart_type) {
|
||||
MP_STATE_PORT(pyb_stdio_uart) = args[0];
|
||||
} else {
|
||||
mp_raise_ValueError("need a UART object");
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_dupterm_obj, 0, 1, os_dupterm);
|
||||
|
||||
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) },
|
||||
|
||||
#if MICROPY_VFS
|
||||
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mod_os_sync_obj) },
|
||||
#endif
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
{ MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) },
|
||||
#endif
|
||||
|
||||
// these are MicroPython extensions
|
||||
{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mod_os_dupterm_obj) },
|
||||
#if MICROPY_VFS
|
||||
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uos = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&os_module_globals,
|
||||
};
|
@ -30,12 +30,8 @@
|
||||
#include <mpconfigboard.h>
|
||||
|
||||
// options to control how MicroPython is built
|
||||
#ifndef MICROPY_VFS
|
||||
#define MICROPY_VFS (1)
|
||||
#endif
|
||||
#define MICROPY_VFS_FAT (MICROPY_VFS)
|
||||
#define MICROPY_ALLOC_PATH_MAX (512)
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (0)
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (1)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (0)
|
||||
@ -48,6 +44,7 @@
|
||||
#define MICROPY_REPL_EMACS_KEYS (0)
|
||||
#define MICROPY_REPL_AUTO_INDENT (1)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
//CP UPDATE: See mpconfigport.h for LONGINT implementation
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#if NRF51
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
@ -64,7 +61,15 @@
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_FATFS_USE_LABEL (1)
|
||||
#define MICROPY_FATFS_RPATH (2)
|
||||
#define MICROPY_FATFS_MULTI_PARTITION (1)
|
||||
#define MICROPY_FATFS_MULTI_PARTITION (0)
|
||||
#define MICROPY_FATFS_NUM_PERSISTENT (1)
|
||||
|
||||
//#define MICROPY_FATFS_MAX_SS (4096)
|
||||
|
||||
#define FILESYSTEM_BLOCK_SIZE 512
|
||||
|
||||
#define MICROPY_VFS (1)
|
||||
#define MICROPY_VFS_FAT (MICROPY_VFS)
|
||||
|
||||
// TODO these should be generic, not bound to fatfs
|
||||
#define mp_type_fileio fatfs_type_fileio
|
||||
@ -82,7 +87,7 @@
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||
#define MICROPY_PY_FUNCTION_ATTRS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_CENTER (0)
|
||||
#define MICROPY_PY_BUILTINS_STR_PARTITION (0)
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (0)
|
||||
@ -203,19 +208,27 @@ typedef unsigned int mp_uint_t; // must be pointer size
|
||||
typedef long mp_off_t;
|
||||
|
||||
// extra built in modules to add to the list of known ones
|
||||
|
||||
extern const struct _mp_obj_module_t microcontroller_module;
|
||||
extern const struct _mp_obj_module_t analogio_module;
|
||||
extern const struct _mp_obj_module_t digitalio_module;
|
||||
extern const struct _mp_obj_module_t pulseio_module;
|
||||
extern const struct _mp_obj_module_t busio_module;
|
||||
extern const struct _mp_obj_module_t board_module;
|
||||
extern const struct _mp_obj_module_t os_module;
|
||||
extern const struct _mp_obj_module_t random_module;
|
||||
extern const struct _mp_obj_module_t storage_module;
|
||||
extern const struct _mp_obj_module_t time_module;
|
||||
extern const struct _mp_obj_module_t supervisor_module;
|
||||
|
||||
extern const struct _mp_obj_module_t pyb_module;
|
||||
extern const struct _mp_obj_module_t machine_module;
|
||||
extern const struct _mp_obj_module_t mp_module_utime;
|
||||
extern const struct _mp_obj_module_t mp_module_uos;
|
||||
extern const struct _mp_obj_module_t mp_module_ubluepy;
|
||||
extern const struct _mp_obj_module_t music_module;
|
||||
extern const struct _mp_obj_module_t random_module;
|
||||
|
||||
#if MICROPY_PY_UBLUEPY
|
||||
#define UBLUEPY_MODULE { MP_ROM_QSTR(MP_QSTR_ubluepy), MP_ROM_PTR(&mp_module_ubluepy) },
|
||||
#else
|
||||
#define UBLUEPY_MODULE
|
||||
#endif
|
||||
extern const struct _mp_obj_module_t ble_module;
|
||||
|
||||
#if MICROPY_PY_MUSIC
|
||||
#define MUSIC_MODULE { MP_ROM_QSTR(MP_QSTR_music), MP_ROM_PTR(&music_module) },
|
||||
@ -229,7 +242,11 @@ extern const struct _mp_obj_module_t random_module;
|
||||
#define RANDOM_MODULE
|
||||
#endif
|
||||
|
||||
#if BLUETOOTH_SD
|
||||
#if MICROPY_PY_UBLUEPY
|
||||
#define UBLUEPY_MODULE { MP_ROM_QSTR(MP_QSTR_ubluepy), MP_ROM_PTR(&mp_module_ubluepy) },
|
||||
#else
|
||||
#define UBLUEPY_MODULE
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_BLE
|
||||
extern const struct _mp_obj_module_t ble_module;
|
||||
@ -239,32 +256,28 @@ extern const struct _mp_obj_module_t ble_module;
|
||||
#endif
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
|
||||
/*{ MP_OBJ_NEW_QSTR(MP_QSTR_storage), (mp_obj_t)&storage_module },*/\
|
||||
{ MP_ROM_QSTR(MP_QSTR_pyb), MP_ROM_PTR(&pyb_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&machine_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_module_utime) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \
|
||||
BLE_MODULE \
|
||||
MUSIC_MODULE \
|
||||
UBLUEPY_MODULE \
|
||||
RANDOM_MODULE \
|
||||
|
||||
|
||||
#else
|
||||
extern const struct _mp_obj_module_t ble_module;
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_ROM_QSTR(MP_QSTR_pyb), MP_ROM_PTR(&pyb_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&machine_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
|
||||
MUSIC_MODULE \
|
||||
RANDOM_MODULE \
|
||||
/*BLE_MODULE \
|
||||
UBLUEPY_MODULE \*/
|
||||
|
||||
|
||||
#endif // BLUETOOTH_SD
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&mp_module_uos) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_module_utime) }, \
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
@ -308,5 +321,6 @@ extern const struct _mp_obj_module_t ble_module;
|
||||
#include <alloca.h>
|
||||
|
||||
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_nrf5.h"
|
||||
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
|
||||
|
||||
#endif
|
||||
|
4
ports/nrf/mpconfigport.mk
Normal file
4
ports/nrf/mpconfigport.mk
Normal file
@ -0,0 +1,4 @@
|
||||
# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk
|
||||
# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers.
|
||||
# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h.
|
||||
MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
|
@ -32,6 +32,8 @@
|
||||
#include "py/mperrno.h"
|
||||
#include "uart.h"
|
||||
|
||||
FIL* boot_output_file;
|
||||
|
||||
// this table converts from HAL_StatusTypeDef to POSIX errno
|
||||
const byte mp_hal_status_to_errno_table[4] = {
|
||||
[HAL_OK] = 0,
|
||||
@ -59,6 +61,11 @@ int mp_hal_stdin_rx_chr(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mp_hal_stdin_any(void)
|
||||
{
|
||||
return uart_rx_any(MP_STATE_PORT(pyb_stdio_uart));
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
|
||||
uart_tx_strn(MP_STATE_PORT(pyb_stdio_uart), str, len);
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "pin.h"
|
||||
#include "hal_gpio.h"
|
||||
|
||||
#include "lib/oofatfs/ff.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_OK = 0x00,
|
||||
@ -40,6 +42,8 @@ typedef enum
|
||||
HAL_TIMEOUT = 0x03
|
||||
} HAL_StatusTypeDef;
|
||||
|
||||
extern FIL* boot_output_file;
|
||||
|
||||
static inline uint32_t hal_tick_fake(void) {
|
||||
return 0;
|
||||
}
|
||||
@ -53,6 +57,7 @@ void mp_hal_set_interrupt_char(int c); // -1 to disable
|
||||
|
||||
int mp_hal_stdin_rx_chr(void);
|
||||
void mp_hal_stdout_tx_str(const char *str);
|
||||
bool mp_hal_stdin_any(void);
|
||||
|
||||
#define mp_hal_pin_obj_t const pin_obj_t*
|
||||
#define mp_hal_get_pin_obj(o) pin_find(o)
|
||||
|
88
ports/nrf/supervisor/filesystem.c
Normal file
88
ports/nrf/supervisor/filesystem.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
|
||||
#include "internal_flash.h"
|
||||
|
||||
fs_user_mount_t fs_user_mount_flash;
|
||||
mp_vfs_mount_t mp_vfs_mount_flash;
|
||||
|
||||
|
||||
void filesystem_init(bool create_allowed) {
|
||||
// init the vfs object
|
||||
fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
|
||||
vfs_fat->flags = 0;
|
||||
flash_init_vfs(vfs_fat);
|
||||
|
||||
// try to mount the flash
|
||||
FRESULT res = f_mount(&vfs_fat->fatfs);
|
||||
|
||||
if (res == FR_NO_FILESYSTEM && create_allowed) {
|
||||
// no filesystem so create a fresh one
|
||||
uint8_t working_buf[_MAX_SS];
|
||||
res = f_mkfs(&vfs_fat->fatfs, FM_FAT | FM_SFD, 4096, working_buf, sizeof(working_buf));
|
||||
// Flush the new file system to make sure its repaired immediately.
|
||||
flash_flush();
|
||||
if (res != FR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set label
|
||||
f_setlabel(&vfs_fat->fatfs, "CIRCUITPY");
|
||||
flash_flush();
|
||||
|
||||
// create lib folder
|
||||
f_mkdir(&vfs_fat->fatfs, "/lib");
|
||||
} else if (res != FR_OK) {
|
||||
return;
|
||||
}
|
||||
mp_vfs_mount_t *vfs = &mp_vfs_mount_flash;
|
||||
vfs->str = "/";
|
||||
vfs->len = 1;
|
||||
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
|
||||
vfs->next = NULL;
|
||||
MP_STATE_VM(vfs_mount_table) = vfs;
|
||||
|
||||
// The current directory is used as the boot up directory.
|
||||
// It is set to the internal flash filesystem by default.
|
||||
MP_STATE_PORT(vfs_cur) = vfs;
|
||||
}
|
||||
|
||||
void filesystem_flush(void) {
|
||||
flash_flush();
|
||||
}
|
||||
|
||||
void filesystem_writable_by_python(bool writable) {
|
||||
}
|
||||
|
||||
bool filesystem_present(void) {
|
||||
return true;
|
||||
}
|
79
ports/nrf/supervisor/port.c
Normal file
79
ports/nrf/supervisor/port.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "supervisor/port.h"
|
||||
#include "boards/board.h"
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/pulseio/PWMOut.h"
|
||||
|
||||
safe_mode_t port_init(void) {
|
||||
board_init();
|
||||
|
||||
#if 0
|
||||
// Configure millisecond timer initialization.
|
||||
tick_init();
|
||||
|
||||
#ifdef CIRCUITPY_CANARY_WORD
|
||||
// Run in safe mode if the canary is corrupt.
|
||||
if (_ezero != CIRCUITPY_CANARY_WORD) {
|
||||
return HARD_CRASH;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (board_requests_safe_mode()) {
|
||||
return USER_SAFE_MODE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NO_SAFE_MODE;
|
||||
}
|
||||
|
||||
void reset_port(void) {
|
||||
pwmout_reset();
|
||||
reset_all_pins();
|
||||
}
|
||||
|
||||
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
#if NRF52
|
||||
// static volatile uint32_t reg;
|
||||
// static volatile uint32_t reg2;
|
||||
// static volatile uint32_t bfar;
|
||||
// reg = SCB->HFSR;
|
||||
// reg2 = SCB->CFSR;
|
||||
// bfar = SCB->BFAR;
|
||||
// for (int i = 0; i < 0; i++)
|
||||
// {
|
||||
// (void)reg;
|
||||
// (void)reg2;
|
||||
// (void)bfar;
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
|
59
ports/nrf/supervisor/serial.c
Normal file
59
ports/nrf/supervisor/serial.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "supervisor/serial.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "mphalport.h"
|
||||
#include "uart.h"
|
||||
|
||||
void serial_init(void) {
|
||||
uart_init0();
|
||||
|
||||
mp_obj_t args[2] = {
|
||||
MP_OBJ_NEW_SMALL_INT(0),
|
||||
MP_OBJ_NEW_SMALL_INT(115200),
|
||||
};
|
||||
MP_STATE_PORT(pyb_stdio_uart) = machine_hard_uart_type.make_new((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args);
|
||||
}
|
||||
|
||||
bool serial_connected(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char serial_read(void) {
|
||||
return (char) mp_hal_stdin_rx_chr();
|
||||
}
|
||||
|
||||
bool serial_bytes_available(void) {
|
||||
return mp_hal_stdin_any();
|
||||
}
|
||||
|
||||
void serial_write(const char* text) {
|
||||
mp_hal_stdout_tx_str(text);
|
||||
}
|
||||
|
@ -57,4 +57,8 @@ void reset_port(void);
|
||||
// Reset the rest of the board.
|
||||
void reset_board(void);
|
||||
|
||||
#ifdef NRF52_SERIES
|
||||
void HardFault_Handler(void);
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H
|
||||
|
Loading…
Reference in New Issue
Block a user