Merge remote-tracking branch 'upstream/master' into stm32-meowbit
This commit is contained in:
commit
1070f2c853
1
conf.py
1
conf.py
@ -125,6 +125,7 @@ exclude_patterns = ["**/build*",
|
||||
"ports/cc3200",
|
||||
"ports/cc3200/FreeRTOS",
|
||||
"ports/cc3200/hal",
|
||||
"ports/cxd56/mkspk",
|
||||
"ports/cxd56/spresense-exported-sdk",
|
||||
"ports/esp32",
|
||||
"ports/esp8266/boards",
|
||||
|
@ -2,18 +2,38 @@
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PA02) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA05) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB08) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PB08) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB09) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB09) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PA04) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA06) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA06) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PA17) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PB23) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PB22) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB17) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB17) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB16) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB16) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA12) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA13) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA14) },
|
||||
@ -24,9 +44,12 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA21) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA22) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PB01) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_PB01) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
|
||||
|
@ -76,6 +76,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
mp_raise_ValueError(translate("Invalid pins"));
|
||||
}
|
||||
|
||||
#if CIRCUITPY_REQUIRE_I2C_PULLUPS
|
||||
// Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
|
||||
gpio_set_pin_function(sda->number, GPIO_PIN_FUNCTION_OFF);
|
||||
gpio_set_pin_function(scl->number, GPIO_PIN_FUNCTION_OFF);
|
||||
@ -98,6 +99,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
reset_pin_number(scl->number);
|
||||
mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
|
||||
}
|
||||
#endif
|
||||
|
||||
gpio_set_pin_function(sda->number, sda_pinmux);
|
||||
gpio_set_pin_function(scl->number, scl_pinmux);
|
||||
|
||||
|
@ -67,13 +67,13 @@ PLATFORM := $(firstword $(subst _, ,$(shell uname -s 2>/dev/null)))
|
||||
|
||||
ifeq ($(PLATFORM),Darwin)
|
||||
# macOS
|
||||
MKSPK = $(SPRESENSE_SDK)/sdk/tools/macos/mkspk
|
||||
MKSPK = mkspk/mkspk
|
||||
else ifeq ($(PLATFORM),Linux)
|
||||
# Linux
|
||||
MKSPK = $(SPRESENSE_SDK)/sdk/tools/linux/mkspk
|
||||
MKSPK = mkspk/mkspk
|
||||
else
|
||||
# Cygwin/MSYS2
|
||||
MKSPK = $(SPRESENSE_SDK)/sdk/tools/windows/mkspk.exe
|
||||
MKSPK = mkspk/mkspk.exe
|
||||
endif
|
||||
|
||||
SERIAL ?= /dev/ttyUSB0
|
||||
@ -131,6 +131,7 @@ LDFLAGS = \
|
||||
-o $(BUILD)/firmware.elf \
|
||||
--start-group \
|
||||
-u spresense_main \
|
||||
-u board_timerhook \
|
||||
$(BUILD)/libmpy.a \
|
||||
$(SPRESENSE_SDK)/sdk/libs/libapps.a \
|
||||
$(SPRESENSE_SDK)/sdk/libs/libsdk.a \
|
||||
@ -200,7 +201,10 @@ $(BUILD)/firmware.elf: $(BUILD)/libmpy.a
|
||||
$(ECHO) "LD $@"
|
||||
$(Q)$(LD) $(LDFLAGS)
|
||||
|
||||
$(BUILD)/firmware.spk: $(BUILD)/firmware.elf
|
||||
$(MKSPK):
|
||||
$(MAKE) -C mkspk
|
||||
|
||||
$(BUILD)/firmware.spk: $(BUILD)/firmware.elf $(MKSPK)
|
||||
$(ECHO) "Creating $@"
|
||||
$(MKSPK) -c 2 $(BUILD)/firmware.elf nuttx $(BUILD)/firmware.spk
|
||||
|
||||
|
3
ports/cxd56/mkspk/.gitignore
vendored
Normal file
3
ports/cxd56/mkspk/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/mkspk
|
||||
/mkspk.exe
|
||||
|
51
ports/cxd56/mkspk/Makefile
Normal file
51
ports/cxd56/mkspk/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
############################################################################
|
||||
# tools/mkspk/Makefile
|
||||
#
|
||||
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# 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 NuttX 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 AND CONTRIBUTORS
|
||||
# "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 OWNER OR CONTRIBUTORS 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
all: mkspk
|
||||
default: mkspk
|
||||
.PHONY: clean
|
||||
|
||||
# Add CFLAGS=-g on the make command line to build debug versions
|
||||
|
||||
CFLAGS = -O2 -Wall -I.
|
||||
|
||||
# mkspk - Convert nuttx.hex image to nuttx.spk image
|
||||
|
||||
mkspk:
|
||||
@gcc $(CFLAGS) -o mkspk mkspk.c clefia.c
|
||||
|
||||
clean:
|
||||
@rm -f *.o *.a *.dSYM *~ .*.swp
|
||||
@rm -f mkspk mkspk.exe
|
517
ports/cxd56/mkspk/clefia.c
Normal file
517
ports/cxd56/mkspk/clefia.c
Normal file
@ -0,0 +1,517 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/clefia.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* 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 NuttX 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 AND CONTRIBUTORS
|
||||
* "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 OWNER OR CONTRIBUTORS 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "clefia.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define clefiamul4(_x) (clefiamul2(clefiamul2((_x))))
|
||||
#define clefiamul6(_x) (clefiamul2((_x)) ^ clefiamul4((_x)))
|
||||
#define clefiamul8(_x) (clefiamul2(clefiamul4((_x))))
|
||||
#define clefiamula(_x) (clefiamul2((_x)) ^ clefiamul8((_x)))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* S0 (8-bit S-box based on four 4-bit S-boxes) */
|
||||
|
||||
static const unsigned char clefia_s0[256] =
|
||||
{
|
||||
0x57u, 0x49u, 0xd1u, 0xc6u, 0x2fu, 0x33u, 0x74u, 0xfbu,
|
||||
0x95u, 0x6du, 0x82u, 0xeau, 0x0eu, 0xb0u, 0xa8u, 0x1cu,
|
||||
0x28u, 0xd0u, 0x4bu, 0x92u, 0x5cu, 0xeeu, 0x85u, 0xb1u,
|
||||
0xc4u, 0x0au, 0x76u, 0x3du, 0x63u, 0xf9u, 0x17u, 0xafu,
|
||||
0xbfu, 0xa1u, 0x19u, 0x65u, 0xf7u, 0x7au, 0x32u, 0x20u,
|
||||
0x06u, 0xceu, 0xe4u, 0x83u, 0x9du, 0x5bu, 0x4cu, 0xd8u,
|
||||
0x42u, 0x5du, 0x2eu, 0xe8u, 0xd4u, 0x9bu, 0x0fu, 0x13u,
|
||||
0x3cu, 0x89u, 0x67u, 0xc0u, 0x71u, 0xaau, 0xb6u, 0xf5u,
|
||||
0xa4u, 0xbeu, 0xfdu, 0x8cu, 0x12u, 0x00u, 0x97u, 0xdau,
|
||||
0x78u, 0xe1u, 0xcfu, 0x6bu, 0x39u, 0x43u, 0x55u, 0x26u,
|
||||
0x30u, 0x98u, 0xccu, 0xddu, 0xebu, 0x54u, 0xb3u, 0x8fu,
|
||||
0x4eu, 0x16u, 0xfau, 0x22u, 0xa5u, 0x77u, 0x09u, 0x61u,
|
||||
0xd6u, 0x2au, 0x53u, 0x37u, 0x45u, 0xc1u, 0x6cu, 0xaeu,
|
||||
0xefu, 0x70u, 0x08u, 0x99u, 0x8bu, 0x1du, 0xf2u, 0xb4u,
|
||||
0xe9u, 0xc7u, 0x9fu, 0x4au, 0x31u, 0x25u, 0xfeu, 0x7cu,
|
||||
0xd3u, 0xa2u, 0xbdu, 0x56u, 0x14u, 0x88u, 0x60u, 0x0bu,
|
||||
0xcdu, 0xe2u, 0x34u, 0x50u, 0x9eu, 0xdcu, 0x11u, 0x05u,
|
||||
0x2bu, 0xb7u, 0xa9u, 0x48u, 0xffu, 0x66u, 0x8au, 0x73u,
|
||||
0x03u, 0x75u, 0x86u, 0xf1u, 0x6au, 0xa7u, 0x40u, 0xc2u,
|
||||
0xb9u, 0x2cu, 0xdbu, 0x1fu, 0x58u, 0x94u, 0x3eu, 0xedu,
|
||||
0xfcu, 0x1bu, 0xa0u, 0x04u, 0xb8u, 0x8du, 0xe6u, 0x59u,
|
||||
0x62u, 0x93u, 0x35u, 0x7eu, 0xcau, 0x21u, 0xdfu, 0x47u,
|
||||
0x15u, 0xf3u, 0xbau, 0x7fu, 0xa6u, 0x69u, 0xc8u, 0x4du,
|
||||
0x87u, 0x3bu, 0x9cu, 0x01u, 0xe0u, 0xdeu, 0x24u, 0x52u,
|
||||
0x7bu, 0x0cu, 0x68u, 0x1eu, 0x80u, 0xb2u, 0x5au, 0xe7u,
|
||||
0xadu, 0xd5u, 0x23u, 0xf4u, 0x46u, 0x3fu, 0x91u, 0xc9u,
|
||||
0x6eu, 0x84u, 0x72u, 0xbbu, 0x0du, 0x18u, 0xd9u, 0x96u,
|
||||
0xf0u, 0x5fu, 0x41u, 0xacu, 0x27u, 0xc5u, 0xe3u, 0x3au,
|
||||
0x81u, 0x6fu, 0x07u, 0xa3u, 0x79u, 0xf6u, 0x2du, 0x38u,
|
||||
0x1au, 0x44u, 0x5eu, 0xb5u, 0xd2u, 0xecu, 0xcbu, 0x90u,
|
||||
0x9au, 0x36u, 0xe5u, 0x29u, 0xc3u, 0x4fu, 0xabu, 0x64u,
|
||||
0x51u, 0xf8u, 0x10u, 0xd7u, 0xbcu, 0x02u, 0x7du, 0x8eu
|
||||
};
|
||||
|
||||
/* S1 (8-bit S-box based on inverse function) */
|
||||
|
||||
static const unsigned char clefia_s1[256] =
|
||||
{
|
||||
0x6cu, 0xdau, 0xc3u, 0xe9u, 0x4eu, 0x9du, 0x0au, 0x3du,
|
||||
0xb8u, 0x36u, 0xb4u, 0x38u, 0x13u, 0x34u, 0x0cu, 0xd9u,
|
||||
0xbfu, 0x74u, 0x94u, 0x8fu, 0xb7u, 0x9cu, 0xe5u, 0xdcu,
|
||||
0x9eu, 0x07u, 0x49u, 0x4fu, 0x98u, 0x2cu, 0xb0u, 0x93u,
|
||||
0x12u, 0xebu, 0xcdu, 0xb3u, 0x92u, 0xe7u, 0x41u, 0x60u,
|
||||
0xe3u, 0x21u, 0x27u, 0x3bu, 0xe6u, 0x19u, 0xd2u, 0x0eu,
|
||||
0x91u, 0x11u, 0xc7u, 0x3fu, 0x2au, 0x8eu, 0xa1u, 0xbcu,
|
||||
0x2bu, 0xc8u, 0xc5u, 0x0fu, 0x5bu, 0xf3u, 0x87u, 0x8bu,
|
||||
0xfbu, 0xf5u, 0xdeu, 0x20u, 0xc6u, 0xa7u, 0x84u, 0xceu,
|
||||
0xd8u, 0x65u, 0x51u, 0xc9u, 0xa4u, 0xefu, 0x43u, 0x53u,
|
||||
0x25u, 0x5du, 0x9bu, 0x31u, 0xe8u, 0x3eu, 0x0du, 0xd7u,
|
||||
0x80u, 0xffu, 0x69u, 0x8au, 0xbau, 0x0bu, 0x73u, 0x5cu,
|
||||
0x6eu, 0x54u, 0x15u, 0x62u, 0xf6u, 0x35u, 0x30u, 0x52u,
|
||||
0xa3u, 0x16u, 0xd3u, 0x28u, 0x32u, 0xfau, 0xaau, 0x5eu,
|
||||
0xcfu, 0xeau, 0xedu, 0x78u, 0x33u, 0x58u, 0x09u, 0x7bu,
|
||||
0x63u, 0xc0u, 0xc1u, 0x46u, 0x1eu, 0xdfu, 0xa9u, 0x99u,
|
||||
0x55u, 0x04u, 0xc4u, 0x86u, 0x39u, 0x77u, 0x82u, 0xecu,
|
||||
0x40u, 0x18u, 0x90u, 0x97u, 0x59u, 0xddu, 0x83u, 0x1fu,
|
||||
0x9au, 0x37u, 0x06u, 0x24u, 0x64u, 0x7cu, 0xa5u, 0x56u,
|
||||
0x48u, 0x08u, 0x85u, 0xd0u, 0x61u, 0x26u, 0xcau, 0x6fu,
|
||||
0x7eu, 0x6au, 0xb6u, 0x71u, 0xa0u, 0x70u, 0x05u, 0xd1u,
|
||||
0x45u, 0x8cu, 0x23u, 0x1cu, 0xf0u, 0xeeu, 0x89u, 0xadu,
|
||||
0x7au, 0x4bu, 0xc2u, 0x2fu, 0xdbu, 0x5au, 0x4du, 0x76u,
|
||||
0x67u, 0x17u, 0x2du, 0xf4u, 0xcbu, 0xb1u, 0x4au, 0xa8u,
|
||||
0xb5u, 0x22u, 0x47u, 0x3au, 0xd5u, 0x10u, 0x4cu, 0x72u,
|
||||
0xccu, 0x00u, 0xf9u, 0xe0u, 0xfdu, 0xe2u, 0xfeu, 0xaeu,
|
||||
0xf8u, 0x5fu, 0xabu, 0xf1u, 0x1bu, 0x42u, 0x81u, 0xd6u,
|
||||
0xbeu, 0x44u, 0x29u, 0xa6u, 0x57u, 0xb9u, 0xafu, 0xf2u,
|
||||
0xd4u, 0x75u, 0x66u, 0xbbu, 0x68u, 0x9fu, 0x50u, 0x02u,
|
||||
0x01u, 0x3cu, 0x7fu, 0x8du, 0x1au, 0x88u, 0xbdu, 0xacu,
|
||||
0xf7u, 0xe4u, 0x79u, 0x96u, 0xa2u, 0xfcu, 0x6du, 0xb2u,
|
||||
0x6bu, 0x03u, 0xe1u, 0x2eu, 0x7du, 0x14u, 0x95u, 0x1du
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void bytecpy(unsigned char *dst, const unsigned char *src, int bytelen)
|
||||
{
|
||||
while (bytelen-- > 0)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char clefiamul2(unsigned char x)
|
||||
{
|
||||
/* multiplication over GF(2^8) (p(x) = '11d') */
|
||||
|
||||
if (x & 0x80u)
|
||||
{
|
||||
x ^= 0x0eu;
|
||||
}
|
||||
|
||||
return ((x << 1) | (x >> 7));
|
||||
}
|
||||
|
||||
static void clefiaf0xor(unsigned char *dst, const unsigned char *src,
|
||||
const unsigned char *rk)
|
||||
{
|
||||
unsigned char x[4];
|
||||
unsigned char y[4];
|
||||
unsigned char z[4];
|
||||
|
||||
/* F0 */
|
||||
|
||||
/* Key addition */
|
||||
|
||||
bytexor(x, src, rk, 4);
|
||||
|
||||
/* Substitution layer */
|
||||
|
||||
z[0] = clefia_s0[x[0]];
|
||||
z[1] = clefia_s1[x[1]];
|
||||
z[2] = clefia_s0[x[2]];
|
||||
z[3] = clefia_s1[x[3]];
|
||||
|
||||
/* Diffusion layer (M0) */
|
||||
|
||||
y[0] = z[0] ^ clefiamul2(z[1]) ^ clefiamul4(z[2]) ^ clefiamul6(z[3]);
|
||||
y[1] = clefiamul2(z[0]) ^ z[1] ^ clefiamul6(z[2]) ^ clefiamul4(z[3]);
|
||||
y[2] = clefiamul4(z[0]) ^ clefiamul6(z[1]) ^ z[2] ^ clefiamul2(z[3]);
|
||||
y[3] = clefiamul6(z[0]) ^ clefiamul4(z[1]) ^ clefiamul2(z[2]) ^ z[3];
|
||||
|
||||
/* Xoring after F0 */
|
||||
|
||||
bytecpy(dst + 0, src + 0, 4);
|
||||
bytexor(dst + 4, src + 4, y, 4);
|
||||
}
|
||||
|
||||
static void clefiaf1xor(unsigned char *dst, const unsigned char *src,
|
||||
const unsigned char *rk)
|
||||
{
|
||||
unsigned char x[4];
|
||||
unsigned char y[4];
|
||||
unsigned char z[4];
|
||||
|
||||
/* F1 */
|
||||
|
||||
/* Key addition */
|
||||
|
||||
bytexor(x, src, rk, 4);
|
||||
|
||||
/* Substitution layer */
|
||||
|
||||
z[0] = clefia_s1[x[0]];
|
||||
z[1] = clefia_s0[x[1]];
|
||||
z[2] = clefia_s1[x[2]];
|
||||
z[3] = clefia_s0[x[3]];
|
||||
|
||||
/* Diffusion layer (M1) */
|
||||
|
||||
y[0] = z[0] ^ clefiamul8(z[1]) ^ clefiamul2(z[2]) ^ clefiamula(z[3]);
|
||||
y[1] = clefiamul8(z[0]) ^ z[1] ^ clefiamula(z[2]) ^ clefiamul2(z[3]);
|
||||
y[2] = clefiamul2(z[0]) ^ clefiamula(z[1]) ^ z[2] ^ clefiamul8(z[3]);
|
||||
y[3] = clefiamula(z[0]) ^ clefiamul2(z[1]) ^ clefiamul8(z[2]) ^ z[3];
|
||||
|
||||
/* Xoring after F1 */
|
||||
|
||||
bytecpy(dst + 0, src + 0, 4);
|
||||
bytexor(dst + 4, src + 4, y, 4);
|
||||
}
|
||||
|
||||
static void clefiagfn4(unsigned char *y, const unsigned char *x,
|
||||
const unsigned char *rk, int r)
|
||||
{
|
||||
unsigned char fin[16];
|
||||
unsigned char fout[16];
|
||||
|
||||
bytecpy(fin, x, 16);
|
||||
while (r-- > 0)
|
||||
{
|
||||
clefiaf0xor(fout + 0, fin + 0, rk + 0);
|
||||
clefiaf1xor(fout + 8, fin + 8, rk + 4);
|
||||
rk += 8;
|
||||
if (r)
|
||||
{
|
||||
/* swapping for encryption */
|
||||
|
||||
bytecpy(fin + 0, fout + 4, 12);
|
||||
bytecpy(fin + 12, fout + 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bytecpy(y, fout, 16);
|
||||
}
|
||||
|
||||
#if 0 /* Not used */
|
||||
static void clefiagfn8(unsigned char *y, const unsigned char *x,
|
||||
const unsigned char *rk, int r)
|
||||
{
|
||||
unsigned char fin[32];
|
||||
unsigned char fout[32];
|
||||
|
||||
bytecpy(fin, x, 32);
|
||||
while (r-- > 0)
|
||||
{
|
||||
clefiaf0xor(fout + 0, fin + 0, rk + 0);
|
||||
clefiaf1xor(fout + 8, fin + 8, rk + 4);
|
||||
clefiaf0xor(fout + 16, fin + 16, rk + 8);
|
||||
clefiaf1xor(fout + 24, fin + 24, rk + 12);
|
||||
rk += 16;
|
||||
if (r)
|
||||
{
|
||||
/* swapping for encryption */
|
||||
|
||||
bytecpy(fin + 0, fout + 4, 28);
|
||||
bytecpy(fin + 28, fout + 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bytecpy(y, fout, 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* Not used */
|
||||
static void clefiagfn4inv(unsigned char *y, const unsigned char *x,
|
||||
const unsigned char *rk, int r)
|
||||
{
|
||||
unsigned char fin[16];
|
||||
unsigned char fout[16];
|
||||
|
||||
rk += (r - 1) * 8;
|
||||
bytecpy(fin, x, 16);
|
||||
while (r-- > 0)
|
||||
{
|
||||
clefiaf0xor(fout + 0, fin + 0, rk + 0);
|
||||
clefiaf1xor(fout + 8, fin + 8, rk + 4);
|
||||
rk -= 8;
|
||||
if (r)
|
||||
{
|
||||
/* swapping for decryption */
|
||||
|
||||
bytecpy(fin + 0, fout + 12, 4);
|
||||
bytecpy(fin + 4, fout + 0, 12);
|
||||
}
|
||||
}
|
||||
|
||||
bytecpy(y, fout, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void clefiadoubleswap(unsigned char *lk)
|
||||
{
|
||||
unsigned char t[16];
|
||||
|
||||
t[0] = (lk[0] << 7) | (lk[1] >> 1);
|
||||
t[1] = (lk[1] << 7) | (lk[2] >> 1);
|
||||
t[2] = (lk[2] << 7) | (lk[3] >> 1);
|
||||
t[3] = (lk[3] << 7) | (lk[4] >> 1);
|
||||
t[4] = (lk[4] << 7) | (lk[5] >> 1);
|
||||
t[5] = (lk[5] << 7) | (lk[6] >> 1);
|
||||
t[6] = (lk[6] << 7) | (lk[7] >> 1);
|
||||
t[7] = (lk[7] << 7) | (lk[15] & 0x7fu);
|
||||
|
||||
t[8] = (lk[8] >> 7) | (lk[0] & 0xfeu);
|
||||
t[9] = (lk[9] >> 7) | (lk[8] << 1);
|
||||
t[10] = (lk[10] >> 7) | (lk[9] << 1);
|
||||
t[11] = (lk[11] >> 7) | (lk[10] << 1);
|
||||
t[12] = (lk[12] >> 7) | (lk[11] << 1);
|
||||
t[13] = (lk[13] >> 7) | (lk[12] << 1);
|
||||
t[14] = (lk[14] >> 7) | (lk[13] << 1);
|
||||
t[15] = (lk[15] >> 7) | (lk[14] << 1);
|
||||
|
||||
bytecpy(lk, t, 16);
|
||||
}
|
||||
|
||||
static void clefiaconset(unsigned char *con, const unsigned char *iv, int lk)
|
||||
{
|
||||
unsigned char t[2];
|
||||
unsigned char tmp;
|
||||
|
||||
bytecpy(t, iv, 2);
|
||||
while (lk-- > 0)
|
||||
{
|
||||
con[0] = t[0] ^ 0xb7u; /* P_16 = 0xb7e1 (natural logarithm) */
|
||||
con[1] = t[1] ^ 0xe1u;
|
||||
con[2] = ~((t[0] << 1) | (t[1] >> 7));
|
||||
con[3] = ~((t[1] << 1) | (t[0] >> 7));
|
||||
con[4] = ~t[0] ^ 0x24u; /* Q_16 = 0x243f (circle ratio) */
|
||||
con[5] = ~t[1] ^ 0x3fu;
|
||||
con[6] = t[1];
|
||||
con[7] = t[0];
|
||||
con += 8;
|
||||
|
||||
/* updating T */
|
||||
|
||||
if (t[1] & 0x01u)
|
||||
{
|
||||
t[0] ^= 0xa8u;
|
||||
t[1] ^= 0x30u;
|
||||
}
|
||||
|
||||
tmp = t[0] << 7;
|
||||
t[0] = (t[0] >> 1) | (t[1] << 7);
|
||||
t[1] = (t[1] >> 1) | tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void left_shift_one(uint8_t * in, uint8_t * out)
|
||||
{
|
||||
int i;
|
||||
int overflow;
|
||||
|
||||
overflow = 0;
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
out[i] = in[i] << 1;
|
||||
out[i] |= overflow;
|
||||
overflow = (in[i] >> 7) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_subkey(struct cipher *c)
|
||||
{
|
||||
uint8_t L[16];
|
||||
|
||||
memset(L, 0, 16);
|
||||
clefiaencrypt(L, L, c->rk, c->round);
|
||||
|
||||
left_shift_one(L, c->k1);
|
||||
if (L[0] & 0x80)
|
||||
{
|
||||
c->k1[15] = c->k1[15] ^ 0x87;
|
||||
}
|
||||
|
||||
left_shift_one(c->k1, c->k2);
|
||||
if (c->k1[0] & 0x80)
|
||||
{
|
||||
c->k2[15] = c->k2[15] ^ 0x87;
|
||||
}
|
||||
|
||||
memset(L, 0, 16);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
struct cipher *cipher_init(uint8_t * key, uint8_t * iv)
|
||||
{
|
||||
struct cipher *c;
|
||||
|
||||
c = (struct cipher *)malloc(sizeof(*c));
|
||||
if (!c)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c->round = clefiakeyset(c->rk, key);
|
||||
|
||||
gen_subkey(c);
|
||||
memset(c->vector, 0, 16);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void cipher_deinit(struct cipher *c)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
free(c);
|
||||
}
|
||||
|
||||
int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac)
|
||||
{
|
||||
uint8_t m[16];
|
||||
uint8_t *p;
|
||||
|
||||
if (size & 0xf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = (uint8_t *) data;
|
||||
while (size)
|
||||
{
|
||||
bytexor(m, c->vector, p, 16);
|
||||
clefiaencrypt(c->vector, m, c->rk, c->round);
|
||||
size -= 16;
|
||||
p += 16;
|
||||
}
|
||||
|
||||
bytexor(cmac, m, c->k1, 16);
|
||||
clefiaencrypt(cmac, cmac, c->rk, c->round);
|
||||
memset(m, 0, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bytexor(unsigned char *dst, const unsigned char *a,
|
||||
const unsigned char *b, int bytelen)
|
||||
{
|
||||
while (bytelen-- > 0)
|
||||
{
|
||||
*dst++ = *a++ ^ *b++;
|
||||
}
|
||||
}
|
||||
|
||||
int clefiakeyset(unsigned char *rk, const unsigned char *skey)
|
||||
{
|
||||
const unsigned char iv[2] =
|
||||
{
|
||||
0x42u, 0x8au /* cubic root of 2 */
|
||||
};
|
||||
|
||||
unsigned char lk[16];
|
||||
unsigned char con128[4 * 60];
|
||||
int i;
|
||||
|
||||
/* generating CONi^(128) (0 <= i < 60, lk = 30) */
|
||||
|
||||
clefiaconset(con128, iv, 30);
|
||||
|
||||
/* GFN_{4,12} (generating L from K) */
|
||||
|
||||
clefiagfn4(lk, skey, con128, 12);
|
||||
|
||||
bytecpy(rk, skey, 8); /* initial whitening key (WK0, WK1) */
|
||||
rk += 8;
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
/* round key (RKi (0 <= i < 36)) */
|
||||
|
||||
bytexor(rk, lk, con128 + i * 16 + (4 * 24), 16);
|
||||
if (i % 2)
|
||||
{
|
||||
bytexor(rk, rk, skey, 16); /* Xoring K */
|
||||
}
|
||||
|
||||
clefiadoubleswap(lk); /* Updating L (DoubleSwap function) */
|
||||
rk += 16;
|
||||
}
|
||||
|
||||
bytecpy(rk, skey + 8, 8); /* final whitening key (WK2, WK3) */
|
||||
|
||||
return 18;
|
||||
}
|
||||
|
||||
void clefiaencrypt(unsigned char *ct, const unsigned char *pt,
|
||||
const unsigned char *rk, const int r)
|
||||
{
|
||||
unsigned char rin[16];
|
||||
unsigned char rout[16];
|
||||
|
||||
bytecpy(rin, pt, 16);
|
||||
|
||||
bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */
|
||||
bytexor(rin + 12, rin + 12, rk + 4, 4);
|
||||
rk += 8;
|
||||
|
||||
clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */
|
||||
|
||||
bytecpy(ct, rout, 16);
|
||||
bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */
|
||||
bytexor(ct + 12, ct + 12, rk + r * 8 + 4, 4);
|
||||
}
|
65
ports/cxd56/mkspk/clefia.h
Normal file
65
ports/cxd56/mkspk/clefia.h
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/clefia.h
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* 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 NuttX 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 AND CONTRIBUTORS
|
||||
* "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 OWNER OR CONTRIBUTORS 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 _TOOLS_CXD56_CLEFIA_H_
|
||||
#define _TOOLS_CXD56_CLEFIA_H_
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct cipher
|
||||
{
|
||||
int mode;
|
||||
int dir;
|
||||
uint8_t rk[8 * 26 + 16];
|
||||
uint8_t vector[16];
|
||||
int round;
|
||||
uint8_t k1[16];
|
||||
uint8_t k2[16];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct cipher *cipher_init(uint8_t * key, uint8_t * iv);
|
||||
void cipher_deinit(struct cipher *c);
|
||||
int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac);
|
||||
void bytexor(unsigned char *dst, const unsigned char *a,
|
||||
const unsigned char *b, int bytelen);
|
||||
int clefiakeyset(unsigned char *rk, const unsigned char *skey);
|
||||
void clefiaencrypt(unsigned char *ct, const unsigned char *pt,
|
||||
const unsigned char *rk, const int r);
|
||||
|
||||
#endif
|
383
ports/cxd56/mkspk/mkspk.c
Normal file
383
ports/cxd56/mkspk/mkspk.c
Normal file
@ -0,0 +1,383 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/mkspk.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* 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 NuttX 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 AND CONTRIBUTORS
|
||||
* "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 OWNER OR CONTRIBUTORS 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mkspk.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct args
|
||||
{
|
||||
int core;
|
||||
char *elffile;
|
||||
char *savename;
|
||||
char *outputfile;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t vmk[16] =
|
||||
"\x27\xc0\xaf\x1b\x5d\xcb\xc6\xc5\x58\x22\x1c\xdd\xaf\xf3\x20\x21";
|
||||
|
||||
static struct args g_options =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static struct args *parse_args(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int show_help;
|
||||
struct args *args = &g_options;
|
||||
char *endp;
|
||||
|
||||
show_help = 0;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
show_help = 1;
|
||||
}
|
||||
|
||||
memset(args, 0, sizeof(*args));
|
||||
args->core = -1;
|
||||
|
||||
while ((opt = getopt(argc, argv, "h:c:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
args->core = strtol(optarg, &endp, 0);
|
||||
if (*endp)
|
||||
{
|
||||
fprintf(stderr, "Invalid core number \"%s\"\n", optarg);
|
||||
show_help = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
show_help = 1;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
args->elffile = argv[0];
|
||||
args->savename = argv[1];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
args->outputfile = strdup(argv[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
show_help = 1;
|
||||
}
|
||||
|
||||
/* Sanity checks for options */
|
||||
|
||||
if (show_help == 1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"mkspk [-c <number>] <filename> <save name> [<output file>]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (args->core < 0)
|
||||
{
|
||||
fprintf(stderr, "Core number is not set. Please use -c option.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strlen(args->savename) > 63)
|
||||
{
|
||||
fprintf(stderr, "savename too long.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
static struct elf_file *load_elf(const char *filename)
|
||||
{
|
||||
size_t fsize;
|
||||
int pos;
|
||||
char *buf;
|
||||
FILE *fp;
|
||||
struct elf_file *ef;
|
||||
Elf32_Shdr *sh;
|
||||
uint16_t i;
|
||||
int ret;
|
||||
|
||||
fp = fopen(filename, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef = (struct elf_file *)malloc(sizeof(*ef));
|
||||
if (!ef)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pos = fseek(fp, 0, SEEK_END);
|
||||
fsize = (size_t) ftell(fp);
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
|
||||
buf = (char *)malloc(fsize);
|
||||
if (!buf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = fread(buf, fsize, 1, fp);
|
||||
fclose(fp);
|
||||
if (ret != 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef->data = buf;
|
||||
|
||||
ef->ehdr = (Elf32_Ehdr *) buf;
|
||||
|
||||
Elf32_Ehdr *h = (Elf32_Ehdr *) buf;
|
||||
|
||||
if (!(h->e_ident[EI_MAG0] == 0x7f &&
|
||||
h->e_ident[EI_MAG1] == 'E' &&
|
||||
h->e_ident[EI_MAG2] == 'L' && h->e_ident[EI_MAG3] == 'F'))
|
||||
{
|
||||
free(ef);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef->phdr = (Elf32_Phdr *) (buf + ef->ehdr->e_phoff);
|
||||
ef->shdr = (Elf32_Shdr *) (buf + ef->ehdr->e_shoff);
|
||||
ef->shstring = buf + ef->shdr[ef->ehdr->e_shstrndx].sh_offset;
|
||||
|
||||
for (i = 0, sh = ef->shdr; i < ef->ehdr->e_shnum; i++, sh++)
|
||||
{
|
||||
if (sh->sh_type == SHT_SYMTAB)
|
||||
{
|
||||
ef->symtab = (Elf32_Sym *) (buf + sh->sh_offset);
|
||||
ef->nsyms = sh->sh_size / sh->sh_entsize;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sh->sh_type == SHT_STRTAB)
|
||||
{
|
||||
if (!strcmp(".strtab", ef->shstring + sh->sh_name))
|
||||
{
|
||||
ef->string = buf + sh->sh_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ef;
|
||||
}
|
||||
|
||||
static void *create_image(struct elf_file *elf, int core, char *savename,
|
||||
int *image_size)
|
||||
{
|
||||
char *img;
|
||||
struct spk_header *header;
|
||||
struct spk_prog_info *pi;
|
||||
Elf32_Phdr *ph;
|
||||
Elf32_Sym *sym;
|
||||
char *name;
|
||||
int snlen;
|
||||
int nphs, psize, imgsize;
|
||||
int i;
|
||||
int j;
|
||||
uint32_t offset;
|
||||
uint32_t sp;
|
||||
|
||||
snlen = alignup(strlen(savename) + 1, 16);
|
||||
|
||||
nphs = 0;
|
||||
psize = 0;
|
||||
for (i = 0, ph = elf->phdr; i < elf->ehdr->e_phnum; i++, ph++)
|
||||
{
|
||||
if (ph->p_type != PT_LOAD || ph->p_filesz == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
nphs++;
|
||||
psize += alignup(ph->p_filesz, 16);
|
||||
}
|
||||
|
||||
imgsize = sizeof(*header) + snlen + (nphs * 16) + psize;
|
||||
|
||||
img = (char *)malloc(imgsize + 32);
|
||||
if (!img)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*image_size = imgsize;
|
||||
sym = elf->symtab;
|
||||
name = elf->string;
|
||||
sp = 0;
|
||||
|
||||
for (j = 0; j < elf->nsyms; j++, sym++)
|
||||
{
|
||||
if (!strcmp("__stack", name + sym->st_name))
|
||||
{
|
||||
sp = sym->st_value;
|
||||
}
|
||||
}
|
||||
|
||||
memset(img, 0, imgsize);
|
||||
|
||||
header = (struct spk_header *)img;
|
||||
header->magic[0] = 0xef;
|
||||
header->magic[1] = 'M';
|
||||
header->magic[2] = 'O';
|
||||
header->magic[3] = 'D';
|
||||
header->cpu = core;
|
||||
|
||||
header->entry = elf->ehdr->e_entry;
|
||||
header->stack = sp;
|
||||
header->core = core;
|
||||
|
||||
header->binaries = nphs;
|
||||
header->phoffs = sizeof(*header) + snlen;
|
||||
header->mode = 0777;
|
||||
|
||||
strncpy(img + sizeof(*header), savename, 63);
|
||||
|
||||
ph = elf->phdr;
|
||||
pi = (struct spk_prog_info *)(img + header->phoffs);
|
||||
offset = ((char *)pi - img) + (nphs * sizeof(*pi));
|
||||
for (i = 0; i < elf->ehdr->e_phnum; i++, ph++)
|
||||
{
|
||||
if (ph->p_type != PT_LOAD || ph->p_filesz == 0)
|
||||
continue;
|
||||
pi->load_address = ph->p_paddr;
|
||||
pi->offset = offset;
|
||||
pi->size = alignup(ph->p_filesz, 16); /* need 16 bytes align for
|
||||
* decryption */
|
||||
pi->memsize = ph->p_memsz;
|
||||
|
||||
memcpy(img + pi->offset, elf->data + ph->p_offset, ph->p_filesz);
|
||||
|
||||
offset += alignup(ph->p_filesz, 16);
|
||||
pi++;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct args *args;
|
||||
struct elf_file *elf;
|
||||
struct cipher *c;
|
||||
uint8_t *spkimage;
|
||||
int size = 0;
|
||||
FILE *fp;
|
||||
char footer[16];
|
||||
|
||||
args = parse_args(argc, argv);
|
||||
|
||||
elf = load_elf(args->elffile);
|
||||
if (!elf)
|
||||
{
|
||||
fprintf(stderr, "Loading ELF %s failure.\n", args->elffile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
spkimage = create_image(elf, args->core, args->savename, &size);
|
||||
free(elf);
|
||||
|
||||
c = cipher_init(vmk, NULL);
|
||||
cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size);
|
||||
cipher_deinit(c);
|
||||
|
||||
size += 16; /* Extend CMAC size */
|
||||
|
||||
snprintf(footer, 16, "MKSPK_BN_HOOTER");
|
||||
footer[15] = '\0';
|
||||
|
||||
fp = fopen(args->outputfile, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Output file open error.\n");
|
||||
free(spkimage);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fwrite(spkimage, size, 1, fp);
|
||||
fwrite(footer, 16, 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
printf("File %s is successfully created.\n", args->outputfile);
|
||||
free(args->outputfile);
|
||||
|
||||
memset(spkimage, 0, size);
|
||||
free(spkimage);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
83
ports/cxd56/mkspk/mkspk.h
Normal file
83
ports/cxd56/mkspk/mkspk.h
Normal file
@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/mkspk.h
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* 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 NuttX 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 AND CONTRIBUTORS
|
||||
* "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 OWNER OR CONTRIBUTORS 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "clefia.h"
|
||||
#include "elf.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define alignup(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
#define swap(a, b) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct spk_header
|
||||
{
|
||||
uint8_t magic[4];
|
||||
uint8_t cpu;
|
||||
uint8_t reserved[11];
|
||||
uint32_t entry;
|
||||
uint32_t stack;
|
||||
uint16_t core;
|
||||
uint16_t binaries;
|
||||
uint16_t phoffs;
|
||||
uint16_t mode;
|
||||
};
|
||||
|
||||
struct spk_prog_info
|
||||
{
|
||||
uint32_t load_address;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t memsize;
|
||||
};
|
||||
|
||||
struct elf_file
|
||||
{
|
||||
Elf32_Ehdr *ehdr;
|
||||
Elf32_Phdr *phdr;
|
||||
Elf32_Shdr *shdr;
|
||||
Elf32_Sym *symtab;
|
||||
int nsyms;
|
||||
char *shstring;
|
||||
char *string;
|
||||
char *data;
|
||||
};
|
@ -98,11 +98,13 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
|
||||
LPI2C_MasterInit(self->i2c, &config, I2C_CLOCK_FREQ);
|
||||
|
||||
#if CIRCUITPY_REQUIRE_I2C_PULLUPS
|
||||
// if (!gpio_get_pin_level(sda->number) || !gpio_get_pin_level(scl->number)) {
|
||||
// reset_pin_number(sda->number);
|
||||
// reset_pin_number(scl->number);
|
||||
// mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
|
||||
// }
|
||||
#endif
|
||||
|
||||
claim_pin(self->sda_pin->pin);
|
||||
claim_pin(self->scl_pin->pin);
|
||||
|
@ -115,6 +115,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
|
||||
mp_raise_ValueError(translate("All I2C peripherals are in use"));
|
||||
}
|
||||
|
||||
#if CIRCUITPY_REQUIRE_I2C_PULLUPS
|
||||
// Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
|
||||
nrf_gpio_cfg_input(scl->number, NRF_GPIO_PIN_PULLDOWN);
|
||||
nrf_gpio_cfg_input(sda->number, NRF_GPIO_PIN_PULLDOWN);
|
||||
@ -132,6 +133,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
|
||||
reset_pin_number(scl->number);
|
||||
mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
|
||||
}
|
||||
#endif
|
||||
|
||||
nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG(scl->number, sda->number);
|
||||
|
||||
|
@ -66,8 +66,24 @@ 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);
|
||||
if (sd_en) {
|
||||
while (length != 0) {
|
||||
uint8_t available = 0;
|
||||
sd_rand_application_bytes_available_get(&available);
|
||||
if (available) {
|
||||
uint32_t request = MIN(length, available);
|
||||
uint32_t result = sd_rand_application_vector_get(buffer, request);
|
||||
if (result != NRF_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
buffer += request;
|
||||
length -= request;
|
||||
} else {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
nrf_rng_event_clear(NRF_RNG, NRF_RNG_EVENT_VALRDY);
|
||||
|
@ -35,51 +35,46 @@
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
STATIC bool reserved_i2c[3];
|
||||
STATIC bool never_reset[3];
|
||||
//arrays use 0 based numbering: I2C1 is stored at index 0
|
||||
#define MAX_I2C 3
|
||||
STATIC bool reserved_i2c[MAX_I2C];
|
||||
STATIC bool never_reset_i2c[MAX_I2C];
|
||||
|
||||
#define ALL_CLOCKS 0xFF
|
||||
STATIC void i2c_clock_enable(uint8_t mask);
|
||||
STATIC void i2c_clock_disable(uint8_t mask);
|
||||
|
||||
void i2c_reset(void) {
|
||||
//Note: I2Cs are also forcibly reset in construct, due to silicon error
|
||||
#ifdef I2C1
|
||||
reserved_i2c[0] = false;
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
#endif
|
||||
#ifdef I2C2
|
||||
reserved_i2c[1] = false;
|
||||
__HAL_RCC_I2C2_CLK_DISABLE();
|
||||
#endif
|
||||
#ifdef I2C3
|
||||
reserved_i2c[2] = false;
|
||||
__HAL_RCC_I2C3_CLK_DISABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
for (size_t i = 0 ; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) {
|
||||
if (self->handle.Instance == mcu_i2c_banks[i]) {
|
||||
never_reset[i] = true;
|
||||
|
||||
never_reset_pin_number(self->scl->pin->port, self->scl->pin->number);
|
||||
never_reset_pin_number(self->sda->pin->port, self->scl->pin->number);
|
||||
break;
|
||||
uint16_t never_reset_mask = 0x00;
|
||||
for(int i = 0; i < MAX_I2C; i++) {
|
||||
if (!never_reset_i2c[i]) {
|
||||
reserved_i2c[i] = false;
|
||||
} else {
|
||||
never_reset_mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
i2c_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
|
||||
}
|
||||
|
||||
|
||||
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, uint32_t timeout) {
|
||||
|
||||
//match pins to I2C objects
|
||||
I2C_TypeDef * I2Cx;
|
||||
uint8_t sda_len = MP_ARRAY_SIZE(mcu_i2c_sda_list);
|
||||
uint8_t scl_len = MP_ARRAY_SIZE(mcu_i2c_scl_list);
|
||||
bool i2c_taken = false;
|
||||
|
||||
uint8_t sda_len = sizeof(mcu_i2c_sda_list)/sizeof(*mcu_i2c_sda_list);
|
||||
uint8_t scl_len = sizeof(mcu_i2c_scl_list)/sizeof(*mcu_i2c_scl_list);
|
||||
for(uint i=0; i<sda_len;i++) {
|
||||
for (uint i = 0; i < sda_len; i++) {
|
||||
if (mcu_i2c_sda_list[i].pin == sda) {
|
||||
for(uint j=0; j<scl_len;j++) {
|
||||
for (uint j = 0; j < scl_len; j++) {
|
||||
if ((mcu_i2c_scl_list[j].pin == scl)
|
||||
&& (mcu_i2c_scl_list[j].i2c_index == mcu_i2c_sda_list[i].i2c_index)) {
|
||||
//keep looking if the I2C is taken, could be another SCL that works
|
||||
if (reserved_i2c[mcu_i2c_scl_list[i].i2c_index - 1]) {
|
||||
i2c_taken = true;
|
||||
continue;
|
||||
}
|
||||
self->scl = &mcu_i2c_scl_list[j];
|
||||
self->sda = &mcu_i2c_sda_list[i];
|
||||
break;
|
||||
@ -89,14 +84,14 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
}
|
||||
|
||||
//handle typedef selection, errors
|
||||
if(self->sda!=NULL && self->scl!=NULL ) {
|
||||
I2Cx = mcu_i2c_banks[self->sda->i2c_index-1];
|
||||
if (self->sda != NULL && self->scl != NULL ) {
|
||||
I2Cx = mcu_i2c_banks[self->sda->i2c_index - 1];
|
||||
} else {
|
||||
mp_raise_RuntimeError(translate("Invalid I2C pin selection"));
|
||||
}
|
||||
|
||||
if(reserved_i2c[self->sda->i2c_index-1]) {
|
||||
mp_raise_RuntimeError(translate("Hardware busy, try alternative pins"));
|
||||
if (i2c_taken) {
|
||||
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
|
||||
} else {
|
||||
mp_raise_ValueError(translate("Invalid I2C pin selection"));
|
||||
}
|
||||
}
|
||||
|
||||
//Start GPIO for each pin
|
||||
@ -115,44 +110,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
GPIO_InitStruct.Alternate = self->scl->altfn_index;
|
||||
HAL_GPIO_Init(pin_port(scl->port), &GPIO_InitStruct);
|
||||
|
||||
//Fix for HAL error caused by soft reboot GPIO init SDA pin voltage drop. See Eratta.
|
||||
//Must be in this exact spot or I2C will get stuck in infinite loop.
|
||||
//TODO: See git issue #2172
|
||||
#ifdef I2C1
|
||||
__HAL_RCC_I2C1_FORCE_RESET();
|
||||
HAL_Delay(2);
|
||||
__HAL_RCC_I2C1_RELEASE_RESET();
|
||||
#endif
|
||||
#ifdef I2C2
|
||||
__HAL_RCC_I2C2_FORCE_RESET();
|
||||
HAL_Delay(2);
|
||||
__HAL_RCC_I2C2_RELEASE_RESET();
|
||||
#endif
|
||||
#ifdef I2C3
|
||||
__HAL_RCC_I2C3_FORCE_RESET();
|
||||
HAL_Delay(2);
|
||||
__HAL_RCC_I2C3_RELEASE_RESET();
|
||||
#endif
|
||||
|
||||
//Keep separate so above hack can be cleanly replaced
|
||||
#ifdef I2C1
|
||||
if(I2Cx==I2C1) {
|
||||
reserved_i2c[0] = true;
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C2
|
||||
if(I2Cx==I2C2) {
|
||||
reserved_i2c[1] = true;
|
||||
__HAL_RCC_I2C2_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C3
|
||||
if(I2Cx==I2C3) {
|
||||
reserved_i2c[2] = true;
|
||||
__HAL_RCC_I2C3_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
//Note: due to I2C soft reboot issue, do not relocate clock init.
|
||||
i2c_clock_enable(1 << (self->sda->i2c_index - 1));
|
||||
reserved_i2c[self->sda->i2c_index - 1] = true;
|
||||
|
||||
self->handle.Instance = I2Cx;
|
||||
self->handle.Init.ClockSpeed = 100000;
|
||||
@ -163,13 +123,26 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
self->handle.Init.OwnAddress2 = 0;
|
||||
self->handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
self->handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if(HAL_I2C_Init(&(self->handle)) != HAL_OK) {
|
||||
self->handle.State = HAL_I2C_STATE_RESET;
|
||||
if (HAL_I2C_Init(&(self->handle)) != HAL_OK) {
|
||||
mp_raise_RuntimeError(translate("I2C Init Error"));
|
||||
}
|
||||
claim_pin(sda);
|
||||
claim_pin(scl);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) {
|
||||
if (self->handle.Instance == mcu_i2c_banks[i]) {
|
||||
never_reset_i2c[i] = true;
|
||||
|
||||
never_reset_pin_number(self->scl->pin->port, self->scl->pin->number);
|
||||
never_reset_pin_number(self->sda->pin->port, self->sda->pin->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
||||
return self->sda->pin == mp_const_none;
|
||||
}
|
||||
@ -178,27 +151,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
#ifdef I2C1
|
||||
if(self->handle.Instance==I2C1) {
|
||||
never_reset[0] = false;
|
||||
reserved_i2c[0] = false;
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C2
|
||||
if(self->handle.Instance==I2C2) {
|
||||
never_reset[1] = false;
|
||||
reserved_i2c[1] = false;
|
||||
__HAL_RCC_I2C2_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C3
|
||||
if(self->handle.Instance==I2C3) {
|
||||
never_reset[2] = false;
|
||||
reserved_i2c[2] = false;
|
||||
__HAL_RCC_I2C3_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
i2c_clock_disable(1 << (self->sda->i2c_index - 1));
|
||||
reserved_i2c[self->sda->i2c_index - 1] = false;
|
||||
never_reset_i2c[self->sda->i2c_index - 1] = false;
|
||||
|
||||
reset_pin_number(self->sda->pin->port,self->sda->pin->number);
|
||||
reset_pin_number(self->scl->pin->port,self->scl->pin->number);
|
||||
self->sda = mp_const_none;
|
||||
@ -206,7 +163,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
return HAL_I2C_IsDeviceReady(&(self->handle), (uint16_t)(addr<<1),2,2) == HAL_OK;
|
||||
return HAL_I2C_IsDeviceReady(&(self->handle), (uint16_t)(addr << 1), 2, 2) == HAL_OK;
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
|
||||
@ -238,11 +195,56 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
|
||||
|
||||
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
|
||||
const uint8_t *data, size_t len, bool transmit_stop_bit) {
|
||||
HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr<<1), (uint8_t *)data, (uint16_t)len, 500);
|
||||
HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1),
|
||||
(uint8_t *)data, (uint16_t)len, 500);
|
||||
return result == HAL_OK ? 0 : MP_EIO;
|
||||
}
|
||||
|
||||
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
|
||||
uint8_t *data, size_t len) {
|
||||
return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) == HAL_OK ? 0 : MP_EIO;
|
||||
return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500)
|
||||
== HAL_OK ? 0 : MP_EIO;
|
||||
}
|
||||
|
||||
STATIC void i2c_clock_enable(uint8_t mask) {
|
||||
//Note: hard reset required due to soft reboot issue.
|
||||
#ifdef I2C1
|
||||
if (mask & (1 << 0)) {
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
__HAL_RCC_I2C1_FORCE_RESET();
|
||||
__HAL_RCC_I2C1_RELEASE_RESET();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C2
|
||||
if (mask & (1 << 1)) {
|
||||
__HAL_RCC_I2C2_CLK_ENABLE();
|
||||
__HAL_RCC_I2C2_FORCE_RESET();
|
||||
__HAL_RCC_I2C2_RELEASE_RESET();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C3
|
||||
if (mask & (1 << 2)) {
|
||||
__HAL_RCC_I2C3_CLK_ENABLE();
|
||||
__HAL_RCC_I2C3_FORCE_RESET();
|
||||
__HAL_RCC_I2C3_RELEASE_RESET();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void i2c_clock_disable(uint8_t mask) {
|
||||
#ifdef I2C1
|
||||
if (mask & (1 << 0)) {
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C2
|
||||
if (mask & (1 << 1)) {
|
||||
__HAL_RCC_I2C2_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef I2C3
|
||||
if (mask & (1 << 2)) {
|
||||
__HAL_RCC_I2C3_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -39,13 +39,12 @@
|
||||
// Note that any bugs introduced in this file can cause crashes at startup
|
||||
// for chips using external SPI flash.
|
||||
|
||||
#define MAX_SPI 6 //TODO; replace this as part of periph cleanup
|
||||
#define ALL_CLOCKS 0xFF
|
||||
|
||||
//arrays use 0 based numbering: SPI1 is stored at index 0
|
||||
#define MAX_SPI 6
|
||||
STATIC bool reserved_spi[MAX_SPI];
|
||||
STATIC bool never_reset_spi[MAX_SPI];
|
||||
|
||||
#define ALL_CLOCKS 0xFF
|
||||
STATIC void spi_clock_enable(uint8_t mask);
|
||||
STATIC void spi_clock_disable(uint8_t mask);
|
||||
|
||||
@ -60,13 +59,39 @@ STATIC uint32_t get_busclock(SPI_TypeDef * instance) {
|
||||
return HAL_RCC_GetPCLK2Freq();
|
||||
}
|
||||
|
||||
STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler, uint32_t busclock) {
|
||||
static const uint32_t baud_map[8][2] = {
|
||||
{2,SPI_BAUDRATEPRESCALER_2},
|
||||
{4,SPI_BAUDRATEPRESCALER_4},
|
||||
{8,SPI_BAUDRATEPRESCALER_8},
|
||||
{16,SPI_BAUDRATEPRESCALER_16},
|
||||
{32,SPI_BAUDRATEPRESCALER_32},
|
||||
{64,SPI_BAUDRATEPRESCALER_64},
|
||||
{128,SPI_BAUDRATEPRESCALER_128},
|
||||
{256,SPI_BAUDRATEPRESCALER_256}
|
||||
};
|
||||
size_t i = 0;
|
||||
uint16_t divisor;
|
||||
do {
|
||||
divisor = baud_map[i][0];
|
||||
if (baudrate >= (busclock/divisor)) {
|
||||
*prescaler = divisor;
|
||||
return baud_map[i][1];
|
||||
}
|
||||
i++;
|
||||
} while (divisor != 256);
|
||||
//only gets here if requested baud is lower than minimum
|
||||
*prescaler = 256;
|
||||
return SPI_BAUDRATEPRESCALER_256;
|
||||
}
|
||||
|
||||
void spi_reset(void) {
|
||||
uint16_t never_reset_mask = 0x00;
|
||||
for(int i=0;i<MAX_SPI;i++) {
|
||||
for (int i = 0; i < MAX_SPI; i++) {
|
||||
if (!never_reset_spi[i]) {
|
||||
reserved_spi[i] = 0x00;
|
||||
reserved_spi[i] = false;
|
||||
} else {
|
||||
never_reset_mask |= 1<<i;
|
||||
never_reset_mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
|
||||
@ -79,26 +104,26 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
//match pins to SPI objects
|
||||
SPI_TypeDef * SPIx;
|
||||
|
||||
uint8_t sck_len = sizeof(mcu_spi_sck_list)/sizeof(*mcu_spi_sck_list);
|
||||
uint8_t mosi_len = sizeof(mcu_spi_mosi_list)/sizeof(*mcu_spi_mosi_list);
|
||||
uint8_t miso_len = sizeof(mcu_spi_miso_list)/sizeof(*mcu_spi_miso_list);
|
||||
uint8_t sck_len = MP_ARRAY_SIZE(mcu_spi_sck_list);
|
||||
uint8_t mosi_len = MP_ARRAY_SIZE(mcu_spi_mosi_list);
|
||||
uint8_t miso_len = MP_ARRAY_SIZE(mcu_spi_miso_list);
|
||||
bool spi_taken = false;
|
||||
|
||||
//SCK is not optional. MOSI and MISO are
|
||||
for (uint i=0; i<sck_len;i++) {
|
||||
for (uint i = 0; i < sck_len; i++) {
|
||||
if (mcu_spi_sck_list[i].pin == sck) {
|
||||
//if both MOSI and MISO exist, loop search normally
|
||||
if ((mosi != mp_const_none) && (miso != mp_const_none)) {
|
||||
//MOSI
|
||||
for (uint j=0; j<mosi_len;j++) {
|
||||
for (uint j = 0; j < mosi_len; j++) {
|
||||
if (mcu_spi_mosi_list[j].pin == mosi) {
|
||||
//MISO
|
||||
for (uint k=0; k<miso_len;k++) {
|
||||
for (uint k = 0; k < miso_len; k++) {
|
||||
if ((mcu_spi_miso_list[k].pin == miso) //everything needs the same index
|
||||
&& (mcu_spi_sck_list[i].spi_index == mcu_spi_mosi_list[j].spi_index)
|
||||
&& (mcu_spi_sck_list[i].spi_index == mcu_spi_miso_list[k].spi_index)) {
|
||||
//keep looking if the SPI is taken, edge case
|
||||
if (reserved_spi[mcu_spi_sck_list[i].spi_index-1]) {
|
||||
if (reserved_spi[mcu_spi_sck_list[i].spi_index - 1]) {
|
||||
spi_taken = true;
|
||||
continue;
|
||||
}
|
||||
@ -113,11 +138,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
}
|
||||
// if just MISO, reduce search
|
||||
} else if (miso != mp_const_none) {
|
||||
for (uint j=0; j<miso_len;j++) {
|
||||
for (uint j = 0; j < miso_len; j++) {
|
||||
if ((mcu_spi_miso_list[j].pin == miso) //only SCK and MISO need the same index
|
||||
&& (mcu_spi_sck_list[i].spi_index == mcu_spi_miso_list[j].spi_index)) {
|
||||
//keep looking if the SPI is taken, edge case
|
||||
if (reserved_spi[mcu_spi_sck_list[i].spi_index-1]) {
|
||||
if (reserved_spi[mcu_spi_sck_list[i].spi_index - 1]) {
|
||||
spi_taken = true;
|
||||
continue;
|
||||
}
|
||||
@ -130,11 +155,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
}
|
||||
// if just MOSI, reduce search
|
||||
} else if (mosi != mp_const_none) {
|
||||
for (uint j=0; j<mosi_len;j++) {
|
||||
for (uint j = 0; j < mosi_len; j++) {
|
||||
if ((mcu_spi_mosi_list[j].pin == mosi) //only SCK and MOSI need the same index
|
||||
&& (mcu_spi_sck_list[i].spi_index == mcu_spi_mosi_list[j].spi_index)) {
|
||||
//keep looking if the SPI is taken, edge case
|
||||
if (reserved_spi[mcu_spi_sck_list[i].spi_index-1]) {
|
||||
if (reserved_spi[mcu_spi_sck_list[i].spi_index - 1]) {
|
||||
spi_taken = true;
|
||||
continue;
|
||||
}
|
||||
@ -153,10 +178,10 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
}
|
||||
|
||||
//handle typedef selection, errors
|
||||
if ( (self->sck!=NULL && self->mosi!=NULL && self->miso != NULL) ||
|
||||
(self->sck!=NULL && self->mosi!=NULL && miso == mp_const_none) ||
|
||||
(self->sck!=NULL && self->miso!=NULL && mosi == mp_const_none)) {
|
||||
SPIx = mcu_spi_banks[self->sck->spi_index-1];
|
||||
if ( (self->sck != NULL && self->mosi != NULL && self->miso != NULL) ||
|
||||
(self->sck != NULL && self->mosi != NULL && miso == mp_const_none) ||
|
||||
(self->sck != NULL && self->miso != NULL && mosi == mp_const_none)) {
|
||||
SPIx = mcu_spi_banks[self->sck->spi_index - 1];
|
||||
} else {
|
||||
if (spi_taken) {
|
||||
mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
|
||||
@ -192,7 +217,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
spi_clock_enable(1<<(self->sck->spi_index - 1));
|
||||
spi_clock_enable(1 << (self->sck->spi_index - 1));
|
||||
reserved_spi[self->sck->spi_index - 1] = true;
|
||||
|
||||
self->handle.Instance = SPIx;
|
||||
@ -212,7 +237,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
{
|
||||
mp_raise_ValueError(translate("SPI Init Error"));
|
||||
}
|
||||
self->baudrate = (get_busclock(SPIx)/16);
|
||||
self->baudrate = (get_busclock(SPIx) / 16);
|
||||
self->prescaler = 16;
|
||||
self->polarity = 0;
|
||||
self->phase = 0;
|
||||
@ -228,7 +253,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
|
||||
for (size_t i = 0 ; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) {
|
||||
if (mcu_spi_banks[i] == self->handle.Instance) {
|
||||
never_reset_spi[i] = true;
|
||||
never_reset_pin_number(self->sck->pin->port, self->sck->pin->number);
|
||||
@ -248,6 +273,9 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
|
||||
if (common_hal_busio_spi_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
spi_clock_disable(1<<(self->sck->spi_index - 1));
|
||||
reserved_spi[self->sck->spi_index - 1] = false;
|
||||
never_reset_spi[self->sck->spi_index - 1] = false;
|
||||
@ -264,32 +292,6 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
|
||||
self->miso = mp_const_none;
|
||||
}
|
||||
|
||||
STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t * prescaler, uint32_t busclock) {
|
||||
static const uint32_t baud_map[8][2] = {
|
||||
{2,SPI_BAUDRATEPRESCALER_2},
|
||||
{4,SPI_BAUDRATEPRESCALER_4},
|
||||
{8,SPI_BAUDRATEPRESCALER_8},
|
||||
{16,SPI_BAUDRATEPRESCALER_16},
|
||||
{32,SPI_BAUDRATEPRESCALER_32},
|
||||
{64,SPI_BAUDRATEPRESCALER_64},
|
||||
{128,SPI_BAUDRATEPRESCALER_128},
|
||||
{256,SPI_BAUDRATEPRESCALER_256}
|
||||
};
|
||||
size_t i = 0;
|
||||
uint16_t divisor;
|
||||
do {
|
||||
divisor = baud_map[i][0];
|
||||
if (baudrate >= (busclock/divisor)) {
|
||||
*prescaler = divisor;
|
||||
return baud_map[i][1];
|
||||
}
|
||||
i++;
|
||||
} while (divisor != 256);
|
||||
//only gets here if requested baud is lower than minimum
|
||||
*prescaler = 256;
|
||||
return SPI_BAUDRATEPRESCALER_256;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
|
||||
uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) {
|
||||
//This resets the SPI, so check before updating it redundantly
|
||||
@ -391,42 +393,66 @@ uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) {
|
||||
|
||||
STATIC void spi_clock_enable(uint8_t mask) {
|
||||
#ifdef SPI1
|
||||
if (mask & 1<<0) __HAL_RCC_SPI1_CLK_ENABLE();
|
||||
if (mask & (1 << 0)) {
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI2
|
||||
if (mask & 1<<1) __HAL_RCC_SPI2_CLK_ENABLE();
|
||||
if (mask & (1 << 1)) {
|
||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI3
|
||||
if (mask & 1<<2) __HAL_RCC_SPI3_CLK_ENABLE();
|
||||
if (mask & (1 << 2)) {
|
||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI4
|
||||
if (mask & 1<<3) __HAL_RCC_SPI4_CLK_ENABLE();
|
||||
if (mask & (1 << 3)) {
|
||||
__HAL_RCC_SPI4_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI5
|
||||
if (mask & 1<<4) __HAL_RCC_SPI5_CLK_ENABLE();
|
||||
if (mask & (1 << 4)) {
|
||||
__HAL_RCC_SPI5_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI6
|
||||
if (mask & 1<<5) __HAL_RCC_SPI6_CLK_ENABLE();
|
||||
if (mask & (1 << 5)) {
|
||||
__HAL_RCC_SPI6_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void spi_clock_disable(uint8_t mask) {
|
||||
#ifdef SPI1
|
||||
if (mask & 1<<0) __HAL_RCC_SPI1_CLK_DISABLE();
|
||||
if (mask & (1 << 0)) {
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI2
|
||||
if (mask & 1<<1) __HAL_RCC_SPI2_CLK_DISABLE();
|
||||
if (mask & (1 << 1)) {
|
||||
__HAL_RCC_SPI2_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI3
|
||||
if (mask & 1<<2) __HAL_RCC_SPI3_CLK_DISABLE();
|
||||
if (mask & (1 << 2)) {
|
||||
__HAL_RCC_SPI3_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI4
|
||||
if (mask & 1<<3) __HAL_RCC_SPI4_CLK_DISABLE();
|
||||
if (mask & (1 << 3)) {
|
||||
__HAL_RCC_SPI4_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI5
|
||||
if (mask & 1<<4) __HAL_RCC_SPI5_CLK_DISABLE();
|
||||
if (mask & (1 << 4)) {
|
||||
__HAL_RCC_SPI5_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI6
|
||||
if (mask & 1<<5) __HAL_RCC_SPI6_CLK_DISABLE();
|
||||
if (mask & (1 << 5)) {
|
||||
__HAL_RCC_SPI6_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#define ALL_UARTS 0xFFFF
|
||||
|
||||
//arrays use 0 based numbering: UART1 is stored at index 0
|
||||
STATIC bool reserved_uart[MAX_UART];
|
||||
int errflag; //Used to restart read halts
|
||||
|
||||
@ -47,14 +48,6 @@ STATIC void uart_clock_enable(uint16_t mask);
|
||||
STATIC void uart_clock_disable(uint16_t mask);
|
||||
STATIC void uart_assign_irq(busio_uart_obj_t* self, USART_TypeDef* USARTx);
|
||||
|
||||
void uart_reset(void) {
|
||||
for (uint8_t i = 0; i < MAX_UART; i++) {
|
||||
reserved_uart[i] = false;
|
||||
MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
|
||||
}
|
||||
uart_clock_disable(ALL_UARTS);
|
||||
}
|
||||
|
||||
STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eval,
|
||||
int uart_index, bool uart_taken) {
|
||||
if (pin_eval) {
|
||||
@ -70,6 +63,14 @@ STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eva
|
||||
}
|
||||
}
|
||||
|
||||
void uart_reset(void) {
|
||||
for (uint8_t i = 0; i < MAX_UART; i++) {
|
||||
reserved_uart[i] = false;
|
||||
MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
|
||||
}
|
||||
uart_clock_disable(ALL_UARTS);
|
||||
}
|
||||
|
||||
void common_hal_busio_uart_construct(busio_uart_obj_t* self,
|
||||
const mcu_pin_obj_t* tx, const mcu_pin_obj_t* rx, uint32_t baudrate,
|
||||
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
|
||||
@ -78,8 +79,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self,
|
||||
//match pins to UART objects
|
||||
USART_TypeDef * USARTx;
|
||||
|
||||
uint8_t tx_len = sizeof(mcu_uart_tx_list)/sizeof(*mcu_uart_tx_list);
|
||||
uint8_t rx_len = sizeof(mcu_uart_rx_list)/sizeof(*mcu_uart_rx_list);
|
||||
uint8_t tx_len = MP_ARRAY_SIZE(mcu_uart_tx_list);
|
||||
uint8_t rx_len = MP_ARRAY_SIZE(mcu_uart_rx_list);
|
||||
bool uart_taken = false;
|
||||
uint8_t uart_index = 0; //origin 0 corrected
|
||||
|
||||
@ -567,33 +568,53 @@ STATIC void uart_clock_disable(uint16_t mask) {
|
||||
|
||||
STATIC void uart_assign_irq(busio_uart_obj_t *self, USART_TypeDef * USARTx) {
|
||||
#ifdef USART1
|
||||
if (USARTx == USART1) self->irq = USART1_IRQn;
|
||||
if (USARTx == USART1) {
|
||||
self->irq = USART1_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef USART2
|
||||
if (USARTx == USART2) self->irq = USART2_IRQn;
|
||||
if (USARTx == USART2) {
|
||||
self->irq = USART2_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef USART3
|
||||
if (USARTx == USART3) self->irq = USART3_IRQn;
|
||||
if (USARTx == USART3) {
|
||||
self->irq = USART3_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef UART4
|
||||
if (USARTx == UART4) self->irq = UART4_IRQn;
|
||||
if (USARTx == UART4) {
|
||||
self->irq = UART4_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef UART5
|
||||
if (USARTx == UART5) self->irq = UART5_IRQn;
|
||||
if (USARTx == UART5) {
|
||||
self->irq = UART5_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef USART6
|
||||
if (USARTx == USART6) self->irq = USART6_IRQn;
|
||||
if (USARTx == USART6) {
|
||||
self->irq = USART6_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef UART7
|
||||
if (USARTx == UART7) self->irq = UART7_IRQn;
|
||||
if (USARTx == UART7) {
|
||||
self->irq = UART7_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef UART8
|
||||
if (USARTx == UART8) self->irq = UART8_IRQn;
|
||||
if (USARTx == UART8) {
|
||||
self->irq = UART8_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef UART9
|
||||
if (USARTx == UART9) self->irq = UART9_IRQn;
|
||||
if (USARTx == UART9) {
|
||||
self->irq = UART9_IRQn;
|
||||
}
|
||||
#endif
|
||||
#ifdef UART10
|
||||
if (USARTx == UART10) self->irq = UART10_IRQn;
|
||||
if (USARTx == UART10) {
|
||||
self->irq = UART10_IRQn;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -69,15 +69,15 @@ STATIC uint32_t timer_get_source_freq(uint32_t tim_id) {
|
||||
|
||||
STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) {
|
||||
//duty cycle is duty/0xFFFF fraction x (number of pulses per period)
|
||||
return (duty*period)/((1<<16)-1);
|
||||
return (duty*period) / ((1 << 16) - 1);
|
||||
}
|
||||
|
||||
STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler,
|
||||
uint32_t frequency, uint32_t source_freq) {
|
||||
//Find the largest possible period supported by this frequency
|
||||
for (int i=0; i<(1 << 16);i++) {
|
||||
*period = source_freq/(i*frequency);
|
||||
if (*period < (1 << 16) && *period>=2) {
|
||||
for (int i = 0; i < (1 << 16); i++) {
|
||||
*period = source_freq / (i * frequency);
|
||||
if (*period < (1 << 16) && *period >= 2) {
|
||||
*prescaler = i;
|
||||
break;
|
||||
}
|
||||
@ -89,60 +89,41 @@ STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler,
|
||||
|
||||
void pwmout_reset(void) {
|
||||
uint16_t never_reset_mask = 0x00;
|
||||
for(int i=0;i<TIM_BANK_ARRAY_LEN;i++) {
|
||||
for (int i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
|
||||
if (!never_reset_tim[i]) {
|
||||
reserved_tim[i] = 0x00;
|
||||
tim_frequencies[i] = 0x00;
|
||||
} else {
|
||||
never_reset_mask |= 1<<i;
|
||||
never_reset_mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
tim_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
|
||||
for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
|
||||
if (mcu_tim_banks[i] == self->handle.Instance) {
|
||||
never_reset_tim[i] = true;
|
||||
never_reset_pin_number(self->tim->pin->port, self->tim->pin->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
|
||||
for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
|
||||
if (mcu_tim_banks[i] == self->handle.Instance) {
|
||||
never_reset_tim[i] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pwmout_result_t 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) {
|
||||
TIM_TypeDef * TIMx;
|
||||
uint8_t tim_num = sizeof(mcu_tim_pin_list)/sizeof(*mcu_tim_pin_list);
|
||||
uint8_t tim_num = MP_ARRAY_SIZE(mcu_tim_pin_list);
|
||||
bool tim_chan_taken = false;
|
||||
bool tim_taken_f_mismatch = false;
|
||||
bool var_freq_mismatch = false;
|
||||
bool first_time_setup = true;
|
||||
mcu_tim_pin_obj_t l_tim = {0};
|
||||
|
||||
for(uint i = 0; i < tim_num; i++) {
|
||||
for (uint i = 0; i < tim_num; i++) {
|
||||
l_tim = mcu_tim_pin_list[i];
|
||||
uint8_t l_tim_index = l_tim.tim_index-1;
|
||||
uint8_t l_tim_channel = l_tim.channel_index-1;
|
||||
uint8_t l_tim_index = l_tim.tim_index - 1;
|
||||
uint8_t l_tim_channel = l_tim.channel_index - 1;
|
||||
|
||||
//if pin is same
|
||||
if (l_tim.pin == pin) {
|
||||
//check if the timer has a channel active
|
||||
if (reserved_tim[l_tim_index] != 0) {
|
||||
//is it the same channel? (or all channels reserved by a var-freq)
|
||||
if (reserved_tim[l_tim_index] & 1<<(l_tim_channel)) {
|
||||
if (reserved_tim[l_tim_index] & 1 << (l_tim_channel)) {
|
||||
tim_chan_taken = true;
|
||||
continue; //keep looking, might be another viable option
|
||||
}
|
||||
@ -165,21 +146,21 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
|
||||
}
|
||||
|
||||
//handle valid/invalid timer instance
|
||||
if (self->tim!=NULL) {
|
||||
if (self->tim != NULL) {
|
||||
//create instance
|
||||
TIMx = mcu_tim_banks[self->tim->tim_index-1];
|
||||
TIMx = mcu_tim_banks[self->tim->tim_index - 1];
|
||||
//reserve timer/channel
|
||||
if (variable_frequency) {
|
||||
reserved_tim[self->tim->tim_index-1] = 0x0F;
|
||||
reserved_tim[self->tim->tim_index - 1] = 0x0F;
|
||||
} else {
|
||||
reserved_tim[self->tim->tim_index-1] |= 1<<(self->tim->channel_index-1);
|
||||
reserved_tim[self->tim->tim_index - 1] |= 1 << (self->tim->channel_index - 1);
|
||||
}
|
||||
tim_frequencies[self->tim->tim_index-1] = frequency;
|
||||
tim_frequencies[self->tim->tim_index - 1] = frequency;
|
||||
} else { //no match found
|
||||
if (tim_chan_taken) {
|
||||
mp_raise_ValueError(translate("No more timers available on this pin."));
|
||||
} else if (tim_taken_f_mismatch) {
|
||||
mp_raise_ValueError(translate("Frequency must be the same as as the existing PWMOut using this timer"));
|
||||
mp_raise_ValueError(translate("Frequency must match existing PWMOut using this timer"));
|
||||
} else if (var_freq_mismatch) {
|
||||
mp_raise_ValueError(translate("Cannot vary frequency on a timer that is already in use"));
|
||||
} else {
|
||||
@ -195,14 +176,15 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
|
||||
GPIO_InitStruct.Alternate = self->tim->altfn_index;
|
||||
HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
|
||||
|
||||
tim_clock_enable(1<<(self->tim->tim_index - 1));
|
||||
tim_clock_enable(1 << (self->tim->tim_index - 1));
|
||||
|
||||
//translate channel into handle value
|
||||
self->channel = 4 * (self->tim->channel_index - 1);
|
||||
|
||||
uint32_t prescaler = 0; //prescaler is 15 bit
|
||||
uint32_t period = 0; //period is 16 bit
|
||||
timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
|
||||
timer_get_optimal_divisors(&period, &prescaler, frequency,
|
||||
timer_get_source_freq(self->tim->tim_index));
|
||||
|
||||
//Timer init
|
||||
self->handle.Instance = TIMx;
|
||||
@ -242,6 +224,25 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
|
||||
return PWMOUT_OK;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
|
||||
for (size_t i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
|
||||
if (mcu_tim_banks[i] == self->handle.Instance) {
|
||||
never_reset_tim[i] = true;
|
||||
never_reset_pin_number(self->tim->pin->port, self->tim->pin->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
|
||||
for(size_t i = 0; i < TIM_BANK_ARRAY_LEN; i++) {
|
||||
if (mcu_tim_banks[i] == self->handle.Instance) {
|
||||
never_reset_tim[i] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) {
|
||||
return self->tim == mp_const_none;
|
||||
}
|
||||
@ -252,18 +253,18 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
|
||||
}
|
||||
//var freq shuts down entire timer, others just their channel
|
||||
if (self->variable_frequency) {
|
||||
reserved_tim[self->tim->tim_index-1] = 0x00;
|
||||
reserved_tim[self->tim->tim_index - 1] = 0x00;
|
||||
} else {
|
||||
reserved_tim[self->tim->tim_index-1] &= ~(1<<self->tim->channel_index);
|
||||
reserved_tim[self->tim->tim_index - 1] &= ~(1 << self->tim->channel_index);
|
||||
HAL_TIM_PWM_Stop(&self->handle, self->channel);
|
||||
}
|
||||
reset_pin_number(self->tim->pin->port,self->tim->pin->number);
|
||||
self->tim = mp_const_none;
|
||||
|
||||
//if reserved timer has no active channels, we can disable it
|
||||
if (!reserved_tim[self->tim->tim_index-1]) {
|
||||
tim_frequencies[self->tim->tim_index-1] = 0x00;
|
||||
tim_clock_disable(1<<(self->tim->tim_index-1));
|
||||
if (!reserved_tim[self->tim->tim_index - 1]) {
|
||||
tim_frequencies[self->tim->tim_index - 1] = 0x00;
|
||||
tim_clock_disable(1 << (self->tim->tim_index - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,11 +280,14 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
|
||||
|
||||
void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
|
||||
//don't halt setup for the same frequency
|
||||
if (frequency == self->frequency) return;
|
||||
if (frequency == self->frequency) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t prescaler = 0;
|
||||
uint32_t period = 0;
|
||||
timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
|
||||
timer_get_optimal_divisors(&period, &prescaler, frequency,
|
||||
timer_get_source_freq(self->tim->tim_index));
|
||||
|
||||
//shut down
|
||||
HAL_TIM_PWM_Stop(&self->handle, self->channel);
|
||||
@ -306,7 +310,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_
|
||||
mp_raise_ValueError(translate("Could not restart PWM"));
|
||||
}
|
||||
|
||||
tim_frequencies[self->tim->tim_index-1] = frequency;
|
||||
tim_frequencies[self->tim->tim_index - 1] = frequency;
|
||||
self->frequency = frequency;
|
||||
self->period = period;
|
||||
}
|
||||
@ -321,80 +325,128 @@ bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self
|
||||
|
||||
STATIC void tim_clock_enable(uint16_t mask) {
|
||||
#ifdef TIM1
|
||||
if (mask & 1<<0) __HAL_RCC_TIM1_CLK_ENABLE();
|
||||
if (mask & (1 << 0)) {
|
||||
__HAL_RCC_TIM1_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM2
|
||||
if (mask & 1<<1) __HAL_RCC_TIM2_CLK_ENABLE();
|
||||
if (mask & (1 << 1)) {
|
||||
__HAL_RCC_TIM2_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM3
|
||||
if (mask & 1<<2) __HAL_RCC_TIM3_CLK_ENABLE();
|
||||
if (mask & (1 << 2)) {
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM4
|
||||
if (mask & 1<<3) __HAL_RCC_TIM4_CLK_ENABLE();
|
||||
if (mask & (1 << 3)) {
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM5
|
||||
if (mask & 1<<4) __HAL_RCC_TIM5_CLK_ENABLE();
|
||||
if (mask & (1 << 4)) {
|
||||
__HAL_RCC_TIM5_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
//6 and 7 are reserved ADC timers
|
||||
#ifdef TIM8
|
||||
if (mask & 1<<7) __HAL_RCC_TIM8_CLK_ENABLE();
|
||||
if (mask & (1 << 7)) {
|
||||
__HAL_RCC_TIM8_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM9
|
||||
if (mask & 1<<8) __HAL_RCC_TIM9_CLK_ENABLE();
|
||||
if (mask & (1 << 8)) {
|
||||
__HAL_RCC_TIM9_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM10
|
||||
if (mask & 1<<9) __HAL_RCC_TIM10_CLK_ENABLE();
|
||||
if (mask & (1 << 9)) {
|
||||
__HAL_RCC_TIM10_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM11
|
||||
if (mask & 1<<10) __HAL_RCC_TIM11_CLK_ENABLE();
|
||||
if (mask & (1 << 10)) {
|
||||
__HAL_RCC_TIM11_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM12
|
||||
if (mask & 1<<11) __HAL_RCC_TIM12_CLK_ENABLE();
|
||||
if (mask & (1 << 11)) {
|
||||
__HAL_RCC_TIM12_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM13
|
||||
if (mask & 1<<12) __HAL_RCC_TIM13_CLK_ENABLE();
|
||||
if (mask & (1 << 12)) {
|
||||
__HAL_RCC_TIM13_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM14
|
||||
if (mask & 1<<13) __HAL_RCC_TIM14_CLK_ENABLE();
|
||||
if (mask & (1 << 13)) {
|
||||
__HAL_RCC_TIM14_CLK_ENABLE();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void tim_clock_disable(uint16_t mask) {
|
||||
#ifdef TIM1
|
||||
if (mask & 1<<0) __HAL_RCC_TIM1_CLK_DISABLE();
|
||||
if (mask & (1 << 0)) {
|
||||
__HAL_RCC_TIM1_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM2
|
||||
if (mask & 1<<1) __HAL_RCC_TIM2_CLK_DISABLE();
|
||||
if (mask & (1 << 1)) {
|
||||
__HAL_RCC_TIM2_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM3
|
||||
if (mask & 1<<2) __HAL_RCC_TIM3_CLK_DISABLE();
|
||||
if (mask & (1 << 2)) {
|
||||
__HAL_RCC_TIM3_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM4
|
||||
if (mask & 1<<3) __HAL_RCC_TIM4_CLK_DISABLE();
|
||||
if (mask & (1 << 3)) {
|
||||
__HAL_RCC_TIM4_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM5
|
||||
if (mask & 1<<4) __HAL_RCC_TIM5_CLK_DISABLE();
|
||||
if (mask & (1 << 4)) {
|
||||
__HAL_RCC_TIM5_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
//6 and 7 are reserved ADC timers
|
||||
#ifdef TIM8
|
||||
if (mask & 1<<7) __HAL_RCC_TIM8_CLK_DISABLE();
|
||||
if (mask & (1 << 7)) {
|
||||
__HAL_RCC_TIM8_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM9
|
||||
if (mask & 1<<8) __HAL_RCC_TIM9_CLK_DISABLE();
|
||||
if (mask & (1 << 8)) {
|
||||
__HAL_RCC_TIM9_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM10
|
||||
if (mask & 1<<9) __HAL_RCC_TIM10_CLK_DISABLE();
|
||||
if (mask & (1 << 9)) {
|
||||
__HAL_RCC_TIM10_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM11
|
||||
if (mask & 1<<10) __HAL_RCC_TIM11_CLK_DISABLE();
|
||||
if (mask & (1 << 10)) {
|
||||
__HAL_RCC_TIM11_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM12
|
||||
if (mask & 1<<11) __HAL_RCC_TIM12_CLK_DISABLE();
|
||||
if (mask & (1 << 11)) {
|
||||
__HAL_RCC_TIM12_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM13
|
||||
if (mask & 1<<12) __HAL_RCC_TIM13_CLK_DISABLE();
|
||||
if (mask & (1 << 12)) {
|
||||
__HAL_RCC_TIM13_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
#ifdef TIM14
|
||||
if (mask & 1<<13) __HAL_RCC_TIM14_CLK_DISABLE();
|
||||
if (mask & (1 << 13)) {
|
||||
__HAL_RCC_TIM14_CLK_DISABLE();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -69,9 +69,7 @@ ifndef CIRCUITPY_DISPLAYIO
|
||||
CIRCUITPY_DISPLAYIO = 1
|
||||
endif
|
||||
|
||||
ifndef MICROPY_CPYTHON_COMPAT
|
||||
MICROPY_CPYTHON_COMPAT = 1
|
||||
endif
|
||||
CFLAGS += -DMICROPY_CPYTHON_COMPAT=1
|
||||
|
||||
#ifeq ($(MCU_SUB_VARIANT), stm32f412zx)
|
||||
#endif
|
||||
|
@ -182,7 +182,10 @@ typedef long mp_off_t;
|
||||
|
||||
// Remove some lesser-used functionality to make small builds fit.
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
|
||||
//TODO: replace this with a rework of the FULL_BUILD system
|
||||
#if !defined(MICROPY_CPYTHON_COMPAT)
|
||||
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
|
||||
#endif
|
||||
#define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
|
||||
#define MICROPY_PY_BUILTINS_COMPLEX (CIRCUITPY_FULL_BUILD)
|
||||
|
@ -310,6 +310,13 @@ CIRCUITPY_BITBANG_APA102 = 0
|
||||
endif
|
||||
CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102)
|
||||
|
||||
# Should busio.I2C() check for pullups?
|
||||
# Some boards in combination with certain peripherals may not want this.
|
||||
ifndef CIRCUITPY_REQUIRE_I2C_PULLUPS
|
||||
CIRCUITPY_REQUIRE_I2C_PULLUPS = 1
|
||||
endif
|
||||
CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS)
|
||||
|
||||
# REPL over BLE
|
||||
ifndef CIRCUITPY_SERIAL_BLE
|
||||
CIRCUITPY_SERIAL_BLE = 0
|
||||
|
@ -71,15 +71,6 @@ void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t ki
|
||||
mp_obj_attrtuple_print_helper(print, fields, &o->tuple);
|
||||
}
|
||||
|
||||
mp_obj_t namedtuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
mp_obj_type_t *type = mp_obj_get_type(self_in);
|
||||
// Check for subclasses of namedtuple and unpack if needed.
|
||||
if (type->parent != &mp_type_tuple) {
|
||||
self_in = ((mp_obj_instance_t*) self_in)->subobj[0];
|
||||
}
|
||||
return mp_obj_tuple_subscr(self_in, index, value);
|
||||
}
|
||||
|
||||
void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
if (dest[0] == MP_OBJ_NULL) {
|
||||
// load attribute
|
||||
@ -177,7 +168,7 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t
|
||||
o->base.unary_op = mp_obj_tuple_unary_op;
|
||||
o->base.binary_op = mp_obj_tuple_binary_op;
|
||||
o->base.attr = namedtuple_attr;
|
||||
o->base.subscr = namedtuple_subscr;
|
||||
o->base.subscr = mp_obj_tuple_subscr;
|
||||
o->base.getiter = mp_obj_tuple_getiter;
|
||||
o->base.parent = &mp_type_tuple;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
|
@ -49,7 +49,6 @@ typedef struct _mp_obj_namedtuple_t {
|
||||
|
||||
void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
|
||||
size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name);
|
||||
mp_obj_t namedtuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
|
||||
void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
|
||||
mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields);
|
||||
mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "py/objtuple.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objtype.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
@ -178,10 +179,14 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
|
||||
if (value == MP_OBJ_SENTINEL) {
|
||||
// load
|
||||
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
// when called with a native type (eg namedtuple) using mp_obj_tuple_subscr, get the native self
|
||||
if (self->base.type->subscr != &mp_obj_tuple_subscr) {
|
||||
self = mp_instance_cast_to_native_base(self_in, &mp_type_tuple);
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_SLICE
|
||||
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||
mp_bound_slice_t slice;
|
||||
|
4
py/py.mk
4
py/py.mk
@ -304,12 +304,12 @@ FORCE:
|
||||
|
||||
$(HEADER_BUILD)/mpversion.h: FORCE | $(HEADER_BUILD)
|
||||
$(STEPECHO) "GEN $@"
|
||||
$(Q)$(PYTHON) $(PY_SRC)/makeversionhdr.py $@
|
||||
$(Q)$(PYTHON3) $(PY_SRC)/makeversionhdr.py $@
|
||||
|
||||
# build a list of registered modules for py/objmodule.c.
|
||||
$(HEADER_BUILD)/moduledefs.h: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h
|
||||
@$(STEPECHO) "GEN $@"
|
||||
$(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py --vpath="., $(TOP), $(USER_C_MODULES)" $(SRC_QSTR) > $@
|
||||
$(Q)$(PYTHON3) $(PY_SRC)/makemoduledefs.py --vpath="., $(TOP), $(USER_C_MODULES)" $(SRC_QSTR) > $@
|
||||
|
||||
SRC_QSTR += $(HEADER_BUILD)/moduledefs.h
|
||||
|
||||
|
@ -50,6 +50,9 @@ void vstr_init(vstr_t *vstr, size_t alloc) {
|
||||
// Init the vstr so it allocs exactly enough ram to hold a null-terminated
|
||||
// string of the given length, and set the length.
|
||||
void vstr_init_len(vstr_t *vstr, size_t len) {
|
||||
if(len == SIZE_MAX) {
|
||||
m_malloc_fail(len);
|
||||
}
|
||||
vstr_init(vstr, len + 1);
|
||||
vstr->len = len;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/os/__init__.h"
|
||||
|
||||
@ -195,11 +196,11 @@ MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
//|
|
||||
STATIC mp_obj_t os_urandom(mp_obj_t size_in) {
|
||||
mp_int_t size = mp_obj_get_int(size_in);
|
||||
uint8_t tmp[size];
|
||||
if (!common_hal_os_urandom(tmp, size)) {
|
||||
mp_obj_str_t *result = MP_OBJ_TO_PTR(mp_obj_new_bytes_of_zeros(size));
|
||||
if (!common_hal_os_urandom((uint8_t*) result->data, size)) {
|
||||
mp_raise_NotImplementedError(translate("No hardware random available"));
|
||||
}
|
||||
return mp_obj_new_bytes(tmp, size);
|
||||
return result;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
|
||||
|
7
tests/basics/subscr_tuple.py
Normal file
7
tests/basics/subscr_tuple.py
Normal file
@ -0,0 +1,7 @@
|
||||
# subscripting a subclassed tuple
|
||||
class Foo(tuple):
|
||||
pass
|
||||
|
||||
foo = Foo((1,2))
|
||||
foo[0]
|
||||
|
Loading…
Reference in New Issue
Block a user