From fb52190f39e01609a9aa90f01a1d59c069bf8c83 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Tue, 30 Oct 2018 17:38:29 +0800 Subject: [PATCH 01/17] Fix tp and sp overlap bug --- lds/kendryte.ld | 7 ++++--- lib/bsp/crt.S | 16 ++-------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/lds/kendryte.ld b/lds/kendryte.ld index b2fdbe88..1e285329 100644 --- a/lds/kendryte.ld +++ b/lds/kendryte.ld @@ -239,11 +239,12 @@ SECTIONS . = ALIGN(64); PROVIDE( _end = ABSOLUTE(.) ); /* Leave 2 holes for stack & TLS, the size can set in kconfig */ - PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); + PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 4 ); PROVIDE( _tp0 = (_end + 63) & (-64) ); PROVIDE( _tp1 = _tp0 + _stack_size ); - PROVIDE( _sp0 = _tp0 + _stack_size ); - PROVIDE( _sp1 = _tp1 + _stack_size ); + PROVIDE( _sp0 = _tp1 + _stack_size ); + PROVIDE( _sp1 = _sp0 + _stack_size ); + /* Heap end is at the end of memory, the memory size can set in kconfig */ PROVIDE( _heap_end = _ram_end ); } diff --git a/lib/bsp/crt.S b/lib/bsp/crt.S index 6d4e6a78..f85348a5 100644 --- a/lib/bsp/crt.S +++ b/lib/bsp/crt.S @@ -72,14 +72,6 @@ _start: li x30,0 li x31,0 - csrr t0, misa - bltz t0, 1f - li a0, 1234 - j sys_exit -1: - - andi t0, t0, 1 << ('f' - 'a') - beqz t0, 1f li t0, MSTATUS_FS csrs mstatus, t0 @@ -117,21 +109,17 @@ _start: fmv.d.x f30,x0 fmv.d.x f31,x0 -1: .option push .option norelax - la gp, __global_pointer$ + la gp, __global_pointer$ .option pop la tp, _end + 63 and tp, tp, -64 csrr a0, mhartid - li a1, 2 - -1:bgeu a0, a1, 1b sll a2, a0, STKSHIFT add tp, tp, a2 - add sp, a0, 1 + add sp, a0, 2 sll sp, sp, STKSHIFT add sp, sp, tp From f2c82a9f2f1de7d96b6e120b872a81082f7abf0f Mon Sep 17 00:00:00 2001 From: 0x00-pl <0x00.pl@gmail.com> Date: Tue, 30 Oct 2018 18:16:34 +0800 Subject: [PATCH 02/17] modified: .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8e16bd03..168d9f1f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ CMakeSettings.json .idea *.tar *.tar.* -cmake-build-* \ No newline at end of file +cmake-build-* +src +~src/hello_world +*.kdev4 From 57db879e8d8d7da8cccb9b2dcadc9005f98cd311 Mon Sep 17 00:00:00 2001 From: 0x00-pl <0x00.pl@gmail.com> Date: Tue, 30 Oct 2018 19:10:58 +0800 Subject: [PATCH 03/17] add eight_bit_mode --- lib/drivers/{ => include}/kpu.h | 7 ++++--- lib/drivers/kpu.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) rename lib/drivers/{ => include}/kpu.h (99%) diff --git a/lib/drivers/kpu.h b/lib/drivers/include/kpu.h similarity index 99% rename from lib/drivers/kpu.h rename to lib/drivers/include/kpu.h index 8aaff4f9..77a8c3ce 100644 --- a/lib/drivers/kpu.h +++ b/lib/drivers/include/kpu.h @@ -312,11 +312,12 @@ extern volatile kpu_config_t *const kpu; typedef struct { kpu_layer_argument_t* layers; - uint32_t length; - int dma_ch; uint64_t* dst; - uint32_t dst_length; plic_irq_callback_t cb; + uint32_t length; + uint32_t dst_length; + uint32_t dma_ch; + uint32_t eight_bit_mode; } kpu_task_t; /** diff --git a/lib/drivers/kpu.c b/lib/drivers/kpu.c index a13a6fb7..72c6a7e6 100644 --- a/lib/drivers/kpu.c +++ b/lib/drivers/kpu.c @@ -102,7 +102,7 @@ static int kpu_run_dma_input_done_push_layers(void* _task) }; kpu->eight_bit_mode.data = (kpu_config_eight_bit_mode_t) { - .eight_bit_mode=0 + .eight_bit_mode=task->eight_bit_mode }; kpu_layer_argument_t* last_layer = &task->layers[task->length-1]; From 0dada11f40168fbf057c0dba8524b1b4a596a925 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 11:40:44 +0800 Subject: [PATCH 04/17] Del common.c --- lib/drivers/common.c | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 lib/drivers/common.c diff --git a/lib/drivers/common.c b/lib/drivers/common.c deleted file mode 100644 index d21a3b37..00000000 --- a/lib/drivers/common.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2018 Canaan Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include "encoding.h" -#include "utils.h" - -void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value) -{ - uint32_t org = (*bits) & ~mask; - *bits = org | (value & mask); -} - -void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value) -{ - set_bit(bits, mask << offset, value << offset); -} - -void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value) -{ - set_bit_offset(bits, 1, offset, value); -} - -uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset) -{ - return ((*bits) & (mask << offset)) >> offset; -} - -uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset) -{ - return get_bit(bits, 1, offset); -} - From 2e85f6cf540ebd3d2ab01ff542188e70e4f30d45 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 11:43:46 +0800 Subject: [PATCH 05/17] Fix redefine bug --- cmake/executable.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/executable.cmake b/cmake/executable.cmake index d890c5ee..3c783002 100644 --- a/cmake/executable.cmake +++ b/cmake/executable.cmake @@ -15,7 +15,9 @@ set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) target_link_libraries(${PROJECT_NAME} -Wl,--start-group + -Wl,--whole-archive gcc m c kendryte + -Wl,--no-whole-archive -Wl,--end-group ) From 6be9a7c731a8785765c19e61b112ba9dd86634c4 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 11:52:40 +0800 Subject: [PATCH 06/17] Fix redefine bug --- cmake/executable.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/executable.cmake b/cmake/executable.cmake index 3c783002..70132ad2 100644 --- a/cmake/executable.cmake +++ b/cmake/executable.cmake @@ -15,8 +15,9 @@ set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) target_link_libraries(${PROJECT_NAME} -Wl,--start-group + gcc m c -Wl,--whole-archive - gcc m c kendryte + kendryte -Wl,--no-whole-archive -Wl,--end-group ) From 2e83c49ded7392a21ed71b4996ade112610f53f3 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 14:04:28 +0800 Subject: [PATCH 07/17] Fix pll init bug --- lib/drivers/sysctl.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/drivers/sysctl.c b/lib/drivers/sysctl.c index a4d05836..41514ba2 100644 --- a/lib/drivers/sysctl.c +++ b/lib/drivers/sysctl.c @@ -753,32 +753,24 @@ static int sysctl_pll_is_lock(sysctl_pll_t pll) * */ - uint8_t lock = 0; - if (pll >= SYSCTL_PLL_MAX) return 0; switch (pll) { case SYSCTL_PLL0: - lock = sysctl->pll_lock.pll_lock0; - break; + return sysctl->pll_lock.pll_lock0 == 3; case SYSCTL_PLL1: - lock = sysctl->pll_lock.pll_lock1; - break; + return sysctl->pll_lock.pll_lock1 & 1; case SYSCTL_PLL2: - lock = sysctl->pll_lock.pll_lock2; - break; + return sysctl->pll_lock.pll_lock2 & 1; default: break; } - if (lock == 3) - return 1; - return 0; } From 3cc1c1af098970b367fee6f0215eb9e9df817ab1 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 14:33:42 +0800 Subject: [PATCH 08/17] Kpu add 8bit mode --- lib/drivers/kpu.c | 7 ++++--- lib/drivers/kpu.h | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/drivers/kpu.c b/lib/drivers/kpu.c index a13a6fb7..94a40cc2 100644 --- a/lib/drivers/kpu.c +++ b/lib/drivers/kpu.c @@ -6,6 +6,7 @@ #include "printf.h" #include "dmac.h" #include +#include "bsp.h" volatile kpu_config_t *const kpu = (volatile kpu_config_t *)AI_BASE_ADDR; @@ -19,7 +20,7 @@ volatile kpu_context_t g_kpu_context; static int kpu_run_all_done(void* _task) { - g_kpu_context.kpu_status = 0; + atomic_swap(&g_kpu_context.kpu_status, 0); kpu_task_t* task = (kpu_task_t*)_task; task->cb(task); return 0; @@ -102,7 +103,7 @@ static int kpu_run_dma_input_done_push_layers(void* _task) }; kpu->eight_bit_mode.data = (kpu_config_eight_bit_mode_t) { - .eight_bit_mode=0 + .eight_bit_mode=task->eight_bit_mode }; kpu_layer_argument_t* last_layer = &task->layers[task->length-1]; @@ -132,7 +133,7 @@ static void kpu_run_dma_input(uint32_t dma_ch, const void* src, plic_irq_callbac int kpu_run(kpu_task_t* v_task, dmac_channel_number_t dma_ch, const void *src, void* dest, plic_irq_callback_t callback) { - if(g_kpu_context.kpu_status) + if(atomic_cas(&g_kpu_context.kpu_status, 0, 1)) return -1; memcpy((void *)&g_kpu_context.kpu_task, v_task, sizeof(kpu_task_t)); diff --git a/lib/drivers/kpu.h b/lib/drivers/kpu.h index 8aaff4f9..77a8c3ce 100644 --- a/lib/drivers/kpu.h +++ b/lib/drivers/kpu.h @@ -312,11 +312,12 @@ extern volatile kpu_config_t *const kpu; typedef struct { kpu_layer_argument_t* layers; - uint32_t length; - int dma_ch; uint64_t* dst; - uint32_t dst_length; plic_irq_callback_t cb; + uint32_t length; + uint32_t dst_length; + uint32_t dma_ch; + uint32_t eight_bit_mode; } kpu_task_t; /** From 738ee6d4b0c6a0034fbc212656ce9cfd1dd07224 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 14:35:17 +0800 Subject: [PATCH 09/17] Modify stack size --- lds/kendryte.ld | 8 ++++---- lib/bsp/crt.S | 4 ++-- lib/bsp/entry_user.c | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lds/kendryte.ld b/lds/kendryte.ld index 1e285329..7043282d 100644 --- a/lds/kendryte.ld +++ b/lds/kendryte.ld @@ -23,7 +23,7 @@ PROVIDE( _ram_start = ORIGIN(ram) ); PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); PROVIDE( _io_start = 0x40000000 ); PROVIDE( _io_end = _io_start + LENGTH(ram) ); -PROVIDE( _stack_size = 1 << 17 ); +PROVIDE( _stack_size = 1 << 16 ); /* @@ -239,11 +239,11 @@ SECTIONS . = ALIGN(64); PROVIDE( _end = ABSOLUTE(.) ); /* Leave 2 holes for stack & TLS, the size can set in kconfig */ - PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 4 ); + PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); PROVIDE( _tp0 = (_end + 63) & (-64) ); PROVIDE( _tp1 = _tp0 + _stack_size ); - PROVIDE( _sp0 = _tp1 + _stack_size ); - PROVIDE( _sp1 = _sp0 + _stack_size ); + PROVIDE( _sp0 = _tp0 + _stack_size ); + PROVIDE( _sp1 = _tp1 + _stack_size ); /* Heap end is at the end of memory, the memory size can set in kconfig */ PROVIDE( _heap_end = _ram_end ); diff --git a/lib/bsp/crt.S b/lib/bsp/crt.S index f85348a5..ba9149d3 100644 --- a/lib/bsp/crt.S +++ b/lib/bsp/crt.S @@ -19,7 +19,7 @@ # define LFREG fld # define SFREG fsd # define REGBYTES 8 -# define STKSHIFT 17 +# define STKSHIFT 16 .section .text.start, "ax", @progbits @@ -119,7 +119,7 @@ _start: sll a2, a0, STKSHIFT add tp, tp, a2 - add sp, a0, 2 + add sp, a0, 1 sll sp, sp, STKSHIFT add sp, sp, tp diff --git a/lib/bsp/entry_user.c b/lib/bsp/entry_user.c index 0b44fae8..d9d3a2de 100644 --- a/lib/bsp/entry_user.c +++ b/lib/bsp/entry_user.c @@ -66,8 +66,6 @@ void _init_bsp(int core_id, int number_of_cores) extern int main(int argc, char* argv[]); extern void __libc_init_array(void); extern void __libc_fini_array(void); - /* Initialize thread local data */ - init_tls(); if (core_id == 0) { From 68c0007f5ab0254be5ad6d7700b9f75e263d2c58 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Thu, 1 Nov 2018 20:50:02 +0800 Subject: [PATCH 10/17] Fix spi recv bug --- lib/drivers/spi.c | 134 ++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 58 deletions(-) diff --git a/lib/drivers/spi.c b/lib/drivers/spi.c index e679c9a2..48761dd1 100644 --- a/lib/drivers/spi.c +++ b/lib/drivers/spi.c @@ -28,7 +28,28 @@ volatile spi_t *const spi[4] = (volatile spi_t *)SPI3_BASE_ADDR }; -static spi_transfer_width_t get_frame_size(size_t data_bit_length) +static spi_frame_format_t spi_get_frame_format(spi_device_num_t spi_num) +{ + uint8_t frf_offset; + switch(spi_num) + { + case 0: + case 1: + frf_offset = 21; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + frf_offset = 22; + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + return ((spi_adapter->ctrlr0 >> frf_offset) & 0x3); +} + +static spi_transfer_width_t spi_get_frame_size(size_t data_bit_length) { if (data_bit_length < 8) return SPI_TRANS_CHAR; @@ -111,7 +132,8 @@ void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_for break; } volatile spi_t *spi_adapter = spi[spi_num]; - spi_adapter->baudr = 0x14; + if(spi_adapter->baudr == 0) + spi_adapter->baudr = 0x14; spi_adapter->imr = 0x00; spi_adapter->dmacr = 0x00; spi_adapter->dmatdlr = 0x10; @@ -196,7 +218,7 @@ void spi_send_data_normal(spi_device_num_t spi_num, spi_chip_select_t chip_selec break; } uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); spi_handle->ssienr = 0x01; spi_handle->ser = 1U << chip_select; @@ -269,7 +291,7 @@ void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_nu break; } uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); uint32_t *buf; size_t v_send_len; @@ -354,10 +376,12 @@ void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_ size_t cmd_len, uint8_t *rx_buff, size_t rx_len) { configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); - + size_t v_cmd_len = cmd_len; size_t index, fifo_len; - - spi_set_tmod(spi_num, SPI_TMOD_EEROM); + if(cmd_len == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); volatile spi_t *spi_handle = spi[spi_num]; uint8_t dfs_offset; @@ -375,20 +399,19 @@ void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_ break; } uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); uint32_t v_rx_len = 0; uint32_t i = 0; - v_rx_len = rx_len / frame_width; spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); spi_handle->ssienr = 0x01; - while (cmd_len) + while (v_cmd_len) { fifo_len = 32 - spi_handle->txflr; - fifo_len = fifo_len < cmd_len ? fifo_len : cmd_len; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; switch(frame_width) { case SPI_TRANS_INT: @@ -407,7 +430,13 @@ void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_ break; } spi_handle->ser = 1U << chip_select; - cmd_len -= fifo_len; + v_cmd_len -= fifo_len; + } + + if(cmd_len == 0) + { + spi_handle->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; } i = 0; @@ -415,24 +444,9 @@ void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_ { fifo_len = spi_handle->rxflr; fifo_len = fifo_len < rx_len ? fifo_len : rx_len; - switch(frame_width) - { - case SPI_TRANS_INT: - fifo_len = fifo_len / 4 * 4; - for (index = 0; index < fifo_len / 4; index++) - ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; - break; - case SPI_TRANS_SHORT: - fifo_len = fifo_len / 2 * 2; - for (index = 0; index < fifo_len / 2; index++) - ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; - break; - default: - for (index = 0; index < fifo_len; index++) - rx_buff[i++] = (uint8_t)spi_handle->dr[0]; - break; - } + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; rx_len -= fifo_len; } @@ -467,7 +481,8 @@ void spi_receive_data_normal_dma(dmac_channel_number_t dma_send_channel_num, if(cmd_len) dmac_set_single_mode(dma_send_channel_num, cmd_buff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, cmd_len); - + if(cmd_len == 0 && spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi[spi_num]->dr[0] = 0xffffffff; spi_handle->ser = 1U << chip_select; if(cmd_len) dmac_wait_done(dma_send_channel_num); @@ -501,7 +516,7 @@ void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, break; } uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); size_t i; @@ -565,7 +580,10 @@ void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_ configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); size_t index, fifo_len; - spi_set_tmod(spi_num, SPI_TMOD_EEROM); + if(cmd_len == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); volatile spi_t *spi_handle = spi[spi_num]; uint8_t dfs_offset; @@ -583,7 +601,7 @@ void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_ break; } uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); uint32_t v_cmd_len = cmd_len * 4; uint32_t i = 0; @@ -606,6 +624,11 @@ void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_ v_cmd_len -= fifo_len; } + if(cmd_len == 0) + { + spi_handle->ser = 1U << chip_select; + } + while (rx_len) { fifo_len = spi_handle->rxflr; @@ -642,13 +665,12 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *cmd_buff, size_t cmd_len, uint8_t *rx_buff, size_t rx_len) { - configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); - spi_set_tmod(spi_num, SPI_TMOD_RECV); - volatile spi_t *spi_handle = spi[spi_num]; + volatile spi_t *spi_handle = spi[spi_num]; - uint8_t dfs_offset; - switch(spi_num){ + uint8_t dfs_offset; + switch(spi_num){ case 0: case 1: dfs_offset = 16; @@ -660,25 +682,23 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, default: dfs_offset = 0; break; - } - uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); - size_t i; + size_t i; - uint32_t *write_cmd; - uint32_t *read_buf; - size_t v_recv_len; - size_t v_cmd_len; - switch(frame_width) - { + uint32_t *write_cmd; + uint32_t *read_buf; + size_t v_recv_len; + switch(frame_width) + { case SPI_TRANS_INT: write_cmd = malloc(cmd_len + rx_len); for(i = 0; i < cmd_len; i++) write_cmd[i] = cmd_buff[i]; read_buf = &write_cmd[i]; v_recv_len = rx_len / 4; - v_cmd_len = cmd_len / 4; break; case SPI_TRANS_SHORT: write_cmd = malloc(cmd_len + rx_len /2 * sizeof(uint32_t)); @@ -686,7 +706,6 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, write_cmd[i] = cmd_buff[i]; read_buf = &write_cmd[i]; v_recv_len = rx_len / 2; - v_cmd_len = cmd_len / 2; break; default: write_cmd = malloc(cmd_len + rx_len * sizeof(uint32_t)); @@ -694,14 +713,13 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, write_cmd[i] = cmd_buff[i]; read_buf = &write_cmd[i]; v_recv_len = rx_len; - v_cmd_len = cmd_len; break; - } + } - spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, v_cmd_len, read_buf, v_recv_len); + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, cmd_len, read_buf, v_recv_len); - switch(frame_width) - { + switch(frame_width) + { case SPI_TRANS_INT: for(i = 0; i < v_recv_len; i++) ((uint32_t *)rx_buff)[i] = read_buf[i]; @@ -714,9 +732,9 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, for(i = 0; i < v_recv_len; i++) rx_buff[i] = read_buf[i]; break; - } + } - free(write_cmd); + free(write_cmd); } @@ -766,7 +784,7 @@ void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_nu break; } uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; - spi_transfer_width_t frame_width = get_frame_size(data_bit_length); + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); uint32_t *buf; size_t v_send_len; From 788250b0891eed20a3924e391082a92c51803ce8 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Fri, 2 Nov 2018 11:11:34 +0800 Subject: [PATCH 11/17] Fix spi standard mode bug --- lib/drivers/spi.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/drivers/spi.c b/lib/drivers/spi.c index 48761dd1..2eb292a8 100644 --- a/lib/drivers/spi.c +++ b/lib/drivers/spi.c @@ -444,9 +444,23 @@ void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_ { fifo_len = spi_handle->rxflr; fifo_len = fifo_len < rx_len ? fifo_len : rx_len; - - for (index = 0; index < fifo_len; index++) - rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + switch(frame_width) + { + case SPI_TRANS_INT: + fifo_len = fifo_len / 4 * 4; + for (index = 0; index < fifo_len / 4; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + fifo_len = fifo_len / 2 * 2; + for (index = 0; index < fifo_len / 2; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } rx_len -= fifo_len; } From 6322001857ef2d434ed43353e430794958c7c40c Mon Sep 17 00:00:00 2001 From: jiangxiangbing Date: Fri, 2 Nov 2018 11:24:26 +0800 Subject: [PATCH 12/17] add i2c slave --- lib/drivers/i2c.c | 60 +++++++++++++++++++++++++++++++++++++++ lib/drivers/include/i2c.h | 16 +++++++++++ 2 files changed, 76 insertions(+) diff --git a/lib/drivers/i2c.c b/lib/drivers/i2c.c index 857979a0..313f6abe 100644 --- a/lib/drivers/i2c.c +++ b/lib/drivers/i2c.c @@ -21,6 +21,14 @@ #include "string.h" #include "sysctl.h" +typedef struct _i2c_slave_context +{ + uint32_t i2c_num; + const i2c_slave_handler_t *slave_handler; +} i2c_slave_context_t; + +i2c_slave_context_t slave_context; + volatile i2c_t* const i2c[3] = { (volatile i2c_t*)I2C0_BASE_ADDR, @@ -65,6 +73,58 @@ void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t addr i2c_adapter->enable = I2C_ENABLE_ENABLE; } +static int i2c_slave_irq(void *userdata) +{ + i2c_slave_context_t *context = (i2c_slave_context_t *)userdata; + volatile i2c_t *i2c_adapter = i2c[context->i2c_num]; + uint32_t status = i2c_adapter->intr_stat; + if (status & I2C_INTR_STAT_START_DET) + { + context->slave_handler->on_event(I2C_EV_START); + readl(&i2c_adapter->clr_start_det); + } + if (status & I2C_INTR_STAT_STOP_DET) + { + context->slave_handler->on_event(I2C_EV_STOP); + readl(&i2c_adapter->clr_stop_det); + } + if (status & I2C_INTR_STAT_RX_FULL) + { + context->slave_handler->on_receive(i2c_adapter->data_cmd); + } + if (status & I2C_INTR_STAT_RD_REQ) + { + i2c_adapter->data_cmd = context->slave_handler->on_transmit(); + readl(&i2c_adapter->clr_rd_req); + } + return 0; +} + +void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, + const i2c_slave_handler_t *handler) +{ + configASSERT(address_width == 7 || address_width == 10); + volatile i2c_t *i2c_adapter = i2c[i2c_num]; + slave_context.i2c_num = i2c_num; + slave_context.slave_handler = handler; + + i2c_clk_init(i2c_num); + i2c_adapter->enable = 0; + i2c_adapter->con = (address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(1) | I2C_CON_STOP_DET_IFADDRESSED; + i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(37); + i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(40); + i2c_adapter->sar = I2C_SAR_ADDRESS(slave_address); + i2c_adapter->rx_tl = I2C_RX_TL_VALUE(0); + i2c_adapter->tx_tl = I2C_TX_TL_VALUE(0); + i2c_adapter->intr_mask = I2C_INTR_MASK_RX_FULL | I2C_INTR_MASK_START_DET | I2C_INTR_MASK_STOP_DET | I2C_INTR_MASK_RD_REQ; + + plic_set_priority(IRQN_I2C0_INTERRUPT + i2c_num, 1); + plic_irq_register(IRQN_I2C0_INTERRUPT + i2c_num, i2c_slave_irq, &slave_context); + plic_irq_enable(IRQN_I2C0_INTERRUPT + i2c_num); + + i2c_adapter->enable = I2C_ENABLE_ENABLE; +} + int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len) { configASSERT(i2c_num < I2C_MAX_NUM); diff --git a/lib/drivers/include/i2c.h b/lib/drivers/include/i2c.h index a6a2e444..c7eeea5f 100644 --- a/lib/drivers/include/i2c.h +++ b/lib/drivers/include/i2c.h @@ -340,6 +340,20 @@ typedef enum _i2c_bus_speed_mode I2C_BS_HIGHSPEED } i2c_bus_speed_mode_t; +typedef enum _i2c_event +{ + I2C_EV_START, + I2C_EV_RESTART, + I2C_EV_STOP +} i2c_event_t; + +typedef struct _i2c_slave_handler +{ + void(*on_receive)(uint32_t data); + uint32_t(*on_transmit)(); + void(*on_event)(i2c_event_t event); +} i2c_slave_handler_t; + /** * @brief Set i2c params * @@ -363,6 +377,8 @@ void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t addr * - Other Fail */ int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len); +void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, + const i2c_slave_handler_t *handler); /** * @brief I2c send data by dma From 266494b3354079ab5a2bf6300612327262d38ea9 Mon Sep 17 00:00:00 2001 From: jiangxiangbing Date: Fri, 2 Nov 2018 11:32:25 +0800 Subject: [PATCH 13/17] i2c_slave : add comments --- lib/drivers/include/i2c.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/drivers/include/i2c.h b/lib/drivers/include/i2c.h index c7eeea5f..6b0bb5cd 100644 --- a/lib/drivers/include/i2c.h +++ b/lib/drivers/include/i2c.h @@ -377,6 +377,15 @@ void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t addr * - Other Fail */ int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t send_buf_len); + +/** + * @brief Init i2c as slave mode. + * + * @param[in] i2c_num i2c number + * @param[in] slave_address i2c slave device address + * @param[in] address_width address width 7bit or 10bit + * @param[in] handler Handle of i2c slave interrupt function. + */ void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, const i2c_slave_handler_t *handler); From 48e6fee93bc34cddb6ca052735697f3d9f61104f Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Fri, 2 Nov 2018 20:04:17 +0800 Subject: [PATCH 14/17] Modify syscall epc --- lib/bsp/entry_user.c | 5 +++++ lib/bsp/syscalls.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/bsp/entry_user.c b/lib/bsp/entry_user.c index d9d3a2de..59f96d27 100644 --- a/lib/bsp/entry_user.c +++ b/lib/bsp/entry_user.c @@ -99,3 +99,8 @@ void _init_bsp(int core_id, int number_of_cores) exit(ret); } +int pthread_setcancelstate(int __state, int *__oldstate) +{ + return 0; +} + diff --git a/lib/bsp/syscalls.c b/lib/bsp/syscalls.c index ccd05f2a..63ded7a6 100644 --- a/lib/bsp/syscalls.c +++ b/lib/bsp/syscalls.c @@ -390,7 +390,7 @@ handle_ecall(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs regs[17] /* n */ ); - return epc + ((*(unsigned short *)epc & 3) == 3 ? 4 : 2); + return epc + 4; } uintptr_t __attribute__((weak, alias("handle_ecall"))) From a7bc36d34a0bcae6a40da2b34b376772d25b21f0 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Fri, 2 Nov 2018 20:52:15 +0800 Subject: [PATCH 15/17] Use weak function for handle_irq_m_ext Using weak function for handle_irq_m_ext, therefore, user can overload it to realize custom interrupt handling. --- lib/drivers/plic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/drivers/plic.c b/lib/drivers/plic.c index 72bed79d..988cc0c9 100644 --- a/lib/drivers/plic.c +++ b/lib/drivers/plic.c @@ -155,7 +155,8 @@ void plic_irq_deregister(plic_irq_t irq) } /*Entry Point for PLIC Interrupt Handler*/ -uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc) +uintptr_t __attribute__((weak)) +handle_irq_m_ext(uintptr_t cause, uintptr_t epc) { /* * After the highest-priority pending interrupt is claimed by a target From 7f165979c6acd0e4fe08ebbdddf94d6734abe31e Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Fri, 2 Nov 2018 20:52:23 +0800 Subject: [PATCH 16/17] Add src gitignore --- src/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..b6896701 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +*/ +!hello_world/ \ No newline at end of file From f60a9de816a5c101ba38c563668966407a92b984 Mon Sep 17 00:00:00 2001 From: zhaozhongxiang Date: Mon, 5 Nov 2018 10:59:38 +0800 Subject: [PATCH 17/17] Del weak function of handle_irq_m_ext --- lib/bsp/interrupt.c | 2 +- lib/drivers/uart.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bsp/interrupt.c b/lib/bsp/interrupt.c index 4695f990..a82fea8b 100644 --- a/lib/bsp/interrupt.c +++ b/lib/bsp/interrupt.c @@ -36,7 +36,7 @@ handle_irq_m_soft(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t uintptr_t __attribute__((weak, alias("handle_irq_dummy"))) handle_irq_m_timer(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32]); -uintptr_t __attribute__((weak, alias("handle_irq_dummy"))) +extern uintptr_t handle_irq_m_ext(uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32]); uintptr_t __attribute__((weak)) diff --git a/lib/drivers/uart.c b/lib/drivers/uart.c index bf0fb96d..3e047fc7 100644 --- a/lib/drivers/uart.c +++ b/lib/drivers/uart.c @@ -183,5 +183,5 @@ void uart_init(uart_device_number_t channel) ring_recv[channel] = rb; plic_irq_register(IRQN_UART1_INTERRUPT + channel, on_irq_apbuart_recv, (void *)uart[channel]); plic_set_priority(IRQN_UART1_INTERRUPT + channel, 1); - plic_irq_enable(IRQN_UART1_INTERRUPT); + plic_irq_enable(IRQN_UART1_INTERRUPT + channel); }