micropython/ports/stm32/boards/NUCLEO_WB55/rfcore_debug.py

246 wiersze
8.9 KiB
Python

# This file is part of the MicroPython project, http://micropython.org/
#
# The MIT License (MIT)
#
# Copyright (c) 2020 Damien P. George
# Copyright (c) 2020 Jim Mussared
#
# 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 script provides some helpers to allow Python code to access the IPCC
# mechanism in the WB55, and works with the memory layout configured in
# ports/stm32/rfcore.c -- i.e. it expects that rfcore_init() has been run.
# e.g.
# ../../tools/pyboard.py --device /dev/ttyACM0 boards/NUCLEO_WB55/rfcore.py
# to print out SRAM2A, register state and FUS/WS info.
#
# The `stm` module provides some helper functions to access rfcore functionality.
# See rfcore_firmware.py for more information.
from machine import mem8, mem16, mem32
from micropython import const
import stm
SRAM2A_BASE = const(0x2003_0000)
# for vendor OGF
OGF_VENDOR = const(0x3F)
OCF_FUS_GET_STATE = const(0x52)
OCF_FUS_FW_UPGRADE = const(0x54)
OCF_FUS_FW_DELETE = const(0x55)
OCF_FUS_START_WS = const(0x5A)
OCF_BLE_INIT = const(0x66)
TABLE_DEVICE_INFO = const(0)
TABLE_BLE = const(1)
TABLE_SYS = const(3)
TABLE_MEM_MANAGER = const(4)
CHANNEL_BLE = const(1)
CHANNEL_SYS = const(2)
CHANNEL_TRACES = const(4)
CHANNEL_ACL = const(6)
INDICATOR_HCI_COMMAND = const(0x01)
INDICATOR_HCI_EVENT = const(0x04)
INDICATOR_FUS_COMMAND = const(0x10)
INDICATOR_FUS_RESPONSE = const(0x11)
INDICATOR_FUS_EVENT = const(0x12)
MAGIC_FUS_ACTIVE = const(0xA94656B9)
def get_ipccdba():
return mem32[stm.FLASH + stm.FLASH_IPCCBR] & 0x3FFF
def get_ipcc_table(table):
return mem32[SRAM2A_BASE + get_ipccdba() + table * 4]
def get_ipcc_table_word(table, offset):
return mem32[get_ipcc_table(table) + offset * 4] & 0xFFFFFFFF
def get_ipcc_table_byte(table, offset):
return mem8[get_ipcc_table(table) + offset] & 0xFF
def sram2a_dump(num_words=64, width=8):
print("SRAM2A @%08x" % SRAM2A_BASE)
for i in range((num_words + width - 1) // width):
print(" %04x " % (i * 4 * width), end="")
for j in range(width):
print(" %08x" % (mem32[SRAM2A_BASE + (i * width + j) * 4] & 0xFFFFFFFF), end="")
print()
SYS_CMD_BUF = 0 # next*,prev*,type8,...; 272 bytes
SYS_SYS_QUEUE = 0 # next*,prev*
MM_BLE_SPARE_EVT_BUF = 0 # next*,prev*; 272 bytes
MM_SYS_SPARE_EVT_BUF = 0 # next*,prev*; 272 bytes
MM_BLE_POOL = 0 # ?
MM_BLE_POOL_SIZE = 0 # ?
MM_FREE_BUF_QUEUE = 0 # next*,prev*
MM_EV_POOL = 0 # ?
MM_EV_POOL_SIZE = 0 # ?
BLE_CMD_BUF = 0
BLE_CS_BUF = 0
BLE_EVT_QUEUE = 0
BLE_HCI_ACL_DATA_BUF = 0
def ipcc_init():
global SYS_CMD_BUF, SYS_SYS_QUEUE
SYS_CMD_BUF = get_ipcc_table_word(TABLE_SYS, 0)
SYS_SYS_QUEUE = get_ipcc_table_word(TABLE_SYS, 1)
global \
MM_BLE_SPARE_EVT_BUF, \
MM_SYS_SPARE_EVT_BUF, \
MM_BLE_POOL, \
MM_BLE_POOL_SIZE, \
MM_FREE_BUF_QUEUE, \
MM_EV_POOL, \
MM_EV_POOL_SIZE
MM_BLE_SPARE_EVT_BUF = get_ipcc_table_word(TABLE_MEM_MANAGER, 0)
MM_SYS_SPARE_EVT_BUF = get_ipcc_table_word(TABLE_MEM_MANAGER, 1)
MM_BLE_POOL = get_ipcc_table_word(TABLE_MEM_MANAGER, 2)
MM_BLE_POOL_SIZE = get_ipcc_table_word(TABLE_MEM_MANAGER, 3)
MM_FREE_BUF_QUEUE = get_ipcc_table_word(TABLE_MEM_MANAGER, 4)
MM_EV_POOL = get_ipcc_table_word(TABLE_MEM_MANAGER, 5)
MM_EV_POOL_SIZE = get_ipcc_table_word(TABLE_MEM_MANAGER, 6)
global BLE_CMD_BUF, BLE_CS_BUF, BLE_EVT_QUEUE, BLE_HCI_ACL_DATA_BUF
BLE_CMD_BUF = get_ipcc_table_word(TABLE_BLE, 0)
BLE_CS_BUF = get_ipcc_table_word(TABLE_BLE, 1)
BLE_EVT_QUEUE = get_ipcc_table_word(TABLE_BLE, 2)
BLE_HCI_ACL_DATA_BUF = get_ipcc_table_word(TABLE_BLE, 3)
# Disable interrupts, the code here uses polling
mem32[stm.IPCC + stm.IPCC_C1CR] = 0
print("IPCC initialised")
print("SYS: 0x%08x 0x%08x" % (SYS_CMD_BUF, SYS_SYS_QUEUE))
print("BLE: 0x%08x 0x%08x 0x%08x" % (BLE_CMD_BUF, BLE_CS_BUF, BLE_EVT_QUEUE))
def fus_active():
return get_ipcc_table_word(TABLE_DEVICE_INFO, 0) == MAGIC_FUS_ACTIVE
def info():
sfr = mem32[stm.FLASH + stm.FLASH_SFR]
srrvr = mem32[stm.FLASH + stm.FLASH_SRRVR]
print("IPCCDBA : 0x%08x" % (get_ipccdba() & 0x3FFF))
print("DDS : %r" % bool(sfr & (1 << 12)))
print("FSD : %r" % bool(sfr & (1 << 8)))
print("SFSA : 0x%08x" % (sfr & 0xFF))
print("C2OPT : %r" % bool(srrvr & (1 << 31)))
print("NBRSD : %r" % bool(srrvr & (1 << 30)))
print("SNBRSA : 0x%08x" % ((srrvr >> 25) & 0x1F))
print("BRSD : %r" % bool(srrvr & (1 << 23)))
print("SBRSA : 0x%08x" % ((srrvr >> 18) & 0x1F))
print("SBRV : 0x%08x" % (srrvr & 0x3FFFF))
def dev_info():
def dump_version(offset):
x = get_ipcc_table_word(TABLE_DEVICE_INFO, offset)
print(
"0x%08x (%u.%u.%u.%u.%u)"
% (x, x >> 24, x >> 16 & 0xFF, x >> 8 & 0xFF, x >> 4 & 0xF, x & 0xF)
)
def dump_memory_size(offset):
x = get_ipcc_table_word(TABLE_DEVICE_INFO, offset)
print(
"0x%08x (SRAM2b=%uk SRAM2a=%uk flash=%uk)"
% (x, x >> 24, x >> 16 & 0xFF, (x & 0xFF) * 4)
)
print("Device information table @%08x:" % get_ipcc_table(TABLE_DEVICE_INFO))
if fus_active():
# layout when running FUS
print("FUS is active")
print("state : 0x%08x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 0))
print("last FUS active state : 0x%02x" % get_ipcc_table_byte(TABLE_DEVICE_INFO, 5))
print("last wireless stack state: 0x%02x" % get_ipcc_table_byte(TABLE_DEVICE_INFO, 6))
print("cur wireless stack type : 0x%02x" % get_ipcc_table_byte(TABLE_DEVICE_INFO, 7))
print("safe boot version : ", end="")
dump_version(2)
print("FUS version : ", end="")
dump_version(3)
print("FUS memory size : ", end="")
dump_memory_size(4)
print("wireless stack version : ", end="")
dump_version(5)
print("wireless stack mem size : ", end="")
dump_memory_size(6)
print("wireless FW-BLE info : 0x%08x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 7))
print("wireless FW-thread info : 0x%08x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 8))
print(
"UID64 : 0x%08x 0x%08x"
% (
get_ipcc_table_word(TABLE_DEVICE_INFO, 9),
get_ipcc_table_word(TABLE_DEVICE_INFO, 10),
)
)
print("device ID : 0x%04x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 11))
else:
# layout when running WS
print("WS is active")
print("safe boot version : ", end="")
dump_version(0)
print("FUS version : ", end="")
dump_version(1)
print("FUS memory size : ", end="")
dump_memory_size(2)
print("FUS info : 0x%08x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 3))
print("wireless stack version : ", end="")
dump_version(4)
print("wireless stack mem size : ", end="")
dump_memory_size(5)
print("wireless stack info : 0x%08x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 7))
print("wireless reserved : 0x%08x" % get_ipcc_table_word(TABLE_DEVICE_INFO, 7))
def ipcc_state():
print("IPCC:")
print(" C1CR: 0x%08x" % (mem32[stm.IPCC + stm.IPCC_C1CR] & 0xFFFFFFFF), end="")
print(" C2CR: 0x%08x" % (mem32[stm.IPCC + stm.IPCC_C2CR] & 0xFFFFFFFF))
print(" C1MR: 0x%08x" % (mem32[stm.IPCC + stm.IPCC_C1MR] & 0xFFFFFFFF), end="")
print(" C2MR: 0x%08x" % (mem32[stm.IPCC + stm.IPCC_C2MR] & 0xFFFFFFFF))
# these always read 0
# print(' C1SCR: 0x%08x' % (mem32[stm.IPCC + stm.IPCC_C1SCR] & 0xffffffff), end='')
# print(' C2SCR: 0x%08x' % (mem32[stm.IPCC + stm.IPCC_C2SCR] & 0xffffffff))
print(" C1TOC2SR: 0x%08x" % (mem32[stm.IPCC + stm.IPCC_C1TOC2SR] & 0xFFFFFFFF), end="")
print(" C2TOC1SR: 0x%08x" % (mem32[stm.IPCC + stm.IPCC_C2TOC1SR] & 0xFFFFFFFF))
sram2a_dump(264)
ipcc_init()
info()
dev_info()
ipcc_state()