• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * Description: SPI Sample Source. \n
16  *
17  * History: \n
18  * 2023-06-25, Create file. \n
19  */
20 #include "pinctrl.h"
21 #include "spi.h"
22 #include "soc_osal.h"
23 #include "app_init.h"
24 
25 #define SPI_SLAVE_NUM                   1
26 #define SPI_FREQUENCY                   2
27 #define SPI_CLK_POLARITY                0
28 #define SPI_CLK_PHASE                   0
29 #define SPI_FRAME_FORMAT                0
30 #define SPI_FRAME_FORMAT_STANDARD       0
31 #define SPI_FRAME_SIZE_8                0x1f
32 #define SPI_TMOD                        0
33 #define SPI_WAIT_CYCLES                 0x10
34 #if defined(CONFIG_SPI_SUPPORT_DMA) && !(defined(CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH))
35 #define SPI_DMA_WIDTH                   2
36 #endif
37 
38 #define SPI_TASK_DURATION_MS            500
39 #define SPI_TASK_PRIO                   24
40 #define SPI_TASK_STACK_SIZE             0x1000
41 
app_spi_init_pin(void)42 static void app_spi_init_pin(void)
43 {
44     uapi_pin_set_mode(CONFIG_SPI_DI_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE);
45     uapi_pin_set_mode(CONFIG_SPI_DO_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE);
46     uapi_pin_set_mode(CONFIG_SPI_CLK_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE);
47     uapi_pin_set_mode(CONFIG_SPI_CS_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE);
48 }
49 
50 #if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1)
app_spi_master_write_int_handler(const void * buffer,uint32_t length)51 static void app_spi_master_write_int_handler(const void *buffer, uint32_t length)
52 {
53     unused(buffer);
54     unused(length);
55     osal_printk("spi master write interrupt start!\r\n");
56 }
57 
app_spi_master_rx_callback(const void * buffer,uint32_t length,bool error)58 static void app_spi_master_rx_callback(const void *buffer, uint32_t length, bool error)
59 {
60     if (buffer == NULL || length == 0) {
61         osal_printk("spi master transfer illegal data!\r\n");
62         return;
63     }
64     if (error) {
65         osal_printk("app_spi_master_read_int error!\r\n");
66         return;
67     }
68 
69     uint8_t *buff = (uint8_t *)buffer;
70     for (uint32_t i = 0; i < length; i++) {
71         osal_printk("buff[%d] = %x\r\n", i, buff[i]);
72     }
73     osal_printk("app_spi_master_read_int success!\r\n");
74 }
75 #endif  /* CONFIG_SPI_SUPPORT_INTERRUPT */
76 
app_spi_master_init_config(void)77 static void app_spi_master_init_config(void)
78 {
79     spi_attr_t config = { 0 };
80     spi_extra_attr_t ext_config = { 0 };
81 
82     config.is_slave = false;
83     config.slave_num = SPI_SLAVE_NUM;
84     config.bus_clk = SPI_CLK_FREQ;
85     config.freq_mhz = SPI_FREQUENCY;
86     config.clk_polarity = SPI_CLK_POLARITY;
87     config.clk_phase = SPI_CLK_PHASE;
88     config.frame_format = SPI_FRAME_FORMAT;
89     config.spi_frame_format = HAL_SPI_FRAME_FORMAT_STANDARD;
90     config.frame_size = SPI_FRAME_SIZE_8;
91     config.tmod = SPI_TMOD;
92     config.sste = 1;
93 
94     ext_config.qspi_param.wait_cycles = SPI_WAIT_CYCLES;
95 
96     uapi_spi_init(CONFIG_SPI_MASTER_BUS_ID, &config, &ext_config);
97 #if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1)
98     uapi_dma_init();
99     uapi_dma_open();
100 #ifndef CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH
101     spi_dma_config_t dma_cfg = {
102         .src_width = SPI_DMA_WIDTH,
103         .dest_width = SPI_DMA_WIDTH,
104         .burst_length = 0,
105         .priority = 0
106     };
107     if (uapi_spi_set_dma_mode(CONFIG_SPI_MASTER_BUS_ID, true, &dma_cfg) != ERRCODE_SUCC) {
108         osal_printk("spi%d master set dma mode fail!\r\n");
109     }
110 #endif
111 #endif  /* CONFIG_SPI_SUPPORT_DMA */
112 
113 #if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1)
114     if (uapi_spi_set_irq_mode(CONFIG_SPI_MASTER_BUS_ID, true, app_spi_master_rx_callback,
115         app_spi_master_write_int_handler) == ERRCODE_SUCC) {
116         osal_printk("spi%d master set irq mode succ!\r\n", CONFIG_SPI_MASTER_BUS_ID);
117     }
118 #endif  /* CONFIG_SPI_SUPPORT_INTERRUPT */
119 }
120 
spi_master_task(const char * arg)121 static void *spi_master_task(const char *arg)
122 {
123     unused(arg);
124     /* SPI pinmux. */
125     app_spi_init_pin();
126 
127     /* SPI master init config. */
128     app_spi_master_init_config();
129 
130     /* SPI data config. */
131     uint8_t tx_data[CONFIG_SPI_TRANSFER_LEN] = { 0 };
132     for (uint32_t loop = 0; loop < CONFIG_SPI_TRANSFER_LEN; loop++) {
133         tx_data[loop] = (loop & 0xFF);
134     }
135     uint8_t rx_data[CONFIG_SPI_TRANSFER_LEN] = { 0 };
136     spi_xfer_data_t data = {
137         .tx_buff = tx_data,
138         .tx_bytes = CONFIG_SPI_TRANSFER_LEN,
139         .rx_buff = rx_data,
140         .rx_bytes = CONFIG_SPI_TRANSFER_LEN,
141     };
142 
143     while (1) {
144         osal_msleep(SPI_TASK_DURATION_MS);
145         osal_printk("spi%d master send start!\r\n", CONFIG_SPI_MASTER_BUS_ID);
146         if (uapi_spi_master_write(CONFIG_SPI_MASTER_BUS_ID, &data, 0xFFFFFFFF) == ERRCODE_SUCC) {
147             osal_printk("spi%d master send succ!\r\n", CONFIG_SPI_MASTER_BUS_ID);
148         } else {
149             continue;
150         }
151         osal_printk("spi%d master receive start!\r\n", CONFIG_SPI_MASTER_BUS_ID);
152         if (uapi_spi_master_read(CONFIG_SPI_MASTER_BUS_ID, &data, 0xFFFFFFFF) == ERRCODE_SUCC) {
153 #ifndef CONFIG_SPI_SUPPORT_INTERRUPT
154             for (uint32_t i = 0; i < data.rx_bytes; i++) {
155                 osal_printk("spi%d master receive data is %x\r\n", CONFIG_SPI_MASTER_BUS_ID, data.rx_buff[i]);
156             }
157 #endif
158             osal_printk("spi%d master receive succ!\r\n", CONFIG_SPI_MASTER_BUS_ID);
159         }
160     }
161 
162     return NULL;
163 }
164 
spi_master_entry(void)165 static void spi_master_entry(void)
166 {
167     osal_task *task_handle = NULL;
168     osal_kthread_lock();
169     task_handle = osal_kthread_create((osal_kthread_handler)spi_master_task, 0, "SpiMasterTask", SPI_TASK_STACK_SIZE);
170     if (task_handle != NULL) {
171         osal_kthread_set_priority(task_handle, SPI_TASK_PRIO);
172         osal_kfree(task_handle);
173     }
174     osal_kthread_unlock();
175 }
176 
177 /* Run the spi_master_entry. */
178 app_run(spi_master_entry);