[AVR] Add CRC lld files for ATxmega.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15908 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
7b713b3ded
commit
50e9ab03a3
|
@ -0,0 +1,332 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2022 Theodore Ateba
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file CRCv1/hal_crc_lld.c
|
||||||
|
* @brief XMEGA CRC subsystem low level driver source.
|
||||||
|
*
|
||||||
|
* @addtogroup CRC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
/* Include CRC low level driver header directly for XMEGA specific driver. */
|
||||||
|
#include "hal_crc_lld.h"
|
||||||
|
|
||||||
|
#if HAL_USE_CRC || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/** @brief CRC1 driver identifier. */
|
||||||
|
#if AVR_CRC_USE_CRC1 || defined(__DOXYGEN__)
|
||||||
|
CRCDriver CRCD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the CRC module.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
*/
|
||||||
|
static void crc_enable(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
switch (crcp->config->source) {
|
||||||
|
case CRC_SOURCE_IO:
|
||||||
|
case CRC_SOURCE_FLASH:
|
||||||
|
case CRC_SOURCE_EDMACH0:
|
||||||
|
case CRC_SOURCE_EDMACH1:
|
||||||
|
case CRC_SOURCE_EDMACH2:
|
||||||
|
crcp->crc->CTRL.bit.SOURCE = crcp->config->source;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select CRC16 algorithm for crc computation.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
*/
|
||||||
|
static void crc_select_algo_crc16(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
/* Wait the CRC module to be ready. */
|
||||||
|
while (crcp->crc->STATUS.bit.BUSY);
|
||||||
|
|
||||||
|
/* Enable CRC16 algorithm. */
|
||||||
|
crcp->crc->CTRL.bit.CRC32 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select CRC32 algorithm for crc computation.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
*/
|
||||||
|
static void crc_select_algo_crc32(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
/* Wait the CRC module to be ready. */
|
||||||
|
while (crcp->crc->STATUS.bit.BUSY);
|
||||||
|
|
||||||
|
/* Enable the CRC32 algorithm. */
|
||||||
|
crcp->crc->CTRL.bit.CRC32 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset CRC module.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
* @param[in] rt reset type that need to be used to reset the CRC module.
|
||||||
|
*/
|
||||||
|
static void crc_reset(CRCDriver *crcp, crcreset_t rt) {
|
||||||
|
|
||||||
|
switch (rt) {
|
||||||
|
case CRC_RESET_RESET0:
|
||||||
|
/* Initialize the CRC with all Zeros. */
|
||||||
|
crcp->crc->CTRL.bit.RESET = CRC_RESET_RESET0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CRC_RESET_RESET1:
|
||||||
|
/* Initialize the CRC with all Ones. */
|
||||||
|
crcp->crc->CTRL.bit.RESET = CRC_RESET_RESET1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CRC_RESET_NO:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disabble the CRC module.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
*/
|
||||||
|
static void crc_disable(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
crcp->crc->CTRL.bit.SOURCE = CRC_SOURCE_DISABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the data into the CRC module to perform.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
* @param[in] srcp pointer to the data used to compute CRC.
|
||||||
|
* @parma[in] size lenght of the data used to compute CRC.
|
||||||
|
*/
|
||||||
|
static void crc_lld_load_data(CRCDriver *crcp, uint8_t *srcp, size_t size) {
|
||||||
|
|
||||||
|
uint8_t index = 0;
|
||||||
|
|
||||||
|
for (index = 0; index < size; index++) {
|
||||||
|
crcp->crc->DATAIN.reg = srcp[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the checksum value computed with CRC16 algorithm
|
||||||
|
*
|
||||||
|
* @param crcp pointer to the @p CRCDriver object.
|
||||||
|
* @return retVal the value of the CRC16 computed .
|
||||||
|
*/
|
||||||
|
static uint16_t crc_get_crc16_checksum(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
crc16_t retVal;
|
||||||
|
retVal.crc16 = 0;
|
||||||
|
|
||||||
|
retVal.crc8.byte0 = crcp->crc->CHECKSUM0.reg;
|
||||||
|
retVal.crc8.byte1 = crcp->crc->CHECKSUM1.reg;
|
||||||
|
|
||||||
|
return retVal.crc16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the checksum value computed with CRC32 algorithm
|
||||||
|
*
|
||||||
|
* @param crcp pointer to the @p CRCDriver object.
|
||||||
|
* @return retVal the value of the CRC32 computed.
|
||||||
|
*/
|
||||||
|
static uint32_t crc_get_crc32_checksum(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
crc32_t retVal;
|
||||||
|
|
||||||
|
retVal.crc32 = 0;
|
||||||
|
|
||||||
|
retVal.crc8.byte0 = crcp->crc->CHECKSUM0.reg;
|
||||||
|
retVal.crc8.byte1 = crcp->crc->CHECKSUM1.reg;
|
||||||
|
retVal.crc8.byte2 = crcp->crc->CHECKSUM2.reg;
|
||||||
|
retVal.crc8.byte3 = crcp->crc->CHECKSUM3.reg;
|
||||||
|
|
||||||
|
return retVal.crc32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the standard part of a @p CRCDriver structure.
|
||||||
|
*
|
||||||
|
* @param[out] crcp pointer to the @p CRCDriver object.
|
||||||
|
*
|
||||||
|
* @init
|
||||||
|
*/
|
||||||
|
void crc_lld_object_init(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
crcp->state = CRC_STOP;
|
||||||
|
crcp->config = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low level CRC driver initialization.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void crc_lld_init(void) {
|
||||||
|
|
||||||
|
#if AVR_CRC_USE_CRC1
|
||||||
|
crc_lld_object_init(&CRCD1);
|
||||||
|
CRCD1.crc = CRC;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures and activates the CRC peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void crc_lld_start(CRCDriver *crcp, CRCConfig *config) {
|
||||||
|
|
||||||
|
/* Copy the config to the CRC driver config. */
|
||||||
|
crcp->config = config;
|
||||||
|
|
||||||
|
/* CRC source I/O interface only support CRC16 algorithm. */
|
||||||
|
if (crcp->config->source == CRC_SOURCE_IO) {
|
||||||
|
crc_select_algo_crc16(crcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CRC source Flash Memory only support CRC32 algorithm. */
|
||||||
|
else if (crcp->config->source == CRC_SOURCE_FLASH) {
|
||||||
|
crc_select_algo_crc32(crcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CRC source DMA support both CRC16 and CRC32. */
|
||||||
|
else {
|
||||||
|
if (crcp->config->algo == CRC_TYPE_CRC16) {
|
||||||
|
crc_select_algo_crc16(crcp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
crc_select_algo_crc32(crcp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable the CRC module. */
|
||||||
|
crc_enable(crcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deactivates the CRC peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void crc_lld_stop(CRCDriver *crcp) {
|
||||||
|
|
||||||
|
crc_disable(crcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the CRC module with all checksum byte to 0x00.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
* @param[in] rt reset type use to initialize the checksum all to zeros or ones.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void crc_lld_reset(CRCDriver *crcp, crcreset_t rt) {
|
||||||
|
|
||||||
|
crc_reset(crcp, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute the CRC16 on data IO interface.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
* @param[in] srcp pointer of data used to compute CRC16.
|
||||||
|
* @param[in] size length of data used to compute CRC16.
|
||||||
|
* @return retVal result of CRC16 operation.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
uint16_t crc_lld_compute_crc16_on_data(CRCDriver *crcp, uint8_t *srcp, size_t size) {
|
||||||
|
|
||||||
|
uint16_t retVal = 0;
|
||||||
|
|
||||||
|
/* Load data to compute the CRC16. */
|
||||||
|
crc_lld_load_data(crcp, srcp, size);
|
||||||
|
|
||||||
|
/* Read the computed CRC result. */
|
||||||
|
retVal = crc_get_crc16_checksum(crcp);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute the CRC32 on data IO interface.
|
||||||
|
*
|
||||||
|
* @param[in] crcp pointer to the @p CRCDriver object.
|
||||||
|
* @param[in] srcp pointer of data used to compute CRC32.
|
||||||
|
* @param[in] size length of data used to compute CRC32.
|
||||||
|
* @return retVal result of CRC32 operation.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
uint32_t crc_lld_compute_crc32_on_data(CRCDriver *crcp, uint8_t *srcp, size_t size) {
|
||||||
|
|
||||||
|
uint32_t retVal = 0;
|
||||||
|
|
||||||
|
/* Load data to compute the CRC32. */
|
||||||
|
crc_lld_load_data(crcp, srcp, size);
|
||||||
|
|
||||||
|
/* Read the computed CRC result. */
|
||||||
|
retVal = crc_get_crc32_checksum(crcp);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAL_USE_CRC */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2022 Theodore Ateba
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file CRCv1/hal_crc_lld.h
|
||||||
|
* @brief XMEGA CRC low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup CRC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_CRC_LLD_H
|
||||||
|
#define HAL_CRC_LLD_H
|
||||||
|
|
||||||
|
#include "xmega_crc.h"
|
||||||
|
|
||||||
|
#if HAL_USE_CRC || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief CRC1 driver enable switch.
|
||||||
|
* @note The default is @p FALSE.
|
||||||
|
*/
|
||||||
|
#if !defined(AVR_CRC_USE_CRC1) || defined(__DOXYGEN__)
|
||||||
|
#define AVR_CRC_USE_CRC1 FALSE
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
/**
|
||||||
|
* @brief Driver state machine possible states.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CRC_UNINIT = 0, /**< Not initialized. */
|
||||||
|
CRC_STOP, /**< Stopped. */
|
||||||
|
CRC_READY /**< Ready. */
|
||||||
|
} crcstate_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CRC available sources.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CRC_SOURCE_DISABLE = 0, /* CRC disable. */
|
||||||
|
CRC_SOURCE_IO = 1, /* I/O interface. */
|
||||||
|
CRC_SOURCE_FLASH = 2, /* Flash. */
|
||||||
|
CRC_SOURCE_EDMACH0 = 4, /* EDMA controller channel 0. */
|
||||||
|
CRC_SOURCE_EDMACH1 = 5, /* EDMA controller channel 1. */
|
||||||
|
CRC_SOURCE_EDMACH2 = 6, /* EDMA controller channel 2. */
|
||||||
|
CRC_SOURCE_EDMACH3 = 7 /* EDMA controller channel 3. */
|
||||||
|
} crcsource_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Available CRC polynomial algorithme.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CRC_TYPE_CRC16 = 0, /* CRC 16 = CRC-CCITT. */
|
||||||
|
CRC_TYPE_CRC32 /* CRC 32 = IEEE 802.3. */
|
||||||
|
} crcalgo_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CRC available reset method.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CRC_RESET_NO = 0, /* No reset. */
|
||||||
|
CRC_RESET_RESET0 = 2, /* Reset all CRC with checksum to all zeros. */
|
||||||
|
CRC_RESET_RESET1 = 3 /* Reset all CRC with checksum to all ones. */
|
||||||
|
} crcreset_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Driver configuration structure.
|
||||||
|
* @note It could be empty on some architectures.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
crcsource_t source;
|
||||||
|
crcalgo_t algo;
|
||||||
|
} CRCConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure representing an CRC driver.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Driver state.
|
||||||
|
*/
|
||||||
|
crcstate_t state;
|
||||||
|
/**
|
||||||
|
* @brief Current configuration data.
|
||||||
|
*/
|
||||||
|
const CRCConfig *config;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the CRC registers block.
|
||||||
|
*/
|
||||||
|
xmega_crc_t *crc;
|
||||||
|
} CRCDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type used while reading CRC16 result.
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
uint16_t crc16;
|
||||||
|
struct {
|
||||||
|
uint16_t byte0 : 8;
|
||||||
|
uint16_t byte1 : 8;
|
||||||
|
} crc8;
|
||||||
|
} crc16_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type used while reading CRC32 result.
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
uint32_t crc32;
|
||||||
|
struct {
|
||||||
|
uint32_t byte0 : 8;
|
||||||
|
uint32_t byte1 : 8;
|
||||||
|
uint32_t byte2 : 8;
|
||||||
|
uint32_t byte3 : 8;
|
||||||
|
} crc8;
|
||||||
|
} crc32_t;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if AVR_CRC_USE_CRC1 && !defined(__DOXYGEN__)
|
||||||
|
extern CRCDriver CRCD1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void crc_lld_object_init(CRCDriver *crcp);
|
||||||
|
void crc_lld_init(void);
|
||||||
|
void crc_lld_start(CRCDriver *crcp, CRCConfig *config);
|
||||||
|
void crc_lld_stop(CRCDriver *crcp);
|
||||||
|
void crc_lld_reset(CRCDriver *crcp, crcreset_t rt);
|
||||||
|
uint16_t crc_lld_compute_crc16_on_data(CRCDriver *crcp, uint8_t *srcp, size_t size);
|
||||||
|
uint32_t crc_lld_compute_crc32_on_data(CRCDriver *crcp, uint8_t *srcp, size_t size);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_CRC */
|
||||||
|
|
||||||
|
#endif /* HAL_CRC_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
Loading…
Reference in New Issue