spifi dma buffer upload

This commit is contained in:
Sergey Shchelkanov 2023-07-26 18:07:48 +03:00
parent 116a001fe0
commit d0ad0a8eae
2 changed files with 450 additions and 32 deletions

329
mik32_dma.py Normal file
View 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

View File

@ -1,8 +1,9 @@
from enum import Enum from enum import Enum
from typing import Dict, List from typing import Dict, List, Union
import time import time
from tclrpc import TclException from tclrpc import TclException
from tclrpc import OpenOcdTclRpc from tclrpc import OpenOcdTclRpc
from mik32_dma import DMA, ChannelMode, ChannelIndex, ChannelAck, ChannelIncrement, ChannelPriority, ChannelRequest, ChannelSize
# -------------------------- # --------------------------
# PM register offset # PM register offset
@ -220,6 +221,22 @@ def spifi_intrq_clear(openocd: OpenOcdTclRpc):
SPIFI_CONFIG_STAT_INTRQ_M) 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): def spifi_init(openocd: OpenOcdTclRpc):
print("MCU clock init", flush=True) 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_APB_M_Set_OFFSET, 0xffffffff)
openocd.write_word(PM_BASE_ADDRESS + PM_Clk_AHB_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) | openocd.write_word(SPIFI_CONFIG_STAT, openocd.read_word(SPIFI_CONFIG_STAT) |
SPIFI_CONFIG_STAT_INTRQ_M | SPIFI_CONFIG_STAT_INTRQ_M |
SPIFI_CONFIG_STAT_RESET_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)) # SPIFI_CONFIG_CTRL) | (7 << SPIFI_CONFIG_CTRL_SCK_DIV_S))
openocd.write_word(SPIFI_CONFIG_ADDR, 0x00) openocd.write_word(SPIFI_CONFIG_ADDR, 0x00)
openocd.write_word(SPIFI_CONFIG_IDATA, 0x00) openocd.write_word(SPIFI_CONFIG_IDATA, 0x00)
openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00) openocd.write_word(SPIFI_CONFIG_CLIMIT, 0x00)
openocd.write_word(SPIFI_CONFIG_MCMD, (0 << SPIFI_CONFIG_MCMD_INTLEN_S) |
time.sleep(1) (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: def SPIFI_WaitIntrqTimeout(openocd: OpenOcdTclRpc, timeout: int) -> int:
@ -289,8 +316,27 @@ def spifi_send_command(
cache_limit=0, cache_limit=0,
idata_length=0, idata_length=0,
direction=SPIFI_Direction.READ, direction=SPIFI_Direction.READ,
data: List[int] = [] data: List[int] = [],
dma: Union[DMA, None] = None
) -> List[int]: ) -> 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_ADDR, address)
openocd.write_word(SPIFI_CONFIG_IDATA, idata) openocd.write_word(SPIFI_CONFIG_IDATA, idata)
openocd.write_word(SPIFI_CONFIG_CLIMIT, cache_limit) openocd.write_word(SPIFI_CONFIG_CLIMIT, cache_limit)
@ -310,26 +356,23 @@ def spifi_send_command(
return out_list return out_list
if direction == SPIFI_Direction.WRITE: if direction == SPIFI_Direction.WRITE:
start_time = time.perf_counter() # start_time = time.perf_counter()
openocd.write_memory(0x02003F00, 8, data) if dma is not None:
dma.dma_wait(dma.channels[0], 0.1)
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])
else: else:
for i in range(byte_count): if (byte_count % 4) == 0:
openocd.write_memory(SPIFI_CONFIG_DATA32, 8, [data[i]]) 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 [] 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: def spifi_read_data(openocd: OpenOcdTclRpc, address: int, byte_count: int, bin_data: List[int]) -> int:
read_data: List[int] = [] read_data: List[int] = []
read_data = spifi_send_command(openocd, READ_DATA_COMMAND, SPIFI_Frameform.OPCODE_3ADDR, spifi_init_memory(openocd)
SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=address) 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): for i in range(byte_count):
if read_data[i] != bin_data[i]: if read_data[i] != bin_data[i]:
print( 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 1
return 0 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) print(f"Writing page {ByteAddress:#010x}... {progress}", flush=True)
if byte_count > 256: if byte_count > 256:
raise Exception("Byte count more than 256") raise Exception("Byte count more than 256")
spifi_init_periphery(openocd)
spifi_write_enable(openocd) spifi_write_enable(openocd)
spifi_send_command(openocd, PAGE_PROGRAM_COMMAND, SPIFI_Frameform.OPCODE_3ADDR, spifi_send_command(openocd, PAGE_PROGRAM_COMMAND, SPIFI_Frameform.OPCODE_3ADDR,
SPIFI_Fieldform.ALL_SERIAL, byte_count=byte_count, address=ByteAddress, 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) spifi_wait_busy(openocd)
@ -495,6 +558,29 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_sp
openocd.halt() openocd.halt()
spifi_init(openocd) 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: if use_chip_erase:
spifi_erase(openocd, EraseType.CHIP_ERASE) spifi_erase(openocd, EraseType.CHIP_ERASE)
else: 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): for index, page_offset in enumerate(pages_offsets):
page_bytes = pages[page_offset] page_bytes = pages[page_offset]
start_time = time.perf_counter() # start_time = time.perf_counter()
if (use_quad_spi): if (use_quad_spi):
spifi_quad_page_program( spifi_quad_page_program(
openocd, page_offset, page_bytes, 256, f"{(index*100)//pages_offsets.__len__()}%") openocd, page_offset, page_bytes, 256, f"{(index*100)//pages_offsets.__len__()}%")
else: else:
spifi_page_program(openocd, page_offset, page_bytes, spifi_page_program(openocd, page_offset, page_bytes,
256, f"{(index*100)//pages_offsets.__len__()}%") 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}")
# 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) 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: if result == 1:
print("Data error") print("Data error")