mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
bootloader: Add Alif port.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
parent
f5dd7de21a
commit
a90be859a5
164
src/boot/src/ports/alif/alif.ld.S
Normal file
164
src/boot/src/ports/alif/alif.ld.S
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// Entry Point
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
#include "omv_boardconfig.h"
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH_TEXT (rx) : ORIGIN = OMV_FLASH_ORIGIN, LENGTH = OMV_FLASH_LENGTH
|
||||
ITCM (rx) : ORIGIN = OMV_ITCM_ORIGIN, LENGTH = OMV_ITCM_LENGTH
|
||||
DTCM (rw) : ORIGIN = OMV_DTCM_ORIGIN, LENGTH = OMV_DTCM_LENGTH
|
||||
#if defined(OMV_SRAM0_ORIGIN)
|
||||
SRAM0 (rw) : ORIGIN = OMV_SRAM0_ORIGIN, LENGTH = OMV_SRAM0_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM1_ORIGIN)
|
||||
SRAM1 (rw) : ORIGIN = OMV_SRAM1_ORIGIN, LENGTH = OMV_SRAM1_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM6_A_ORIGIN)
|
||||
SRAM6_A (rw) : ORIGIN = OMV_SRAM6_A_ORIGIN, LENGTH = OMV_SRAM6_A_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM6_B_ORIGIN)
|
||||
SRAM6_B (rw) : ORIGIN = OMV_SRAM6_B_ORIGIN, LENGTH = OMV_SRAM6_B_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM7_ORIGIN)
|
||||
SRAM7 (rw) : ORIGIN = OMV_SRAM7_ORIGIN, LENGTH = OMV_SRAM7_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM8_ORIGIN)
|
||||
SRAM8 (rw) : ORIGIN = OMV_SRAM8_ORIGIN, LENGTH = OMV_SRAM8_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM9_A_ORIGIN)
|
||||
SRAM9_A (rw) : ORIGIN = OMV_SRAM9_A_ORIGIN, LENGTH = OMV_SRAM9_A_LENGTH
|
||||
#endif
|
||||
#if defined(OMV_SRAM9_B_ORIGIN)
|
||||
SRAM9_B (rw) : ORIGIN = OMV_SRAM9_B_ORIGIN, LENGTH = OMV_SRAM9_B_LENGTH
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : ALIGN(16)
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
. = ALIGN(4);
|
||||
*(.text*)
|
||||
. = ALIGN(4);
|
||||
*(.rodata*)
|
||||
. = ALIGN(16);
|
||||
} > FLASH_TEXT
|
||||
|
||||
.copy.table : ALIGN(4)
|
||||
{
|
||||
__copy_table_start__ = .;
|
||||
LONG ( LOADADDR(.data) )
|
||||
LONG ( ADDR(.data) )
|
||||
LONG ( SIZEOF(.data)/4 )
|
||||
__copy_table_end__ = .;
|
||||
. = ALIGN(16);
|
||||
} > FLASH_TEXT
|
||||
|
||||
.zero.table : ALIGN(4)
|
||||
{
|
||||
__zero_table_start__ = .;
|
||||
LONG (ADDR(.bss))
|
||||
LONG (SIZEOF(.bss)/4)
|
||||
LONG (ADDR(.bss.sram))
|
||||
LONG (SIZEOF(.bss.sram)/4)
|
||||
__zero_table_end__ = .;
|
||||
. = ALIGN(16);
|
||||
} > FLASH_TEXT
|
||||
|
||||
.data : ALIGN(8)
|
||||
{
|
||||
*(.data)
|
||||
. = ALIGN(8);
|
||||
*(.data.*)
|
||||
. = ALIGN(8);
|
||||
. = ALIGN(16);
|
||||
} > OMV_MAIN_MEMORY AT > FLASH_TEXT
|
||||
|
||||
/* Peripherals in expansion master 0 (such as USB, Ethernet, SD/MMC)
|
||||
are by default configured as non-secure, so they don't have access
|
||||
to DTCMs. This can be fixed in the ToC by allowing access to DTCMs
|
||||
to all bus masters, for now these peripherals should place buffers
|
||||
in regular SRAM */
|
||||
.bss.sram (NOLOAD) : ALIGN(16)
|
||||
{
|
||||
*(.bss.sram*)
|
||||
. = ALIGN(16);
|
||||
} > SRAM1
|
||||
|
||||
.bss : ALIGN(4)
|
||||
{
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
*(.bss.*)
|
||||
. = ALIGN(4);
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > OMV_MAIN_MEMORY
|
||||
|
||||
.init_fini_arrays : ALIGN(16)
|
||||
{
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
. = ALIGN(16);
|
||||
} > FLASH_TEXT
|
||||
|
||||
#include "common.ld.S"
|
||||
}
|
||||
67
src/boot/src/ports/alif/alif_flash.c
Normal file
67
src/boot/src/ports/alif/alif_flash.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* Alif Flash driver.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include ALIF_CMSIS_H
|
||||
|
||||
#include "omv_boardconfig.h"
|
||||
#include "omv_bootconfig.h"
|
||||
#include "mram.h"
|
||||
|
||||
#if OMV_BOOT_AXI_FLASH_ENABLE
|
||||
|
||||
int axi_flash_read(uint32_t addr, uint8_t *buf, size_t size) {
|
||||
memcpy(buf, (void *) addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int axi_flash_write(uint32_t addr, const uint8_t *buf, size_t size) {
|
||||
// Note TinyUSB buffers are aligned to a multiple of the MRAM sector size.
|
||||
if ((addr % MRAM_SECTOR_SIZE) || ((uint32_t) buf % MRAM_SECTOR_SIZE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Round up to multiple of the MRAM sector size.
|
||||
// Note TinyUSB buffers are much bigger than the MRAM sector size, so the
|
||||
// writes can be rounded up, and we can read more than the specified size.
|
||||
if (size % MRAM_SECTOR_SIZE) {
|
||||
size = (size + (MRAM_SECTOR_SIZE - 1)) & ~(MRAM_SECTOR_SIZE - 1);
|
||||
}
|
||||
|
||||
// Note writes must be 16 bytes aligned and a multiple of 16 bytes.
|
||||
for (size_t i = 0; i < size / sizeof(uint64_t); i += 2) {
|
||||
((volatile uint64_t *) addr)[i + 0] = ((volatile uint64_t *) buf)[i + 0];
|
||||
((volatile uint64_t *) addr)[i + 1] = ((volatile uint64_t *) buf)[i + 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // OMV_BOOT_AXI_FLASH_ENABLE
|
||||
524
src/boot/src/ports/alif/alif_ospi.c
Normal file
524
src/boot/src/ports/alif/alif_ospi.c
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* ALif OSPI driver.
|
||||
* Note this driver uses SPI mode, and should support any standard flash.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include ALIF_CMSIS_H
|
||||
#include "omv_boardconfig.h"
|
||||
#include "omv_bootconfig.h"
|
||||
|
||||
#if OMV_BOOT_SPI_FLASH_ENABLE
|
||||
#include "gpio.h"
|
||||
#include "pinconf.h"
|
||||
#include "ospi_private.h"
|
||||
|
||||
#define OSPI_INST_0BIT (0x00U)
|
||||
#define OSPI_INST_4BIT (0x01U)
|
||||
#define OSPI_INST_8BIT (0x02U)
|
||||
#define OSPI_INST_16BIT (0x03U)
|
||||
|
||||
#define OSPI_DFS_8BIT (0x07U)
|
||||
#define OSPI_DFS_16BIT (0x0FU)
|
||||
#define OSPI_DFS_32BIT (0x1FU)
|
||||
|
||||
#define OSPI_FRF_SINGLE (0x00U)
|
||||
#define OSPI_FRF_DUAL (0x01U)
|
||||
#define OSPI_FRF_QUAD (0x02U)
|
||||
#define OSPI_FRF_OCTAL (0x03U)
|
||||
|
||||
#define OSPI_ADDR_0BIT (0x00U)
|
||||
#define OSPI_ADDR_24BIT (0x06U)
|
||||
#define OSPI_ADDR_32BIT (0x08U)
|
||||
|
||||
#define OSPI_FIFO_SIZE (128) // 256 words
|
||||
#define OSPI_PAGE_SIZE (128)
|
||||
#define OSPI_SECTOR_SIZE (4096)
|
||||
#define OSPI_POLL_TIMEOUT (1000000)
|
||||
|
||||
#define OSPI_WRSR_COMMAND (0x01)
|
||||
#define OSPI_RDSR_COMMAND (0x05)
|
||||
#define OSPI_RDSR_DCYCLES (0)
|
||||
|
||||
#define OSPI_WRVL_COMMAND (0x81)
|
||||
#define OSPI_RDVL_COMMAND (0x85)
|
||||
|
||||
#define OSPI_WRNV_COMMAND (0xB1)
|
||||
#define OSPI_RDNV_COMMAND (0xB5)
|
||||
|
||||
#define OSPI_RDID_COMMAND (0x9F)
|
||||
#define OSPI_RDID_DCYCLES (0)
|
||||
|
||||
#define OSPI_READ_COMMAND (0x13)
|
||||
#define OSPI_READ_DCYCLES (0)
|
||||
|
||||
#define OSPI_WREN_COMMAND (0x06)
|
||||
#define OSPI_WRITE_COMMAND (0x12)
|
||||
|
||||
#define OSPI_ERASE_COMMAND (0x21)
|
||||
#define OSPI_ERASE_CHIP_COMMAND (0xC7)
|
||||
|
||||
typedef struct ospi_flash {
|
||||
uint8_t ddr_mode;
|
||||
uint8_t spi_mode;
|
||||
ssi_regs_t *regs;
|
||||
aes_regs_t *aes_regs;
|
||||
volatile void *xip_base;
|
||||
uint8_t initialized;
|
||||
bool bswap16;
|
||||
bool recovered;
|
||||
} ospi_flash_t;
|
||||
|
||||
static ospi_flash_t ospi = { 0 };
|
||||
|
||||
static void port_delay_ns(uint32_t ns) {
|
||||
for (size_t i = 0; i < (ns / 2.5); i++) {
|
||||
}
|
||||
}
|
||||
|
||||
static void ospi_setup(ospi_flash_t *ospi, uint32_t addr_len, uint32_t ndf, uint32_t wait_cycles) {
|
||||
ospi_writel(ospi, ser, 0);
|
||||
spi_disable(ospi);
|
||||
|
||||
uint32_t val = CTRLR0_IS_MST
|
||||
| (OSPI_DFS_8BIT << CTRLR0_DFS_OFFSET)
|
||||
| (OSPI_FRF_SINGLE << CTRLR0_SPI_FRF_OFFSET)
|
||||
| ((ndf ? SPI_TMOD_TR : TMOD_TO) << CTRLR0_TMOD_OFFSET);
|
||||
|
||||
ospi_writel(ospi, ctrlr0, val);
|
||||
ospi_writel(ospi, ctrlr1, (ndf ? (ndf - 1) : 0));
|
||||
|
||||
val = TRANS_TYPE_FRF_DEFINED
|
||||
| (1 << CTRLR0_SPI_RXDS_EN_OFFSET)
|
||||
| (addr_len << CTRLR0_ADDR_L_OFFSET)
|
||||
| (OSPI_INST_8BIT << CTRLR0_INST_L_OFFSET)
|
||||
| (wait_cycles << CTRLR0_WAIT_CYCLES_OFFSET);
|
||||
|
||||
ospi_writel(ospi, spi_ctrlr0, val);
|
||||
spi_enable(ospi);
|
||||
}
|
||||
|
||||
static inline void ospi_push(ospi_flash_t *ospi, uint32_t data) {
|
||||
ospi_writel(ospi, data_reg, data);
|
||||
}
|
||||
|
||||
static int ospi_flash_wait_busy(ospi_flash_t *ospi) {
|
||||
uint32_t timeout = OSPI_POLL_TIMEOUT;
|
||||
while ((ospi_readl(ospi, sr) & (SR_TF_EMPTY | SR_BUSY)) != SR_TF_EMPTY) {
|
||||
if (--timeout == 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_send(ospi_flash_t *ospi, uint32_t cmd, uint32_t addr_len,
|
||||
uint32_t addr, uint32_t data_len, const uint8_t *data) {
|
||||
ospi_setup(ospi, addr_len, 0, 0);
|
||||
ospi_push(ospi, cmd);
|
||||
|
||||
// Push the address (0, 24, or 32 bits).
|
||||
for (size_t i = 0; i < addr_len / 2; i++) {
|
||||
ospi_push(ospi, addr >> ((addr_len / 2 - 1) * 8 - i * 8));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data_len; i++) {
|
||||
ospi_push(ospi, data[i]);
|
||||
}
|
||||
|
||||
ospi_writel(ospi, ser, OMV_BOOT_OSPI_SER);
|
||||
return ospi_flash_wait_busy(ospi);
|
||||
}
|
||||
|
||||
static int ospi_recv(ospi_flash_t *ospi, uint32_t cmd, uint32_t addr_len,
|
||||
uint32_t addr, size_t data_len, uint8_t *data, uint32_t dcycles) {
|
||||
|
||||
ospi_setup(ospi, addr_len, data_len, dcycles);
|
||||
ospi_push(ospi, cmd);
|
||||
|
||||
// Push the address (0, 24, or 32 bits).
|
||||
for (size_t i = 0; i < addr_len / 2; i++) {
|
||||
ospi_push(ospi, addr >> ((addr_len / 2 - 1) * 8 - i * 8));
|
||||
}
|
||||
|
||||
// Push dummy bytes as many as the data size.
|
||||
for (size_t i = 0; i < data_len; i++) {
|
||||
ospi_push(ospi, 0x00);
|
||||
}
|
||||
|
||||
ospi_writel(ospi, ser, OMV_BOOT_OSPI_SER);
|
||||
|
||||
// Skip the command and address high-z bytes.
|
||||
uint32_t skip_len = addr_len / 2 + 1;
|
||||
|
||||
for (size_t i = 0; i < skip_len + data_len; i++) {
|
||||
unsigned int timeout = 100000;
|
||||
|
||||
while (ospi_readl(ospi, rxflr) == 0) {
|
||||
if (--timeout == 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < skip_len) {
|
||||
(void) ospi_readl(ospi, data_reg);
|
||||
} else {
|
||||
data[i - skip_len] = ospi_readl(ospi, data_reg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_flash_wait_sr(ospi_flash_t *ospi, uint8_t mask, uint8_t val, uint32_t timeout) {
|
||||
do {
|
||||
uint8_t sr;
|
||||
if (ospi_recv(ospi, OSPI_RDSR_COMMAND, OSPI_ADDR_0BIT, 0, 1, &sr, OSPI_RDSR_DCYCLES) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if ((sr & mask) == val) {
|
||||
return 0; // success
|
||||
}
|
||||
} while (timeout--);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ospi_flash_wait_wel1(ospi_flash_t *ospi) {
|
||||
return ospi_flash_wait_sr(ospi, 2, 2, OSPI_POLL_TIMEOUT);
|
||||
}
|
||||
|
||||
static int ospi_flash_wait_wip0(ospi_flash_t *ospi) {
|
||||
return ospi_flash_wait_sr(ospi, 1, 0, OSPI_POLL_TIMEOUT);
|
||||
}
|
||||
|
||||
static int ospi_flash_write_enable(ospi_flash_t *ospi) {
|
||||
ospi_send(ospi, OSPI_WREN_COMMAND, OSPI_ADDR_0BIT, 0, 0, NULL);
|
||||
return ospi_flash_wait_wel1(ospi);
|
||||
}
|
||||
|
||||
int ospi_flash_read_reg(ospi_flash_t *ospi, uint32_t cmd, uint32_t addr_len, uint32_t addr) {
|
||||
uint8_t buf;
|
||||
if (ospi_recv(ospi, cmd, addr_len, addr, 1, &buf, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ospi_flash_write_reg(ospi_flash_t *ospi, uint32_t cmd, uint32_t addr_len, uint32_t addr, uint8_t buf) {
|
||||
if (ospi_flash_write_enable(ospi) != 0 ||
|
||||
ospi_send(ospi, cmd, addr_len, addr, 1, &buf) != 0 ||
|
||||
ospi_flash_wait_wip0(ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_flash_chip_erase(ospi_flash_t *ospi, uint32_t value) {
|
||||
// Configure erase value
|
||||
uint32_t nv_reg = 0x7F | ((value & 1) << 7);
|
||||
if (ospi_flash_write_reg(ospi, OSPI_WRVL_COMMAND, OSPI_ADDR_24BIT, 0x08, nv_reg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (ospi_flash_write_enable(ospi) != 0 ||
|
||||
ospi_send(ospi, OSPI_ERASE_CHIP_COMMAND, OSPI_ADDR_0BIT, 0, 0, NULL) != 0 ||
|
||||
ospi_flash_wait_sr(ospi, 1, 0, 400000) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_flash_reset(ospi_flash_t *ospi) {
|
||||
port_pin_write(OMV_BOOT_OSPI_RST_PIN, 0);
|
||||
port_delay_ms(1);
|
||||
port_pin_write(OMV_BOOT_OSPI_RST_PIN, 1);
|
||||
port_delay_ms(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_flash_init(ospi_flash_t *ospi) {
|
||||
if (ospi->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Reset flash.
|
||||
ospi_flash_reset(ospi);
|
||||
|
||||
// Use SPI mode for initialization.
|
||||
ospi->spi_mode = true;
|
||||
ospi->regs = (ssi_regs_t *) OMV_BOOT_OSPI_SSI_BASE;
|
||||
ospi->aes_regs = (aes_regs_t *) OMV_BOOT_OSPI_AES_BASE;
|
||||
ospi->xip_base = (volatile void *) OMV_BOOT_OSPI_XIP_BASE;
|
||||
|
||||
// Initialize OSPI.
|
||||
spi_disable(ospi);
|
||||
ospi_writel(ospi, ser, 0);
|
||||
ospi_writel(ospi, rx_sample_dly, OMV_BOOT_OSPI_RX_DELAY);
|
||||
ospi_writel(ospi, txd_drive_edge, OMV_BOOT_OSPI_DDR_EDGE);
|
||||
ospi->aes_regs->aes_control &= ~AES_CONTROL_XIP_EN;
|
||||
ospi->aes_regs->aes_rxds_delay = OMV_BOOT_OSPI_RXDS_DELAY;
|
||||
spi_set_clk(ospi, (GetSystemAXIClock() / OMV_BOOT_OSPI_CLOCK));
|
||||
spi_enable(ospi);
|
||||
|
||||
// Detect onboard flash based on ID.
|
||||
uint8_t id[3] = { 0 };
|
||||
ospi_recv(ospi, OSPI_RDID_COMMAND, OSPI_ADDR_0BIT, 0, 3, id, OSPI_RDID_DCYCLES);
|
||||
// The byte order of 16-bit words is swapped when written in 1-1-1 and read back
|
||||
// in 8D-8D-8D. The MX chips seems to be the only one that doesn't swap 16-bit words.
|
||||
ospi->bswap16 = id[0] != 0xC2;
|
||||
ospi->initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_flash_deinit(ospi_flash_t *ospi) {
|
||||
if (ospi->regs) {
|
||||
spi_disable(ospi);
|
||||
spi_set_clk(ospi, 0);
|
||||
}
|
||||
ospi->initialized = false;
|
||||
|
||||
// Reset flash.
|
||||
return ospi_flash_reset(ospi);
|
||||
}
|
||||
|
||||
static int ospi_flash_erase(ospi_flash_t *ospi, uint32_t addr) {
|
||||
if (ospi_flash_write_enable(ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (ospi_send(ospi, OSPI_ERASE_COMMAND, OSPI_ADDR_32BIT, addr, 0, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return ospi_flash_wait_wip0(ospi);
|
||||
}
|
||||
|
||||
static int ospi_flash_read_page(ospi_flash_t *ospi, uint32_t addr, uint8_t *buf, uint32_t size) {
|
||||
return ospi_recv(ospi, OSPI_READ_COMMAND, OSPI_ADDR_32BIT, addr, size, buf, OSPI_READ_DCYCLES);
|
||||
}
|
||||
|
||||
static int ospi_flash_write_page(ospi_flash_t *ospi, uint32_t addr, const uint8_t *buf, uint32_t size) {
|
||||
if (ospi_flash_write_enable(ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (ospi_send(ospi, OSPI_WRITE_COMMAND, OSPI_ADDR_32BIT, addr, size, buf) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return ospi_flash_wait_wip0(ospi);
|
||||
}
|
||||
|
||||
int spi_flash_read(uint32_t addr, uint8_t *buf, uint32_t size) {
|
||||
if (ospi_flash_init(&ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size / OSPI_FIFO_SIZE; i++) {
|
||||
if (ospi_flash_read_page(&ospi, addr, buf, OSPI_FIFO_SIZE) != 0) {
|
||||
return -1;
|
||||
}
|
||||
buf += OSPI_FIFO_SIZE;
|
||||
addr += OSPI_FIFO_SIZE;
|
||||
}
|
||||
|
||||
if ((size % OSPI_FIFO_SIZE)) {
|
||||
return ospi_flash_read_page(&ospi, addr, buf, (size % OSPI_FIFO_SIZE));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_write(uint32_t addr, const uint8_t *buf, uint32_t size) {
|
||||
if (ospi_flash_init(&ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((addr % OSPI_SECTOR_SIZE) == 0) {
|
||||
if (ospi_flash_erase(&ospi, addr) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ospi.bswap16) {
|
||||
uint16_t *buf16 = (uint16_t *) buf;
|
||||
for (size_t i = 0; i < size / 2; i++) {
|
||||
buf16[i] = __REV16(buf16[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size / OSPI_PAGE_SIZE; i++) {
|
||||
if (ospi_flash_write_page(&ospi, addr, buf, OSPI_PAGE_SIZE) != 0) {
|
||||
return -1;
|
||||
}
|
||||
buf += OSPI_PAGE_SIZE;
|
||||
addr += OSPI_PAGE_SIZE;
|
||||
}
|
||||
|
||||
if ((size % OSPI_PAGE_SIZE)) {
|
||||
return ospi_flash_write_page(&ospi, addr, buf, (size % OSPI_PAGE_SIZE));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_recovery(uint32_t addr, const uint8_t *buf, uint32_t size) {
|
||||
static const uint8_t key[] = {
|
||||
0x15, 0x9e, 0x7d, 0x42, 0x96, 0x1a, 0x71, 0xeb,
|
||||
0x73, 0xa3, 0x26, 0x29, 0x2b, 0x08, 0x09, 0x0e,
|
||||
};
|
||||
|
||||
if (ospi.recovered) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check recovery key.
|
||||
if (size < 16 || memcmp(buf, key, sizeof(key))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Init flash.
|
||||
if (ospi_flash_init(&ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 1. Perform JESD reset
|
||||
const pin_t *cs = &omv_boot_pins[OMV_BOOT_OSPI_CS_PIN];
|
||||
pinconf_set(cs->port, cs->pin, OMV_BOOT_ALT_GPIO, cs->pad);
|
||||
port_pin_mode(OMV_BOOT_OSPI_CS_PIN, PIN_MODE_OUTPUT);
|
||||
port_pin_write(OMV_BOOT_OSPI_CS_PIN, 1);
|
||||
|
||||
const pin_t *d0 = &omv_boot_pins[OMV_BOOT_OSPI_D0_PIN];
|
||||
pinconf_set(d0->port, d0->pin, OMV_BOOT_ALT_GPIO, d0->pad);
|
||||
port_pin_mode(OMV_BOOT_OSPI_D0_PIN, PIN_MODE_OUTPUT);
|
||||
port_pin_write(OMV_BOOT_OSPI_D0_PIN, 0);
|
||||
|
||||
// Clock out 0, 1, 0, 1
|
||||
for (size_t i = 0, v = 1; i < 4; v ^= 1, i++) {
|
||||
port_pin_write(OMV_BOOT_OSPI_CS_PIN, 0);
|
||||
port_delay_ns(500);
|
||||
|
||||
port_pin_write(OMV_BOOT_OSPI_D0_PIN, v);
|
||||
|
||||
port_pin_write(OMV_BOOT_OSPI_CS_PIN, 1);
|
||||
port_delay_ns(500);
|
||||
}
|
||||
|
||||
// Revert pin state.
|
||||
pinconf_set(d0->port, d0->pin, d0->alt, d0->pad);
|
||||
pinconf_set(cs->port, cs->pin, cs->alt, cs->pad);
|
||||
|
||||
// 2.Write Enable. Write Opcode 0x06 to set WEL bit to 1
|
||||
if (ospi_flash_write_enable(&ospi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 4. DFIM entry
|
||||
if (ospi_flash_write_reg(&ospi, OSPI_WRVL_COMMAND, OSPI_ADDR_24BIT, 0x1E, 0x6B) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ospi_flash_read_reg(&ospi, OSPI_RDVL_COMMAND, OSPI_ADDR_24BIT, 0x1E) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
// 5.a Initialize status register to 0xFF
|
||||
if (ospi_flash_write_reg(&ospi, OSPI_WRSR_COMMAND, OSPI_ADDR_0BIT, 0x00, 0xFF) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 5.c Initialize status register to 0x00
|
||||
if (ospi_flash_write_reg(&ospi, OSPI_WRSR_COMMAND, OSPI_ADDR_0BIT, 0x00, 0x00) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 6.a Initialize NCRs (Command=0xB1; Addr=0x00 to 0x0C; Data=0x00)
|
||||
for (size_t addr = 0x00; addr <= 0x0C; addr++) {
|
||||
if (ospi_flash_write_reg(&ospi, 0xB1, OSPI_ADDR_24BIT, addr, 0x00) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 6.c Initialize NCRs (Command=0xB1; Addr=0x00 to 0x0C; Data=0x00)
|
||||
for (size_t addr = 0x00; addr <= 0x0C; addr++) {
|
||||
if (ospi_flash_write_reg(&ospi, 0xB1, OSPI_ADDR_24BIT, addr, 0xFF) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
// 7.a Disable lock: Command=0x81; Addr=0x08; Data=0xF9
|
||||
if (ospi_flash_write_reg(&ospi, 0x81, OSPI_ADDR_24BIT, 0x08, 0xF9) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 7.b Write 13: Command=0x42; Addr=0x00 to end (n=257); Data=0xFF
|
||||
for (size_t addr = 0; addr < 256; addr++) {
|
||||
if (ospi_flash_write_reg(&ospi, 0x42, OSPI_ADDR_24BIT, addr, 0xFF) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 8.a Disable lock: Command=0x81; Addr=0x08; Data=0xF9
|
||||
if (ospi_flash_write_reg(&ospi, 0x81, OSPI_ADDR_24BIT, 0x08, 0xF9) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 8.b Write 03: Command=0x42; Addr=0x00 to end (n=257); Data=0x00
|
||||
for (size_t addr = 0; addr < 256; addr++) {
|
||||
if (ospi_flash_write_reg(&ospi, 0x42, OSPI_ADDR_24BIT, addr, 0x00) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
// 9, 11 Write entire Device to 0
|
||||
if (ospi_flash_chip_erase(&ospi, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 10, 12 Write entire Device to 1
|
||||
if (ospi_flash_chip_erase(&ospi, 1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// DFIM exit
|
||||
if (ospi_flash_write_reg(&ospi, OSPI_WRVL_COMMAND, OSPI_ADDR_24BIT, 0x1E, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ospi.recovered = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_deinit() {
|
||||
return ospi_flash_deinit(&ospi);
|
||||
}
|
||||
#endif // OMV_BOOT_SPI_FLASH_ENABLE
|
||||
208
src/boot/src/ports/alif/alif_port.c
Normal file
208
src/boot/src/ports/alif/alif_port.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* DFU bootloader Alif port.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include ALIF_CMSIS_H
|
||||
#include "gpio.h"
|
||||
#include "pinconf.h"
|
||||
|
||||
#include "omv_boardconfig.h"
|
||||
#include "omv_bootconfig.h"
|
||||
#include "flash.h"
|
||||
#include "alif_services.h"
|
||||
|
||||
static volatile uint32_t ticks_ms;
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
ticks_ms += 1;
|
||||
}
|
||||
|
||||
int port_init(void) {
|
||||
// Initialize the MPU and configure
|
||||
// the default attributes and regions.
|
||||
port_mpu_init();
|
||||
|
||||
// Initialize the services API.
|
||||
alif_services_init();
|
||||
|
||||
// Initialize and configure SysTick.
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
|
||||
// Configure pin mux.
|
||||
for (size_t i = 0; i < OMV_BOOT_PINS_COUNT; i++) {
|
||||
const pin_t *pin = &omv_boot_pins[i];
|
||||
pinconf_set(pin->port, pin->pin, pin->alt, pin->pad);
|
||||
}
|
||||
|
||||
// Configure USB MUX GPIO.
|
||||
port_pin_mode(OMV_BOOT_MUX_PIN, PIN_MODE_OUTPUT);
|
||||
port_pin_write(OMV_BOOT_MUX_PIN, 1);
|
||||
|
||||
// Configure LED GPIO.
|
||||
port_pin_mode(OMV_BOOT_LED_PIN, PIN_MODE_OUTPUT);
|
||||
port_pin_write(OMV_BOOT_LED_PIN, 1);
|
||||
|
||||
// Configure OSPI reset GPIO.
|
||||
port_pin_mode(OMV_BOOT_OSPI_RST_PIN, PIN_MODE_OUTPUT);
|
||||
port_pin_write(OMV_BOOT_OSPI_RST_PIN, 0);
|
||||
|
||||
// Configure and enable USB IRQs.
|
||||
NVIC_ClearPendingIRQ(USB_IRQ_IRQn);
|
||||
NVIC_SetPriority(USB_IRQ_IRQn, OMV_BOOT_USB_IRQ_PRI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int port_deinit(void) {
|
||||
// Deinit DCD and disable USB IRQs.
|
||||
extern void dcd_uninit(void);
|
||||
dcd_uninit();
|
||||
|
||||
// Deinit services API.
|
||||
alif_services_deinit();
|
||||
|
||||
// Deinitialize SPI Flash.
|
||||
#if OMV_BOOT_SPI_FLASH_ENABLE
|
||||
spi_flash_deinit();
|
||||
#endif
|
||||
|
||||
// Disable SysTick and its IRQ.
|
||||
NVIC_DisableIRQ(SysTick_IRQn);
|
||||
NVIC_ClearPendingIRQ(SysTick_IRQn);
|
||||
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
|
||||
|
||||
// Clean/invalidate any cached lines.
|
||||
SCB_CleanInvalidateDCache();
|
||||
|
||||
// Clear default regions and configure XIP regions (if any).
|
||||
port_mpu_deinit();
|
||||
|
||||
// Turn off LED.
|
||||
gpio_set_value_high(omv_boot_pins[OMV_BOOT_LED_PIN].gpio, omv_boot_pins[OMV_BOOT_LED_PIN].pin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int port_get_uid(uint8_t *buf) {
|
||||
alif_services_get_unique_id(buf, 12);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void port_mpu_protect(const partition_t *p, bool enable) {
|
||||
if (p->region != -1) {
|
||||
ARM_MPU_Disable();
|
||||
MPU->RNR = p->region;
|
||||
MPU->RBAR = ARM_MPU_RBAR(p->start, ARM_MPU_SH_NON, enable & 1, 1, 0); // RO/NP/XN.
|
||||
MPU->RLAR = ARM_MPU_RLAR(p->limit - 1, p->attr);
|
||||
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t port_ticks_ms() {
|
||||
return ticks_ms;
|
||||
}
|
||||
|
||||
void port_delay_ms(uint32_t ms) {
|
||||
uint32_t start_ms = port_ticks_ms();
|
||||
while ((port_ticks_ms() - start_ms) < ms) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
void port_pin_mode(uint32_t pin, uint32_t mode) {
|
||||
if (mode == PIN_MODE_OUTPUT) {
|
||||
gpio_set_direction_output(omv_boot_pins[pin].gpio, omv_boot_pins[pin].pin);
|
||||
} else {
|
||||
gpio_set_direction_input(omv_boot_pins[pin].gpio, omv_boot_pins[pin].pin);
|
||||
}
|
||||
}
|
||||
|
||||
void port_pin_write(uint32_t pin, uint32_t state) {
|
||||
if (state) {
|
||||
gpio_set_value_high(omv_boot_pins[pin].gpio, omv_boot_pins[pin].pin);
|
||||
} else {
|
||||
gpio_set_value_low(omv_boot_pins[pin].gpio, omv_boot_pins[pin].pin);
|
||||
}
|
||||
}
|
||||
|
||||
void port_led_blink(uint32_t interval_ms) {
|
||||
static uint32_t start_ms = 0;
|
||||
static uint32_t led_state = 0;
|
||||
|
||||
if ((port_ticks_ms() - start_ms) < interval_ms) {
|
||||
return;
|
||||
}
|
||||
|
||||
led_state ^= 1;
|
||||
port_pin_write(OMV_BOOT_LED_PIN, led_state);
|
||||
start_ms += interval_ms;
|
||||
}
|
||||
|
||||
// Bypass startup MPU defaults.
|
||||
void MPU_Setup(void) {
|
||||
|
||||
}
|
||||
|
||||
// Bypass startup MPU regions.
|
||||
void MPU_Load_Regions(void) {
|
||||
|
||||
}
|
||||
|
||||
void port_mpu_load_defaults() {
|
||||
static const ARM_MPU_Region_t mpu_table[] __STARTUP_RO_DATA_ATTRIBUTE = {
|
||||
{ /* SRAM0 - 4MB : RO-0, NP-1, XN-0 */
|
||||
.RBAR = ARM_MPU_RBAR(0x02000000, ARM_MPU_SH_NON, 0, 1, 0),
|
||||
.RLAR = ARM_MPU_RLAR(0x023FFFFF, MEMATTR_NORMAL_RA)
|
||||
},
|
||||
{ /* SRAM1 - 2.5MB : RO-0, NP-1, XN-0 */
|
||||
.RBAR = ARM_MPU_RBAR(0x08000000, ARM_MPU_SH_NON, 0, 1, 0),
|
||||
.RLAR = ARM_MPU_RLAR(0x0827FFFF, MEMATTR_NORMAL_WB_RA_WA)
|
||||
},
|
||||
{ /* Host Peripherals - 16MB : RO-0, NP-1, XN-1 */
|
||||
.RBAR = ARM_MPU_RBAR(0x1A000000, ARM_MPU_SH_NON, 0, 1, 1),
|
||||
.RLAR = ARM_MPU_RLAR(0x1AFFFFFF, MEMATTR_DEVICE_nGnRE)
|
||||
},
|
||||
{ /* OSPI Regs - 16MB : RO-0, NP-1, XN-1 */
|
||||
.RBAR = ARM_MPU_RBAR(0x83000000, ARM_MPU_SH_NON, 0, 1, 1),
|
||||
.RLAR = ARM_MPU_RLAR(0x83FFFFFF, MEMATTR_DEVICE_nGnRE)
|
||||
},
|
||||
};
|
||||
|
||||
/* Load the regions from the table */
|
||||
ARM_MPU_Load(0, mpu_table, sizeof(mpu_table) / sizeof(ARM_MPU_Region_t));
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) __fatal_error(const char *msg) {
|
||||
while (1) {
|
||||
port_led_blink(50);
|
||||
}
|
||||
}
|
||||
192
src/boot/src/ports/alif/alif_port.mk
Normal file
192
src/boot/src/ports/alif/alif_port.mk
Normal file
@ -0,0 +1,192 @@
|
||||
# Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
#
|
||||
# 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. Any redistribution, use, or modification in source or binary form
|
||||
# is done solely for personal benefit and not for any commercial
|
||||
# purpose or for monetary gain. For commercial licensing options,
|
||||
# please contact openmv@openmv.io
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
# OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Include OpenMV board config first to set the port.
|
||||
include $(OMV_BOARD_CONFIG_DIR)/omv_boardconfig.mk
|
||||
|
||||
LDSCRIPT ?= alif
|
||||
BUILD := $(BUILD)/bootloader
|
||||
FIRMWARE := bootloader
|
||||
CMSIS_MCU_H := '<system_utils.h>'
|
||||
|
||||
# Compiler Flags
|
||||
CFLAGS += -std=gnu99 \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-Warray-bounds \
|
||||
-nostartfiles \
|
||||
-fdata-sections \
|
||||
-ffunction-sections \
|
||||
-fno-inline-small-functions \
|
||||
-mfloat-abi=hard \
|
||||
-mthumb \
|
||||
-mcpu=$(CPU) \
|
||||
-mtune=$(CPU) \
|
||||
-mfpu=$(FPU) \
|
||||
-march=armv8.1-m.main+fp+mve.fp \
|
||||
-fsingle-precision-constant \
|
||||
-Wdouble-promotion
|
||||
|
||||
CFLAGS += -D__VFP_FP__ \
|
||||
-D$(TARGET) \
|
||||
-D$(MCU_CORE) \
|
||||
-DCORE_$(MCU_CORE)=1 \
|
||||
-D$(ARM_MATH) \
|
||||
-DARM_NN_TRUNCATE \
|
||||
-DETHOS_U \
|
||||
-DPINS_AF_H=$(PINS_AF_H) \
|
||||
-DCMSIS_MCU_H=$(CMSIS_MCU_H) \
|
||||
-DALIF_CMSIS_H=$(CMSIS_MCU_H) \
|
||||
-DBOOTLOADER=1 \
|
||||
-DOMV_NOSYS_STUBS_ENABLE=1 \
|
||||
-DTUSB_ALIF_NO_IRQ_CFG \
|
||||
-DOMV_BOOT_JUMP=$(OMV_FIRM_ADDR) \
|
||||
$(OMV_BOOT_CFLAGS) \
|
||||
$(OMV_BOARD_CFLAGS)
|
||||
|
||||
CFLAGS += -I$(OMV_BOARD_CONFIG_DIR) \
|
||||
-I$(TOP_DIR)/$(BOOT_DIR)/include \
|
||||
-I$(TOP_DIR)/$(BOOT_DIR)/$(PORT_DIR) \
|
||||
-I$(TOP_DIR)/$(CMSIS_DIR)/include \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/drivers/include \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/ospi_xip/source/ospi \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/se_services/include \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/Device/common/config \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/Device/common/include \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/Device/core/$(MCU_CORE)/config \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/Device/core/$(MCU_CORE)/include \
|
||||
-I$(TOP_DIR)/$(HAL_DIR)/Device/$(MCU_SERIES)/$(MCU_VARIANT) \
|
||||
-I$(TOP_DIR)/$(TINYUSB_DIR)/src
|
||||
|
||||
# Linker Flags
|
||||
LDFLAGS = -mthumb \
|
||||
-mcpu=$(CPU) \
|
||||
-mfpu=$(FPU) \
|
||||
-mfloat-abi=hard \
|
||||
-mabi=aapcs-linux \
|
||||
-Wl,--print-memory-usage \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,--no-warn-rwx-segment \
|
||||
-Wl,-Map=$(BUILD)/$(FIRMWARE).map \
|
||||
-Wl,-T$(BUILD)/$(LDSCRIPT).lds
|
||||
|
||||
SRC_C += $(addprefix src/common/, \
|
||||
dfu.c \
|
||||
mpu.c \
|
||||
desc.c \
|
||||
main.c \
|
||||
)
|
||||
|
||||
SRC_C += $(addprefix $(PORT_DIR)/, \
|
||||
alif_ospi.c \
|
||||
alif_port.c \
|
||||
alif_flash.c \
|
||||
alif_services.c \
|
||||
)
|
||||
|
||||
SRC_C += $(addprefix $(OMV_COMMON_DIR)/, \
|
||||
nosys_stubs.c \
|
||||
)
|
||||
|
||||
SRC_C += $(addprefix $(TINYUSB_DIR)/, \
|
||||
src/tusb.c \
|
||||
src/class/dfu/dfu_device.c \
|
||||
src/common/tusb_fifo.c \
|
||||
src/device/usbd.c \
|
||||
src/device/usbd_control.c \
|
||||
)
|
||||
|
||||
SRC_C += $(addprefix $(HAL_DIR)/, \
|
||||
drivers/source/pinconf.c \
|
||||
drivers/source/mhu_driver.c \
|
||||
drivers/source/mhu_receiver.c \
|
||||
drivers/source/mhu_sender.c \
|
||||
Device/common/source/clk.c \
|
||||
Device/common/source/dcd.c \
|
||||
Device/common/source/mpu_M55.c \
|
||||
Device/common/source/tgu_M55.c \
|
||||
Device/common/source/system_M55.c \
|
||||
Device/common/source/system_utils.c \
|
||||
Device/common/source/tcm_partition.c \
|
||||
Device/core/$(MCU_CORE)/source/startup_$(MCU_CORE).c \
|
||||
se_services/source/services_host_clocks.c \
|
||||
se_services/source/services_host_handler.c \
|
||||
se_services/source/services_host_power.c \
|
||||
se_services/source/services_host_system.c \
|
||||
se_services/source/services_host_maintenance.c \
|
||||
)
|
||||
|
||||
# Firmware objects
|
||||
OBJS += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJS += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJS_DIR = $(sort $(dir $(OBJS)))
|
||||
|
||||
$(BUILD)/$(HAL_DIR)/se_services/source/services_host_boot.o: override CFLAGS += -Wno-stringop-truncation
|
||||
$(BUILD)/$(HAL_DIR)/se_services/source/services_host_system.o: override CFLAGS += -Wno-maybe-uninitialized
|
||||
|
||||
all: $(FIRMWARE)
|
||||
$(SIZE) $(FW_DIR)/$(FIRMWARE).elf
|
||||
|
||||
$(OBJS_DIR):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
$(BUILD)/%.o : %.c
|
||||
$(ECHO) "CC $<"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(BUILD)/$(HAL_DIR)/%.o : $(TOP_DIR)/$(HAL_DIR)/%.c
|
||||
$(ECHO) "CC $(shell realpath --relative-to=pwd $<)"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(BUILD)/$(TINYUSB_DIR)/%.o : $(TOP_DIR)/$(TINYUSB_DIR)/%.c
|
||||
$(ECHO) "CC $(shell realpath --relative-to=pwd $<)"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(BUILD)/$(OMV_COMMON_DIR)/%.o : $(TOP_DIR)/$(OMV_COMMON_DIR)/%.c
|
||||
$(ECHO) "CC $(shell realpath --relative-to=pwd $<)"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(BUILD)/%.o : %.s
|
||||
$(ECHO) "AS $<"
|
||||
$(AS) $(AFLAGS) $< -o $@
|
||||
|
||||
FIRMWARE_OBJS: | $(OBJS_DIR) $(OBJS)
|
||||
|
||||
$(FIRMWARE): FIRMWARE_OBJS
|
||||
$(CPP) -P -E -DBOOTLOADER -DLINKER_SCRIPT -DCORE_$(MCU_CORE) -I$(OMV_COMMON_DIR) \
|
||||
-I$(OMV_BOARD_CONFIG_DIR) $(PORT_DIR)/$(LDSCRIPT).ld.S > $(BUILD)/$(LDSCRIPT).lds
|
||||
$(CC) $(LDFLAGS) $(OBJS) -o $(FW_DIR)/$(FIRMWARE).elf
|
||||
$(OBJCOPY) -Obinary $(FW_DIR)/$(FIRMWARE).elf $(FW_DIR)/$(FIRMWARE).bin
|
||||
BIN_SIZE=$$(stat -c%s "$(FW_DIR)/$(FIRMWARE).bin"); \
|
||||
PADDED_SIZE=$$(( (BIN_SIZE + 15) / 16 * 16 )); \
|
||||
if [ $$BIN_SIZE -lt $$PADDED_SIZE ]; then \
|
||||
dd if=/dev/zero bs=1 count=$$((PADDED_SIZE - BIN_SIZE)) >> $(FW_DIR)/$(FIRMWARE).bin; \
|
||||
fi
|
||||
|
||||
-include $(OBJS:%.o=%.d)
|
||||
153
src/boot/src/ports/alif/alif_services.c
Normal file
153
src/boot/src/ports/alif/alif_services.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2025 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* SE services helper functions.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include ALIF_CMSIS_H
|
||||
#include "alif_services.h"
|
||||
#include "services_lib_bare_metal.h"
|
||||
|
||||
// MHU indices.
|
||||
#define MHU_M55_SE_MHU0 0
|
||||
#define MAX_MHU 1
|
||||
|
||||
extern void __fatal_error(const char *msg);
|
||||
|
||||
static uint32_t se_handle;
|
||||
static uint32_t se_buffer[SERVICES_MAX_PACKET_BUFFER_SIZE / sizeof(uint32_t)];
|
||||
static mhu_driver_out_t mhu_driver_out;
|
||||
|
||||
static const uint32_t mhu_sender_base_address_list[MAX_MHU] = {
|
||||
MHU_SESS_S_TX_BASE,
|
||||
};
|
||||
|
||||
static const uint32_t mhu_receiver_base_address_list[MAX_MHU] = {
|
||||
MHU_SESS_S_RX_BASE,
|
||||
};
|
||||
|
||||
void MHU_SESS_S_TX_IRQHandler(void) {
|
||||
mhu_driver_out.sender_irq_handler(MHU_M55_SE_MHU0);
|
||||
}
|
||||
|
||||
void MHU_SESS_S_RX_IRQHandler(void) {
|
||||
mhu_driver_out.receiver_irq_handler(MHU_M55_SE_MHU0);
|
||||
}
|
||||
|
||||
static int dummy_printf(const char *fmt, ...) {
|
||||
(void) fmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void alif_services_init(void) {
|
||||
// Initialize MHU.
|
||||
mhu_driver_in_t mhu_driver_in = {
|
||||
.sender_base_address_list = (uint32_t *) mhu_sender_base_address_list,
|
||||
.receiver_base_address_list = (uint32_t *) mhu_receiver_base_address_list,
|
||||
.mhu_count = MAX_MHU,
|
||||
.send_msg_acked_callback = SERVICES_send_msg_acked_callback,
|
||||
.rx_msg_callback = SERVICES_rx_msg_callback,
|
||||
.debug_print = NULL, // not currently used by MHU_driver_initialize
|
||||
};
|
||||
MHU_driver_initialize(&mhu_driver_in, &mhu_driver_out);
|
||||
|
||||
// Initialize SE services.
|
||||
services_lib_t services_init_params = {
|
||||
.packet_buffer_address = (uint32_t) se_buffer,
|
||||
.fn_send_mhu_message = mhu_driver_out.send_message,
|
||||
.fn_wait_ms = NULL, // not currently used by services_host_handler.c
|
||||
.wait_timeout = 1000000,
|
||||
.fn_print_msg = dummy_printf,
|
||||
};
|
||||
SERVICES_initialize(&services_init_params);
|
||||
|
||||
// Create SE services channel for sending requests.
|
||||
se_handle = SERVICES_register_channel(MHU_M55_SE_MHU0, 0);
|
||||
|
||||
// Enable MHU RX IRQ.
|
||||
NVIC_SetPriority(MHU_SESS_S_RX_IRQ_IRQn, 0);
|
||||
NVIC_ClearPendingIRQ(MHU_SESS_S_RX_IRQ_IRQn);
|
||||
NVIC_EnableIRQ(MHU_SESS_S_RX_IRQ_IRQn);
|
||||
|
||||
// Enable MHU TX IRQ.
|
||||
NVIC_SetPriority(MHU_SESS_S_TX_IRQ_IRQn, 0);
|
||||
NVIC_ClearPendingIRQ(MHU_SESS_S_TX_IRQ_IRQn);
|
||||
NVIC_EnableIRQ(MHU_SESS_S_TX_IRQ_IRQn);
|
||||
|
||||
// Send heartbeat services requests until one succeeds.
|
||||
SERVICES_synchronize_with_se(se_handle);
|
||||
|
||||
// Set default run profile
|
||||
run_profile_t run_profile = {
|
||||
.dcdc_mode = DCDC_MODE_PWM,
|
||||
.dcdc_voltage = DCDC_VOUT_0825,
|
||||
.aon_clk_src = CLK_SRC_LFXO,
|
||||
.run_clk_src = CLK_SRC_PLL,
|
||||
#if CORE_M55_HP
|
||||
.cpu_clk_freq = CLOCK_FREQUENCY_400MHZ,
|
||||
#else
|
||||
.cpu_clk_freq = CLOCK_FREQUENCY_160MHZ,
|
||||
#endif
|
||||
.scaled_clk_freq = SCALED_FREQ_XO_HIGH_DIV_38_4_MHZ,
|
||||
.power_domains = PD_VBAT_AON_MASK | PD_SSE700_AON_MASK | PD_SYST_MASK |
|
||||
PD_DBSS_MASK | PD_SESS_MASK | PD_SRAMS_MASK | PD_SRAM_CTRL_AON_MASK,
|
||||
.memory_blocks = SERAM_MASK | SRAM0_MASK | SRAM1_MASK | MRAM_MASK | BACKUP4K_MASK,
|
||||
.ip_clock_gating = OSPI_1_MASK | USB_MASK | LP_PERIPH_MASK,
|
||||
.phy_pwr_gating = LDO_PHY_MASK | USB_PHY_MASK,
|
||||
.vdd_ioflex_3V3 = IOFLEX_LEVEL_3V3,
|
||||
};
|
||||
|
||||
uint32_t error;
|
||||
SERVICES_set_run_cfg(se_handle, &run_profile, &error);
|
||||
if (error) {
|
||||
__fatal_error("SERVICES_set_run_cfg");
|
||||
}
|
||||
}
|
||||
|
||||
void alif_services_deinit(void) {
|
||||
// Disable MHU RX IRQ.
|
||||
NVIC_DisableIRQ(MHU_SESS_S_RX_IRQ_IRQn);
|
||||
NVIC_ClearPendingIRQ(MHU_SESS_S_RX_IRQ_IRQn);
|
||||
|
||||
// Disable MHU TX IRQ.
|
||||
NVIC_DisableIRQ(MHU_SESS_S_TX_IRQ_IRQn);
|
||||
NVIC_ClearPendingIRQ(MHU_SESS_S_TX_IRQ_IRQn);
|
||||
}
|
||||
|
||||
void alif_services_get_unique_id(uint8_t *id, size_t len) {
|
||||
uint32_t error;
|
||||
SERVICES_version_data_t data = { 0 };
|
||||
SERVICES_system_get_device_data(se_handle, &data, &error);
|
||||
if (error == 0) {
|
||||
memcpy(id, data.MfgData, len);
|
||||
}
|
||||
}
|
||||
38
src/boot/src/ports/alif/alif_services.h
Normal file
38
src/boot/src/ports/alif/alif_services.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2025 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* SE services helper functions.
|
||||
*/
|
||||
#ifndef __ALIF_PORT_SE_H__
|
||||
#define __ALIF_PORT_SE_H__
|
||||
void alif_services_init(void);
|
||||
void alif_services_deinit(void);
|
||||
void alif_services_get_unique_id(uint8_t *id, size_t len);
|
||||
#endif // __ALIF_PORT_SE_H__
|
||||
52
src/boot/src/ports/alif/tusb_config.h
Normal file
52
src/boot/src/ports/alif/tusb_config.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 OpenMV, LLC.
|
||||
*
|
||||
* 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. Any redistribution, use, or modification in source or binary form
|
||||
* is done solely for personal benefit and not for any commercial
|
||||
* purpose or for monetary gain. For commercial licensing options,
|
||||
* please contact openmv@openmv.io
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "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 LICENSOR OR COPYRIGHT
|
||||
* OWNER 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.
|
||||
*
|
||||
* TinyUSB config.
|
||||
*/
|
||||
#ifndef __ALIF_TUSB_CONFIG_H__
|
||||
#define __ALIF_TUSB_CONFIG_H__
|
||||
// Common configuration
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_MCU OPT_MCU_NONE
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define TUP_DCD_ENDPOINT_MAX (8)
|
||||
|
||||
// Device stack configuration.
|
||||
#define CFG_TUD_ENABLED (1)
|
||||
#define CFG_TUD_DFU (1)
|
||||
#define CFG_TUD_ENDPOINT0_SIZE (64)
|
||||
#define CFG_TUD_DFU_XFER_BUFSIZE (4096)
|
||||
|
||||
// Peripherals in expansion master 0 (such as USB, Ethernet, SD/MMC)
|
||||
// are by default configured as non-secure, so they don't have access
|
||||
// to DTCMs. These peripherals should place buffers in regular SRAM.
|
||||
#define CFG_TUSB_MEM_SECTION __attribute__((section(".bss.sram0")))
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(256)))
|
||||
#endif //__ALIF_TUSB_CONFIG_H__
|
||||
Loading…
Reference in New Issue
Block a user