nRF52 update with internal file system support

This commit is contained in:
microbuilder 2017-12-21 13:49:14 +01:00
parent 36ec29d4e8
commit 60a23f0fb6
75 changed files with 4033 additions and 614 deletions

3
.gitmodules vendored
View File

@ -40,3 +40,6 @@
[submodule "tools/usb_descriptor"] [submodule "tools/usb_descriptor"]
path = tools/usb_descriptor path = tools/usb_descriptor
url = https://github.com/adafruit/usb_descriptor.git 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

@ -0,0 +1 @@
Subproject commit 07b43832ee53a4a248c30f5a3014e2632d8aeb88

View File

@ -1,6 +1,6 @@
# Select the board to build for: if not given on the command line, # Select the board to build for: if not given on the command line,
# then default to pca10040. # then default to feather52.
BOARD ?= pca10040 BOARD ?= feather52
ifeq ($(wildcard boards/$(BOARD)/.),) ifeq ($(wildcard boards/$(BOARD)/.),)
$(error Invalid BOARD specified) $(error Invalid BOARD specified)
endif endif
@ -11,33 +11,38 @@ SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]')
# TODO: Verify that it is a valid target. # TODO: Verify that it is a valid target.
ifeq ($(SD), ) ifeq ($(SD), )
# If the build directory is not given, make it reflect the board name. # If the build directory is not given, make it reflect the board name.
BUILD ?= build-$(BOARD) BUILD ?= build-$(BOARD)
include ../../py/mkenv.mk include ../../py/mkenv.mk
include boards/$(BOARD)/mpconfigboard.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 else
# If the build directory is not given, make it reflect the board name. # If the build directory is not given, make it reflect the board name.
BUILD ?= build-$(BOARD)-$(SD_LOWER) BUILD ?= build-$(BOARD)-$(SD_LOWER)
include ../../py/mkenv.mk include ../../py/mkenv.mk
include boards/$(BOARD)/mpconfigboard_$(SD_LOWER).mk include boards/$(BOARD)/mpconfigboard_$(SD_LOWER).mk
-include mpconfigport.mk
include drivers/bluetooth/bluetooth_common.mk include drivers/bluetooth/bluetooth_common.mk
endif endif
# qstr definitions (must come before including py.mk) # qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h QSTR_DEFS = qstrdefsport.h
FROZEN_MPY_DIR = freeze FROZEN_MPY_DIR = freeze
# include py core make definitions # include py core make definitions
include ../../py/py.mk include ../../py/py.mk
include $(TOP)/supervisor/supervisor.mk
FATFS_DIR = lib/oofatfs FATFS_DIR = lib/oofatfs
MPY_CROSS = ../../mpy-cross/mpy-cross
MPY_TOOL = ../../tools/mpy-tool.py
CROSS_COMPILE = arm-none-eabi- CROSS_COMPILE = arm-none-eabi-
@ -105,22 +110,12 @@ LIBS += -L $(dir $(LIBC_FILE_NAME)) -lc
LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
endif 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/,\ SRC_HAL = $(addprefix hal/,\
hal_uart.c \ hal_uart.c \
hal_uarte.c \ hal_uarte.c \
hal_spi.c \ hal_spi.c \
hal_spie.c \ hal_spie.c \
hal_time.c \ hal_time.c \
hal_rtc.c \
hal_timer.c \ hal_timer.c \
hal_twi.c \ hal_twi.c \
hal_adc.c \ hal_adc.c \
@ -136,17 +131,31 @@ SRC_HAL += $(addprefix hal/,\
) )
endif endif
SRC_C += \ SRC_C += \
main.c \
mphalport.c \ mphalport.c \
help.c \ help.c \
gccollect.c \
pin_named_pins.c \ pin_named_pins.c \
fatfs_port.c \ fatfs_port.c \
fifo.c \
drivers/softpwm.c \ drivers/softpwm.c \
drivers/ticker.c \ drivers/ticker.c \
drivers/bluetooth/ble_drv.c \ drivers/bluetooth/ble_drv.c \
drivers/bluetooth/ble_uart.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/,\ DRIVERS_SRC_C += $(addprefix modules/,\
machine/modmachine.c \ machine/modmachine.c \
@ -156,11 +165,9 @@ DRIVERS_SRC_C += $(addprefix modules/,\
machine/adc.c \ machine/adc.c \
machine/pin.c \ machine/pin.c \
machine/timer.c \ machine/timer.c \
machine/rtc.c \
machine/pwm.c \ machine/pwm.c \
machine/led.c \ machine/led.c \
machine/temp.c \ machine/temp.c \
uos/moduos.c \
utime/modutime.c \ utime/modutime.c \
pyb/modpyb.c \ pyb/modpyb.c \
ubluepy/modubluepy.c \ ubluepy/modubluepy.c \
@ -179,18 +186,72 @@ DRIVERS_SRC_C += $(addprefix modules/,\
random/modrandom.c \ random/modrandom.c \
) )
SRC_C += \
device/$(MCU_VARIANT)/system_$(MCU_SUB_VARIANT).c \ SRC_COMMON_HAL += \
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ 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_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
OBJ += $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.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 $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
@ -241,11 +302,11 @@ endif
$(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ) $(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ)
$(ECHO) "LINK $@" $(ECHO) "LINK $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) -Wl,--start-group $(LIBS) -Wl,--end-group
$(Q)$(SIZE) $@ $(Q)$(SIZE) $@
# List of sources for qstr extraction # 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 # Append any auto-generated sources that are needed by sources listed in
# SRC_QSTR # SRC_QSTR
@ -256,16 +317,16 @@ SRC_QSTR_AUTO_DEPS +=
# any of the objects. The normal dependency generation will deal with the # 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 # case when pins.h is modified. But when it doesn't exist, we don't know
# which source files might need it. # 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 # Use a pattern rule here so that make will only call make-pins.py once to make
# both pins_$(BOARD).c and pins.h # 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) #$(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 $@" # $(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) # $(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 #$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
$(call compile_c) # $(call compile_c)
MAKE_PINS = boards/make-pins.py MAKE_PINS = boards/make-pins.py
BOARD_PINS = boards/$(BOARD)/pins.csv 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 CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
endif endif
include ../../py/mkrules.mk include $(TOP)/py/mkrules.mk

47
ports/nrf/boards/board.h Normal file
View 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

View File

@ -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 */ /* define output sections */
SECTIONS SECTIONS
{ {
@ -75,8 +79,8 @@ SECTIONS
.heap : .heap :
{ {
. = ALIGN(4); . = ALIGN(4);
PROVIDE ( end = . ); PROVIDE ( end = . );
PROVIDE ( _end = . ); PROVIDE ( _end = . );
_heap_start = .; /* define a global symbol at heap start */ _heap_start = .; /* define a global symbol at heap start */
. = . + _minimum_heap_size; . = . + _minimum_heap_size;
} >RAM } >RAM
@ -101,3 +105,4 @@ SECTIONS
.ARM.attributes 0 : { *(.ARM.attributes) } .ARM.attributes 0 : { *(.ARM.attributes) }
} }

View File

@ -1,6 +1,10 @@
# Setup # 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 $ cd circuitpython
@ -8,7 +12,7 @@ $ git submodule update --init
$ make -C mpy-cross $ 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. > 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 $ ./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 and flashing firmware images
## Building CircuitPython ## Building CircuitPython binaries
#### REPL over UART (default settings) #### REPL over UART (default settings)
To build a CircuitPython binary with default settings for the To build a CircuitPython binary with default settings for the
`feather52` target enter: `feather52` target enter:
> **NOTE:** `BOARD=feather52` is the default option and isn't stricly required.
``` ```
$ make BOARD=feather52 V=1 $ 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 To build a CircuitPython binary with BLE support (S132) include `SD=s132`
`bluetooth_conf.h` with the following values (under as part of the build process:
`#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:
``` ```
$ make BOARD=feather52 V=1 SD=s132 $ make BOARD=feather52 V=1 SD=s132
``` ```
## Flashing with `nrfutil` ## Flashing binaries 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.
### 1. **Update bootloader** to single-bank version ### 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 $ 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 The following command will package and flash the CircuitPython binary using the
appropriate bootloader mentionned above. 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 $ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART dfu-gen dfu-flash
``` ```
If you built your CircuitPython binary with **BLE UART** support you will If you built your CircuitPython binary with **BLE** support you will need to
need to add the `SD=s132` flag as shown below: add the `SD=s132` flag as shown below:
``` ```
$ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 dfu-gen dfu-flash $ 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)

View 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);
}

View 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.

View File

@ -5,10 +5,15 @@
------------------------------------------------------------------------ ------------------------------------------------------------------------
START ADDR END ADDR SIZE DESCRIPTION START ADDR END ADDR SIZE DESCRIPTION
---------- ---------- ------- ----------------------------------------- ---------- ---------- ------- -----------------------------------------
0x00074000..0x00080000 ( 48KB) Serial + OTA Bootloader 0x0007F000..0x0007FFFF ( 4KB) Bootloader Settings
0x0006D000..0x00073FFF ( 28KB) Private Config Data (Bonding, Keys, etc.) 0x0007E000..0x0007EFFF ( 4KB) Master Boot Record Params
0x00055000..0x0006CFFF ( 96KB) User Filesystem 0x00074000..0x0007DFFF ( 40KB) Serial + OTA Bootloader
0x0001C000..0x00054FFF (228KB) Application Code
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 0x00001000..0x0001BFFF (108KB) SoftDevice
0x00000000..0x00000FFF (4KB) Master Boot Record 0x00000000..0x00000FFF (4KB) Master Boot Record
*/ */
@ -16,15 +21,16 @@
/* Specify the memory areas (S132 2.0.1) */ /* Specify the memory areas (S132 2.0.1) */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */
FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */ FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */
FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x038000 /* APP - ISR, 224 KiB */ FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x03C000 /* APP - ISR, 240 KiB */
RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */ 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 */ /* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K; _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 */ /* top end of the stack */
@ -35,4 +41,4 @@ _estack = ORIGIN(RAM) + LENGTH(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = 0x20007000; /* tunable */ _heap_end = 0x20007000; /* tunable */
INCLUDE "boards/common.ld" INCLUDE "boards/common.ld"

View File

@ -5,10 +5,15 @@
------------------------------------------------------------------------ ------------------------------------------------------------------------
START ADDR END ADDR SIZE DESCRIPTION START ADDR END ADDR SIZE DESCRIPTION
---------- ---------- ------- ----------------------------------------- ---------- ---------- ------- -----------------------------------------
0x00074000..0x00080000 ( 48KB) Serial + OTA Bootloader 0x0007F000..0x0007FFFF ( 4KB) Bootloader Settings
0x0006D000..0x00073FFF ( 28KB) Private Config Data (Bonding, Keys, etc.) 0x0007E000..0x0007EFFF ( 4KB) Master Boot Record Params
0x00055000..0x0006CFFF ( 96KB) User Filesystem 0x00074000..0x0007DFFF ( 40KB) Serial + OTA Bootloader
0x00023000..0x00054FFF (200KB) Application Code
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 0x00001000..0x00022FFF (136KB) SoftDevice
0x00000000..0x00000FFF (4KB) Master Boot Record 0x00000000..0x00000FFF (4KB) Master Boot Record
*/ */
@ -18,13 +23,14 @@ MEMORY
{ {
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x080000 /* entire flash, 512 KiB */
FLASH_ISR (rx) : ORIGIN = 0x00023000, LENGTH = 0x001000 /* sector 0, 4 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 */ 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 */ /* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K; _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 */ /* top end of the stack */

View 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)

View 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()

View 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)

View File

@ -24,8 +24,6 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define PCA10040
#define MICROPY_HW_BOARD_NAME "Bluefruit nRF52 Feather" #define MICROPY_HW_BOARD_NAME "Bluefruit nRF52 Feather"
#define MICROPY_HW_MCU_NAME "NRF52832" #define MICROPY_HW_MCU_NAME "NRF52832"
#define MICROPY_PY_SYS_PLATFORM "nrf52" #define MICROPY_PY_SYS_PLATFORM "nrf52"
@ -33,7 +31,7 @@
#define MICROPY_PY_MACHINE_HW_PWM (1) #define MICROPY_PY_MACHINE_HW_PWM (1)
#define MICROPY_PY_MACHINE_HW_SPI (1) #define MICROPY_PY_MACHINE_HW_SPI (1)
#define MICROPY_PY_MACHINE_TIMER (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_I2C (1)
#define MICROPY_PY_MACHINE_ADC (1) #define MICROPY_PY_MACHINE_ADC (1)
#define MICROPY_PY_MACHINE_TEMP (1) #define MICROPY_PY_MACHINE_TEMP (1)
@ -59,18 +57,23 @@
#define MICROPY_HW_LED2 (19) // LED2 #define MICROPY_HW_LED2 (19) // LED2
// UART config // UART config
#define MICROPY_HW_UART1_RX (pin_A8) #define MICROPY_HW_UART1_RX (pin_PA08)
#define MICROPY_HW_UART1_TX (pin_A6) #define MICROPY_HW_UART1_TX (pin_PA06)
#define MICROPY_HW_UART1_HWFC (0) #define MICROPY_HW_UART1_HWFC (0)
// SPI0 config // SPI0 config
#define MICROPY_HW_SPI0_NAME "SPI0" #define MICROPY_HW_SPI0_NAME "SPI0"
#define MICROPY_HW_SPI0_SCK (pin_A12) // (Arduino D13) #define MICROPY_HW_SPI0_SCK (pin_PA12) // (Arduino D13)
#define MICROPY_HW_SPI0_MOSI (pin_A13) // (Arduino D11) #define MICROPY_HW_SPI0_MOSI (pin_PA13) // (Arduino D11)
#define MICROPY_HW_SPI0_MISO (pin_A14) // (Arduino D12) #define MICROPY_HW_SPI0_MISO (pin_PA14) // (Arduino D12)
#define MICROPY_HW_PWM0_NAME "PWM0" #define MICROPY_HW_PWM0_NAME "PWM0"
#define MICROPY_HW_PWM1_NAME "PWM1" #define MICROPY_HW_PWM1_NAME "PWM1"
#define MICROPY_HW_PWM2_NAME "PWM2" #define MICROPY_HW_PWM2_NAME "PWM2"
#define HELP_TEXT_BOARD_LED "1,2" #define HELP_TEXT_BOARD_LED "1,2"
#define PORT_HEAP_SIZE (32*1024)
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500

View File

@ -8,7 +8,7 @@ BOOTLOADER_PKG = boards/feather52/bootloader/feather52_bootloader_$(SOFTDEV_VERS
NRF_DEFINES += -DNRF52832_XXAA NRF_DEFINES += -DNRF52832_XXAA
CFLAGS += -DADAFRUIT_FEATHER52
check_defined = \ check_defined = \
$(strip $(foreach 1,$1, \ $(strip $(foreach 1,$1, \

View 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);

View File

@ -1,25 +1,25 @@
PA2,PA2,ADC0_IN0 A0,PA2,ADC0_IN0
PA3,PA3,ADC0_IN1 A1,PA3,ADC0_IN1
PA4,PA4,ADC0_IN2 A2,PA4,ADC0_IN2
PA5,PA5,ADC0_IN3 A3,PA5,ADC0_IN3
UART_TX,PA6 TX,PA6
PA7,PA7 PA7,PA7
UART_RX,PA8 RX,PA8
NFC1,PA9 NFC1,PA9
NFC2,PA10 NFC2,PA10
PA11,PA11 D11,PA11
SPI_SCK,PA12 SCK,PA12
SPI_MOSI,PA13 MOSI,PA13
SPI_MISO,PA14 MISO,PA14
PA15,PA15 D15,PA15
PA16,PA16 D16,PA16
LED1,PA17 LED1,PA17
LED2,PA19 LED2,PA19
PA20,PA20 DFU,PA20
I2C_SDA,PA25 SDA,PA25
I2C_SCL,PA26 SCL,PA26
PA27,PA27 D27,PA27
PA28,PA28,ADC0_IN4 A4,PA28,ADC0_IN4
PA29,PA29,ADC0_IN5 A5,PA29,ADC0_IN5
PA30,PA30,ADC0_IN6 A6,PA30,ADC0_IN6
PA31,PA31,ADC0_IN7 A7,PA31,ADC0_IN7

1 PA2,PA2,ADC0_IN0 A0,PA2,ADC0_IN0
2 PA3,PA3,ADC0_IN1 A1,PA3,ADC0_IN1
3 PA4,PA4,ADC0_IN2 A2,PA4,ADC0_IN2
4 PA5,PA5,ADC0_IN3 A3,PA5,ADC0_IN3
5 UART_TX,PA6 TX,PA6
6 PA7,PA7 PA7,PA7
7 UART_RX,PA8 RX,PA8
8 NFC1,PA9 NFC1,PA9
9 NFC2,PA10 NFC2,PA10
10 PA11,PA11 D11,PA11
11 SPI_SCK,PA12 SCK,PA12
12 SPI_MOSI,PA13 MOSI,PA13
13 SPI_MISO,PA14 MISO,PA14
14 PA15,PA15 D15,PA15
15 PA16,PA16 D16,PA16
16 LED1,PA17 LED1,PA17
17 LED2,PA19 LED2,PA19
18 PA20,PA20 DFU,PA20
19 I2C_SDA,PA25 SDA,PA25
20 I2C_SCL,PA26 SCL,PA26
21 PA27,PA27 D27,PA27
22 PA28,PA28,ADC0_IN4 A4,PA28,ADC0_IN4
23 PA29,PA29,ADC0_IN5 A5,PA29,ADC0_IN5
24 PA30,PA30,ADC0_IN6 A6,PA30,ADC0_IN6
25 PA31,PA31,ADC0_IN7 A7,PA31,ADC0_IN7

View 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[];

View File

@ -233,22 +233,22 @@ class Pins(object):
self.board_pins.append(NamedPin(row[0], pin)) self.board_pins.append(NamedPin(row[0], pin))
def print_named(self, label, named_pins): 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: for named_pin in named_pins:
pin = named_pin.pin() pin = named_pin.pin()
if pin.is_board_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(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},'.format(named_pin.name(), pin.cpu_pin_name()))
print('};') 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): def print(self):
for named_pin in self.cpu_pins: for named_pin in self.cpu_pins:
pin = named_pin.pin() pin = named_pin.pin()
if pin.is_board_pin(): if pin.is_board_pin():
pin.print() pin.print()
self.print_named('cpu', self.cpu_pins) self.print_named('mcu_pin_globals', self.cpu_pins)
print('') print('')
self.print_named('board', self.board_pins) self.print_named('board_module_globals', self.board_pins)
def print_adc(self, adc_num): def print_adc(self, adc_num):
print(''); print('');

View File

@ -35,7 +35,7 @@
#define MICROPY_PY_MACHINE_HW_SPI (1) #define MICROPY_PY_MACHINE_HW_SPI (1)
#define MICROPY_PY_MACHINE_TIMER (1) #define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_PY_MACHINE_RTC (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_ADC (1)
#define MICROPY_PY_MACHINE_TEMP (1) #define MICROPY_PY_MACHINE_TEMP (1)

View File

@ -19,7 +19,7 @@
#define PIN(p_port, p_pin, p_af, p_adc_num, p_adc_channel) \ #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, \ .name = MP_QSTR_ ## p_port ## p_pin, \
.port = PORT_ ## p_port, \ .port = PORT_ ## p_port, \
.pin = (p_pin), \ .pin = (p_pin), \

View 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;
}

View 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

View 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);
}

View 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

View File

@ -0,0 +1 @@
// No analogio module functions.

View 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.

View 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;
}

View 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

View 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;
}

View 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

View File

@ -0,0 +1 @@
// No busio module functions.

View 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;
}
}
}

View 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

View File

@ -0,0 +1 @@
// No digitalio module functions.

View 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) {
}

View 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

View 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;
}

View 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

View 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,
},
};

View 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;
}

View 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;
}

View 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

View 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

View 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

View 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

View 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

View File

@ -0,0 +1 @@
// No pulseio module functions.

View 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);
}
}

View 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);
}

View File

@ -35,6 +35,8 @@ extern uint32_t _ebss;
typedef void (*func)(void); typedef void (*func)(void);
#define _start main
extern void _start(void) __attribute__((noreturn)); extern void _start(void) __attribute__((noreturn));
extern void SystemInit(void); extern void SystemInit(void);

View File

@ -35,6 +35,8 @@ extern uint32_t _ebss;
typedef void (*func)(void); typedef void (*func)(void);
#define _start main
extern void _start(void) __attribute__((noreturn)); extern void _start(void) __attribute__((noreturn));
extern void SystemInit(void); extern void SystemInit(void);

View File

@ -52,15 +52,33 @@ function download_s132_nrf52_3_0_0
cd - 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)" SCRIPT_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
echo "No Bluetooth LE stack defined, downloading all." echo "No Bluetooth LE stack defined, downloading all."
download_s110_nrf51_8_0_0 ${SCRIPT_DIR} download_s110_nrf51_8_0_0 ${SCRIPT_DIR}
download_s132_nrf52_2_0_1 ${SCRIPT_DIR} download_s132_nrf52_2_0_1 ${SCRIPT_DIR}
download_s132_nrf52_3_0_0 ${SCRIPT_DIR} download_s132_nrf52_3_0_0 ${SCRIPT_DIR}
else download_s132_nrf52_5_0_0 ${SCRIPT_DIR}
else
case $1 in case $1 in
"s110_nrf51" ) "s110_nrf51" )
download_s110_nrf51_8_0_0 ${SCRIPT_DIR} ;; download_s110_nrf51_8_0_0 ${SCRIPT_DIR} ;;
@ -68,6 +86,8 @@ else
download_s132_nrf52_2_0_1 ${SCRIPT_DIR} ;; download_s132_nrf52_2_0_1 ${SCRIPT_DIR} ;;
"s132_nrf52_3_0_0" ) "s132_nrf52_3_0_0" )
download_s132_nrf52_3_0_0 ${SCRIPT_DIR} ;; download_s132_nrf52_3_0_0 ${SCRIPT_DIR} ;;
"s132_nrf52_5_0_0" )
download_s132_nrf52_5_0_0 ${SCRIPT_DIR} ;;
esac esac
fi fi

267
ports/nrf/fifo.c Normal file
View 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
View 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

View File

@ -45,8 +45,8 @@
#define GPIO_BASE(x) ((NRF_GPIO_Type *)POINTERS[x]) #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_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 = (p)->pin_mask) #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) #define hal_gpio_pin_read(p) (((NRF_GPIO_Type *)(GPIO_BASE((p)->port)))->IN >> ((p)->pin) & 1)
typedef enum { typedef enum {
@ -74,6 +74,28 @@ static inline void hal_gpio_cfg_pin(uint8_t port, uint32_t pin_number, hal_gpio_
| mode; | 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) { static inline void hal_gpio_out_set(uint8_t port, uint32_t pin_mask) {
GPIO_BASE(port)->OUTSET = 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); 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) { static inline void hal_gpio_pin_toggle(uint8_t port, uint32_t pin) {
uint32_t pin_mask = (1 << pin); uint32_t pin_mask = (1 << pin);
uint32_t pins_state = NRF_GPIO->OUT; uint32_t pins_state = NRF_GPIO->OUT;

View File

@ -30,9 +30,12 @@
#include "nrf.h" #include "nrf.h"
#include "mphalport.h" #include "mphalport.h"
#include "hal_uart.h" #include "hal_uart.h"
#include "fifo.h"
#ifdef HAL_UART_MODULE_ENABLED #ifdef HAL_UART_MODULE_ENABLED
FIFO_DEF(_ff_uart, 128, uint8_t, true, UARTE0_UART0_IRQn);
uint32_t hal_uart_baudrate_lookup[] = { uint32_t hal_uart_baudrate_lookup[] = {
UART_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud. UART_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud.
UART_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 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) { hal_uart_error_t hal_uart_char_read(NRF_UART_Type * p_instance, uint8_t * ch) {
p_instance->ERRORSRC = 0; // p_instance->ERRORSRC = 0;
while (p_instance->EVENTS_RXDRDY != 1) { // while (p_instance->EVENTS_RXDRDY != 1) {
// Wait for RXD data. // // Wait for RXD data.
} // }
//
// p_instance->EVENTS_RXDRDY = 0;
// *ch = p_instance->RXD;
//
// return p_instance->ERRORSRC;
p_instance->EVENTS_RXDRDY = 0; while ( !fifo_read(_ff_uart, ch) ) {
*ch = p_instance->RXD; // 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) { 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; 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) { 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->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); 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->EVENTS_RXDRDY = 0;
p_instance->TASKS_STARTTX = 1; p_instance->TASKS_STARTTX = 1;
p_instance->TASKS_STARTRX = 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 #endif // HAL_UART_MODULE_ENABLED

View File

@ -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_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); 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__ #endif // HAL_UART_H__

208
ports/nrf/internal_flash.c Normal file
View 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;
}

View 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

View File

@ -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);}

View File

@ -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, "Pin(Pin.cpu.%q, mode=Pin.", self->name);
mp_printf(print, "port=0x%x, ", self->port); mp_printf(print, "port=0x%x, ", self->port);
mp_printf(print, "pin=0x%x, ", self->pin); 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); 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_AF_OD), MP_ROM_INT(GPIO_MODE_AF_OD) },
{ MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(GPIO_NOPULL) }, { 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); STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);

View File

@ -51,17 +51,21 @@ typedef struct {
typedef struct { typedef struct {
mp_obj_base_t base; mp_obj_base_t base;
qstr name; qstr name;
uint32_t port : 4;
uint32_t pin : 5; // Some ARM processors use 32 bits/PORT uint32_t port : 1;
uint32_t num_af : 4; uint32_t pin : 5; // Some ARM processors use 32 bits/PORT
uint32_t adc_channel : 5; // Some ARM processors use 32 bits/PORT uint32_t num_af : 4;
uint32_t adc_num : 3; // 1 bit per ADC uint32_t adc_channel : 4; // 0 is no ADC, ADC channel from 1 to 8
uint32_t pin_mask;
// uint32_t pin_mask;
pin_gpio_t *gpio; pin_gpio_t *gpio;
const pin_af_obj_t *af; const pin_af_obj_t *af;
uint32_t pull; uint32_t pull;
} pin_obj_t; } 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_type;
extern const mp_obj_type_t pin_af_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_board_pins_obj_type;
extern const mp_obj_type_t pin_cpu_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_cpu_pins_locals_dict;
extern const mp_obj_dict_t pin_board_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); MP_DECLARE_CONST_FUN_OBJ_KW(pin_init_obj);

View File

@ -34,7 +34,8 @@
#if MICROPY_PY_MACHINE_HW_PWM #if MICROPY_PY_MACHINE_HW_PWM
#include "pin.h" #include "pin.h"
#include "genhdr/pins.h" //#include "genhdr/pins.h"
#include "pins.h"
#include "pwm.h" #include "pwm.h"
#if NRF52 #if NRF52

View File

@ -33,7 +33,8 @@
#include "py/mphal.h" #include "py/mphal.h"
#include "extmod/machine_spi.h" #include "extmod/machine_spi.h"
#include "pin.h" #include "pin.h"
#include "genhdr/pins.h" //#include "genhdr/pins.h"
#include "pins.h"
#include "spi.h" #include "spi.h"
#include "hal_spi.h" #include "hal_spi.h"

View File

@ -35,7 +35,8 @@
#include "py/mperrno.h" #include "py/mperrno.h"
#include "py/mphal.h" #include "py/mphal.h"
#include "pin.h" #include "pin.h"
#include "genhdr/pins.h" //#include "genhdr/pins.h"
#include "pins.h"
#include "uart.h" #include "uart.h"
#include "mpconfigboard.h" #include "mpconfigboard.h"
@ -65,6 +66,8 @@ void uart_init0(void) {
// reset the UART handles // reset the UART handles
memset(&UARTHandle0, 0, sizeof(UART_HandleTypeDef)); memset(&UARTHandle0, 0, sizeof(UART_HandleTypeDef));
UARTHandle0.p_instance = UART_BASE(0); UARTHandle0.p_instance = UART_BASE(0);
UARTHandle0.init.irq_num = UARTE0_UART0_IRQn;
#if NRF52840_XXAA #if NRF52840_XXAA
memset(&UARTHandle1, 0, sizeof(UART_HandleTypeDef)); memset(&UARTHandle1, 0, sizeof(UART_HandleTypeDef));
UARTHandle0.p_instance = UART_BASE(1); 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)); "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) { bool uart_rx_any(machine_hard_uart_obj_t *uart_obj) {
// TODO: uart will block for now. // 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) { int uart_rx_char(machine_hard_uart_obj_t * self) {

View File

@ -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,
};

View File

@ -30,12 +30,8 @@
#include <mpconfigboard.h> #include <mpconfigboard.h>
// options to control how MicroPython is built // 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_ALLOC_PATH_MAX (512)
#define MICROPY_PERSISTENT_CODE_LOAD (0) #define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_THUMB (0)
#define MICROPY_EMIT_INLINE_THUMB (0) #define MICROPY_EMIT_INLINE_THUMB (0)
#define MICROPY_COMP_MODULE_CONST (0) #define MICROPY_COMP_MODULE_CONST (0)
@ -48,6 +44,7 @@
#define MICROPY_REPL_EMACS_KEYS (0) #define MICROPY_REPL_EMACS_KEYS (0)
#define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_REPL_AUTO_INDENT (1)
#define MICROPY_ENABLE_SOURCE_LINE (0) #define MICROPY_ENABLE_SOURCE_LINE (0)
//CP UPDATE: See mpconfigport.h for LONGINT implementation
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#if NRF51 #if NRF51
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) #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_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
#define MICROPY_FATFS_USE_LABEL (1) #define MICROPY_FATFS_USE_LABEL (1)
#define MICROPY_FATFS_RPATH (2) #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 // TODO these should be generic, not bound to fatfs
#define mp_type_fileio fatfs_type_fileio #define mp_type_fileio fatfs_type_fileio
@ -82,7 +87,7 @@
#define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1)
#define MICROPY_USE_INTERNAL_ERRNO (1) #define MICROPY_USE_INTERNAL_ERRNO (1)
#define MICROPY_PY_FUNCTION_ATTRS (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_CENTER (0)
#define MICROPY_PY_BUILTINS_STR_PARTITION (0) #define MICROPY_PY_BUILTINS_STR_PARTITION (0)
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (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; typedef long mp_off_t;
// extra built in modules to add to the list of known ones // 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 pyb_module;
extern const struct _mp_obj_module_t machine_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_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 mp_module_ubluepy;
extern const struct _mp_obj_module_t music_module; extern const struct _mp_obj_module_t music_module;
extern const struct _mp_obj_module_t random_module; extern const struct _mp_obj_module_t random_module;
#if MICROPY_PY_UBLUEPY extern const struct _mp_obj_module_t ble_module;
#define UBLUEPY_MODULE { MP_ROM_QSTR(MP_QSTR_ubluepy), MP_ROM_PTR(&mp_module_ubluepy) },
#else
#define UBLUEPY_MODULE
#endif
#if MICROPY_PY_MUSIC #if MICROPY_PY_MUSIC
#define MUSIC_MODULE { MP_ROM_QSTR(MP_QSTR_music), MP_ROM_PTR(&music_module) }, #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 #define RANDOM_MODULE
#endif #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 #if MICROPY_PY_BLE
extern const struct _mp_obj_module_t ble_module; extern const struct _mp_obj_module_t ble_module;
@ -239,32 +256,28 @@ extern const struct _mp_obj_module_t ble_module;
#endif #endif
#define MICROPY_PORT_BUILTIN_MODULES \ #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)&microcontroller_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_pyb), MP_ROM_PTR(&pyb_module) }, \
{ MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&machine_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_utime), MP_ROM_PTR(&mp_module_utime) }, \
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_module_utime) }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \
{ MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
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) }, \
MUSIC_MODULE \ MUSIC_MODULE \
RANDOM_MODULE \ RANDOM_MODULE \
/*BLE_MODULE \
UBLUEPY_MODULE \*/
#endif // BLUETOOTH_SD
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ #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) }, \ { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_module_utime) }, \
// extra built in names to add to the global namespace // 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> #include <alloca.h>
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_nrf5.h" #define MICROPY_PIN_DEFS_PORT_H "pin_defs_nrf5.h"
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
#endif #endif

View 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

View File

@ -32,6 +32,8 @@
#include "py/mperrno.h" #include "py/mperrno.h"
#include "uart.h" #include "uart.h"
FIL* boot_output_file;
// this table converts from HAL_StatusTypeDef to POSIX errno // this table converts from HAL_StatusTypeDef to POSIX errno
const byte mp_hal_status_to_errno_table[4] = { const byte mp_hal_status_to_errno_table[4] = {
[HAL_OK] = 0, [HAL_OK] = 0,
@ -59,6 +61,11 @@ int mp_hal_stdin_rx_chr(void) {
return 0; 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) { void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) { if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
uart_tx_strn(MP_STATE_PORT(pyb_stdio_uart), str, len); uart_tx_strn(MP_STATE_PORT(pyb_stdio_uart), str, len);

View File

@ -32,6 +32,8 @@
#include "pin.h" #include "pin.h"
#include "hal_gpio.h" #include "hal_gpio.h"
#include "lib/oofatfs/ff.h"
typedef enum typedef enum
{ {
HAL_OK = 0x00, HAL_OK = 0x00,
@ -40,6 +42,8 @@ typedef enum
HAL_TIMEOUT = 0x03 HAL_TIMEOUT = 0x03
} HAL_StatusTypeDef; } HAL_StatusTypeDef;
extern FIL* boot_output_file;
static inline uint32_t hal_tick_fake(void) { static inline uint32_t hal_tick_fake(void) {
return 0; return 0;
} }
@ -53,6 +57,7 @@ void mp_hal_set_interrupt_char(int c); // -1 to disable
int mp_hal_stdin_rx_chr(void); int mp_hal_stdin_rx_chr(void);
void mp_hal_stdout_tx_str(const char *str); 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_pin_obj_t const pin_obj_t*
#define mp_hal_get_pin_obj(o) pin_find(o) #define mp_hal_get_pin_obj(o) pin_find(o)

View 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;
}

View 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
}

View 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);
}

View File

@ -57,4 +57,8 @@ void reset_port(void);
// Reset the rest of the board. // Reset the rest of the board.
void reset_board(void); void reset_board(void);
#ifdef NRF52_SERIES
void HardFault_Handler(void);
#endif
#endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H #endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H