370 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			370 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  | 
 | ||
|  | This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics 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. | ||
|  | ****************************************************************************/ | ||
|  | /*  Copied on iot_gpio_simu_spi.c and slightly modified  */ | ||
|  | #include "os_types.h"
 | ||
|  | 
 | ||
|  | #include "gpio_hw.h"
 | ||
|  | #include "clk.h"
 | ||
|  | #include "uart.h"
 | ||
|  | 
 | ||
|  | #include "iot_gpio.h"
 | ||
|  | #include "iot_clock.h"
 | ||
|  | #include "iot_errno.h"
 | ||
|  | 
 | ||
|  | #include "iot_io_api.h"
 | ||
|  | #include "iot_gpio_api.h"
 | ||
|  | 
 | ||
|  | #include "fdma_mst_protocol.h"
 | ||
|  | 
 | ||
|  | #define IRQ_DISABLE()
 | ||
|  | #define IRQ_ENABLE()
 | ||
|  | 
 | ||
|  | #define USE_HAL_API      1
 | ||
|  | 
 | ||
|  | #if !USE_HAL_API
 | ||
|  | static volatile int clk_val = 0; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | static void cs_high(void) | ||
|  | { | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CS, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CS, 1); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | static void cs_low(void) | ||
|  | { | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CS, 0); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CS, 0); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | static void clk_overturn(void) | ||
|  | { | ||
|  | #if USE_HAL_API
 | ||
|  |     int val = 0; | ||
|  |     iot_gpio_output_value_get(GPIO_S_CLK, &val); | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, val^1); | ||
|  | #else
 | ||
|  |     for (volatile uint32_t i = 0; i < 10; i++); | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, !clk_val); | ||
|  |     clk_val = !clk_val; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | static void spi_write_byte(unsigned char d) | ||
|  | { | ||
|  |     int i; | ||
|  | 
 | ||
|  |     for (i = 15; i >= 0; i--) { | ||
|  |         // From high 7 to low 0 written sequentially.
 | ||
|  | #if USE_HAL_API
 | ||
|  |         iot_gpio_value_set(GPIO_S_MS, d & (1 << i / 2)); | ||
|  | #else
 | ||
|  |         hw_gpio_api_table.set_value(GPIO_S_MS, d & (1 << i / 2)); | ||
|  | #endif
 | ||
|  |         clk_overturn(); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | static int iot_s_spi_write_data(int dev, char* buf, int wt_size) | ||
|  | { | ||
|  |     int i; | ||
|  | 
 | ||
|  |     for (i = 0; i < wt_size; i++) { | ||
|  |         spi_write_byte(buf[i]); | ||
|  |     } | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | static uint8_t spi_read_byte(void) | ||
|  | { | ||
|  |     int i; | ||
|  |     uint8_t r = 0; | ||
|  | 
 | ||
|  |     for (i = 0; i <= 15; i++) { | ||
|  |         // From high 7 to low 0 serial readout
 | ||
|  |         clk_overturn(); | ||
|  | #if USE_HAL_API
 | ||
|  |         r = r | ((uint8_t)iot_gpio_value_get(GPIO_S_MS) << (7 - i / 2)); | ||
|  | #else
 | ||
|  |         r = r | ((uint8_t)hw_gpio_api_table.get_value(GPIO_S_MS) << (7 - i / 2)); | ||
|  | #endif
 | ||
|  |     } | ||
|  | 
 | ||
|  |     return r; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t iot_s_spi_read_data(int dev, int rd_size) | ||
|  | { | ||
|  |     int i; | ||
|  |     uint32_t data = 0; | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_close(GPIO_S_MS); | ||
|  |     iot_gpio_open_as_input(GPIO_S_MS); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_MS, 0); | ||
|  |     hw_gpio_api_table.set_gpio_mode(GPIO_S_MS, GPIO_INPUT); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     // Read in teh data.
 | ||
|  |     for (i = 0; i < rd_size; i++) { | ||
|  |         data = data | ((uint32_t)spi_read_byte() << (8 * (rd_size - 1 - i))); | ||
|  |     } | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_close(GPIO_S_MS); | ||
|  |     iot_gpio_open_as_output(GPIO_S_MS); | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, 0); | ||
|  |     iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_gpio_mode(GPIO_S_MS, GPIO_OUTPUT); | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, 1); | ||
|  |     clk_val = 1; | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     return data; | ||
|  | } | ||
|  | 
 | ||
|  | // purpose:Shake hands with slave
 | ||
|  | static void spi_start(void) | ||
|  | { | ||
|  |     uint16_t i; | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, 0); | ||
|  |     clk_val = 0; | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     iot_delay_us(100); | ||
|  | //    iot_delay_us_cpu_cycle(100);
 | ||
|  | 
 | ||
|  |     for (i = 0; i < 15; i++) { | ||
|  | #if USE_HAL_API
 | ||
|  |         iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |         hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  |         clk_overturn(); | ||
|  |     } | ||
|  | 
 | ||
|  |     cs_low(); | ||
|  | } | ||
|  | 
 | ||
|  | // purpose:goodbye with slave
 | ||
|  | static void spi_end(void) | ||
|  | { | ||
|  |     uint16_t i; | ||
|  | 
 | ||
|  |     for (i = 0; i < 14; i++) { | ||
|  | #if USE_HAL_API
 | ||
|  |         iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |         hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  |         clk_overturn(); | ||
|  |     } | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, 1); | ||
|  |     iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, 1); | ||
|  |     clk_val = 1; | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  |     cs_high(); | ||
|  | } | ||
|  | 
 | ||
|  | void iot_spi_fdma_master_write(uint32_t addr, uint32_t w_lenth, | ||
|  |                                uint32_t* w_data) | ||
|  | { | ||
|  |     uint32_t fifo[2]; | ||
|  |     uint16_t i; | ||
|  |     uint32_t data_temp; | ||
|  | 
 | ||
|  |     fifo[0] = NTOHL(FMST_SET_CMD(FMST_CMD_WRITE, w_lenth)); | ||
|  |     fifo[1] = NTOHL(addr); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  | 
 | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)fifo, sizeof(fifo)); | ||
|  |     for (i = 0; i < w_lenth; i++) { | ||
|  |         data_temp = NTOHL(w_data[i]); | ||
|  |         iot_s_spi_write_data(INVALID_DRIVER, (char*)&data_temp, | ||
|  |                              sizeof(uint32_t)); | ||
|  |     } | ||
|  | 
 | ||
|  |     spi_end(); | ||
|  |     IRQ_ENABLE(); | ||
|  | } | ||
|  | 
 | ||
|  | uint16_t iot_spi_fdma_master_read(uint32_t addr, uint32_t r_lenth, | ||
|  |     uint32_t* rx_buff) | ||
|  | { | ||
|  |     uint32_t fifo[2]; | ||
|  |     uint32_t fifo2[1]; | ||
|  |     uint16_t i; | ||
|  | 
 | ||
|  |     if (!r_lenth) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     fifo[0] = NTOHL(FMST_SET_CMD(FMST_CMD_READ_ALLOCATE, r_lenth)); | ||
|  |     fifo[1] = NTOHL(addr); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)fifo, sizeof(fifo)); | ||
|  |     spi_end(); | ||
|  | 
 | ||
|  |     fifo2[0] = NTOHL(FMST_SET_CMD(FMST_CMD_READ_FETCH, r_lenth)); | ||
|  | 
 | ||
|  |     spi_start(); | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)fifo2, sizeof(fifo2)); | ||
|  | 
 | ||
|  |     for (i = 0; i < r_lenth;) { | ||
|  |         rx_buff[i] = iot_s_spi_read_data(INVALID_DRIVER, sizeof(uint32_t)); | ||
|  |         i++; | ||
|  |     } | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, 1); | ||
|  |     iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, 1); | ||
|  |     clk_val = 1; | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  |     cs_high(); | ||
|  |     IRQ_ENABLE(); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint16_t iot_spi_fdma_master_get_debuginfo(uint32_t id, uint32_t* rx_buff) | ||
|  | { | ||
|  |     uint32_t cmd; | ||
|  |     uint16_t i; | ||
|  | 
 | ||
|  |     cmd = NTOHL(FMST_SET_CMD(FMST_CMD_MODULE_STS, id)); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  | 
 | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd)); | ||
|  | 
 | ||
|  |     for (i = 0; i < 8; i++) { | ||
|  |         rx_buff[i] = iot_s_spi_read_data(INVALID_DRIVER, sizeof(uint32_t)); | ||
|  |     } | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, 1); | ||
|  |     iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, 1); | ||
|  |     clk_val = 1; | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  |     cs_high(); | ||
|  |     IRQ_ENABLE(); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_spi_fdma_master_reset_cpu(void) | ||
|  | { | ||
|  |     uint32_t cmd; | ||
|  | 
 | ||
|  |     cmd = NTOHL(FMST_SET_CMD(FMST_CMD_CPU_RESET, 0)); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  | 
 | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd)); | ||
|  | 
 | ||
|  |     spi_end(); | ||
|  |     IRQ_ENABLE(); | ||
|  | } | ||
|  | 
 | ||
|  | void iot_spi_fdma_master_reset_release_cpu(void) | ||
|  | { | ||
|  |     uint32_t cmd; | ||
|  | 
 | ||
|  |     cmd = NTOHL(FMST_SET_CMD(FMST_CMD_CPU_RESET_RELEASE, 0)); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  | 
 | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd)); | ||
|  | 
 | ||
|  |     spi_end(); | ||
|  |     IRQ_ENABLE(); | ||
|  | } | ||
|  | 
 | ||
|  | uint16_t iot_spi_fdma_master_ping(uint32_t* rx_buff) | ||
|  | { | ||
|  |     uint32_t cmd; | ||
|  |     uint16_t i; | ||
|  | 
 | ||
|  |     cmd = NTOHL(FMST_SET_CMD(FMST_CMD_PING, 0)); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  | 
 | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd)); | ||
|  | 
 | ||
|  |     for (i = 0; i < 4; i++) { | ||
|  |         rx_buff[i] = iot_s_spi_read_data(INVALID_DRIVER, sizeof(uint32_t)); | ||
|  |     } | ||
|  | 
 | ||
|  | #if USE_HAL_API
 | ||
|  |     iot_gpio_value_set(GPIO_S_CLK, 1); | ||
|  |     iot_gpio_value_set(GPIO_S_MS, 1); | ||
|  | #else
 | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_CLK, 1); | ||
|  |     clk_val = 1; | ||
|  |     hw_gpio_api_table.set_value(GPIO_S_MS, 1); | ||
|  | #endif
 | ||
|  |     cs_high(); | ||
|  |     IRQ_ENABLE(); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_spi_fdma_master_nop(void) | ||
|  | { | ||
|  |     uint32_t cmd; | ||
|  | 
 | ||
|  |     cmd = NTOHL(FMST_SET_CMD(FMST_CMD_NOP, 0)); | ||
|  | 
 | ||
|  |     IRQ_DISABLE(); | ||
|  |     spi_start(); | ||
|  | 
 | ||
|  |     iot_s_spi_write_data(INVALID_DRIVER, (char*)&cmd, sizeof(cmd)); | ||
|  | 
 | ||
|  |     spi_end(); | ||
|  |     IRQ_ENABLE(); | ||
|  | } | ||
|  | 
 |