Add apu comment, kpu for new nncase, fix spi 32bit mode bug
This commit is contained in:
parent
2c38d4e0e7
commit
c41a0ff39c
|
@ -1,3 +1,17 @@
|
|||
/* 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
@ -18,7 +32,7 @@ the average value of samples from different channels is required, this right shi
|
|||
is used to perform division.
|
||||
0x0: no right shift; 0x1: right shift by 1-bit;
|
||||
. . . . . .
|
||||
0xF: right shift by 14-bit.
|
||||
0xF: right shift by 15-bit.
|
||||
*/
|
||||
void apu_set_audio_gain(uint16_t gain)
|
||||
{
|
||||
|
@ -40,6 +54,7 @@ void apu_set_smpl_shift(uint8_t smpl_shift)
|
|||
tmp.smpl_shift_bits = smpl_shift;
|
||||
apu->bf_dwsz_cfg_reg = tmp;
|
||||
}
|
||||
|
||||
/*get sampling shift*/
|
||||
uint8_t apu_get_smpl_shift(void)
|
||||
{
|
||||
|
@ -49,13 +64,13 @@ uint8_t apu_get_smpl_shift(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* BF unit sound channel enable control bits. Bit 'x' corresponds to enable bit for sound
|
||||
* channel 'x' (x = 0, 1, 2, . . ., 7). BF sound channels are related with I2S host RX channels.
|
||||
* BF sound channel 0/1 correspond to the left/right channel of I2S RX0; BF channel 2/3 correspond
|
||||
* APU unit sound channel enable control bits. Bit 'x' corresponds to enable bit for sound
|
||||
* channel 'x' (x = 0, 1, 2, . . ., 7). APU sound channels are related with I2S host RX channels.
|
||||
* APU sound channel 0/1 correspond to the left/right channel of I2S RX0; APU channel 2/3 correspond
|
||||
* to left/right channels of I2S RX1; and things like that. Software write '1' to enable a sound
|
||||
* channel and hardware automatically clear the bit after the sample buffers used for direction
|
||||
* searching is filled full.
|
||||
* 0x1: writing '1' to enable the corresponding BF sound channel.
|
||||
* 0x1: writing '1' to enable the corresponding APU sound channel.
|
||||
*/
|
||||
void apu_set_channel_enabled(uint8_t channel_bit)
|
||||
{
|
||||
|
@ -69,13 +84,13 @@ void apu_set_channel_enabled(uint8_t channel_bit)
|
|||
}
|
||||
|
||||
/*
|
||||
* BF unit sound channel enable control bits. Bit 'x' corresponds to enable bit for sound
|
||||
* channel 'x' (x = 0, 1, 2, . . ., 7). BF sound channels are related with I2S host RX channels.
|
||||
* BF sound channel 0/1 correspond to the left/right channel of I2S RX0; BF channel 2/3 correspond
|
||||
* APU unit sound channel enable control bits. Bit 'x' corresponds to enable bit for sound
|
||||
* channel 'x' (x = 0, 1, 2, . . ., 7). APU sound channels are related with I2S host RX channels.
|
||||
* APU sound channel 0/1 correspond to the left/right channel of I2S RX0; APU channel 2/3 correspond
|
||||
* to left/right channels of I2S RX1; and things like that. Software write '1' to enable a sound
|
||||
* channel and hardware automatically clear the bit after the sample buffers used for direction
|
||||
* searching is filled full.
|
||||
* 0x1: writing '1' to enable the corresponding BF sound channel.
|
||||
* 0x1: writing '1' to enable the corresponding APU sound channel.
|
||||
*/
|
||||
void apu_channel_enable(uint8_t channel_bit)
|
||||
{
|
||||
|
@ -267,7 +282,6 @@ void apu_voc_set_direction(en_bf_dir_t direction)
|
|||
apu->bf_ctl_reg = bf_en_tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*I2S host beam-forming Filter FIR16 Coefficient Register
|
||||
*/
|
||||
|
@ -283,6 +297,7 @@ void apu_dir_set_prev_fir(uint16_t *fir_coef)
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
void apu_dir_set_post_fir(uint16_t *fir_coef)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
@ -295,6 +310,7 @@ void apu_dir_set_post_fir(uint16_t *fir_coef)
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
void apu_voc_set_prev_fir(uint16_t *fir_coef)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
@ -307,6 +323,7 @@ void apu_voc_set_prev_fir(uint16_t *fir_coef)
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
void apu_voc_set_post_fir(uint16_t *fir_coef)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
@ -367,7 +384,6 @@ void apu_voc_set_interrupt_mask(uint8_t voc_int_mask)
|
|||
apu->bf_int_mask_reg = tmp;
|
||||
}
|
||||
|
||||
|
||||
void apu_set_down_size(uint8_t dir_dwn_size, uint8_t voc_dwn_size)
|
||||
{
|
||||
apu_dwsz_cfg_t tmp = apu->bf_dwsz_cfg_reg;
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/* 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.
|
||||
*/
|
||||
#ifndef _apu_H_
|
||||
#define _apu_H_
|
||||
|
||||
|
@ -160,7 +174,7 @@ typedef struct _apu_fir_coef
|
|||
typedef struct _apu_dwsz_cfg
|
||||
{
|
||||
/**
|
||||
* TThe down-sizing ratio used for direction searching.
|
||||
* The down-sizing ratio used for direction searching.
|
||||
* 0x0: no down-sizing;
|
||||
* 0x1: 1/2 down sizing;
|
||||
* 0x2: 1/3 down sizing;
|
||||
|
@ -283,38 +297,237 @@ typedef struct _apu_reg
|
|||
|
||||
extern volatile apu_reg_t *const apu;
|
||||
|
||||
/**
|
||||
* @brief Voice strength average value right shift factor. When performing sound direction detect,
|
||||
* the average value of samples from different channels is required, this right shift factor
|
||||
* is used to perform division.
|
||||
*
|
||||
* @param[in] gain value of audio gain.
|
||||
* 0x0: no right shift;
|
||||
* 0x1: right shift by 1-bit;
|
||||
* . . . . . .
|
||||
* 0xF: right shift by 15-bit.
|
||||
*
|
||||
*/
|
||||
void apu_set_audio_gain(uint16_t gain);
|
||||
|
||||
/**
|
||||
* @brief Set sampling shift.
|
||||
*
|
||||
* @param[in] smpl_shift vlaue of sampling shift
|
||||
*
|
||||
*/
|
||||
void apu_set_smpl_shift(uint8_t smpl_shift);
|
||||
|
||||
/**
|
||||
* @brief Get sampling shift
|
||||
*
|
||||
* @return vlaue of sampling shift
|
||||
*/
|
||||
uint8_t apu_get_smpl_shift(void);
|
||||
|
||||
/**
|
||||
* @brief APU unit sound channel enable control bits. Bit 'x' corresponds to enable bit for sound
|
||||
* channel 'x' (x = 0, 1, 2, . . ., 7). APU sound channels are related with I2S host RX channels.
|
||||
* APU sound channel 0/1 correspond to the left/right channel of I2S RX0; APU channel 2/3 correspond
|
||||
* to left/right channels of I2S RX1; and things like that. Software write '1' to enable a sound
|
||||
* channel and hardware automatically clear the bit after the sample buffers used for direction
|
||||
* searching is filled full.
|
||||
*
|
||||
*
|
||||
* @param[in] channel_bit APU sound channel.0x1: writing
|
||||
* '1' to enable the corresponding APU sound channel.
|
||||
*
|
||||
*/
|
||||
void apu_set_channel_enabled(uint8_t channel_bit);
|
||||
|
||||
/**
|
||||
* @brief I2S host beam-forming direction sample ibuffer read index configure register
|
||||
*
|
||||
* @param[in] dir_num the direction of index
|
||||
* @param[in] dir_bidx
|
||||
*
|
||||
*/
|
||||
void apu_set_direction_delay(uint8_t dir_num, uint8_t *dir_bidx);
|
||||
|
||||
/**
|
||||
* @brief I2S host beam-forming direction sample ibuffer read index configure register
|
||||
*
|
||||
* @param[in] radius radius
|
||||
* @param[in] mic_num_a_circle the num of mic per circle
|
||||
* @param[in] center 0: no center mic, 1:have center mic
|
||||
*
|
||||
*/
|
||||
void apu_set_delay(float radius, uint8_t mic_num_a_circle, uint8_t center);
|
||||
|
||||
/**
|
||||
* @brief Set ffp shift factor
|
||||
*
|
||||
* @param[in] enable_flag enable fft
|
||||
* @param[in] shift_factor shift factor
|
||||
*
|
||||
*/
|
||||
void apu_set_fft_shift_factor(uint8_t enable_flag, uint16_t shift_factor);
|
||||
void apu_set_down_size(uint8_t dir_dwn_siz, uint8_t voc_dwn_siz); /*split to 2 functions*/
|
||||
void apu_set_interrupt_mask(uint8_t dir_int_mask, uint8_t voc_int_mask); /*split to 2 functions*/
|
||||
|
||||
/**
|
||||
* @brief Set down-sizing ratio used for voice direction searching and voice stream generation.
|
||||
*
|
||||
* @param[in] dir_dwn_siz down-sizing ratio used for voice direction searching
|
||||
* 0x0: no down-sizing
|
||||
* 0x1: 1/2 down sizing
|
||||
* 0x2: 1/3 down sizing
|
||||
* . . . . . .
|
||||
* 0xF: 1/16 down sizing
|
||||
* @param[in] voc_dwn_siz down-sizing ratio used for voice stream generation
|
||||
* 0x0: no down-sizing
|
||||
* 0x1: 1/2 down sizing
|
||||
* 0x2: 1/3 down sizing
|
||||
* . . . . . .
|
||||
* 0xF: 1/16 down sizing
|
||||
*/
|
||||
void apu_set_down_size(uint8_t dir_dwn_siz, uint8_t voc_dwn_siz);
|
||||
|
||||
/**
|
||||
* @brief Set direction and voice interrupt mask
|
||||
*
|
||||
* @param[in] dir_int_mask direction interrupt mask
|
||||
* @param[in] voc_int_mask voice interrupt mask
|
||||
*
|
||||
*/
|
||||
void apu_set_interrupt_mask(uint8_t dir_int_mask, uint8_t voc_int_mask);
|
||||
|
||||
/**
|
||||
* @brief Enable direction searching.
|
||||
*
|
||||
*/
|
||||
void apu_dir_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Reset direction searching.
|
||||
*
|
||||
*/
|
||||
void apu_dir_reset(void);
|
||||
|
||||
void apu_dir_set_prev_fir(uint16_t *fir_coef);
|
||||
|
||||
void apu_dir_set_post_fir(uint16_t *fir_coef);
|
||||
|
||||
/**
|
||||
* @brief Set down-sizing ratio used for voice direction searching
|
||||
*
|
||||
* @param[in] dir_dwn_siz down-sizing ratio used for voice direction searching
|
||||
* 0x0: no down-sizing
|
||||
* 0x1: 1/2 down sizing
|
||||
* 0x2: 1/3 down sizing
|
||||
* . . . . . .
|
||||
* 0xF: 1/16 down sizing
|
||||
*/
|
||||
void apu_dir_set_down_size(uint8_t dir_dwn_size);
|
||||
|
||||
/**
|
||||
* @brief Set direction searching interrupt mask
|
||||
*
|
||||
* @param[in] dir_int_mask direction interrupt mask
|
||||
*
|
||||
*/
|
||||
void apu_dir_set_interrupt_mask(uint8_t dir_int_mask);
|
||||
|
||||
/**
|
||||
* @brief Clear direction interrupt
|
||||
*
|
||||
*/
|
||||
void apu_dir_clear_int_state(void);
|
||||
|
||||
/**
|
||||
* @brief Valid voice sample stream generation enable bit. After sound direction searching is done, software can
|
||||
* configure this bit to generate a stream of voice samples for voice recognition.
|
||||
*
|
||||
* @param[in] enable_flag 0x1: enable output of voice sample stream. 0x0: stop the voice samlpe stream output.
|
||||
*
|
||||
*/
|
||||
void apu_voc_enable(uint8_t enable_flag);
|
||||
|
||||
/**
|
||||
* @brief Reset voice sample
|
||||
*
|
||||
*/
|
||||
void apu_voc_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Target direction select for valid voice output. When the source voice direaction searching
|
||||
* is done, software can use this field to select one from 16 sound directions for the following
|
||||
* voice recognition
|
||||
*
|
||||
* @param[in] direction 0x0: select sound direction 0;
|
||||
* 0x1: select sound direction 1;
|
||||
* . . . . . .
|
||||
* 0xF: select sound direction 15.
|
||||
*/
|
||||
void apu_voc_set_direction(en_bf_dir_t direction);
|
||||
|
||||
void apu_voc_set_prev_fir(uint16_t *fir_coef);
|
||||
|
||||
void apu_voc_set_post_fir(uint16_t *fir_coef);
|
||||
|
||||
/**
|
||||
* @brief Set down-sizing ratio used for voice stream generation.
|
||||
*
|
||||
* @param[in] voc_dwn_siz down-sizing ratio used for voice stream generation
|
||||
* 0x0: no down-sizing
|
||||
* 0x1: 1/2 down sizing
|
||||
* 0x2: 1/3 down sizing
|
||||
* . . . . . .
|
||||
* 0xF: 1/16 down sizing
|
||||
*/
|
||||
void apu_voc_set_down_size(uint8_t voc_dwn_size);
|
||||
|
||||
/**
|
||||
* @brief Set voice stream generation interrupt mask
|
||||
*
|
||||
* @param[in] voc_int_mask voice interrupt mask
|
||||
*
|
||||
*/
|
||||
void apu_voc_set_interrupt_mask(uint8_t voc_int_mask);
|
||||
|
||||
/**
|
||||
* @brief Clear voice interrupt
|
||||
*
|
||||
*/
|
||||
void apu_voc_clear_int_state(void);
|
||||
|
||||
/**
|
||||
* @brief Reset saturation_counter
|
||||
*
|
||||
*/
|
||||
void apu_voc_reset_saturation_counter(void);
|
||||
|
||||
/**
|
||||
* @brief Get saturation counter
|
||||
*
|
||||
* @return vlaue of saturation counter.heigh 16 bit is counter, low 16 bit is total
|
||||
*/
|
||||
uint32_t apu_voc_get_saturation_counter(void);
|
||||
|
||||
/**
|
||||
* @brief set saturation limit
|
||||
*
|
||||
* @param[in] upper heigh 16 bit is counter
|
||||
* @param[in] bottom low 16 bit is total
|
||||
*
|
||||
*/
|
||||
void apu_voc_set_saturation_limit(uint16_t upper, uint16_t bottom);
|
||||
|
||||
/**
|
||||
* @brief Get saturation limit
|
||||
*
|
||||
* @return vlaue of saturation limit.heigh 16 bit is counter, low 16 bit is total
|
||||
*/
|
||||
uint32_t apu_voc_get_saturation_limit(void);
|
||||
|
||||
/**
|
||||
* @brief Print apu setting for debug
|
||||
*
|
||||
*/
|
||||
void apu_print_setting(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -425,11 +425,11 @@ int i2c_recv_data(i2c_device_number_t i2c_num, const uint8_t *send_buf, size_t s
|
|||
*
|
||||
* @param[in] dma_send_channel_num send dma channel
|
||||
* @param[in] dma_receive_channel_num receive dma channel
|
||||
* @param[in] i2c_num i2c number
|
||||
* @param[in] send_buf send data address
|
||||
* @param[in] send_buf_len length of send buf
|
||||
* @param[in] receive_buf receive buf address
|
||||
* @param[in] receive_buf_len length of receive buf
|
||||
* @param[in] i2c_num i2c number
|
||||
* @param[in] send_buf send data address
|
||||
* @param[in] send_buf_len length of send buf
|
||||
* @param[in] receive_buf receive buf address
|
||||
* @param[in] receive_buf_len length of receive buf
|
||||
*
|
||||
* @return result
|
||||
* - 0 Success
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/* 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.
|
||||
*/
|
||||
#ifndef _KPU_H
|
||||
#define _KPU_H
|
||||
|
||||
|
@ -840,9 +854,53 @@ void kpu_matmul_end(const uint8_t *src, int channels, float *dest, const quantiz
|
|||
*/
|
||||
void kpu_dequantize(const uint8_t *src, const quantize_param_t *src_param, size_t count, float *dest);
|
||||
|
||||
/**
|
||||
* @brief Kpu load kmodel
|
||||
*
|
||||
* @param[in] ctx Kmodel object
|
||||
* @param[in] buffer Kmodel buffer
|
||||
*
|
||||
* @return result
|
||||
* - 0 Success
|
||||
* - Other Fail.
|
||||
*/
|
||||
int kpu_load_kmodel(kpu_model_context_t *ctx, const uint8_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief Kpu free kmodel buffer
|
||||
*
|
||||
* @param[in] ctx kmodel object
|
||||
*
|
||||
*/
|
||||
void kpu_model_free(kpu_model_context_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Kpu load kmodel
|
||||
*
|
||||
* @param[in] ctx Kmodel object
|
||||
* @param[in] index Output index
|
||||
* @param[in] data Output data
|
||||
* @param[in] size Output data size
|
||||
*
|
||||
* @return result
|
||||
* - 0 Success
|
||||
* - Other Fail.
|
||||
*/
|
||||
int kpu_get_output(kpu_model_context_t *ctx, uint32_t index, uint8_t **data, size_t *size);
|
||||
|
||||
/**
|
||||
* @brief Kpu run kmodel
|
||||
*
|
||||
* @param[in] ctx Kmodel object
|
||||
* @param[in] src Source data
|
||||
* @param[in] dma_ch Dma channel
|
||||
* @param[in] done_callback Kpu complete callback
|
||||
* @param[in] userdata Data of callback
|
||||
*
|
||||
* @return result
|
||||
* - 0 Success
|
||||
* - Other Fail.
|
||||
*/
|
||||
int kpu_run_kmodel(kpu_model_context_t *ctx, const uint8_t *src, dmac_channel_number_t dma_ch, kpu_done_callback_t done_callback, void *userdata);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "sysctl.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
volatile spi_t *const spi[4] =
|
||||
{
|
||||
|
@ -222,6 +223,11 @@ void spi_send_data_normal(spi_device_num_t spi_num, spi_chip_select_t chip_selec
|
|||
uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F;
|
||||
spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length);
|
||||
|
||||
uint8_t v_misalign_flag = 0;
|
||||
uint32_t v_send_data;
|
||||
if((uintptr_t)tx_buff % frame_width)
|
||||
v_misalign_flag = 1;
|
||||
|
||||
spi_handle->ssienr = 0x01;
|
||||
spi_handle->ser = 1U << chip_select;
|
||||
uint32_t i = 0;
|
||||
|
@ -233,13 +239,37 @@ void spi_send_data_normal(spi_device_num_t spi_num, spi_chip_select_t chip_selec
|
|||
{
|
||||
case SPI_TRANS_INT:
|
||||
fifo_len = fifo_len / 4 * 4;
|
||||
for (index = 0; index < fifo_len / 4; index++)
|
||||
spi_handle->dr[0] = ((uint32_t *)tx_buff)[i++];
|
||||
if(v_misalign_flag)
|
||||
{
|
||||
for(index = 0; index < fifo_len; index +=4)
|
||||
{
|
||||
i += 4;
|
||||
memcpy(&v_send_data, tx_buff + i , 4);
|
||||
spi_handle->dr[0] = v_send_data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 0; index < fifo_len / 4; index++)
|
||||
spi_handle->dr[0] = ((uint32_t *)tx_buff)[i++];
|
||||
}
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
fifo_len = fifo_len / 2 * 2;
|
||||
for (index = 0; index < fifo_len / 2; index++)
|
||||
spi_handle->dr[0] = ((uint16_t *)tx_buff)[i++];
|
||||
if(v_misalign_flag)
|
||||
{
|
||||
for(index = 0; index < fifo_len; index +=2)
|
||||
{
|
||||
i += 4;
|
||||
memcpy(&v_send_data, tx_buff + (i++), 2);
|
||||
spi_handle->dr[0] = v_send_data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 0; index < fifo_len / 2; index++)
|
||||
spi_handle->dr[0] = ((uint16_t *)tx_buff)[i++];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (index = 0; index < fifo_len; index++)
|
||||
|
@ -770,7 +800,6 @@ void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_
|
|||
case SPI_TRANS_SHORT:
|
||||
for (index = 0; index < fifo_len; index++)
|
||||
((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0];
|
||||
|
||||
break;
|
||||
default:
|
||||
for (index = 0; index < fifo_len; index++)
|
||||
|
@ -821,10 +850,6 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num,
|
|||
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;
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
|
@ -842,14 +867,14 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num,
|
|||
v_recv_len = rx_len;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
if(frame_width == SPI_TRANS_INT)
|
||||
spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, cmd_buff, cmd_len, rx_buff, v_recv_len);
|
||||
else
|
||||
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)
|
||||
{
|
||||
case SPI_TRANS_INT:
|
||||
for(i = 0; i < v_recv_len; i++)
|
||||
((uint32_t *)rx_buff)[i] = read_buf[i];
|
||||
break;
|
||||
case SPI_TRANS_SHORT:
|
||||
for(i = 0; i < v_recv_len; i++)
|
||||
|
@ -861,7 +886,8 @@ void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num,
|
|||
break;
|
||||
}
|
||||
|
||||
free(write_cmd);
|
||||
if(frame_width != SPI_TRANS_INT)
|
||||
free(write_cmd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1002,7 +1028,7 @@ static void spi_slave_command_mode(void)
|
|||
{
|
||||
volatile spi_t *spi_handle = spi[2];
|
||||
uint8_t cmd_data[8], sum = 0;
|
||||
|
||||
|
||||
spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1);
|
||||
uint32_t data_width = g_instance.data_bit_length / 8;
|
||||
spi_device_num_t spi_num = SPI_DEVICE_2;
|
||||
|
@ -1114,11 +1140,11 @@ static void spi_slave_command_mode(void)
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (g_instance.command.cmd == WRITE_DATA_BLOCK)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs);
|
||||
|
||||
|
||||
spi_handle->dmacr = 0x01;
|
||||
spi_handle->imr = 0x00;
|
||||
spi_handle->ssienr = 0x01;
|
||||
|
@ -1128,7 +1154,7 @@ static void spi_slave_command_mode(void)
|
|||
dmac_set_single_mode(g_instance.dmac_channel, (void *)(&spi_handle->dr[0]), (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
|
||||
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4);
|
||||
}
|
||||
else if (g_instance.command.cmd == READ_DATA_BLOCK)
|
||||
else if (g_instance.command.cmd == READ_DATA_BLOCK)
|
||||
{
|
||||
spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs);
|
||||
spi_set_tmod(2, SPI_TMOD_TRANS);
|
||||
|
@ -1290,7 +1316,7 @@ void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t
|
|||
gpiohs_set_drive_mode(g_instance.int_pin, GPIO_DM_INPUT_PULL_UP);
|
||||
gpiohs_set_pin_edge(g_instance.int_pin, GPIO_PE_RISING);
|
||||
gpiohs_set_irq(g_instance.int_pin, 3, spi_slave_cs_irq);
|
||||
|
||||
|
||||
plic_set_priority(IRQN_SPI_SLAVE_INTERRUPT, 4);
|
||||
plic_irq_enable(IRQN_SPI_SLAVE_INTERRUPT);
|
||||
plic_irq_register(IRQN_SPI_SLAVE_INTERRUPT, spi_slave_irq, NULL);
|
||||
|
|
Loading…
Reference in New Issue