205 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			205 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  |  * | ||
|  |  * Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  |  * | ||
|  |  * This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics Ltd and MAY NOT | ||
|  |  * be copied by any method or incorporated into another program without | ||
|  |  * the express written consent of Aerospace C.Power. This Information or any portion | ||
|  |  * thereof remains the property of Aerospace C.Power. The Information contained herein | ||
|  |  * is believed to be accurate and Aerospace C.Power assumes no responsibility or | ||
|  |  * liability for its use in any way and conveys no license or title under | ||
|  |  * any patent or copyright and makes no representation or warranty that this | ||
|  |  * Information is free from patent or copyright infringement. | ||
|  |  * | ||
|  |  * ****************************************************************************/ | ||
|  | #include "os_types.h"
 | ||
|  | #include "dbg_io.h"
 | ||
|  | #include "iot_diag.h"
 | ||
|  | #include "iot_io.h"
 | ||
|  | #include "flash.h"
 | ||
|  | #include "gpio_mtx.h"
 | ||
|  | #include "iot_wdg.h"
 | ||
|  | #include "iot_irq.h"
 | ||
|  | #include "irq.h"
 | ||
|  | #include "gp_timer.h"
 | ||
|  | #include "clk_hw.h"
 | ||
|  | #define REG32(a)    (*((volatile uint32_t *)(a)))
 | ||
|  | 
 | ||
|  | typedef enum { | ||
|  |     AHB_CLK_25M = 0, | ||
|  |     AHB_CLK_200M = 1, | ||
|  | } ahb_clk_25m_t; | ||
|  | 
 | ||
|  | iot_irq_t g_timer_handle; | ||
|  | 
 | ||
|  | void switch_clk(uint8_t clk) | ||
|  | { | ||
|  |     if (clk == AHB_CLK_25M) { | ||
|  |         clk_set_freq(CPU_FREQ_25M); | ||
|  |     } else if (clk == AHB_CLK_200M) { | ||
|  |         clk_set_freq(CPU_FREQ_200M); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t rdata[0x100] = {0}; | ||
|  | uint8_t wdata[0x100] = {1,2,3,4,5,6,7,8,9,0,255,254,253,252,251,250}; | ||
|  | uint8_t flash_write_test() | ||
|  | { | ||
|  | #define FLASH_TEST_OFFSET 0x0
 | ||
|  |     uint8_t ret = 0; | ||
|  |     for(uint32_t i = 0; i < 0x100; i++) { | ||
|  |         wdata[i] = i; | ||
|  |         rdata[i] = 0; | ||
|  |     } | ||
|  |     iot_printf("\n[SFC API TEST] start write test\n"); | ||
|  |     g_sfc_ctrl->erase_sector(FLASH_TEST_OFFSET, MOD_SW_MODE_DIS); | ||
|  |     g_sfc_ctrl->write(wdata,FLASH_TEST_OFFSET, sizeof(wdata), | ||
|  |             MOD_SFC_PROG_STAND, MOD_SW_MODE_DIS); | ||
|  |     g_sfc_ctrl->read(rdata,FLASH_TEST_OFFSET,sizeof(wdata), MOD_SFC_READ_SIG); | ||
|  | 
 | ||
|  |     for(uint32_t i = 0; i < 0x100; i++) { | ||
|  |         if (wdata[i] != rdata[i]) { | ||
|  |             iot_printf("qspi write, qspi read error\n"); | ||
|  |             ret = 1; | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_printf("quad write test\n"); | ||
|  |     g_sfc_ctrl->erase_sector(FLASH_TEST_OFFSET, MOD_SW_MODE_DIS); | ||
|  |     wdata[10] = 0xa5; | ||
|  |     rdata[10] = 0x0; | ||
|  |     g_sfc_ctrl->write(wdata,FLASH_TEST_OFFSET,sizeof(wdata), | ||
|  |                       MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS); | ||
|  |     g_sfc_ctrl->read(rdata,FLASH_TEST_OFFSET,sizeof(wdata), MOD_SFC_READ_SIG); | ||
|  |     for(uint32_t i = 0; i < 0x100; i++) { | ||
|  |         if (wdata[i] != rdata[i]) { | ||
|  |             iot_printf("qspi write, qspi read error\n"); | ||
|  |             ret = 1; | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     iot_printf("[SFC API TEST] end write test\n"); | ||
|  | 
 | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | void flash_gpio_bind() | ||
|  | { | ||
|  | #define SFC_CLK 53
 | ||
|  | #define SFC_CS 48
 | ||
|  | #define SFC_D0 52
 | ||
|  | #define SFC_D1 49
 | ||
|  | #define SFC_D2 50
 | ||
|  | #define SFC_D3 51
 | ||
|  | 
 | ||
|  | #define SIG_IN_SFC_D0   4
 | ||
|  | #define SIG_IN_SFC_D1   5
 | ||
|  | #define SIG_IN_SFC_D2   6
 | ||
|  | #define SIG_IN_SFC_D3   7
 | ||
|  | 
 | ||
|  |     gpio_mtx_enable(); | ||
|  | 
 | ||
|  |     gpio_pin_select(SFC_CLK, 1); | ||
|  |     gpio_pin_select(SFC_CS, 1); | ||
|  |     gpio_pin_select(SFC_D0, 1); | ||
|  |     gpio_pin_select(SFC_D1, 1); | ||
|  |     gpio_pin_select(SFC_D2, 1); | ||
|  |     gpio_pin_select(SFC_D3, 1); | ||
|  | 
 | ||
|  |     gpio_mtx_sig_in(SIG_IN_SFC_D0, SFC_D0, GPIO_MTX_MODE_CORE); | ||
|  |     gpio_mtx_sig_in(SIG_IN_SFC_D1, SFC_D1, GPIO_MTX_MODE_CORE); | ||
|  |     gpio_mtx_sig_in(SIG_IN_SFC_D2, SFC_D2, GPIO_MTX_MODE_CORE); | ||
|  |     gpio_mtx_sig_in(SIG_IN_SFC_D3, SFC_D3, GPIO_MTX_MODE_CORE); | ||
|  | } | ||
|  | 
 | ||
|  | void write_test_done(uint8_t val) | ||
|  | { | ||
|  |     volatile uint32_t *reg = (volatile uint32_t *) 0x44000010; | ||
|  |     *reg = val; | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t g_test_done = 0; | ||
|  | uint8_t g_test_cnt = 0; | ||
|  | uint32_t timer_handle(uint32_t vector, iot_addrword_t data) | ||
|  | { | ||
|  |     if (vector == HAL_VECTOR_GPTMR) { | ||
|  |         g_test_cnt++; | ||
|  |         if (g_test_cnt >= 10) { | ||
|  |             gp_timer_stop(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         gp_timer_clear_int_status(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | int main() | ||
|  | { | ||
|  |     uint8_t ret = 0; | ||
|  |     dbg_uart_init(); | ||
|  | 
 | ||
|  |     /* clock frequency switch test */ | ||
|  |     iot_printf("[CLK TEST] start...\n"); | ||
|  |     for(uint8_t i = 0; i < 5; i++) { | ||
|  |         switch_clk(AHB_CLK_200M); | ||
|  |         for(volatile uint8_t j = 0; j < 100; j++); | ||
|  |         switch_clk(AHB_CLK_25M); | ||
|  |         for(volatile uint8_t j = 0; j < 100; j++); | ||
|  |     } | ||
|  |     iot_printf("[CLK TEST] end---\n"); | ||
|  | 
 | ||
|  |     /* 100MHz flash test */ | ||
|  |     iot_printf("[FLASH TEST] start...\n"); | ||
|  |     switch_clk(AHB_CLK_200M); | ||
|  |     clk_apb_div(1); | ||
|  |     flash_gpio_bind(); | ||
|  | 
 | ||
|  |     // emc enable
 | ||
|  |     REG32(0x62000004) |= (1); | ||
|  |     REG32(0x62000008) |= (1); | ||
|  |     for(volatile uint8_t i = 0; i < 100; i++); | ||
|  |     REG32(0x62000008) &= ~(1); | ||
|  | 
 | ||
|  |     flash_init(1); | ||
|  |     // switch sfc clock to 100MHz
 | ||
|  |     ret = flash_write_test(); | ||
|  | 
 | ||
|  |     iot_printf("flash test result: %d\n", ret); | ||
|  |     g_test_done = ret; | ||
|  | 
 | ||
|  |     /* wfi test */ | ||
|  |     gp_timer_init(); | ||
|  |     gp_timer_set(0, 1*1000, 1); | ||
|  |     g_timer_handle = | ||
|  |         iot_interrupt_create(HAL_VECTOR_GPTMR, HAL_INTR_PRI_7, | ||
|  |         0, timer_handle); | ||
|  |     iot_interrupt_attach(g_timer_handle); | ||
|  |     iot_interrupt_unmask(g_timer_handle); | ||
|  |     gp_timer_start(0); | ||
|  |     while(1) { | ||
|  |         if (g_test_cnt >= 10) { | ||
|  |             break; | ||
|  |         } | ||
|  |         // cpu1 sleep ena
 | ||
|  |         REG32(0x6200000c) |= 0x4; | ||
|  |         __asm volatile ("wfi"); | ||
|  |         switch_clk(AHB_CLK_200M); | ||
|  |         for(volatile uint8_t j = 0; j < 100; j++); | ||
|  |         switch_clk(AHB_CLK_25M); | ||
|  |         for(volatile uint8_t j = 0; j < 100; j++); | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     if(g_test_done) { | ||
|  |         write_test_done(g_test_done); | ||
|  |     } else { | ||
|  |         write_test_done(0x5a); | ||
|  |     } | ||
|  | 
 | ||
|  |     while(1); | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 |