504 lines
14 KiB
C
504 lines
14 KiB
C
|
/**
|
||
|
*********************************************************************************
|
||
|
*
|
||
|
* @file ald_crc.c
|
||
|
* @brief CRC module driver.
|
||
|
*
|
||
|
* @version V1.0
|
||
|
* @date 06 Mar. 2023
|
||
|
* @author AE Team
|
||
|
* @note
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 06 Mar. 2023 Lisq The first version
|
||
|
*
|
||
|
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* 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
|
||
|
*
|
||
|
* 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 "ald_crc.h"
|
||
|
|
||
|
/** @addtogroup ES32VF2264_ALD
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/** @defgroup CRC CRC
|
||
|
* @brief CRC module driver
|
||
|
* @{
|
||
|
*/
|
||
|
/** @addtogroup CRC_Private_Functions CRC Private Functions
|
||
|
* @{
|
||
|
*/
|
||
|
void ald_crc_reset(ald_crc_handle_t *hperh);
|
||
|
static void crc_dma_calculate_cplt(void *arg);
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
|
||
|
/** @defgroup CRC_Public_Functions CRC Public Functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/** @defgroup CRC_Public_Functions_Group1 Initialization functions
|
||
|
* @brief Initialization and Configuration functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Initializes the CRC mode according to the specified parameters in
|
||
|
* the crc_handle_t and create the associated handle.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_init(ald_crc_handle_t *hperh)
|
||
|
{
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
if (hperh == NULL)
|
||
|
return ALD_ERROR;
|
||
|
|
||
|
assert_param(IS_CRC(hperh->perh));
|
||
|
assert_param(IS_CRC_MODE(hperh->init.mode));
|
||
|
assert_param(IS_FUNC_STATE(hperh->init.chs_rev));
|
||
|
assert_param(IS_FUNC_STATE(hperh->init.data_inv));
|
||
|
assert_param(IS_FUNC_STATE(hperh->init.data_rev));
|
||
|
assert_param(IS_FUNC_STATE(hperh->init.chs_inv));
|
||
|
|
||
|
ald_crc_reset(hperh);
|
||
|
__LOCK(hperh);
|
||
|
|
||
|
ALD_CRC_ENABLE(hperh);
|
||
|
|
||
|
tmp = hperh->perh->CR;
|
||
|
|
||
|
tmp |= ((hperh->init.chs_rev << CRC_CR_CHSREV_POS) | (hperh->init.data_inv << CRC_CR_DATINV_POS) |
|
||
|
(hperh->init.chs_inv << CRC_CR_CHSINV_POS) | (hperh->init.mode << CRC_CR_MODE_POSS) |
|
||
|
(ALD_CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS) | (hperh->init.data_rev << CRC_CR_DATREV_POS) |
|
||
|
(0 << CRC_CR_BYTORD_POS));
|
||
|
|
||
|
hperh->perh->CR = tmp;
|
||
|
hperh->perh->SEED = hperh->init.seed;
|
||
|
ALD_CRC_RESET(hperh);
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
|
||
|
__UNLOCK(hperh);
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup CRC_Public_Functions_Group2 Calculate functions
|
||
|
* @brief Calculate functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Calculate the crc value of data by byte.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @param buf: Pointer to data buffer
|
||
|
* @param size: The size of data to be calculate
|
||
|
* @retval result, the result of a amount data
|
||
|
*/
|
||
|
uint32_t ald_crc_calculate(ald_crc_handle_t *hperh, uint8_t *buf, uint32_t size)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
uint32_t ret;
|
||
|
|
||
|
assert_param(IS_CRC(hperh->perh));
|
||
|
|
||
|
if (buf == NULL || size == 0)
|
||
|
return 0;
|
||
|
|
||
|
__LOCK(hperh);
|
||
|
MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, ALD_CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS);
|
||
|
hperh->state = ALD_CRC_STATE_BUSY;
|
||
|
|
||
|
for (i = 0; i < size; i++)
|
||
|
*((volatile uint8_t *)&(hperh->perh->DATA)) = buf[i];
|
||
|
|
||
|
ret = CRC->CHECKSUM;
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
__UNLOCK(hperh);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Calculate the crc value of data by halfword.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @param buf: Pointer to data buffer
|
||
|
* @param size: The size of data to be calculate,width is 2 bytes.
|
||
|
* @retval result, the result of a amount data
|
||
|
*/
|
||
|
uint32_t ald_crc_calculate_halfword(ald_crc_handle_t *hperh, uint16_t *buf, uint32_t size)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
uint32_t ret;
|
||
|
|
||
|
assert_param(IS_CRC(hperh->perh));
|
||
|
|
||
|
if (buf == NULL || size == 0)
|
||
|
return 0;
|
||
|
|
||
|
__LOCK(hperh);
|
||
|
MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, ALD_CRC_DATASIZE_16 << CRC_CR_DATLEN_POSS);
|
||
|
hperh->state = ALD_CRC_STATE_BUSY;
|
||
|
|
||
|
for (i = 0; i < size; i++)
|
||
|
*((volatile uint16_t *)&(hperh->perh->DATA)) = buf[i];
|
||
|
|
||
|
ret = CRC->CHECKSUM;
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
__UNLOCK(hperh);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Calculate the crc value of data by word.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @param buf: Pointer to data buffer
|
||
|
* @param size: The size of data to be calculate,width is 4 bytes
|
||
|
* @retval result, the result of a amount data
|
||
|
*/
|
||
|
uint32_t ald_crc_calculate_word(ald_crc_handle_t *hperh, uint32_t *buf, uint32_t size)
|
||
|
{
|
||
|
uint32_t i;
|
||
|
uint32_t ret;
|
||
|
|
||
|
assert_param(IS_CRC(hperh->perh));
|
||
|
|
||
|
if (buf == NULL || size == 0)
|
||
|
return 0;
|
||
|
|
||
|
__LOCK(hperh);
|
||
|
MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, ALD_CRC_DATASIZE_32 << CRC_CR_DATLEN_POSS);
|
||
|
hperh->state = ALD_CRC_STATE_BUSY;
|
||
|
|
||
|
for (i = 0; i < size; i++)
|
||
|
CRC->DATA = buf[i];
|
||
|
|
||
|
for (i = 0; i < 3; i++);
|
||
|
|
||
|
ret = CRC->CHECKSUM;
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
__UNLOCK(hperh);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup CRC_Public_Functions_Group3 DMA operation functions
|
||
|
* @brief DMA operation functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Calculate an amount of data used dma channel
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @param buf: Pointer to data buffer
|
||
|
* @param res: Pointer to result
|
||
|
* @param size: Amount of data to be Calculate
|
||
|
* @param channel: DMA channel as CRC transmit
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_calculate_by_dma(ald_crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel)
|
||
|
{
|
||
|
if (hperh->state != ALD_CRC_STATE_READY)
|
||
|
return ALD_BUSY;
|
||
|
|
||
|
if (buf == NULL || size == 0)
|
||
|
return ALD_ERROR;
|
||
|
|
||
|
__LOCK(hperh);
|
||
|
MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, ALD_CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS);
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_BUSY;
|
||
|
|
||
|
hperh->cal_buf = buf;
|
||
|
hperh->cal_res = res;
|
||
|
|
||
|
if (hperh->hdma.perh == NULL)
|
||
|
hperh->hdma.perh = DMA;
|
||
|
|
||
|
hperh->hdma.cplt_tc_arg = (void *)hperh;
|
||
|
hperh->hdma.cplt_tc_cbk = &crc_dma_calculate_cplt;
|
||
|
|
||
|
ald_dma_config_struct(&(hperh->hdma.config));
|
||
|
hperh->hdma.config.src_data_width = ALD_DMA_DATA_SIZE_BYTE;
|
||
|
hperh->hdma.config.dst_data_width = ALD_DMA_DATA_SIZE_BYTE;
|
||
|
hperh->hdma.config.src = (void *)buf;
|
||
|
hperh->hdma.config.dst = (void *)&hperh->perh->DATA;
|
||
|
hperh->hdma.config.size = size;
|
||
|
hperh->hdma.config.src_inc = ALD_DMA_DATA_INC_ENABLE;
|
||
|
hperh->hdma.config.dst_inc = ALD_DMA_DATA_INC_DISABLE;
|
||
|
hperh->hdma.config.msel = ALD_DMA_MSEL_CRC;
|
||
|
hperh->hdma.config.msigsel = ALD_DMA_MSIGSEL_NONE;
|
||
|
hperh->hdma.config.channel = channel;
|
||
|
ald_dma_config_basic(&(hperh->hdma));
|
||
|
ald_dma_interrupt_config(channel, ALD_DMA_IT_FLAG_TC, ENABLE);
|
||
|
|
||
|
__UNLOCK(hperh);
|
||
|
ALD_CRC_DMA_ENABLE(hperh);
|
||
|
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Calculate an amount of data used dma channel,data width is half-word.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @param buf: Pointer to half_word data buffer
|
||
|
* @param res: Pointer to result
|
||
|
* @param size: Amount of half_word data to be Calculate
|
||
|
* @param channel: DMA channel as CRC transmit
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_calculate_halfword_by_dma(ald_crc_handle_t *hperh, uint16_t *buf, uint32_t *res, uint16_t size, uint8_t channel)
|
||
|
{
|
||
|
if (hperh->state != ALD_CRC_STATE_READY)
|
||
|
return ALD_BUSY;
|
||
|
|
||
|
if (buf == NULL || size == 0)
|
||
|
return ALD_ERROR;
|
||
|
|
||
|
__LOCK(hperh);
|
||
|
MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, ALD_CRC_DATASIZE_16 << CRC_CR_DATLEN_POSS);
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_BUSY;
|
||
|
|
||
|
hperh->cal_buf = (uint8_t *)buf;
|
||
|
hperh->cal_res = res;
|
||
|
|
||
|
if (hperh->hdma.perh == NULL)
|
||
|
hperh->hdma.perh = DMA;
|
||
|
|
||
|
hperh->hdma.cplt_tc_arg = (void *)hperh;
|
||
|
hperh->hdma.cplt_tc_cbk = &crc_dma_calculate_cplt;
|
||
|
|
||
|
ald_dma_config_struct(&(hperh->hdma.config));
|
||
|
hperh->hdma.config.src_data_width = ALD_DMA_DATA_SIZE_HALFWORD;
|
||
|
hperh->hdma.config.dst_data_width = ALD_DMA_DATA_SIZE_HALFWORD;
|
||
|
hperh->hdma.config.src = (void *)buf;
|
||
|
hperh->hdma.config.dst = (void *)&hperh->perh->DATA;
|
||
|
hperh->hdma.config.size = size;
|
||
|
hperh->hdma.config.src_inc = ALD_DMA_DATA_INC_ENABLE;
|
||
|
hperh->hdma.config.dst_inc = ALD_DMA_DATA_INC_DISABLE;
|
||
|
hperh->hdma.config.msel = ALD_DMA_MSEL_CRC;
|
||
|
hperh->hdma.config.msigsel = ALD_DMA_MSIGSEL_NONE;
|
||
|
hperh->hdma.config.channel = channel;
|
||
|
ald_dma_config_basic(&(hperh->hdma));
|
||
|
ald_dma_interrupt_config(channel, ALD_DMA_IT_FLAG_TC, ENABLE);
|
||
|
|
||
|
__UNLOCK(hperh);
|
||
|
ALD_CRC_DMA_ENABLE(hperh);
|
||
|
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Calculate an amount of data used dma channel,data width is word.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @param buf: Pointer to word data buffer
|
||
|
* @param res: Pointer to result
|
||
|
* @param size: Amount of word data to be Calculate
|
||
|
* @param channel: DMA channel as CRC transmit
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_calculate_word_by_dma(ald_crc_handle_t *hperh, uint32_t *buf, uint32_t *res, uint16_t size, uint8_t channel)
|
||
|
{
|
||
|
if (hperh->state != ALD_CRC_STATE_READY)
|
||
|
return ALD_BUSY;
|
||
|
|
||
|
if (buf == NULL || size == 0)
|
||
|
return ALD_ERROR;
|
||
|
|
||
|
__LOCK(hperh);
|
||
|
MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, ALD_CRC_DATASIZE_32 << CRC_CR_DATLEN_POSS);
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_BUSY;
|
||
|
|
||
|
hperh->cal_buf = (uint8_t *)buf;
|
||
|
hperh->cal_res = res;
|
||
|
|
||
|
if (hperh->hdma.perh == NULL)
|
||
|
hperh->hdma.perh = DMA;
|
||
|
|
||
|
hperh->hdma.cplt_tc_arg = (void *)hperh;
|
||
|
hperh->hdma.cplt_tc_cbk = &crc_dma_calculate_cplt;
|
||
|
|
||
|
ald_dma_config_struct(&(hperh->hdma.config));
|
||
|
hperh->hdma.config.src_data_width = ALD_DMA_DATA_SIZE_WORD;
|
||
|
hperh->hdma.config.dst_data_width = ALD_DMA_DATA_SIZE_WORD;
|
||
|
hperh->hdma.config.src = (void *)buf;
|
||
|
hperh->hdma.config.dst = (void *)&hperh->perh->DATA;
|
||
|
hperh->hdma.config.size = size;
|
||
|
hperh->hdma.config.src_inc = ALD_DMA_DATA_INC_ENABLE;
|
||
|
hperh->hdma.config.dst_inc = ALD_DMA_DATA_INC_DISABLE;
|
||
|
hperh->hdma.config.msel = ALD_DMA_MSEL_CRC;
|
||
|
hperh->hdma.config.msigsel = ALD_DMA_MSIGSEL_NONE;
|
||
|
hperh->hdma.config.channel = channel;
|
||
|
ald_dma_config_basic(&(hperh->hdma));
|
||
|
ald_dma_interrupt_config(channel, ALD_DMA_IT_FLAG_TC, ENABLE);
|
||
|
|
||
|
__UNLOCK(hperh);
|
||
|
ALD_CRC_DMA_ENABLE(hperh);
|
||
|
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Pauses the DMA Transfer.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_dma_pause(ald_crc_handle_t *hperh)
|
||
|
{
|
||
|
__LOCK(hperh);
|
||
|
ALD_CRC_DMA_DISABLE(hperh);
|
||
|
__UNLOCK(hperh);
|
||
|
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Resumes the DMA Transfer.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_dma_resume(ald_crc_handle_t *hperh)
|
||
|
{
|
||
|
__LOCK(hperh);
|
||
|
ALD_CRC_DMA_ENABLE(hperh);
|
||
|
__UNLOCK(hperh);
|
||
|
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Stops the DMA Transfer.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval Status, see @ref ald_status_t.
|
||
|
*/
|
||
|
ald_status_t ald_crc_dma_stop(ald_crc_handle_t *hperh)
|
||
|
{
|
||
|
__LOCK(hperh);
|
||
|
ALD_CRC_DMA_DISABLE(hperh);
|
||
|
__UNLOCK(hperh);
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
return ALD_OK;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup CRC_Public_Functions_Group4 Peripheral State and Errors functions
|
||
|
* @brief CRC State and Errors functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Returns the CRC state.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval CRC state
|
||
|
*/
|
||
|
ald_crc_state_t ald_crc_get_state(ald_crc_handle_t *hperh)
|
||
|
{
|
||
|
assert_param(IS_CRC(hperh->perh));
|
||
|
|
||
|
return hperh->state;
|
||
|
}
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/** @defgroup CRC_Private_Functions CRC Private Functions
|
||
|
* @brief CRC Private functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Reset the CRC peripheral.
|
||
|
* @param hperh: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void ald_crc_reset(ald_crc_handle_t *hperh)
|
||
|
{
|
||
|
hperh->perh->DATA = 0x0;
|
||
|
hperh->perh->CR = 0x2;
|
||
|
hperh->perh->SEED = 0xFFFFFFFF;
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
__UNLOCK(hperh);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief DMA CRC calculate process complete callback.
|
||
|
* @param arg: Pointer to a crc_handle_t structure that contains
|
||
|
* the configuration information for the specified CRC module.
|
||
|
* @retval None
|
||
|
*/
|
||
|
static void crc_dma_calculate_cplt(void *arg)
|
||
|
{
|
||
|
ald_crc_handle_t *hperh = (ald_crc_handle_t *)arg;
|
||
|
|
||
|
*(hperh->cal_res) = CRC->CHECKSUM;
|
||
|
ALD_CRC_DMA_DISABLE(hperh);
|
||
|
|
||
|
hperh->state = ALD_CRC_STATE_READY;
|
||
|
|
||
|
if (hperh->cal_cplt_cbk)
|
||
|
hperh->cal_cplt_cbk(hperh);
|
||
|
}
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|