mirror of
https://github.com/MikronMIK32/mik32-uploader.git
synced 2026-01-01 13:37:03 +03:00
spifi dma buffer upload
This commit is contained in:
parent
116a001fe0
commit
d0ad0a8eae
329
mik32_dma.py
Normal file
329
mik32_dma.py
Normal file
@ -0,0 +1,329 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, List
|
||||
import time
|
||||
from tclrpc import TclException
|
||||
from tclrpc import OpenOcdTclRpc
|
||||
|
||||
|
||||
# --------------------------
|
||||
# DMA register offset
|
||||
# --------------------------
|
||||
DMA_REGS_BASE_ADDRESS = 0x00040000
|
||||
|
||||
DMA_CONTROL = DMA_REGS_BASE_ADDRESS + 0x40
|
||||
|
||||
DMA_CHANNEL_SIZEOF = 0x4 * 4
|
||||
|
||||
|
||||
def DMA_CHANNEL_DESTINATION(i):
|
||||
return DMA_REGS_BASE_ADDRESS + i*DMA_CHANNEL_SIZEOF + 0x4*0
|
||||
|
||||
|
||||
def DMA_CHANNEL_SOURCE(i):
|
||||
return DMA_REGS_BASE_ADDRESS + i*DMA_CHANNEL_SIZEOF + 0x4*1
|
||||
|
||||
|
||||
def DMA_CHANNEL_LEN(i):
|
||||
return DMA_REGS_BASE_ADDRESS + i*DMA_CHANNEL_SIZEOF + 0x4*2
|
||||
|
||||
|
||||
def DMA_CHANNEL_CONFIG(i):
|
||||
return DMA_REGS_BASE_ADDRESS + i*DMA_CHANNEL_SIZEOF + 0x4*3
|
||||
|
||||
# --------------------------
|
||||
# DMA register fields
|
||||
# --------------------------
|
||||
|
||||
|
||||
DMA_CHANNEL_COUNT = 4
|
||||
|
||||
DMA_CHANNEL_M = ((1 << DMA_CHANNEL_COUNT) - 1)
|
||||
|
||||
# DMA_CONTROL
|
||||
|
||||
DMA_CONTROL_CLEAR_LOCAL_IRQ_S = 0
|
||||
DMA_CONTROL_CLEAR_LOCAL_IRQ_M = (
|
||||
DMA_CHANNEL_M << DMA_CONTROL_CLEAR_LOCAL_IRQ_S)
|
||||
|
||||
|
||||
def DMA_CONTROL_CLEAR_LOCAL_IRQ(i):
|
||||
return ((1 << (DMA_CONTROL_CLEAR_LOCAL_IRQ_S + (i))) & DMA_CONTROL_CLEAR_LOCAL_IRQ_M)
|
||||
|
||||
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_S = (DMA_CHANNEL_COUNT + 0)
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M = (1 << DMA_CONTROL_CLEAR_GLOBAL_IRQ_S)
|
||||
DMA_CONTROL_CLEAR_ERROR_IRQ_S = (DMA_CHANNEL_COUNT + 1)
|
||||
DMA_CONTROL_CLEAR_ERROR_IRQ_M = (1 << DMA_CONTROL_CLEAR_ERROR_IRQ_S)
|
||||
DMA_CONTROL_GLOBAL_IRQ_ENA_S = (DMA_CHANNEL_COUNT + 2)
|
||||
DMA_CONTROL_GLOBAL_IRQ_ENA_M = (1 << DMA_CONTROL_GLOBAL_IRQ_ENA_S)
|
||||
DMA_CONTROL_ERROR_IRQ_ENA_S = (DMA_CHANNEL_COUNT + 3)
|
||||
DMA_CONTROL_ERROR_IRQ_ENA_M = (1 << DMA_CONTROL_ERROR_IRQ_ENA_S)
|
||||
DMA_CONTROL_CURRENT_VALUE_S = (DMA_CHANNEL_COUNT + 4)
|
||||
DMA_CONTROL_CURRENT_VALUE_M = (1 << DMA_CONTROL_CURRENT_VALUE_S)
|
||||
|
||||
DMA_CFG_CH_ENABLE_S = 0
|
||||
DMA_CFG_CH_ENABLE_M = (1 << DMA_CFG_CH_ENABLE_S)
|
||||
DMA_CFG_CH_DISABLE_M = (0 << DMA_CFG_CH_ENABLE_S)
|
||||
|
||||
DMA_CFG_CH_PRIOR_S = 1
|
||||
DMA_CFG_CH_PRIOR_M = (0x3 << DMA_CFG_CH_PRIOR_S)
|
||||
|
||||
DMA_CFG_CH_READ_MODE_S = 3
|
||||
DMA_CFG_CH_READ_MODE_memory_M = (1 << DMA_CFG_CH_READ_MODE_S)
|
||||
DMA_CFG_CH_READ_MODE_periphery_M = (0 << DMA_CFG_CH_READ_MODE_S)
|
||||
|
||||
DMA_CFG_CH_WRITE_MODE_S = 4
|
||||
DMA_CFG_CH_WRITE_MODE_memory_M = (1 << DMA_CFG_CH_WRITE_MODE_S)
|
||||
DMA_CFG_CH_WRITE_MODE_periphery_M = (0 << DMA_CFG_CH_WRITE_MODE_S)
|
||||
|
||||
DMA_CFG_CH_READ_INCREMENT_S = 5
|
||||
DMA_CFG_CH_READ_INCREMENT_M = (1 << DMA_CFG_CH_READ_INCREMENT_S)
|
||||
DMA_CFG_CH_READ_no_INCREMENT_M = (0 << DMA_CFG_CH_READ_INCREMENT_S)
|
||||
|
||||
DMA_CFG_CH_READ_INCREMENT_S = 5
|
||||
DMA_CFG_CH_READ_INCREMENT_M = (1 << DMA_CFG_CH_READ_INCREMENT_S)
|
||||
DMA_CFG_CH_READ_no_INCREMENT_M = (0 << DMA_CFG_CH_READ_INCREMENT_S)
|
||||
|
||||
DMA_CFG_CH_WRITE_INCREMENT_S = 6
|
||||
DMA_CFG_CH_WRITE_INCREMENT_M = (1 << DMA_CFG_CH_WRITE_INCREMENT_S)
|
||||
DMA_CFG_CH_WRITE_no_INCREMENT_M = (0 << DMA_CFG_CH_WRITE_INCREMENT_S)
|
||||
|
||||
DMA_CFG_CH_READ_SIZE_S = 7
|
||||
DMA_CFG_CH_READ_SIZE_byte_M = (0B00 << DMA_CFG_CH_READ_SIZE_S) # байт
|
||||
DMA_CFG_CH_READ_SIZE_2byte_M = (0B01 << DMA_CFG_CH_READ_SIZE_S) # полуслово
|
||||
DMA_CFG_CH_READ_SIZE_4byte_M = (0B10 << DMA_CFG_CH_READ_SIZE_S) # слово
|
||||
DMA_CFG_CH_READ_SIZE_rez_M = (0B11 << DMA_CFG_CH_READ_SIZE_S) # резерв
|
||||
|
||||
DMA_CFG_CH_WRITE_SIZE_S = 9
|
||||
DMA_CFG_CH_WRITE_SIZE_byte_M = (0B00 << DMA_CFG_CH_WRITE_SIZE_S) # байт
|
||||
DMA_CFG_CH_WRITE_SIZE_2byte_M = (0B01 << DMA_CFG_CH_WRITE_SIZE_S) # полуслово
|
||||
DMA_CFG_CH_WRITE_SIZE_4byte_M = (0B10 << DMA_CFG_CH_WRITE_SIZE_S) # слово
|
||||
DMA_CFG_CH_WRITE_SIZE_rez_M = (0B11 << DMA_CFG_CH_WRITE_SIZE_S) # резерв
|
||||
|
||||
# Кол-во байт пакетной передачи: 2^Read_burst_size
|
||||
DMA_CFG_CH_READ_BURST_SIZE_S = 11
|
||||
# Кол-во байт пакетной передачи: 2^Write_burst_size
|
||||
DMA_CFG_CH_WRITE_BURST_SIZE_S = 14
|
||||
|
||||
DMA_CFG_CH_READ_REQ_S = 17 # выбор канала чтения
|
||||
DMA_CFG_CH_READ_REQ_M = (0xF << DMA_CFG_CH_READ_REQ_S)
|
||||
|
||||
|
||||
def DMA_CFG_CH_READ_REQ(v):
|
||||
return (((v) << DMA_CFG_CH_READ_REQ_S) & DMA_CFG_CH_READ_REQ_M)
|
||||
|
||||
|
||||
DMA_CFG_CH_WRITE_REQ_S = 21 # выбор канала записи
|
||||
DMA_CFG_CH_WRITE_REQ_M = (0xF << DMA_CFG_CH_WRITE_REQ_S)
|
||||
|
||||
|
||||
def DMA_CFG_CH_WRITE_REQ(v):
|
||||
return (((v) << DMA_CFG_CH_WRITE_REQ_S) & DMA_CFG_CH_WRITE_REQ_M)
|
||||
|
||||
|
||||
DMA_CFG_CH_ACK_READ_S = 25
|
||||
DMA_CFG_CH_ACK_READ_M = (1 << DMA_CFG_CH_ACK_READ_S)
|
||||
DMA_CFG_CH_ACK_WRITE_S = 26
|
||||
DMA_CFG_CH_ACK_WRITE_M = (1 << DMA_CFG_CH_ACK_WRITE_S)
|
||||
|
||||
DMA_STATUS_READY_S = 0
|
||||
|
||||
|
||||
# ReadStatus. Разрешить читать текущий статус канала
|
||||
class CurrentValue(Enum):
|
||||
ENABLE = 0 # Текущие значения
|
||||
DISABLE = 1 # Значения при настройке
|
||||
|
||||
|
||||
class ChannelIndex(Enum):
|
||||
CHANNEL_0 = 0
|
||||
CHANNEL_1 = 1
|
||||
CHANNEL_2 = 2
|
||||
CHANNEL_3 = 3
|
||||
|
||||
|
||||
class ChannelPriority(Enum):
|
||||
LOW = 0
|
||||
MEDIUM = 1
|
||||
HIGH = 2
|
||||
VERY_HIGH = 3
|
||||
|
||||
|
||||
class ChannelMode(Enum):
|
||||
PERIPHERY = 0
|
||||
MEMORY = 1
|
||||
|
||||
|
||||
class ChannelIncrement(Enum):
|
||||
DISABLE = 0
|
||||
ENABLE = 1
|
||||
|
||||
|
||||
class ChannelSize(Enum):
|
||||
BYTE = 0
|
||||
HALFWORD = 1
|
||||
WORD = 1
|
||||
|
||||
|
||||
class ChannelAck(Enum):
|
||||
DISABLE = 0
|
||||
ENABLE = 1
|
||||
|
||||
|
||||
class ChannelRequest(Enum):
|
||||
USART_0_REQUEST = 0
|
||||
USART_1_REQUEST = 1
|
||||
CRYPTO_REQUEST = 2
|
||||
SPI_0_REQUEST = 3
|
||||
SPI_1_REQUEST = 4
|
||||
I2C_0_REQUEST = 5
|
||||
I2C_1_REQUEST = 6
|
||||
SPIFI_REQUEST = 7
|
||||
TIMER32_1_REQUEST = 8
|
||||
TIMER32_2_REQUEST = 9
|
||||
TIMER32_0_REQUEST = 10
|
||||
|
||||
|
||||
class DMA_Channel:
|
||||
openocd: OpenOcdTclRpc
|
||||
|
||||
write_buffer: int = 0
|
||||
|
||||
channel: ChannelIndex
|
||||
priority: ChannelPriority
|
||||
|
||||
read_mode: ChannelMode
|
||||
read_increment: ChannelIncrement
|
||||
read_size: ChannelSize
|
||||
read_ack: ChannelAck
|
||||
read_burst_size: int
|
||||
read_request: ChannelRequest
|
||||
|
||||
write_mode: ChannelMode
|
||||
write_increment: ChannelIncrement
|
||||
write_size: ChannelSize
|
||||
write_ack: ChannelAck
|
||||
write_burst_size: int
|
||||
write_request: ChannelRequest
|
||||
|
||||
def __init__(self, openocd: OpenOcdTclRpc):
|
||||
self.openocd = openocd
|
||||
|
||||
def set_source(self, source: int):
|
||||
self.openocd.write_word(DMA_CHANNEL_SOURCE(1), source)
|
||||
|
||||
def set_destination(self, source: int):
|
||||
self.openocd.write_word(DMA_CHANNEL_DESTINATION(1), source)
|
||||
|
||||
def set_length(self, source: int):
|
||||
self.openocd.write_word(DMA_CHANNEL_LEN(1), source)
|
||||
|
||||
def set_config(self, source: int):
|
||||
self.openocd.write_word(DMA_CHANNEL_CONFIG(1), source)
|
||||
|
||||
def start(
|
||||
self,
|
||||
source_address: int,
|
||||
destination_address: int,
|
||||
length: int,
|
||||
):
|
||||
self.set_source(source_address)
|
||||
self.set_destination(destination_address)
|
||||
self.set_length(length)
|
||||
|
||||
self.write_buffer |= (DMA_CFG_CH_ENABLE_M
|
||||
| (self.priority.value << DMA_CFG_CH_PRIOR_S)
|
||||
| (self.read_mode.value << DMA_CFG_CH_READ_MODE_S)
|
||||
| (self.read_increment.value << DMA_CFG_CH_READ_INCREMENT_S)
|
||||
| (self.read_size.value << DMA_CFG_CH_READ_SIZE_S)
|
||||
| (self.read_burst_size << DMA_CFG_CH_READ_BURST_SIZE_S)
|
||||
| (self.read_request.value << DMA_CFG_CH_READ_REQ_S)
|
||||
| (self.read_ack.value << DMA_CFG_CH_ACK_READ_S)
|
||||
| (self.write_mode.value << DMA_CFG_CH_WRITE_MODE_S)
|
||||
| (self.write_increment.value << DMA_CFG_CH_WRITE_INCREMENT_S)
|
||||
| (self.write_size.value << DMA_CFG_CH_WRITE_SIZE_S)
|
||||
| (self.write_burst_size << DMA_CFG_CH_WRITE_BURST_SIZE_S)
|
||||
| (self.write_request.value << DMA_CFG_CH_WRITE_REQ_S)
|
||||
| (self.write_ack.value << DMA_CFG_CH_ACK_WRITE_S))
|
||||
|
||||
self.set_config(self.write_buffer)
|
||||
|
||||
|
||||
class DMA:
|
||||
openocd: OpenOcdTclRpc
|
||||
|
||||
current_value: CurrentValue = CurrentValue.ENABLE
|
||||
write_buffer: int = 0
|
||||
|
||||
channels: List[DMA_Channel] = []
|
||||
|
||||
def __init__(self, openocd: OpenOcdTclRpc):
|
||||
self.openocd = openocd
|
||||
self.channels.append(DMA_Channel(self.openocd))
|
||||
self.channels.append(DMA_Channel(self.openocd))
|
||||
self.channels.append(DMA_Channel(self.openocd))
|
||||
self.channels.append(DMA_Channel(self.openocd))
|
||||
|
||||
def init(self):
|
||||
self.current_value = CurrentValue.ENABLE
|
||||
|
||||
self.write_buffer = 0
|
||||
self.clear_irq()
|
||||
self.set_current_value(self.current_value)
|
||||
|
||||
def set_control(self, control: int):
|
||||
if (control > 2**32 or control < 0):
|
||||
raise ValueError
|
||||
|
||||
self.openocd.write_word(DMA_CONTROL, control)
|
||||
|
||||
def get_control(self) -> int:
|
||||
return self.openocd.read_word(DMA_CONTROL)
|
||||
|
||||
def clear_irq(self):
|
||||
self.clear_local_irq()
|
||||
self.clear_global_irq()
|
||||
self.clear_error_irq()
|
||||
|
||||
def clear_local_irq(self):
|
||||
self.write_buffer &= ~(DMA_CONTROL_CLEAR_LOCAL_IRQ_M |
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M | DMA_CONTROL_CLEAR_ERROR_IRQ_M)
|
||||
self.write_buffer |= DMA_CONTROL_CLEAR_LOCAL_IRQ_M
|
||||
self.set_control(self.write_buffer)
|
||||
self.write_buffer &= ~(DMA_CONTROL_CLEAR_LOCAL_IRQ_M |
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M | DMA_CONTROL_CLEAR_ERROR_IRQ_M)
|
||||
|
||||
def clear_global_irq(self):
|
||||
self.write_buffer &= ~(DMA_CONTROL_CLEAR_LOCAL_IRQ_M |
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M | DMA_CONTROL_CLEAR_ERROR_IRQ_M)
|
||||
self.write_buffer |= DMA_CONTROL_CLEAR_GLOBAL_IRQ_M
|
||||
self.set_control(self.write_buffer)
|
||||
self.write_buffer &= ~(DMA_CONTROL_CLEAR_LOCAL_IRQ_M |
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M | DMA_CONTROL_CLEAR_ERROR_IRQ_M)
|
||||
|
||||
def clear_error_irq(self):
|
||||
self.write_buffer &= ~(DMA_CONTROL_CLEAR_LOCAL_IRQ_M |
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M | DMA_CONTROL_CLEAR_ERROR_IRQ_M)
|
||||
self.write_buffer |= DMA_CONTROL_CLEAR_ERROR_IRQ_M
|
||||
self.set_control(self.write_buffer)
|
||||
self.write_buffer &= ~(DMA_CONTROL_CLEAR_LOCAL_IRQ_M |
|
||||
DMA_CONTROL_CLEAR_GLOBAL_IRQ_M | DMA_CONTROL_CLEAR_ERROR_IRQ_M)
|
||||
|
||||
def set_current_value(self, current_value: CurrentValue):
|
||||
self.current_value = current_value
|
||||
self.write_buffer &= ~(DMA_CONTROL_CURRENT_VALUE_M)
|
||||
self.write_buffer |= current_value.value << DMA_CONTROL_CURRENT_VALUE_S
|
||||
self.set_control(self.write_buffer)
|
||||
|
||||
def dma_wait(self, channel: DMA_Channel, timeout: float):
|
||||
channel_index = channel.channel.value
|
||||
mask = (1 << channel_index) << DMA_STATUS_READY_S
|
||||
|
||||
begin = time.perf_counter()
|
||||
|
||||
while (begin - time.perf_counter()) < timeout:
|
||||
if self.get_control() & mask != 0:
|
||||
return
|
||||
|
||||
raise Exception
|
||||
|
||||
153
mik32_spifi.py
153
mik32_spifi.py
@ -1,8 +1,9 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, List
|
||||
from typing import Dict, List, Union
|
||||
import time
|
||||
from tclrpc import TclException
|
||||
from tclrpc import OpenOcdTclRpc
|
||||
from mik32_dma import DMA, ChannelMode, ChannelIndex, ChannelAck, ChannelIncrement, ChannelPriority, ChannelRequest, ChannelSize
|
||||
|
||||
# --------------------------
|
||||
# PM register offset
|
||||
@ -220,6 +221,22 @@ def spifi_intrq_clear(openocd: OpenOcdTclRpc):
|
||||
SPIFI_CONFIG_STAT_INTRQ_M)
|
||||
|
||||
|
||||
INIT_DELAY = 0.001
|
||||
|
||||
|
||||
def spifi_init_periphery(openocd: OpenOcdTclRpc):
|
||||
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word(SPIFI_CONFIG_STAT) |
|
||||
# SPIFI_CONFIG_STAT_INTRQ_M |
|
||||
SPIFI_CONFIG_STAT_RESET_M)
|
||||
# openocd.write_word(SPIFI_CONFIG_CTRL, openocd.read_word(
|
||||
# SPIFI_CONFIG_CTRL) | (7 << SPIFI_CONFIG_CTRL_SCK_DIV_S))
|
||||
openocd.write_word(SPIFI_CONFIG_ADDR, 0x00)
|
||||
openocd.write_word(SPIFI_CONFIG_IDATA, 0x00)
|
||||
openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00)
|
||||
|
||||
time.sleep(INIT_DELAY)
|
||||
|
||||
|
||||
def spifi_init(openocd: OpenOcdTclRpc):
|
||||
print("MCU clock init", flush=True)
|
||||
|
||||
@ -228,6 +245,12 @@ def spifi_init(openocd: OpenOcdTclRpc):
|
||||
openocd.write_word(PM_BASE_ADDRESS + PM_Clk_APB_M_Set_OFFSET, 0xffffffff)
|
||||
openocd.write_word(PM_BASE_ADDRESS + PM_Clk_AHB_Set_OFFSET, 0xffffffff)
|
||||
|
||||
spifi_init_periphery(openocd)
|
||||
|
||||
time.sleep(INIT_DELAY)
|
||||
|
||||
|
||||
def spifi_init_memory(openocd: OpenOcdTclRpc):
|
||||
openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word(SPIFI_CONFIG_STAT) |
|
||||
SPIFI_CONFIG_STAT_INTRQ_M |
|
||||
SPIFI_CONFIG_STAT_RESET_M)
|
||||
@ -235,9 +258,13 @@ def spifi_init(openocd: OpenOcdTclRpc):
|
||||
# SPIFI_CONFIG_CTRL) | (7 << SPIFI_CONFIG_CTRL_SCK_DIV_S))
|
||||
openocd.write_word(SPIFI_CONFIG_ADDR, 0x00)
|
||||
openocd.write_word(SPIFI_CONFIG_IDATA, 0x00)
|
||||
openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00)
|
||||
|
||||
time.sleep(1)
|
||||
openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00)
|
||||
openocd.write_word(SPIFI_CONFIG_MCMD, (0 << SPIFI_CONFIG_MCMD_INTLEN_S) |
|
||||
(SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL << SPIFI_CONFIG_MCMD_FIELDFORM_S) |
|
||||
(SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR << SPIFI_CONFIG_MCMD_FRAMEFORM_S) |
|
||||
(0x03 << SPIFI_CONFIG_MCMD_OPCODE_S))
|
||||
|
||||
time.sleep(INIT_DELAY)
|
||||
|
||||
|
||||
def SPIFI_WaitIntrqTimeout(openocd: OpenOcdTclRpc, timeout: int) -> int:
|
||||
@ -289,8 +316,27 @@ def spifi_send_command(
|
||||
cache_limit=0,
|
||||
idata_length=0,
|
||||
direction=SPIFI_Direction.READ,
|
||||
data: List[int] = []
|
||||
data: List[int] = [],
|
||||
dma: Union[DMA, None] = None
|
||||
) -> List[int]:
|
||||
if dma is not None:
|
||||
control = openocd.read_word(SPIFI_CONFIG_CTRL)
|
||||
control |= SPIFI_CONFIG_CTRL_DMAEN_M
|
||||
openocd.write_word(SPIFI_CONFIG_CTRL, control)
|
||||
|
||||
# start_time = time.perf_counter()
|
||||
|
||||
openocd.write_memory(0x02003F00, 8, data)
|
||||
|
||||
# write_time = time.perf_counter() - start_time
|
||||
# print(f"write ram time {write_time:.2f}")
|
||||
|
||||
dma.channels[0].start(
|
||||
0x02003F00,
|
||||
SPIFI_CONFIG_DATA32,
|
||||
255
|
||||
)
|
||||
|
||||
openocd.write_word(SPIFI_CONFIG_ADDR, address)
|
||||
openocd.write_word(SPIFI_CONFIG_IDATA, idata)
|
||||
openocd.write_word(SPIFI_CONFIG_CLIMIT, cache_limit)
|
||||
@ -310,26 +356,23 @@ def spifi_send_command(
|
||||
return out_list
|
||||
|
||||
if direction == SPIFI_Direction.WRITE:
|
||||
start_time = time.perf_counter()
|
||||
# start_time = time.perf_counter()
|
||||
|
||||
openocd.write_memory(0x02003F00, 8, data)
|
||||
|
||||
write_time = time.perf_counter() - start_time
|
||||
print(f"write ram time {write_time:.2f}")
|
||||
|
||||
start_time = time.perf_counter()
|
||||
|
||||
if (byte_count % 4) == 0:
|
||||
for i in range(0, byte_count, 4):
|
||||
# openocd.write_word(SPIFI_CONFIG_DATA32, data[i+ByteAddress])
|
||||
openocd.write_memory(SPIFI_CONFIG_DATA32, 32, [data[i] + data[i+1] * 256 + data[i+2] * 256 * 256 + data[i+3] * 256 * 256 * 256])
|
||||
if dma is not None:
|
||||
dma.dma_wait(dma.channels[0], 0.1)
|
||||
else:
|
||||
for i in range(byte_count):
|
||||
openocd.write_memory(SPIFI_CONFIG_DATA32, 8, [data[i]])
|
||||
if (byte_count % 4) == 0:
|
||||
for i in range(0, byte_count, 4):
|
||||
# openocd.write_word(SPIFI_CONFIG_DATA32, data[i+ByteAddress])
|
||||
openocd.write_memory(SPIFI_CONFIG_DATA32, 32, [
|
||||
data[i] + data[i+1] * 256 + data[i+2] * 256 * 256 + data[i+3] * 256 * 256 * 256])
|
||||
else:
|
||||
for i in range(byte_count):
|
||||
openocd.write_memory(SPIFI_CONFIG_DATA32, 8, [data[i]])
|
||||
|
||||
# write_time = time.perf_counter() - start_time
|
||||
# print(f"write memory time {write_time:.2f}")
|
||||
|
||||
write_time = time.perf_counter() - start_time
|
||||
print(f"write memory time {write_time:.2f}")
|
||||
|
||||
return []
|
||||
|
||||
|
||||
@ -369,27 +412,47 @@ def spifi_sector_erase(openocd: OpenOcdTclRpc, address: int):
|
||||
def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int:
|
||||
read_data: List[int] = []
|
||||
|
||||
read_data = spifi_send_command(openocd, READ_DATA_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
|
||||
SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=address)
|
||||
spifi_init_memory(openocd)
|
||||
read_data = openocd.read_memory(0x80000000 + address, 8, 1)
|
||||
read_data = openocd.read_memory(0x80000000 + address, 8, 256)
|
||||
|
||||
# read_data = spifi_send_command(openocd, READ_DATA_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
|
||||
# SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=address)
|
||||
|
||||
for i in range(byte_count):
|
||||
if read_data[i] != bin_data[i]:
|
||||
print(
|
||||
f"DATA[{i+address}] = {read_data[i]:#0x} - ошибка", flush=True)
|
||||
f"DATA[{i+address}] = {read_data[i]:#0x} expect {bin_data[i]:#0x}", flush=True)
|
||||
|
||||
spifi_init_periphery(openocd)
|
||||
read_periph = spifi_send_command(openocd, READ_DATA_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
|
||||
SPIFI_Fieldform.ALL_SERIAL, byte_count=1, address=(i+address))
|
||||
print(
|
||||
f"DATA[{i+address}] = {read_periph[0]:#0x} expect {bin_data[i]:#0x}", flush=True)
|
||||
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def spifi_page_program(openocd: OpenOcdTclRpc, ByteAddress: int, data: List[int], byte_count: int, progress: str = ""):
|
||||
def spifi_page_program(
|
||||
openocd: OpenOcdTclRpc,
|
||||
ByteAddress: int,
|
||||
data: List[int],
|
||||
byte_count: int,
|
||||
progress: str = "",
|
||||
dma: Union[DMA, None] = None
|
||||
):
|
||||
print(f"Writing page {ByteAddress:#010x}... {progress}", flush=True)
|
||||
if byte_count > 256:
|
||||
raise Exception("Byte count more than 256")
|
||||
|
||||
spifi_init_periphery(openocd)
|
||||
|
||||
spifi_write_enable(openocd)
|
||||
spifi_send_command(openocd, PAGE_PROGRAM_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
|
||||
SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=ByteAddress,
|
||||
idata=0, cache_limit=0, direction=SPIFI_Direction.WRITE, data=data)
|
||||
idata=0, cache_limit=0, direction=SPIFI_Direction.WRITE, data=data, dma=dma)
|
||||
spifi_wait_busy(openocd)
|
||||
|
||||
|
||||
@ -495,6 +558,29 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_sp
|
||||
|
||||
openocd.halt()
|
||||
spifi_init(openocd)
|
||||
|
||||
dma = DMA(openocd)
|
||||
dma.init()
|
||||
|
||||
dma.channels[0].write_buffer = 0
|
||||
|
||||
dma.channels[0].channel = ChannelIndex.CHANNEL_0
|
||||
dma.channels[0].priority = ChannelPriority.VERY_HIGH
|
||||
|
||||
dma.channels[0].read_mode = ChannelMode.MEMORY
|
||||
dma.channels[0].read_increment = ChannelIncrement.ENABLE
|
||||
dma.channels[0].read_size = ChannelSize.BYTE
|
||||
dma.channels[0].read_burst_size = 0
|
||||
dma.channels[0].read_request = ChannelRequest.SPIFI_REQUEST
|
||||
dma.channels[0].read_ack = ChannelAck.DISABLE
|
||||
|
||||
dma.channels[0].write_mode = ChannelMode.PERIPHERY
|
||||
dma.channels[0].write_increment = ChannelIncrement.DISABLE
|
||||
dma.channels[0].write_size = ChannelSize.BYTE
|
||||
dma.channels[0].write_burst_size = 0
|
||||
dma.channels[0].write_request = ChannelRequest.SPIFI_REQUEST
|
||||
dma.channels[0].write_ack = ChannelAck.DISABLE
|
||||
|
||||
if use_chip_erase:
|
||||
spifi_erase(openocd, EraseType.CHIP_ERASE)
|
||||
else:
|
||||
@ -513,19 +599,22 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_sp
|
||||
for index, page_offset in enumerate(pages_offsets):
|
||||
page_bytes = pages[page_offset]
|
||||
|
||||
start_time = time.perf_counter()
|
||||
# start_time = time.perf_counter()
|
||||
|
||||
if (use_quad_spi):
|
||||
spifi_quad_page_program(
|
||||
openocd, page_offset, page_bytes, 256, f"{(index*100)//pages_offsets.__len__()}%")
|
||||
else:
|
||||
spifi_page_program(openocd, page_offset, page_bytes,
|
||||
256, f"{(index*100)//pages_offsets.__len__()}%")
|
||||
|
||||
page_program_time = time.perf_counter() - start_time
|
||||
print(f"page program time {page_program_time:.2f}")
|
||||
256, f"{(index*100)//pages_offsets.__len__()}%", dma=dma)
|
||||
|
||||
# page_program_time = time.perf_counter() - start_time
|
||||
# print(f"page program time {page_program_time:.2f}")
|
||||
|
||||
# start_time = time.perf_counter()
|
||||
result = spifi_read_data(openocd, page_offset, 256, page_bytes)
|
||||
# page_program_time = time.perf_counter() - start_time
|
||||
# print(f"page check time {page_program_time:.2f}")
|
||||
|
||||
if result == 1:
|
||||
print("Data error")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user