238 lines
5.5 KiB
C
238 lines
5.5 KiB
C
#include "system/includes.h"
|
|
#include "asm/includes.h"
|
|
#include "asm/sh50_isp.h"
|
|
|
|
|
|
|
|
const char log_tag_const_v_ISP = 0;
|
|
const char log_tag_const_i_ISP = 0;
|
|
const char log_tag_const_d_ISP = 0;
|
|
const char log_tag_const_w_ISP = 0;
|
|
const char log_tag_const_e_ISP = 0;
|
|
|
|
|
|
|
|
#define ISP_SPI JL_SPI1
|
|
#define ISP_SPI_PORT 'B'
|
|
#define ISP_SPI_CLOCK clk_get("lsb")
|
|
|
|
#define ISPKEY_CLK_IO IO_PORTC_04
|
|
#define ISPKEY_DO_IO IO_PORTC_05
|
|
#define ISPKEY_DI_IO IO_PORTC_03
|
|
|
|
static u32 cur_sys_clk = 48000000;
|
|
|
|
AT(.volatile_ram_code)
|
|
static void isp_udelay(u32 usec)
|
|
{
|
|
u32 mips = (usec * (cur_sys_clk / 1000000)) / 9;
|
|
while (mips --) {
|
|
asm("nop");
|
|
}
|
|
}
|
|
|
|
static void isp_hw_init(void)
|
|
{
|
|
gpio_set_die(ISPKEY_CLK_IO, 1);
|
|
gpio_set_pull_up(ISPKEY_CLK_IO, 0);
|
|
gpio_set_pull_down(ISPKEY_CLK_IO, 0);
|
|
gpio_write(ISPKEY_CLK_IO, 0);
|
|
gpio_set_direction(ISPKEY_CLK_IO, 0);
|
|
|
|
gpio_set_die(ISPKEY_DO_IO, 1);
|
|
gpio_set_pull_up(ISPKEY_DO_IO, 0);
|
|
gpio_set_pull_down(ISPKEY_DO_IO, 0);
|
|
gpio_write(ISPKEY_DO_IO, 0);
|
|
gpio_set_direction(ISPKEY_DO_IO, 0);
|
|
|
|
gpio_set_die(ISPKEY_DI_IO, 1);
|
|
gpio_set_pull_up(ISPKEY_DI_IO, 1);
|
|
gpio_set_pull_down(ISPKEY_DI_IO, 0);
|
|
gpio_set_direction(ISPKEY_DI_IO, 1);
|
|
|
|
if (ISP_SPI == JL_SPI1) {
|
|
SFR(JL_IOMAP->CON1, 4, 1, ISP_SPI_PORT - 'A');
|
|
} else {
|
|
SFR(JL_IOMAP->CON1, 16, 1, ISP_SPI_PORT - 'A');
|
|
}
|
|
|
|
ISP_SPI->CON = BIT(14);
|
|
ISP_SPI->CON &= ~BIT(5);//上升沿 更新数据
|
|
ISP_SPI->CON |= BIT(4);//下降沿 采集数据
|
|
ISP_SPI->CON |= BIT(3);
|
|
ISP_SPI->CON |= BIT(0);//SPI EN
|
|
|
|
ISP_SPI->BAUD = 255;
|
|
|
|
}
|
|
|
|
static void isp_hw_close(void)
|
|
{
|
|
gpio_set_die(ISPKEY_CLK_IO, 0);
|
|
gpio_set_pull_up(ISPKEY_CLK_IO, 0);
|
|
gpio_set_pull_down(ISPKEY_CLK_IO, 0);
|
|
gpio_set_direction(ISPKEY_CLK_IO, 1);
|
|
|
|
gpio_set_die(ISPKEY_DO_IO, 0);
|
|
gpio_set_pull_up(ISPKEY_DO_IO, 0);
|
|
gpio_set_pull_down(ISPKEY_DO_IO, 0);
|
|
gpio_set_direction(ISPKEY_DO_IO, 1);
|
|
|
|
gpio_set_die(ISPKEY_DI_IO, 0);
|
|
gpio_set_pull_up(ISPKEY_DI_IO, 0);
|
|
gpio_set_pull_down(ISPKEY_DI_IO, 0);
|
|
gpio_set_direction(ISPKEY_DI_IO, 1);
|
|
|
|
ISP_SPI->CON = BIT(14);
|
|
}
|
|
|
|
static u8 isp_hw_rx_byte(void)
|
|
{
|
|
ISP_SPI->CON |= BIT(14);
|
|
ISP_SPI->CON |= BIT(12);
|
|
ISP_SPI->BUF = 0xff;
|
|
while (!(ISP_SPI->CON & BIT(15)));
|
|
ISP_SPI->CON |= BIT(14);
|
|
return ISP_SPI->BUF;
|
|
}
|
|
|
|
static void isp_hw_tx_byte(u8 byte)
|
|
{
|
|
ISP_SPI->CON |= BIT(14);
|
|
ISP_SPI->CON &= ~BIT(12);
|
|
ISP_SPI->BUF = byte;
|
|
while (!(ISP_SPI->CON & BIT(15)));
|
|
ISP_SPI->CON |= BIT(14);
|
|
}
|
|
|
|
static u8 isp_soft_rx_byte(void)
|
|
{
|
|
ISP_SPI->CON &= ~BIT(0);//SPI EN
|
|
u8 i, byte = 0;
|
|
for (i = 0; i < 8; i++) {
|
|
gpio_write(ISPKEY_CLK_IO, 1);
|
|
isp_udelay(10);
|
|
byte = byte << 1;
|
|
if (gpio_read(ISPKEY_DI_IO)) {
|
|
byte ++;
|
|
}
|
|
gpio_write(ISPKEY_CLK_IO, 0);
|
|
isp_udelay(10);
|
|
}
|
|
isp_udelay(20);
|
|
ISP_SPI->CON |= BIT(0);//SPI EN
|
|
return byte;
|
|
}
|
|
|
|
static void isp_soft_tx_byte(u8 byte)
|
|
{
|
|
ISP_SPI->CON &= ~BIT(0);//SPI EN
|
|
for (u8 i = 0; i < 8; i++) {
|
|
if (byte & BIT(7)) {
|
|
gpio_write(ISPKEY_DO_IO, 1);
|
|
} else {
|
|
gpio_write(ISPKEY_DO_IO, 0);
|
|
}
|
|
byte = byte << 1;
|
|
gpio_write(ISPKEY_CLK_IO, 1);
|
|
isp_udelay(10);
|
|
gpio_write(ISPKEY_CLK_IO, 0);
|
|
isp_udelay(10);
|
|
}
|
|
gpio_write(ISPKEY_DO_IO, 0);
|
|
isp_udelay(20);
|
|
ISP_SPI->CON |= BIT(0);//SPI EN
|
|
}
|
|
|
|
static void isp_hw_dma_tx(u8 *buf, u32 len)
|
|
{
|
|
ISP_SPI->CON |= BIT(14);
|
|
ISP_SPI->CON &= ~BIT(12);
|
|
ISP_SPI->ADR = (u32)buf;
|
|
ISP_SPI->CNT = len;
|
|
while (!(ISP_SPI->CON & BIT(15)));
|
|
ISP_SPI->CON |= BIT(14);
|
|
}
|
|
|
|
static void isp_hw_set_clk(u32 freq)
|
|
{
|
|
u32 baud = ISP_SPI_CLOCK / freq;
|
|
if (baud > 255) {
|
|
baud = 255;
|
|
}
|
|
ISP_SPI->BAUD = baud ? (baud - 1) : 0;
|
|
}
|
|
|
|
|
|
extern u32 RAM1_LIMIT_L;
|
|
static void isp_hw_clk_out(void)
|
|
{
|
|
gpio_set_direction(ISPKEY_DO_IO, 1);
|
|
isp_hw_set_clk(24000000);
|
|
isp_hw_dma_tx((u8 *)&RAM1_LIMIT_L, 1000);
|
|
}
|
|
|
|
#include "sh50_ssi.c"
|
|
|
|
|
|
const struct isp_fd_t isp_fd = {
|
|
.chip_id = 0xaa,
|
|
/* .isp_rx_byte = isp_hw_rx_byte, */
|
|
/* .isp_tx_byte = isp_hw_tx_byte, */
|
|
.isp_rx_byte = isp_soft_rx_byte,
|
|
.isp_tx_byte = isp_soft_tx_byte,
|
|
.isp_dma_tx = isp_hw_dma_tx,
|
|
.isp_set_clk = isp_hw_set_clk,
|
|
.isp_clk_out = isp_hw_clk_out,
|
|
.udelay = isp_udelay,
|
|
.decode_buf = NULL,
|
|
};
|
|
|
|
|
|
#define TEST_CODE_FILE_PATH SDFILE_RES_ROOT_PATH"AD10x_code.bin"
|
|
|
|
void sh50_isp_up_code(void)
|
|
{
|
|
printf("\n\n\n\n\n\n*************************** isp up start **************************\n");
|
|
|
|
FILE *fp = fopen(TEST_CODE_FILE_PATH, "r");
|
|
if (!fp) {
|
|
return;
|
|
}
|
|
printf("open %s succ", TEST_CODE_FILE_PATH);
|
|
struct vfs_attr attr = {0};
|
|
fget_attrs(fp, &attr);
|
|
u8 *file_addr = (u8 *)attr.sclust;
|
|
u32 file_len = attr.fsize;
|
|
printf("file_addr = 0x%x, file_len = %d", (u32)file_addr, file_len);
|
|
/* put_buf(file_addr, 512); */
|
|
|
|
local_irq_disable();
|
|
|
|
cur_sys_clk = clk_get("sys");
|
|
|
|
ssi_init();
|
|
if (sh50_check_chip(&ssi_fd, 10)) {
|
|
ssi_close();
|
|
local_irq_enable();
|
|
printf("ssi check sh50 error !\n\n\n\n\n");
|
|
return;
|
|
}
|
|
sh50_chip_reset(&ssi_fd);
|
|
ssi_close();
|
|
|
|
isp_udelay(3000);
|
|
|
|
isp_hw_init();
|
|
|
|
isp_push_code(&isp_fd, file_addr, file_len);
|
|
|
|
isp_hw_close();
|
|
|
|
local_irq_enable();
|
|
|
|
printf("*************************** isp up end **************************\n\n\n\n\n\n\n");
|
|
}
|
|
|
|
|